# How OfficeCLI's Architecture Caters to AI Agents: A Two-Layer Design

> Discover OfficeCLI's two-layer architecture enabling AI agents to read, manipulate, and annotate documents via global hooks and an event-driven SSE interface without DOM interference.

- Repository: [OfficeAI/OfficeCLI](https://github.com/iofficeai/OfficeCLI)
- Tags: architecture
- Published: 2026-07-22

---

**OfficeCLI employs a two-layer front-end architecture that cleanly separates document rendering from interactive overlays, exposing global hooks and an event-driven SSE interface that allows AI agents to read, manipulate, and annotate documents without touching internal DOM details.**

OfficeCLI, developed by iOfficeAI, is structured specifically to support automated interactions. Its design allows AI agents to integrate seamlessly with Word, Excel, and PowerPoint documents through a predictable JavaScript API. The architecture splits responsibilities between core rendering and visual decoration, ensuring that programmatic changes and user interactions remain synchronized.

## The Two-Layer Architecture

OfficeCLI's front-end consists of distinct layers that handle different aspects of document interaction. This separation enables AI agents to target specific functionalities without interfering with unrelated systems.

### Layer 1 – Core Rendering

Layer 1 manages all document-level mutations and server communication. Located in [`src/officecli/Resources/watch-sse-core.js`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Resources/watch-sse-core.js), this layer opens an `EventSource` connection to `/events` and processes Server-Sent Events (SSE) containing document updates.

The core responsibilities include:
- Receiving SSE messages describing full-document swaps, incremental `word-patch`, `excel-patch`, or `scroll` actions
- Performing DOM updates such as replacing the document body, inserting or removing slides, and applying patches
- Maintaining a `_clientVersion` counter to track document state
- Exposing `window._watchEs` (the EventSource instance) and `window._watchReapplyHook` for cross-layer coordination

When Layer 1 detects a version mismatch between the local `_clientVersion` and an incoming message's `baseVersion`, it gracefully falls back to `wordDiffUpdate` or a full reload to prevent stale data operations.

### Layer 2 – Overlay & Decoration

Layer 2 handles user interactions and visual annotations without touching the underlying document content. Implemented in [`src/officecli/Resources/watch-overlay.js`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Resources/watch-overlay.js), this layer manages selections, marks, and highlighting.

Key functions include:
- Listening to the same `EventSource` for `selection-update` and `mark-update` events
- Maintaining local copies of current selections (`_selection`) and marks (`_marks`)
- Drawing CSS-styled overlays for Excel-style range selections
- Handling click, drag, and rubber-band interactions
- Registering `window._watchReapplyHook = reapplyDecorations` so Layer 1 can request overlay refresh after DOM mutations

## Global APIs for AI Integration

The architecture exposes specific global objects that serve as the primary interface for AI agents. These APIs abstract away internal implementation details while providing full control over document state and visualization.

```javascript
// Layer 1 - Core connection
window._watchEs            // EventSource for receiving server updates

// Layer 2 - Decoration control  
window._officecliReapplyDecorations   // Re-apply selection/marks after DOM swap
window._officecliSetMarks(arr)        // Replace current mark list
window._officecliGetMarks()           // Retrieve marks for inspection

```

AI agents can subscribe to `window._watchEs` for real-time updates or invoke the decoration APIs to manage visual annotations programmatically.

## Event-Driven Communication Flow

OfficeCLI uses Server-Sent Events (SSE) as the backbone for AI-to-document communication. The server pushes updates through the EventSource, while the client maintains state consistency through versioning hooks.

### Versioning and Gap Detection

Layer 1 tracks document versions to ensure AI agents operate on current data. When an AI agent triggers a mutation, the system checks `baseVersion` against `_clientVersion`. If they mismatch, Layer 1 automatically requests a full diff or reload rather than applying partial updates to stale content.

### The Re-apply Hook Mechanism

After every DOM mutation, Layer 1 executes `window._watchReapplyHook()`. Layer 2 implements this as `reapplyDecorations()`, ensuring that AI-driven highlights and selections persist even when the underlying HTML is completely swapped. This guarantees visual annotations remain synchronized with document changes.

## Practical Implementation Examples

### Listening to SSE Events from an AI Agent

Subscribe to document changes and react to selection updates in real time:

```javascript
const es = window._watchEs;
es.addEventListener('update', e => {
  const msg = JSON.parse(e.data);
  if (msg.action === 'selection-update') {
    console.log('Server selection changed:', msg.paths);
  }
});

```

### Adding Custom Marks Programmatically

Define and apply visual highlights using the declarative mark system. Marks are stored as JSON objects and rendered via CSS spans:

```javascript
const myMark = {
  id: 'todo-highlight',
  path: '/sheet1',
  find: 'TODO',
  color: '#ffeb3b',
  note: 'Unresolved task',
  stale: false
};

window._officecliSetMarks([myMark]);

```

### Triggering Document Mutations

AI agents can initiate structural changes by sending commands to the server, which then pushes updates through the SSE stream:

```javascript
fetch('/api/send', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    action: 'replace',
    slide: 3,
    html: '<div class="slide-container" data-slide="3">…new content…</div>'
  })
});

```

### Forcing Decoration Re-application

After batch mutations, ensure overlays remain synchronized:

```javascript
window._officecliReapplyDecorations();

```

## Key Source Files

Understanding the following files is essential for extending AI capabilities:

- **[`src/officecli/Resources/watch-sse-core.js`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Resources/watch-sse-core.js)**: Handles SSE connections, parses update messages, performs DOM mutations, manages versioning, and invokes the re-apply hook.
- **[`src/officecli/Resources/watch-overlay.js`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Resources/watch-overlay.js)**: Implements selection handling, mark rendering, rubber-band dragging, and registers the re-apply hook used by Layer 1.
- **[`src/officecli/Resources/preview.js`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Resources/preview.js)**: Provides lightweight read-only document previews for AI agents requiring observation-only access.
- **[`npm/officecli.js`](https://github.com/iOfficeAI/OfficeCLI/blob/main/npm/officecli.js)**: Entry point that launches the web UI and initializes the server feeding the SSE stream.

## Summary

- OfficeCLI implements a **two-layer architecture** separating document mutations (Layer 1) from visual decorations (Layer 2).
- **Global APIs** like `window._watchEs` and `window._officecliSetMarks()` provide AI agents with event-driven interfaces.
- **Version tracking** (`_clientVersion`) and gap detection prevent operations on stale document fragments.
- The **re-apply hook** ensures AI-generated highlights and selections persist across DOM updates.
- All functionality is accessible through standard JavaScript without requiring DOM manipulation knowledge.

## Frequently Asked Questions

### How does the separation of concerns benefit AI agents?

The split allows AI agents to focus on specific tasks without side effects. Agents modifying document structure interact only with Layer 1's SSE interface, while those managing annotations use Layer 2's mark APIs. This prevents visual updates from interfering with content mutations and vice versa.

### What happens if an AI agent triggers a mutation while the user is editing?

Layer 1's versioning system detects conflicts through `baseVersion` comparison. If the local `_clientVersion` differs from the incoming message's base version, the system falls back to `wordDiffUpdate` or a full reload rather than applying patches to outdated content, ensuring consistency.

### Can AI agents add visual annotations without modifying document content?

Yes. Through `window._officecliSetMarks()`, agents can create highlights, notes, and selections using JSON mark objects. These render as CSS overlays via Layer 2 without altering the underlying document HTML, allowing non-destructive annotation workflows.

### Which files should developers inspect to extend AI capabilities?

Start with [`src/officecli/Resources/watch-sse-core.js`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Resources/watch-sse-core.js) for document mutation logic and [`src/officecli/Resources/watch-overlay.js`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Resources/watch-overlay.js) for annotation systems. For CLI integration points, examine [`npm/officecli.js`](https://github.com/iOfficeAI/OfficeCLI/blob/main/npm/officecli.js) to understand how the server initializes the SSE streams that power AI interactions.