# How OfficeCLI's Three-Layer Architecture Works: L1, L2, and L3 Explained

> Explore OfficeCLI's three-layer architecture (L1, L2, L3). Understand semantic views, DOM manipulation, and XPath access for Office XML automation in the iOfficeAI/OfficeCLI project.

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

---

**OfficeCLI implements a progressive three-layer architecture where L1 provides semantic document views, L2 offers DOM-like element manipulation, and L3 exposes raw XPath access to Office XML, allowing developers to choose the appropriate abstraction level for their automation tasks.**

The iOfficeAI/OfficeCLI repository structures document interaction through a clean, three-layer architecture that separates reading, manipulation, and low-level access concerns. This design enables both human developers and AI agents to work with Word, Excel, and PowerPoint files at exactly the right level of abstraction. Understanding how OfficeCLI's three-layer architecture works ensures you select the most efficient and safe approach for each document operation.

## Overview of the Three Layers

OfficeCLI organizes commands into three progressively lower-level layers, documented in [`README.md`](https://github.com/iOfficeAI/OfficeCLI/blob/main/README.md) at lines 342-347. Each layer serves distinct use cases while building upon the capabilities of the underlying implementation.

### Layer 1 (L1) – Semantic Read Layer

**Layer 1** provides read-only, semantic views of Office documents without exposing underlying XML complexity. This layer parses files into high-level models suitable for human inspection and AI processing, offering commands like `view` that generate plain text, outlines, annotated HTML, and document statistics.

```bash
officecli view report.docx annotated
officecli view deck.pptx html

```

These commands transform complex binary formats into accessible representations, making L1 ideal for content extraction, preview generation, and automated reporting workflows where modification is not required.

### Layer 2 (L2) – DOM Manipulation Layer

**Layer 2** exposes a structured element model that enables precise querying and mutation while abstracting raw XML details. According to the source documentation, this layer supports commands including `get`, `query`, `set`, `add`, `remove`, `move`, and `swap`, operating on DOM-like paths that reference document elements directly.

```bash
officecli set report.docx /body/p[1] --prop bold=true
officecli add deck.pptx /slide[1] --type shape --prop text="Revenue ↑"

```

The first example updates paragraph formatting using an element path, while the second injects a new shape into a specific PowerPoint slide. L2 strikes a balance between power and safety by handling XML namespace complexities internally while allowing fine-grained document surgery.

### Layer 3 (L3) – Raw XML Access Layer

**Layer 3** provides direct XPath access to the underlying Office Open XML, serving as a universal fallback when higher-level operations prove insufficient. This layer handles commands such as `raw`, `raw-set`, `add-part`, and `validate`, requiring knowledge of specific XML schemas like WordprocessingML or PresentationML.

```bash
officecli raw-set report.docx document --xpath "//w:p[1]" --action append --xml '<w:r><w:t>Injected text</w:t></w:r>'

```

This example directly injects a new run into the first paragraph using XPath, bypassing the DOM abstraction entirely. While L3 offers maximum flexibility for edge cases, it carries higher risk of document corruption and requires understanding of Office XML standards.

## How the Layers Interact in Practice

The architecture follows a **progressive disclosure** pattern: start with the simplest, most expressive API (L1) and only descend to L2 or L3 when necessary. This design keeps common use cases straightforward while preserving full control for complex automation scenarios.

The watch-mode implementation in [`src/officecli/Core/Watch/WatchServer.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Core/Watch/WatchServer.cs) demonstrates explicit layer coupling between L1 and L2. According to lines 81-86 of this file, Layer 1 manages Server-Sent Events (SSE) connections and core DOM updates, while Layer 2 handles UI overlays including selection boxes, rubber-banding, and CSS injection.

The coupling mechanism uses a hook pattern: Layer 1 calls `window._watchReapplyHook()` after each DOM mutation, and Layer 2 provides this hook implementation to re-apply visual decorations. This separation ensures that document rendering (L1) remains independent of presentation enhancements (L2) while maintaining synchronization.

Key implementation files include:
- [`src/officecli/Resources/watch-sse-core.js`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Resources/watch-sse-core.js) – Implements SSE connections and DOM diff/patch logic for Layer 1
- [`src/officecli/Resources/watch-overlay.js`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Resources/watch-overlay.js) – Adds UI decorations and selection marks for Layer 2

## Practical Examples by Layer

Each layer addresses specific document automation needs through distinct command patterns.

**L1 – Content Extraction:**

```bash
officecli view contract.docx plain > contract.txt

```

Extracts clean text for NLP processing or diff comparisons without risking document corruption.

**L2 – Structured Modification:**

```bash
officecli query report.docx "//table[1]/row" --format json
officecli remove deck.pptx /slide[5]

```

Queries table structures as JSON or removes specific slides using DOM-aware operations.

**L3 – Emergency XML Surgery:**

```bash
officecli validate document.docx --strict
officecli raw document.docx --xpath "//w:docPr" --namespace w=http://schemas...

```

Validates XML integrity or extracts specific properties unavailable through L2 abstractions.

## Summary

- OfficeCLI's three-layer architecture separates document access into **L1** (semantic read), **L2** (DOM manipulation), and **L3** (raw XML) abstraction levels
- **Layer 1** commands like `view` provide human-readable outputs without exposing XML complexity, ideal for extraction and preview workflows
- **Layer 2** enables structured element operations through commands such as `set`, `add`, and `remove` using DOM-like paths that abstract XML details
- **Layer 3** offers direct XPath access via `raw-set` for edge cases requiring precise XML control, though it requires schema knowledge
- The watch-mode implementation in [`WatchServer.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/WatchServer.cs) demonstrates explicit coupling between layers through the `window._watchReapplyHook()` function, maintaining clean separation while allowing coordinated updates

## Frequently Asked Questions

### What is the difference between OfficeCLI's L2 and L3 layers?

**Layer 2** operates on a DOM-like abstraction that hides XML namespace complexities and provides structured element methods like `set` and `add`. **Layer 3** removes this abstraction entirely, offering direct XPath queries against raw Office Open XML. While L2 protects you from XML schema details and validation risks, L3 handles edge cases—such as manipulating custom XML parts or unsupported schema elements—that L2 cannot express.

### When should I use Layer 1 versus Layer 2 commands?

Use **Layer 1** (`view` commands) when extracting content, generating reports, or previewing documents without modification. Use **Layer 2** (`get`, `set`, `add`, `remove`) when modifying specific document elements like paragraphs, tables, or slides. The progressive architecture encourages starting with L1 for inspection, then using L2 for targeted modifications, and only resorting to L3 when necessary for unsupported operations.

### Is the three-layer architecture available for all Office formats supported by OfficeCLI?

Yes, the architecture applies uniformly across Word (.docx), Excel (.xlsx), and PowerPoint (.pptx) files. However, specific DOM paths and XML schemas differ by format. For example, Word uses paragraph paths like `/body/p[1]`, while PowerPoint references slides like `/slide[1]`. The command structure (`view`, `set`, `raw-set`) remains consistent across formats, but path syntax and available properties vary according to each format's schema.

### How does watch mode demonstrate the interaction between L1 and L2?

The watch server in [`src/officecli/Core/Watch/WatchServer.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Core/Watch/WatchServer.cs) separates concerns by assigning **Layer 1** to handle core document rendering and SSE streaming, while **Layer 2** manages UI overlays and selection decorations. After each DOM mutation, Layer 1 explicitly calls `window._watchReapplyHook()` (provided by Layer 2) to refresh visual decorations. This hook-based communication illustrates how higher layers can extend lower layer functionality without tight coupling or shared implementation details.