# How the OfficeCLI Watch Command Provides Live Browser Preview with Auto-Refresh

> Discover how the OfficeCLI watch command delivers live browser preview and auto-refresh. It uses an SSE server and named-pipe IPC for seamless real-time HTML updates without file-lock issues.

- Repository: [OfficeAI/OfficeCLI](https://github.com/iofficeai/OfficeCLI)
- Tags: how-to-guide
- Published: 2026-07-13

---

**The OfficeCLI watch command launches a lightweight Server-Sent Events (SSE) server that broadcasts HTML snapshots to connected browsers via named-pipe IPC, enabling real-time updates without file-lock contention.**

The `iOfficeAI/OfficeCLI` repository provides a command-line interface for manipulating Microsoft Office documents. Its `watch` feature creates a self-contained preview environment that automatically refreshes browser views whenever the underlying document changes, without requiring manual reloads or suffering from file-lock conflicts.

## Architecture of the Live Preview System

The live preview system operates as a multi-process architecture that separates document mutation from rendering. This design prevents the watch server from locking the Office file while still providing instantaneous visual feedback.

### The SSE Relay Server

At the core of the system is `WatchServer`, implemented in [`src/officecli/Core/Watch/WatchServer.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Core/Watch/WatchServer.cs). This lightweight TCP listener serves HTTP on `localhost:26315` by default and maintains an in-memory HTML cache of the document state.

The server embeds two JavaScript resources—[`watch-sse-core.js`](https://github.com/iOfficeAI/OfficeCLI/blob/main/watch-sse-core.js) and [`watch-overlay.js`](https://github.com/iOfficeAI/OfficeCLI/blob/main/watch-overlay.js)—which it injects into every served page. These handle the client-side EventSource connection and overlay UI features like marks and selection indicators. As implemented in the source, the server never opens the Office document directly; it only operates on HTML snapshots passed via inter-process communication.

## Initial HTML Rendering

When you execute `officecli watch mydoc.docx`, the command first attempts to obtain an HTML view through the resident daemon process. According to [`src/officecli/CommandBuilder.Watch.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/CommandBuilder.Watch.cs) (lines 34-70), the code calls `ResidentClient.TrySend` to request a pre-rendered snapshot from the long-running `officecli` service.

If the resident process is unavailable, the watch command falls back to opening the document directly using the appropriate handler—`PowerPointHandler`, `ExcelHandler`, or `WordHandler`—and invokes `RenderViaRegistry` to generate the initial HTML. This snapshot is then cached in memory within the `WatchServer` instance.

## Real-Time Update Mechanism via Named Pipes

All other OfficeCLI commands that modify documents—such as `set`, `add`, or `remove`—communicate with the watch server through a named pipe. The `WatchNotifier` class in [`src/officecli/Core/Watch/WatchNotifier.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Core/Watch/WatchNotifier.cs) (lines 15-25) opens the pipe `officecli-watch-<hash>` and transmits JSON messages describing the change.

These messages support two update modes:

- **Full HTML replacement** – Contains a complete `FullHtml` snapshot that replaces the entire document view
- **Incremental patching** – Provides slide-specific or block-level mutations (fields: `replace`, `add`, `remove` plus slide numbers)

When `WatchServer.RunPipeListenerAsync` detects an incoming connection, `HandleSinglePipeClientAsync` parses the JSON via `HandleWatchMessage`. If `FullHtml` is present, it updates `_currentHtml` directly. For patches, it applies methods like `PatchSlideInHtml`, `AppendSlideToHtml`, or `RemoveSlideFromHtml` to mutate the cached HTML. After updating the snapshot, the server increments an internal version counter and broadcasts the change via `SendSseEvent`.

## Client-Side DOM Synchronization

The embedded [`watch-sse-core.js`](https://github.com/iOfficeAI/OfficeCLI/blob/main/watch-sse-core.js) script establishes an `EventSource` connection back to the server. Upon receiving SSE messages, it parses the `action` field and applies updates to the DOM:

- **Full refresh** – Replaces the entire `<body>` element with the new HTML
- **Slide-level updates** – For PowerPoint documents, patches individual slide elements by ID
- **Word block updates** – Computes block-level diffs using `ComputeWordPatches` for granular text updates
- **Auto-scroll** – If the SSE message includes a `scroll` selector, the script scrolls the viewport to the target element

The companion [`watch-overlay.js`](https://github.com/iOfficeAI/OfficeCLI/blob/main/watch-overlay.js) handles auxiliary UI features including visual marks, selection rectangles, and rubber-band highlighting, all synchronized through the same SSE channel.

## Configuration and Usage

Start a watch session with automatic port assignment:

```bash

# Start watching a Word document (default port 26315)

officecli watch mydoc.docx

```

The command outputs a URL like `Watch: http://localhost:26315`. Opening this in any browser connects you to the live preview.

Modify the document in another terminal:

```bash

# Update text content - triggers automatic browser refresh

officecli set mydoc.docx --text "Hello, world!"

# Add a visual mark in the preview

officecli watch mark mydoc.docx "/body/p[1]" --color "#ff0000" --note "Important"

```

The watch server supports environment-based configuration:

- **`OFFICECLI_WATCH_IDLE_SECONDS`** – Configures the idle timeout (default: 300 seconds). If no browser remains connected for this duration, `WatchServer` triggers graceful shutdown via `StopAsync`, closing TCP sockets and cleaning up the on-disk marker file.
- **Signal handling** – The server captures SIGTERM, SIGHUP, SIGQUIT, and Ctrl-C to ensure clean termination.

## Summary

- **Server-Sent Events** provide the transport mechanism for live updates, with `WatchServer` acting as the SSE relay.
- **Named-pipe IPC** (`officecli-watch-<hash>`) allows mutation commands to push changes without file-lock conflicts.
- **Incremental HTML patching** minimizes bandwidth and DOM manipulation for large presentations.
- **Embedded JavaScript resources** handle DOM synchronization, scrolling, and UI overlays client-side.
- **Resident process fallback** ensures the initial render succeeds even when the daemon is unavailable.

## Frequently Asked Questions

### How does the watch server avoid locking the Office document?

The `WatchServer` process never opens the actual `.docx`, `.pptx`, or `.xlsx` file. Instead, it receives HTML snapshots through the named pipe from other `officecli` processes that perform the document manipulation. This architecture, visible in [`WatchServer.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/WatchServer.cs), ensures the preview server remains completely decoupled from file I/O operations.

### What happens if I edit the document while the watch server is running?

Any `officecli` command that modifies the document—such as `set`, `add`, or `remove`—automatically notifies the watch server via `WatchNotifier.Send`. The command opens the named pipe, transmits a JSON message describing the change, and the server broadcasts an SSE event to all connected browsers, triggering an immediate DOM update without requiring a manual refresh.

### Can I use the watch feature without the resident daemon process?

Yes. While [`CommandBuilder.Watch.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/CommandBuilder.Watch.cs) first attempts to use `ResidentClient.TrySend` for the initial HTML snapshot to improve performance, the watch command gracefully falls back to direct document rendering via `RenderViaRegistry` if the daemon is unavailable. This ensures the preview works in standalone mode.

### How do I configure the auto-shutdown timeout?

Set the `OFFICECLI_WATCH_IDLE_SECONDS` environment variable before starting the watch server. The default value is 300 seconds (5 minutes). When configured, `WatchServer` monitors active SSE connections in its idle watchdog loop (lines 55-73 in [`WatchServer.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/WatchServer.cs)) and calls `StopAsync` to terminate cleanly if no clients remain connected past the threshold.