OfficeCLI Watch Command Live HTML Preview Auto-Refresh: Architecture and Usage
The officecli watch command launches a Server-Sent Events (SSE) relay server that pushes HTML updates to your browser automatically whenever the document changes, using named pipes for IPC and embedded JavaScript for DOM diffing.
The OfficeCLI watch command live HTML preview auto-refresh feature transforms document editing into a real-time web experience. Found in the iOfficeAI/OfficeCLI repository, this subsystem renders Word, Excel, and PowerPoint files as HTML and updates the browser instantly on every modification. The architecture cleanly separates document handling from network transmission through a three-layer design involving CLI orchestration, an SSE relay server, and client-side JavaScript overlays.
Architecture Overview
The implementation spans three tightly-coupled layers that ensure the browser preview stays synchronized with your document without requiring manual refreshes.
CLI Orchestration Layer (CommandBuilder.Watch.cs)
The entry point lives in src/officecli/CommandBuilder.Watch.cs (lines 12-34), where the watch command parses arguments and initializes the rendering pipeline.
Argument handling expects a file path and an optional --port flag (default 26315). The system first attempts to obtain HTML via a resident process (ResidentClient.TrySend) using mode=html and Json=true. If no resident process exists, it falls back to DocumentHandlerFactory.Open followed by RenderViaRegistry to generate the initial HTML snapshot.
Once rendering completes, the code creates a WatchServer instance with the file path, chosen port, and initial HTML. The entire lifecycle wraps in SafeRun to guarantee clean shutdown on SIGINT or SIGTERM.
SSE Relay Server (WatchServer.cs)
The WatchServer class in src/officecli/Core/Watch/WatchServer.cs (lines 16-30) functions as a pure SSE relay that never touches the document file directly. It receives pre-rendered HTML through a named pipe (WatchNotifier) and forwards updates to connected browsers via Server-Sent Events.
Key server responsibilities include:
- Embedded script injection: The
SseScriptContentproperty lazily loadswatch-sse-core.jsandwatch-overlay.jsviaLoadWatchResource, injecting them into the page header to ensure the client possesses the required logic. - State management: The server maintains in-memory selection (
_currentSelection) and marks (_currentMarks) protected by_selectionLockand_marksLock, enabling fast queries viaWatchNotifier.GetSelectionand modifications viaWatchNotifier.AddMark. - Idle shutdown: The
ResolveIdleTimeoutmethod (lines 106-119) reads theOFFICECLI_WATCH_IDLE_SECONDSenvironment variable (default 5 minutes) and terminates the server automatically when no activity occurs. - Robust termination: All shutdown paths—idle timeout,
unwatchcommand, or OS signals—converge on a single_shutdownTaskguarded by_shutdownLock, ensuring the underlyingTcpListenerstops cleanly.
Client-Side Overlay (Embedded JavaScript)
Two embedded JavaScript resources handle the browser-side update mechanism:
Layer 1 – watch-sse-core.js: This script creates the SSE connection, listens for "html" events, and applies DOM diffs using a minimal patch algorithm. It exposes window._watchEs (the EventSource instance) and invokes window._watchReapplyHook after each mutation.
Layer 2 – watch-overlay.js: This script registers window._watchReapplyHook to implement selection handling, mark rendering, and UI decorations such as rubber-band drawing and CSS injection. It communicates back to the server via the named pipe for actions like mark, goto, and unmark.
Starting Watch Sessions and Managing State
To initiate a live preview session, specify the target document and optional port:
# Default port 26315
officecli watch MyReport.docx
# Custom port
officecli watch MyPresentation.pptx --port 3000
While the watch server runs, you can interact with the session through sub-commands:
Mark the current selection (adds an advisory annotation):
officecli watch MyReport.docx mark --color yellow --path /body/p[3]
List all marks:
officecli watch MyReport.docx marks
Navigate to a specific element:
officecli watch MyReport.docx goto --path /body/p[5]
Terminate the session:
officecli unwatch MyReport.docx
Programmatic Integration with WatchNotifier
External tools can push updates to the watch server using the WatchNotifier static API in src/officecli/Core/Watch/WatchNotifier.cs. This named-pipe client provides non-blocking methods that fail silently if no watch process exists, preventing CLI crashes.
// C# example – push a new HTML snapshot programmatically
bool ok = WatchNotifier.SendRefresh(
filePath: @"C:\Docs\MyReport.docx",
html: "<html>…</html>",
version: 42);
Other available methods include GetSelection for querying the current selection, AddMark/RemoveMark for annotation management, and Close for shutting down the server remotely.
Summary
- The OfficeCLI watch command provides live HTML preview auto-refresh for Word, Excel, and PowerPoint documents through a three-layer architecture.
- CommandBuilder.Watch.cs handles CLI argument parsing, initial rendering via resident process or direct handler invocation, and
WatchServerlifecycle management. - WatchServer.cs acts as a pure SSE relay using named pipes for IPC, maintaining in-memory selection and mark state with thread-safe locks.
- The client-side overlay uses
watch-sse-core.jsfor DOM diffing andwatch-overlay.jsfor UI interactions, enabling seamless auto-refresh without page reloads. - Optional environment variable
OFFICECLI_WATCH_IDLE_SECONDScontrols automatic server shutdown (default 5 minutes). - WatchNotifier provides a programmatic API for external tools to send updates, query state, and control the server.
Frequently Asked Questions
How does the auto-refresh mechanism work without reloading the page?
The browser maintains a persistent Server-Sent Events connection to the WatchServer. When the document changes, the CLI sends new HTML through a named pipe to the server, which pushes it to the browser via SSE. The embedded watch-sse-core.js applies a minimal DOM diff patch to update only changed elements, preserving scroll position and selection state.
What happens if the watch server becomes idle?
The server monitors activity through the ResolveIdleTimeout method (lines 106-119 in WatchServer.cs). If no updates, selections, or mark operations occur within the duration specified by OFFICECLI_WATCH_IDLE_SECONDS (default 300 seconds), the server triggers automatic shutdown to free resources. All cleanup operations flow through _shutdownTask to ensure the TCP listener closes properly.
Can I use the watch feature with custom HTML generators?
Yes. While the CLI defaults to the internal DocumentHandlerFactory and registry-based rendering, you can bypass the resident process and inject custom HTML programmatically using WatchNotifier.SendRefresh. This method accepts an arbitrary HTML string and version number, pushing it directly to connected browsers regardless of the source document format.
How do I clean up a running watch server?
Use the unwatch command followed by the file path: officecli unwatch MyReport.docx. This sends a termination signal through the named pipe that triggers the server's _shutdownTask. Alternatively, sending SIGINT (Ctrl+C) to the original watch process or allowing the idle timeout to expire will also terminate the server cleanly.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →