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

> Explore how the OfficeCLI watch command delivers real-time browser previews with auto-refresh. Learn about its SSE streaming and lightweight server for instant updates without file watchers.

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

---

**The `officecli watch` command creates a lightweight HTTP server that streams live document updates to the browser via Server-Sent Events (SSE), enabling instant auto-refresh without external file watchers.**

The `iOfficeAI/OfficeCLI` repository implements a self-contained live preview system that eliminates the need for traditional file-watching utilities. When you invoke the **OfficeCLI watch command**, it initializes a multi-layered architecture combining a C#-based HTTP server, named-pipe IPC, and browser-side JavaScript to deliver real-time browser preview capabilities. This system pushes incremental DOM patches rather than full page reloads, ensuring near-instantaneous visual feedback as you modify Office documents.

## CLI-Side Orchestration and Server Initialization

The entry point for the preview functionality resides in [`CommandBuilder.Watch.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/CommandBuilder.Watch.cs). When the user executes `officecli watch <file>`, the command builder constructs a `WatchServer` instance at lines 81-84, supplying the document path, HTTP port (defaulting to 26315), and an optional initial HTML snapshot.

```csharp
// CommandBuilder.Watch.cs (lines 81-84)
var server = new WatchServer(
    documentPath: file,
    port: options.Port,
    initialHtml: residentProcess?.GetHtmlView() ?? RenderDirectly(file)
);
server.Start();

```

If a resident Office process is already running, the CLI requests a rendered HTML view from it; otherwise, it opens the file directly and renders it via the appropriate document handler. This ensures the browser immediately displays the current document state upon connection.

## The Watch Server Process

[`WatchServer.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/WatchServer.cs) hosts a small HTTP endpoint that serves both the preview page and a dedicated **Server-Sent Events (SSE)** endpoint at `/events`. During construction (lines 90-98), the server loads two critical embedded JavaScript resources that handle the client-side update logic:

