iOfficeAI / iOfficeAI/OfficeCLI

watch: preview stuck at "Waiting for first update..." when watch and mutations use different path forms (relative vs absolute)

Open
#294 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
C#
Stars
30.7k
Forks
2.1k
Avg merge
9d 8h
Merged PRs (30d)
5

Description

## Summary

`officecli watch` never pushes the first render (browser stuck at "Waiting for first update... Run an officecli command to see the preview") when the watch command and the mutation commands refer to the same file with **different path forms** (relative vs. absolute).

The watch↔CLI notification pipe name appears to be hashed from the path string **as typed**, without normalizing to an absolute path first. `watch test.pptx` and `set /full/path/test.pptx ...` therefore produce two different pipe names, the mutation notification goes to a pipe nobody listens on, and the browser waits forever.

## Environment

- officecli 1.0.143 (single binary, `~/.local/bin/officecli`)
- macOS 26 (Darwin 25.5.0), Apple Silicon
- Shell: zsh

## Reproduction

```bash
cd /tmp && mkdir watch-repro && cd watch-repro
officecli create test.pptx
officecli add test.pptx / --type slide --prop title="t"

# Terminal A: start watch with a RELATIVE path
officecli watch test.pptx --port 26399

# Terminal B: mutate with an ABSOLUTE path
officecli set /tmp/watch-repro/test.pptx '/slide[1]/shape[1]' --prop text="hello"
```

Open `http://localhost:26399` → page stays at "Waiting for first update..." forever.

Verified matrix (all combinations tested live, SSE `/events` stream captured with curl):

| watch started with | mutation command uses | update pushed? |
|---|---|---|
| relative (`test.pptx`) | absolute (`/tmp/.../test.pptx`) | ❌ never |
| absolute | absolute | ✅ `{"action":"replace",...}` arrives immediately |
| relative | relative (same cwd) | ✅ |

## Evidence

With a mismatched path form, the SSE stream only ever carries the connect-time state events, even after multiple successful `set`/`add` mutations (and a manual `save`):

```
event: update
data: {"action":"selection-update","paths":[]}

event: update
data: {"action":"mark-update","version":0,"marks":[]}
```

With matching path forms the same stream immediately gets `{"action":"replace","slide":1,"version":1,"html":"..."}`.

The pipe registration files in `$TMPDIR` confirm the hash input differs by path form: a running watch registers `CoreFxPipe_officecli-watch-` / `officecli-watch-.port` (containing `\n`), and mutations presumably compute the target pipe name from their own path argument string.

## Suggested fix

Normalize the document path (e.g. `Path.GetFullPath`) before hashing it into the pipe/registry name, on **both** sides: `watch` registration and the mutation-side notify lookup. That makes the notification channel identity path-form-independent.

## Workaround (for users hitting this)

Use the exact same path string for `watch` and all subsequent mutation commands — simplest is to use absolute paths everywhere.

Contributor guide

Open the contributing guide

Research direction

Reproduce the mismatch with the relative and absolute path commands, then locate the watch registration and mutation-side notification lookup that derive the pipe name. Trace how each path is converted before hashing; done means both path forms reach the same pipe and the SSE stream receives the first mutation update.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
cli
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.