1. **[`watch-sse-core.js`](https://github.com/iOfficeAI/OfficeCLI/blob/main/watch-sse-core.js)** – Establishes the SSE connection and exposes global hooks
2. **[`watch-overlay.js`](https://github.com/iOfficeAI/OfficeCLI/blob/main/watch-overlay.js)** – Applies fine-grained DOM mutations and re-executes scripts

The server injects these scripts directly into the HTML response sent to the browser, creating a zero-dependency preview environment.

```csharp
// WatchServer.cs – Loading embedded resources (lines 90-98)
var coreJs = LoadWatchResource("Resources.watch-sse-core.js");
var overlayJs = LoadWatchResource("Resources.watch-overlay.js");

await response.WriteAsync($"<script>{coreJs}</script>");
await response.WriteAsync($"<script>{overlayJs}</script>");

```

The server also implements graceful shutdown handling (lines 84-99), ensuring the TCP listener cleans up properly when receiving SIGTERM or SIGINT signals.

## Browser-Side Update Mechanism

### Layer 1: SSE Connection Core

The [`watch-sse-core.js`](https://github.com/iOfficeAI/OfficeCLI/blob/main/watch-sse-core.js) file creates an `EventSource` connection to the `/events` endpoint and exposes it as `window._watchEs`. After every DOM mutation performed by the overlay layer, it invokes `window._watchReapplyHook()` to restore selection highlights and visual marks.

```javascript
// watch-sse-core.js (lines 11-18)
(function () {
    var es = new EventSource('/events');
    window._watchEs = es;
    
    window._watchReapplyHook = function() {
        // Re-applies selection highlights and marks
        restoreSelectionState();
    };
})();

```

### Layer 2: DOM Patching and Script Re-execution

The [`watch-overlay.js`](https://github.com/iOfficeAI/OfficeCLI/blob/main/watch-overlay.js) layer receives JSON messages from the SSE stream and performs surgical DOM updates—including node replacement, insertion, and removal. It re-executes any `<script>` tags found in the updated content to ensure interactive elements function correctly, then calls the re-apply hook established by Layer 1 to synchronize UI decorations like scroll positions and colored marks.

## Bidirectional IPC and Message Flow

The CLI communicates with the running watch server through a **named-pipe client** implemented in [`WatchNotifier.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/WatchNotifier.cs). When document mutations occur (e.g., via `officecli set` or `officecli watch mark`), the notifier serializes a `WatchMessage` to JSON and writes it to the pipe at lines 15-25.

```csharp
// WatchNotifier.cs (lines 15-25)
public void Notify(WatchMessage message)
{
    if (!IsWatchProcessRunning()) return;
    
    using var pipe = new NamedPipeClientStream(".", "OfficeCLIMonitor", 
        PipeDirection.Out);
    pipe.Connect(100); // 100ms timeout
    
    var json = JsonSerializer.Serialize(message);
    using var writer = new StreamWriter(pipe);
    writer.WriteLine(json);
}

```

If no watch process is listening, the notifier silently discards the call. Otherwise, the `WatchServer` receives the payload and forwards it to all connected browser clients via the SSE stream, triggering the DOM patching sequence described above.

## Complete Data Flow Architecture

```

officecli watch <file> ──► WatchServer (HTTP + SSE)
   │                               │
   │ 1. Render initial HTML        │
   │    (resident or direct)       │
   ▼                               ▼
Browser loads preview page      EventSource connects to /events
   │                               │
   │ 2. CLI sends updates via   ──► SSE pushes JSON messages
   │    WatchNotifier (named pipe) │
   ▼                               ▼
watch-overlay.js applies DOM patches,
re-executes scripts, updates selection,
and calls window._watchReapplyHook()

```

Because the preview runs purely in the browser and receives only incremental patches, the page refreshes instantly after each `officecli` modification. No external file-watcher is required; the preview remains "watch-aware" only while the `officecli watch` process is alive.

## Usage Examples

Start a live preview for a presentation on the default port:

```bash
officecli watch my-presentation.pptx

```

While the preview runs, modify the document—the browser updates automatically:

```bash
officecli set slide 2 "Title" "Updated content"

```

Add visual marks to the current selection in the preview window:

```bash
officecli watch mark --color=yellow selected

```

## Summary

- **CommandBuilder.Watch.cs** instantiates the `WatchServer` with document context and port configuration at lines 81-84.
- **WatchServer.cs** hosts an HTTP server with an SSE endpoint at `/events`, serving embedded [`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) resources (lines 90-98).
- **WatchNotifier.cs** enables CLI-to-server communication via named pipes, serializing `WatchMessage` objects to JSON (lines 15-25).
- The browser-side architecture uses two JavaScript layers: one for SSE connection management and one for DOM patching and script re-execution.
- The system pushes incremental updates rather than full page reloads, achieving real-time preview with minimal latency.
- Graceful shutdown handling ensures proper resource cleanup when the watch process terminates (lines 84-99 in WatchServer.cs).

## Frequently Asked Questions

### What port does the OfficeCLI watch server use by default?

The `officecli watch` command defaults to **port 26315** unless overridden with the `--port` flag. You can specify an alternative port when starting the watch server: `officecli watch document.pptx --port 8080`.

### How does the browser connect to the OfficeCLI watch server?

The browser establishes an `EventSource` connection to the `/events` endpoint served by the `WatchServer` instance. This Server-Sent Events (SSE) connection, implemented in [`watch-sse-core.js`](https://github.com/iOfficeAI/OfficeCLI/blob/main/watch-sse-core.js) (lines 11-18), maintains a persistent channel through which the server pushes JSON update messages whenever the document changes.

### Can I use the watch command with any Office document type?

Yes, the architecture supports any document format that OfficeCLI can render to HTML. The [`CommandBuilder.Watch.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/CommandBuilder.Watch.cs) logic either requests an HTML view from a resident Office process or renders the file directly using the appropriate handler, making the preview system agnostic to specific document extensions as long as a rendering backend exists.

### What happens if the watch process is not running when I make changes?

If no watch server is listening, the [`WatchNotifier.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/WatchNotifier.cs) client silently discards the update message after detecting the absence of a named pipe listener. Your CLI commands will still execute successfully, but no browser refresh will occur until you restart the `officecli watch` process and reload the preview page.