@a3s-lab/office 0.37.1 → 0.37.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,365 +1,174 @@
1
1
  <p align="center">
2
- <img src="assets/readme/hero.svg" width="1200" alt="A3S Office five browser editors behind one typed boundary">
2
+ <img src="./assets/readme/hero.svg" width="100%" alt="A3S Office brings five format-native editors into a host-owned product boundary">
3
3
  </p>
4
4
 
5
5
  <p align="center">
6
- <strong>AI-native Office surfaces for the browser, backed by deterministic native automation.</strong>
6
+ <strong>Open-source browser editors and deterministic native automation for real Office files.</strong>
7
7
  </p>
8
8
 
9
9
  <p align="center">
10
- Edit documents, Markdown, spreadsheets, presentations, and PDFs inside your product.<br>
11
- Keep persistence, identity, collaboration, authorization, and AI in your host application.
10
+ Document · Spreadsheet · Presentation · Markdown · PDF
11
+ </p>
12
+
13
+ <p align="center">
14
+ <a href="https://a3s-lab.github.io/Office/playground/"><strong>Open the Playground</strong></a>
15
+ ·
16
+ <a href="https://a3s-lab.github.io/Office/docs/">Read the documentation</a>
17
+ ·
18
+ <a href="#quick-start">Embed an editor</a>
12
19
  </p>
13
20
 
14
21
  <p align="center">
15
22
  <a href="https://github.com/A3S-Lab/Office/actions/workflows/ci.yml"><img alt="CI status" src="https://img.shields.io/github/actions/workflow/status/A3S-Lab/Office/ci.yml?branch=main&amp;style=flat-square&amp;label=CI"></a>
16
- <a href="https://a3s-lab.github.io/Office/playground/"><img alt="Open the live Playground" src="https://img.shields.io/badge/Live_Playground-open-2f6fed?style=flat-square"></a>
17
- <a href="#project-status"><img alt="Project status: pre-1.0" src="https://img.shields.io/badge/status-pre--1.0-7a5bd6?style=flat-square"></a>
18
- <a href="LICENSE"><img alt="MIT License" src="https://img.shields.io/badge/license-MIT-159469?style=flat-square"></a>
23
+ <a href="https://www.npmjs.com/package/@a3s-lab/office"><img alt="npm version" src="https://img.shields.io/npm/v/@a3s-lab/office?style=flat-square&amp;color=1456f0"></a>
24
+ <a href="#project-status"><img alt="Project status: pre-1.0" src="https://img.shields.io/badge/status-pre--1.0-7457c8?style=flat-square"></a>
25
+ <a href="./LICENSE"><img alt="MIT License" src="https://img.shields.io/badge/license-MIT-16845b?style=flat-square"></a>
19
26
  </p>
20
27
 
21
28
  <p align="center">
22
- <a href="https://a3s-lab.github.io/Office/playground/">Playground</a> ·
23
- <a href="https://a3s-lab.github.io/Office/docs/">Documentation</a> ·
29
+ <a href="#proof-not-promises">Product</a> ·
30
+ <a href="#the-core-design">Design</a> ·
24
31
  <a href="#quick-start">Quick start</a> ·
25
- <a href="#editor-capability-comparison">Editors</a> ·
26
- <a href="#real-time-collaboration">Collaboration</a> ·
27
- <a href="#native-automation">Automation</a> ·
28
- <a href="#architecture">Architecture</a> ·
29
- <a href="ROADMAP.md">Capability roadmap</a> ·
30
- <a href="COLLABORATION_ROADMAP.md">Collaboration roadmap</a> ·
31
- <a href="CONTRIBUTING.md">Contributing</a>
32
+ <a href="#collaboration-without-a-bundled-cloud">Collaboration</a> ·
33
+ <a href="#automation-without-ui-scraping">Automation</a> ·
34
+ <a href="#capabilities-and-boundaries">Boundaries</a> ·
35
+ <a href="./ROADMAP.md">Roadmap</a> ·
36
+ <a href="./CONTRIBUTING.md">Contributing</a>
32
37
  </p>
33
38
 
34
39
  ---
35
40
 
36
- A3S Office is an open-source Office engine for product teams that need rich
37
- browser editing and agent-ready file automation without adopting an A3S
38
- backend. It ships complete editor surfaces, typed host contracts, browser file
39
- workflows, and a separate Rust automation plane.
40
-
41
- - **Embed complete editors** through React, Vue 3, Web Components, or the
42
- framework-neutral Core API.
43
- - **Keep format-native behavior** instead of forcing every file through one
44
- lowest-common-denominator model.
45
- - **Own the product boundary**: your application controls content, storage,
46
- permissions, collaboration, and model providers.
47
- - **Collaborate across every editor** with shared Yjs/Yrs content, Awareness
48
- participants and remote locations, plus browser, CLI, MCP, and A3S Code peers.
49
- Document reviewers can submit attributed insertions, deletions, and
50
- replacements without directly changing canonical text. Editors can also
51
- track character- and paragraph-formatting revisions, accept the new
52
- formatting or restore the exact prior marks/properties, and retain either
53
- result in the immutable shared decision audit.
54
- - **Automate deterministically** through the native CLI, standard MCP server,
55
- or packaged Office Skill.
56
-
57
- ## Latest on `main`
58
-
59
- The `0.37.1` release exposes these capabilities as normal user-facing
60
- Playground templates, with matching implementation detail in the documentation:
61
-
62
- | Editor | Latest capability | Public entry |
63
- | --- | --- | --- |
64
- | Presentation | Author, reorder, preview, collaborate on, and play ordered appear, fade, fly-in, and zoom entrance animations with on-click, with-previous, and after-previous triggers; the bounded subset round-trips through native PPTX timing trees | Playground **Latest capabilities → 入场动画** · [Presentation reference](docs/latest/en/components/presentation.mdx#entrance-animations) |
65
- | Writer | Compare the current document with an imported DOCX, HTML, or TXT version and generate deterministic insertion, deletion, character-formatting, and paragraph-formatting revisions; combine a reviewed copy only after exact baseline verification | Playground **Latest capabilities → 文档比较** · [Document reference](docs/latest/en/components/document.mdx#document-compare-and-combine) |
66
- | Writer | Insert, customize, navigate, and explicitly refresh a typed Table of Contents with heading and native outline levels 1–9, hyperlinks, page numbers, alignment, four leader styles, and native DOCX `TOC` round trips | Playground **Latest capabilities → 可更新目录** · [Document reference](docs/latest/en/components/document.mdx#native-table-of-contents) |
67
- | Writer | Mark primary and secondary index terms, cross-references, and bold/italic page numbers; insert, navigate, customize, and refresh a bounded native index with editable DOCX `XE` and `INDEX` round trips | Playground **Latest capabilities → 原生索引** · [Document reference](docs/latest/en/components/document.mdx#native-document-index) |
68
- | Writer | Native character shading with exact `w:shd` patterns, foreground/background color identity, explicit resets, authoring, and DOCX reopen | Playground **Latest capabilities → 字符底纹** · [Document reference](docs/latest/en/components/document.mdx#native-character-shading) |
69
- | Writer | Independent Latin, East Asian, and bidi proofing languages plus explicit `w:noProof` inclusion/exclusion | Playground **Latest capabilities → 校对语言** · [Document reference](docs/latest/en/components/document.mdx#native-proofing-languages) |
70
- | Spreadsheet | Complete common Data Validation input, blank/dropdown, and Stop/Warning/Information error settings with native XLSX round trips | Playground **Latest capabilities → 数据验证** · [Spreadsheet reference](docs/latest/en/components/spreadsheet.mdx#data-validation) |
71
- | Spreadsheet | Native totals-row authoring with per-column aggregates, labels, custom formulas, filtered-row-aware `SUBTOTAL`, automatic calculated-column fill for newly inserted table body rows, and bounded structured-reference calculation across Rust/WASM and JavaScript fallback | Playground **Latest capabilities → 结构化引用** · [Totals-row reference](docs/latest/en/components/spreadsheet.mdx#native-totals-row-authoring) · [Structured-reference calculation](docs/latest/en/components/spreadsheet.mdx#structured-reference-calculation) |
72
- | PDF | Insert, delete, rotate, reorder, extract, merge, and split pages through a dedicated Web Worker, with Blob-level Undo/Redo and independent binary reopen verification | Playground **Latest capabilities → 组织 PDF 页面** · [PDF reference](docs/latest/en/components/pdf.mdx#page-organization) |
73
-
74
- All nine entries are reachable from the first Playground viewport. The
75
- filterable capability gallery groups releases by editor, publishes the source
76
- release on every card, and grows from one shared metadata list instead of a
77
- fixed-width strip. The eight content templates also remain under **新建**;
78
- **组织 PDF 页面** opens the normal PDF file workflow because page organization
79
- must operate on host-provided source bytes.
80
-
81
- ## See it working
82
-
83
- The images below are committed visual-regression baselines from the real
84
- [Playground](https://a3s-lab.github.io/Office/playground/), not conceptual mockups.
41
+ A3S Office is an open-source Office engine for teams building editing into
42
+ their own products. It provides complete browser surfaces for documents,
43
+ spreadsheets, presentations, Markdown, and PDFs, plus a separate Rust
44
+ automation plane for files and coding agents.
45
+
46
+ The product boundary is deliberate: A3S Office owns format-aware editing,
47
+ layout, import, export, and typed mutations. Your application keeps control of
48
+ content, persistence, identity, authorization, collaboration transport, and AI
49
+ providers. Core editing and file workflows require no A3S backend or bundled
50
+ cloud service.
51
+
52
+ ## Proof, not promises
53
+
54
+ These are committed visual-regression baselines from the real
55
+ [Playground](https://a3s-lab.github.io/Office/playground/), not concept art.
85
56
 
86
57
  <p align="center">
87
- <a href="visual-tests/__snapshots__/linux/desktop-1280/document.png">
88
- <img src="visual-tests/__snapshots__/linux/desktop-1280/document.png" alt="A3S Office document editor with a ribbon and paginated project brief" width="1280">
58
+ <a href="./visual-tests/__snapshots__/linux/desktop-1280/document.png">
59
+ <img src="./visual-tests/__snapshots__/linux/desktop-1280/document.png" alt="A3S Office Document editor with an Office-style ribbon and paginated project brief" width="100%">
89
60
  </a>
90
61
  </p>
91
62
 
92
63
  <table>
93
64
  <tr>
94
65
  <td width="50%" valign="top">
95
- <a href="visual-tests/__snapshots__/linux/desktop-1280/spreadsheet.png">
96
- <img src="visual-tests/__snapshots__/linux/desktop-1280/spreadsheet.png" alt="A3S Office spreadsheet editor showing a quarterly execution plan">
66
+ <a href="./visual-tests/__snapshots__/linux/desktop-1280/spreadsheet.png">
67
+ <img src="./visual-tests/__snapshots__/linux/desktop-1280/spreadsheet.png" alt="A3S Office Spreadsheet editor showing a quarterly execution plan">
97
68
  </a>
98
- <br><sub><strong>Spreadsheet</strong> — workbook editing and formula workflows</sub>
69
+ <br><sub><strong>Spreadsheet</strong> — formulas, tables, formatting, sort, filter, and print workflows</sub>
99
70
  </td>
100
71
  <td width="50%" valign="top">
101
- <a href="visual-tests/__snapshots__/linux/desktop-1280/presentation.png">
102
- <img src="visual-tests/__snapshots__/linux/desktop-1280/presentation.png" alt="A3S Office presentation editor with slide thumbnails and a slide canvas">
72
+ <a href="./visual-tests/__snapshots__/linux/desktop-1280/presentation.png">
73
+ <img src="./visual-tests/__snapshots__/linux/desktop-1280/presentation.png" alt="A3S Office Presentation editor with slide thumbnails and a slide canvas">
103
74
  </a>
104
- <br><sub><strong>Presentation</strong> — structured slides, objects, and presenter flows</sub>
75
+ <br><sub><strong>Presentation</strong> — structured slides, objects, animations, and presenter flows</sub>
105
76
  </td>
106
77
  </tr>
107
78
  <tr>
108
79
  <td width="50%" valign="top">
109
- <a href="visual-tests/__snapshots__/linux/desktop-1280/markdown.png">
110
- <img src="visual-tests/__snapshots__/linux/desktop-1280/markdown.png" alt="A3S Office Markdown editor in synchronized source and preview mode">
80
+ <a href="./visual-tests/__snapshots__/linux/desktop-1280/markdown.png">
81
+ <img src="./visual-tests/__snapshots__/linux/desktop-1280/markdown.png" alt="A3S Office Markdown editor in synchronized source and preview mode">
111
82
  </a>
112
- <br><sub><strong>Markdown</strong> — GFM source and synchronized preview</sub>
83
+ <br><sub><strong>Markdown</strong> — GFM source, visual editing, and synchronized preview</sub>
113
84
  </td>
114
85
  <td width="50%" valign="top">
115
- <a href="visual-tests/__snapshots__/linux/desktop-1280/pdf.png">
116
- <img src="visual-tests/__snapshots__/linux/desktop-1280/pdf.png" alt="A3S Office PDF editor with search, annotation, page organization, save, and download controls">
86
+ <a href="./visual-tests/__snapshots__/linux/desktop-1280/pdf.png">
87
+ <img src="./visual-tests/__snapshots__/linux/desktop-1280/pdf.png" alt="A3S Office PDF editor with search, annotation, page organization, save, and download controls">
117
88
  </a>
118
- <br><sub><strong>PDF</strong> — PDFium rendering, forms, annotations, page organization, Yjs overlays, and save</sub>
89
+ <br><sub><strong>PDF</strong> — PDFium rendering, forms, annotations, page organization, and save</sub>
119
90
  </td>
120
91
  </tr>
121
92
  </table>
122
93
 
123
- ## Editor capability comparison
124
-
125
- The tables below compare capability families, not button counts or visual
126
- similarity. **Supported** means the editable path has deterministic tests or
127
- native round-trip evidence. **Partial** means a useful path exists with a
128
- documented fidelity boundary. **Gap** means no product-grade editable path
129
- exists yet. Traditional Office availability varies by application, platform,
130
- edition, and subscription; its column describes the conventional suite
131
- baseline rather than one specific release.
132
-
133
- ### Document
134
-
135
- | Capability | A3S Office today | Traditional Office baseline |
136
- | --- | --- | --- |
137
- | Text, paragraphs, lists, and styles | **Supported** structured editing, independent native ASCII, high ANSI, East Asian, and complex-script font slots with direct/theme identity, independent Latin/East Asian/bidi proofing-language slots and explicit proofing inclusion/exclusion, native all-caps and small-caps effects, exact DOCX character scale plus signed spacing, half-point kerning thresholds, all five native East Asian emphasis marks, native hidden text with explicit visible resets, native character borders with 25 visible line styles plus `nil` and `none`, direct or theme color, width, spacing, shadow, and frame semantics, four independent native outline/shadow/emboss/imprint effects with conflict-safe authoring, and baseline position in one advanced font dialog, all 18 native DOCX underline values with direct or theme color identity, independent native single/double strikethrough with explicit resets, formatting revisions, clipboard, format painter, and undo/redo | Mature authoring with a broader long-tail style and typography catalog |
138
- | Page layout and rendering | **Partial** sections, margins, page size, columns, headers/footers, fields, and live pagination | Desktop-grade pagination, print layout, and vector output |
139
- | Tables, pictures, and equations | **Partial** — rich table geometry, floating pictures, crop/wrap, and structured OMML | Broader drawings, text boxes, charts, WordArt, and SmartArt |
140
- | Comments, revisions, and collaboration | **Partial** — comments, suggestions, text/format revisions, decisions, Yjs presence, and host relay contracts | Full revision families plus integrated sharing and review services |
141
- | Document compare and combine | **Partial** — deterministic same-layout paragraph/heading comparison produces reviewable text, character-formatting, and paragraph-formatting revisions; reviewed-copy combine requires an exact reject-all baseline match | Mature structural, object, move-range, and multi-copy conflict handling |
142
- | References and document generation | **Partial** typed Table of Contents and native index authoring/refresh, bookmarks, links, captions, cross-references, citations, notes, and common fields | Mail merge, tables of figures/authorities, and broader fields |
143
- | Ribbon and shortcuts | **Supported** — responsive Office-style ribbon and editor-scoped daily-writing shortcuts | Complete desktop shortcut and contextual-tool surface |
144
- | Very large documents | **Supported with boundaries** bounded 100,000-block plain-document windows and measured edit/navigation budgets | Native-engine virtualization with device-dependent limits |
145
- | DOCX and PDF fidelity | **Partial** — source-aware DOCX preservation and live-layout raster PDF export | Broader legacy/OOXML compatibility and searchable vector PDF output |
146
-
147
- ### Spreadsheet
148
-
149
- | Capability | A3S Office today | Traditional Office baseline |
150
- | --- | --- | --- |
151
- | Cells, sheets, navigation, and history | **Supported** — multiple sheets, sparse editing, search, clipboard, four-direction fill, exact formula/value copy from above, and undo/redo | Mature grid workflows across desktop and web |
152
- | Formatting and style rendering | **Partial** — native fonts, colors, borders, alignment, number formats, cell styles, all 17 native non-solid OOXML pattern fills, native linear/path XLSX gradients, and one Format Cells surface that authors none, solid, pattern, or gradient fills with exact geometry and 2–256 ordered stops; static date/time entry, contrast-safe font preview, native XLSX rich-text runs, selected-text font formatting, direct formula-bar/F2 insertion or deletion, and bounded authenticated formatted-HTML paste | Disjoint multi-edit rich-text authoring, broader themes, locale formats, and advanced style effects |
153
- | Ribbon and shortcuts | **Partial** — common Office-style Home/Data/View commands, grid-scoped shortcuts, and focused Font-dialog aliases | Larger command catalog and platform-specific accelerators |
154
- | Formulas and recalculation | **Partial** — dependency-aware calculation plus bounded structured references (`Table[Column]`, contiguous ranges, `#All`/`#Headers`/`#Data`/`#Totals`/`#This Row`, and `[@Column]`) in the shared Rust/WASM and JavaScript paths | Wider functions, arrays, volatile semantics, and calculation parity |
155
- | Sort and filter | **Partial** — Traditional Office-style current-region expansion warnings for partial selections; Traditional Office-compatible top-to-bottom or left-to-right Custom Sort with stable value, custom-list, effective cell-color, effective font-color, and conditional-format icon keys; offline Simplified Chinese pinyin/stroke comparison, optional lowercase-before-uppercase case sensitivity, and lexical numeric text; seven built-in month/weekday sequences; bounded typed host-stored or mounted-session sequences; header retention for top-to-bottom sorting; top/bottom or left/right appearance placement; up to 64 ordered keys; blanks-last value behavior; axis-aware relative-formula translation; and one-step Undo; plus worksheet AutoFilter authoring, keyboard menus, common text/value/numeric/blank conditions, exactly two same-column conditions joined by AND or OR, native OOXML `*`/`?`/`~` wildcard expressions, negative prefix/suffix operators, tie-aware Top/Bottom item and percentage filters, locally evaluated above/below-average and complete native relative-date, month, and quarter dynamic families on typed 1900-system date cells, multi-column row ownership, manual-hide preservation, and native XLSX criteria round trips with imported dynamic-filter recomputation | Custom-list deletion/reordering UI, broader locale collation, source-level 1904 date-system retention for dynamic dates, large aggregate/rank Worker/WASM offload, and table/AutoFilter-integrated custom sorting |
156
- | Tables, pivots, charts, and rules | **Partial** — native tables, bounded structured-reference formulas, calculated-column formulas with automatic fill for newly inserted body rows, complete common totals-row authoring, pivots, charts, conditional formatting, and common validation rules with complete input/error-setting authoring | Slicers, pivot charts, custom/dependent validation rules, advanced analysis, and broader browser alert flows |
157
- | Large worksheets | **Supported with boundaries** maximum-dimension sparse import/editing and viewport-bounded Canvas painting | Highly optimized native grid with hardware-dependent limits |
158
- | Files and printing | **Partial** XLS/XLSX/ODS/CSV import, XLSX export, and PDF output | Broader round trips, external data, print fidelity, and legacy conversion |
159
- | External data, macros, and specialist analysis | **Gap** — active macros are never executed; bounded models are still needed for data connections and solver-like tools | Established data, macro/add-in, scenario, and optimization ecosystems |
94
+ ## Why A3S Office exists
95
+
96
+ Embedding Office work is not one problem. A dependable product needs four
97
+ things at the same time:
98
+
99
+ 1. **A complete interaction surface** ribbons, dialogs, panes, shortcuts,
100
+ responsive layouts, accessibility, and predictable focus.
101
+ 2. **Format-native behavior** — DOCX, XLSX, PPTX, Markdown, and PDF cannot be
102
+ flattened into one lowest-common-denominator model without losing meaning.
103
+ 3. **A clear ownership boundary** — the editor should not dictate where files
104
+ live, who users are, how permissions work, or which AI provider is allowed.
105
+ 4. **Deterministic automation** — agents and backend jobs need typed,
106
+ conflict-aware mutations instead of UI scraping.
107
+
108
+ A3S Office keeps those concerns separate while exposing them through one
109
+ package and one set of bounded contracts.
110
+
111
+ ## Five surfaces, one product boundary
112
+
113
+ - **Document** (`DOCX`, `HTML`, `TXT`) structured authoring, live
114
+ pagination, tables, equations, references, review, and PDF output.
115
+ - **Spreadsheet** (`XLSX`, `XLS`, `ODS`, `CSV`)sparse worksheets,
116
+ formulas, tables, formatting, sort/filter, validation, pivots, charts, and
117
+ print workflows.
118
+ - **Presentation** (`PPTX`) — slides, typed scene objects, masters/layouts,
119
+ transitions, bounded entrance animations, notes, slideshow, and presenter
120
+ view.
121
+ - **Markdown** (`MD`) GFM source, visual mode, split preview, direct round
122
+ trips, and native automation.
123
+ - **PDF** — PDFium rendering, search, forms, annotations, history, save, and
124
+ page organization.
125
+
126
+ The surface is requested lazily. Large or expensive work is isolated behind
127
+ cancellable Workers, Rust WebAssembly, viewport-bounded rendering, and an
128
+ explicit PDFium runtime. React, Vue 3, Web Components, and the framework-neutral
129
+ Core API use the same controlled content models.
130
+
131
+ ## The core design
160
132
 
161
- ### Presentation
133
+ <p align="center">
134
+ <a href="./assets/readme/architecture.svg">
135
+ <img src="./assets/readme/architecture.svg" width="100%" alt="A3S Office architecture with browser editing and native automation planes controlled by the host product">
136
+ </a>
137
+ </p>
162
138
 
163
- | Capability | A3S Office today | Traditional Office baseline |
164
- | --- | --- | --- |
165
- | Slide and object editing | **Supported** — slide lifecycle, scene editing, multi-selection, grouping, transforms, and guides | Mature slide and drawing workflows |
166
- | Text, shapes, tables, charts, and images | **Partial** — typed editable objects with native import/export paths | Broader shapes, connectors, effects, SmartArt, and embedded chart editing |
167
- | Masters and layouts | **Partial** — import/export inheritance with editable common paths | Full visual master, layout, and placeholder authoring |
168
- | Transitions and timings | **Partial** — fade, push, wipe, split, cut, and click/automatic advance | Broader transition catalog and timing controls |
169
- | Animations and media | **Partial** — the Work scene model authors, validates, copies, collaborates on, previews, and plays ordered appear/fade/fly-in/zoom entrance cues with click/with-previous/after-previous triggers and bounded timing; this supported entrance subset round-trips through native PPTX timing trees | Exit/emphasis effects, motion paths, audio, video, recording, and broader PPTX preservation |
170
- | Slideshow and presenter workflows | **Supported** — current/beginning start, keyboard playback, notes, timer, and responsive presenter view | Rehearsal, recording, ink/laser, and richer multi-display controls |
171
- | Review and collaboration | **Partial** — comments, shared presence, remote object locations, and host transport | Threads, assignments, mentions, and integrated cloud review |
172
- | PPTX, print, PDF, and video | **Partial** — PPTX round trip plus slide/notes/handout PDF models; no video export | Broader print controls, vector fidelity, media preservation, and video export |
139
+ The two execution planes solve different jobs:
173
140
 
174
- ### PDF
141
+ - **Browser editing** provides complete interactive surfaces through React,
142
+ Vue 3, Web Components, and the Core API. Workers, Rust/WASM, and PDFium keep
143
+ layout, calculation, parsing, and rendering bounded.
144
+ - **Native automation** provides deterministic file reads, validation,
145
+ mutation, batching, CLI commands, a standard MCP server, and an Office Skill
146
+ without launching desktop Office.
175
147
 
176
- | Capability | A3S Office today | Traditional Office baseline |
177
- | --- | --- | --- |
178
- | Rendering and navigation | **Supported** — PDFium pages, thumbnails, zoom, keyboard navigation, and bounded long-file windows | Mature desktop/web viewing and navigation |
179
- | Search and text evidence | **Supported with boundaries** — browser search and bounded native text-layer evidence | Broader tagged-PDF reading order and accessibility extraction |
180
- | Annotations, forms, and save | **Supported** — common annotations, appearance controls, form filling, history, and save | Broader stamps, measurements, form authoring, scripts, and signatures |
181
- | Existing text, image, and object editing | **Gap** — no safe production content-stream editing path | Direct text/object editing with font and layout recovery |
182
- | Page organization | **Supported with boundaries** — insert, delete, rotate, reorder, extract, merge, and split run in a dedicated Worker, replace one complete Blob per mutation, and participate in Undo/Redo | Broader document-level catalog preservation and signed/encrypted-file workflows |
183
- | Compression, conversion, and OCR | **Gap / host boundary** — provider contracts are required for authoritative conversion and OCR | Integrated optimization, conversion, and scanned-document recognition |
184
- | Signatures, protection, and redaction | **Gap / host boundary** — trusted identity and destructive-content guarantees are required | E-signing, certificate validation, encryption, sanitization, and true redaction |
185
- | AI and real-time collaboration | **Host-owned** — typed page/text evidence, Yjs review records, presence, and provider-neutral ports | Typically bundled with account, storage, and model services |
148
+ Both planes are controlled by the host:
186
149
 
187
- ### Markdown
150
+ | A3S Office owns | Your product owns |
151
+ | --- | --- |
152
+ | Format-native models and commands | Content persistence and version history |
153
+ | Import, export, layout, and rendering | Identity, authorization, and policy |
154
+ | Editor UI and responsive interaction | Application shell and navigation |
155
+ | Typed collaboration and agent ports | Rooms, transport, model providers, and AI lifecycle |
188
156
 
189
- Markdown is an A3S Office differentiator rather than a parity target.
190
-
191
- | Capability | A3S Office today | Traditional Office baseline |
192
- | --- | --- | --- |
193
- | Source and visual editing | **Supported** — GFM source, visual mode, synchronized split preview, and source-native history | No standard first-class Markdown editor |
194
- | Tables, tasks, links, images, and code | **Supported** — format-native Markdown structures in both editing modes | Usually represented through rich-document conversion or plain text |
195
- | Responsive UI and shortcuts | **Supported** — desktop split view, phone single-surface modes, and editor-scoped formatting | Depends on a text editor, add-in, or conversion workflow |
196
- | Collaboration | **Supported** — Yjs content, Awareness presence, remote selections, and host-owned transport | Usually available only after conversion into a cloud document format |
197
- | Import, export, and automation | **Supported** — direct Markdown round trip plus typed browser, CLI, MCP, and agent mutations | No shared native Markdown automation contract |
198
-
199
- Document and Markdown accept public TipTap Extensions. Spreadsheet,
200
- Presentation, and PDF expose stable host ports rather than private command
201
- contexts. Editor engines and large runtime assets load only when their surface
202
- is requested. The complete gap inventory and exit evidence live in the
203
- [capability roadmap](ROADMAP.md).
204
-
205
- ## Why A3S Office
206
-
207
- - **Product-native UI** — Complete Office-style surfaces with no required
208
- backend, account system, or storage model.
209
- - **Accessible responsive shell** — Compact sidebars, slide navigation, AI
210
- panes, responsive chart inspectors, dialogs, menus, and popovers share
211
- bounded keyboard navigation, background isolation, topmost Escape handling,
212
- and focus restoration.
213
- Persistent desktop navigation and the temporary phone drawer keep separate
214
- open states, so live breakpoint changes never turn a desktop sidebar into an
215
- unexpected blocking modal or steal focus from the workspace.
216
- Shared color palettes expand to an eight-column touch layout on phones while
217
- preserving spatial arrow-key navigation.
218
- Shared Office selects use 44 px phone option rows and bounded internal
219
- scrolling while retaining keyboard selection and exact focus restoration.
220
- Host-provided file menus keep every action visually identifiable with an
221
- explicit or neutral fallback icon, readable long labels, grouped destructive
222
- actions, and a visible keyboard focus ring.
223
- - **Editor-scoped zoom** — Status controls and Ctrl/Cmd + mouse-wheel gestures
224
- share each surface's bounded zoom model without changing the host browser's
225
- page scale.
226
- - **Predictable state** — Controlled content values, typed callbacks, explicit
227
- file actions, conflict-aware document edits, and one document typography
228
- baseline across editing, preview, and PDF rendering. Word editing and
229
- read-only preview retain the same canonical TipTap tree, while browser PDF
230
- export captures that same Worker/WASM page layout instead of rebuilding
231
- content from compatibility HTML. Caption numbering and cross-reference
232
- validity also update in that same transaction graph, including a truthful
233
- missing-target state after deletion. Paired Word bookmarks can span blocks,
234
- retain stable native identities through edits, drive live editable REF
235
- fields, and keep internal links distinct from external hyperlink
236
- relationships; deleting a target exposes truthful missing-link and
237
- missing-reference states that undo repairs. Footnote and endnote references
238
- remain paired with one editable definition, renumber live in independent
239
- reference-order sequences, receive new identities when copied, and are
240
- deleted or restored together through one undoable transaction. Body `PAGE`,
241
- `NUMPAGES`, `SECTION`, `SECTIONPAGES`, `DATE`, and `TIME` fields are atomic,
242
- copied under fresh stable identities, and resolve from the live Worker/WASM
243
- page containing each field. Automatic reflow updates numeric fields without
244
- adding history or ticking clock fields; F9 refreshes every field in one
245
- undoable action. Safe inline DOCX fields round-trip natively, while nested,
246
- incomplete, cross-paragraph, deleted, or instructionless structures stay
247
- text and produce an explicit compatibility warning.
248
- Writer Table of Contents blocks reuse the same heading outline and live
249
- Worker/WASM page resolver instead of maintaining parallel heading or page
250
- state. Insert, customize, and explicit refresh each commit one TipTap
251
- transaction and one Undo record. Semantic headings and native outline-level
252
- paragraphs cover levels 1–9; included items without a native paragraph
253
- identity receive one in the same transaction so hyperlinks survive
254
- structural edits. Page-number visibility and alignment,
255
- dot/dash/underline/no leaders, and at most 512 cached entries remain typed in
256
- the DOM. DOCX export writes a native `w:sdt`/`TOC` content control and live
257
- field with cached entries; import accepts the common `\\o`, `\\h`, `\\z`,
258
- `\\u`, full-range `\\n`, and space-separator `\\p` subset while diagnosing
259
- lossy custom style mappings. The Playground's **可更新目录** template exposes
260
- the complete flow.
261
- Writer indexes use hidden, selectable inline entry atoms and a separate
262
- selectable generated block. Primary terms, secondary terms, cross-references,
263
- and bold/italic page-number intent remain typed; duplicate terms on the same
264
- page merge while retaining every stable marker target. The live Worker/WASM
265
- field resolver remains the only page-number source. Mark, edit, insert,
266
- customize, and explicit all-index refresh each commit one TipTap transaction
267
- and one Undo record. At most 2,048 markers contribute to at most 512 cached
268
- rows, with explicit truncation beyond either bound. DOCX export writes
269
- native `XE` simple fields and a real `w:sdt`/`INDEX` content control with cached
270
- `Index1`/`Index2` rows, columns, cross-references, page emphasis, alignment,
271
- and dot/dash/underline/no leaders. Import accepts the lossless common `XE`
272
- `\\b`, `\\i`, and `\\t` plus `INDEX` `\\c`, `\\e`, and `\\r` subset;
273
- unsupported switches remain diagnosed instead of approximated. The
274
- Playground's **原生索引** template exposes marking, navigation, refresh,
275
- export, and reopen.
276
- - **Framework choice** — React components, Vue 3 adapters, Custom Elements,
277
- and a framework-neutral Core API over the same engine.
278
- - **Responsive computation** — Lazy editor chunks, cancellable Workers,
279
- streamed dense XLSX and eligible large-DOCX parsing in dedicated
280
- transferable-input Workers, including a fail-closed plain-OOXML path that
281
- reuses the package Worker's decompressed worksheet XML and aborts speculative
282
- SheetJS parsing only after package authentication,
283
- CSS-compatible font-weight matching, Rust WebAssembly layout and
284
- calculation, and PDFium rendering. Spreadsheet Canvas painting is bounded
285
- to the visible row and column range. Eligible structurally plain large DOCX
286
- files retain one complete canonical structured model while TipTap initially
287
- materializes only two equal-position chunks and hydrates a selected chunk on
288
- demand. The large-DOCX Worker streams 2,048-item batches and columnar table
289
- metadata instead of cloning one complete object graph. Pooled semantic
290
- previews, physical page sheets, and pagination widgets are windowed
291
- independently. The PDF rail mounts at most 32 thumbnail buttons, aborts the
292
- exact PDFium task when a thumbnail leaves the window, and uses instant
293
- long-distance keyboard jumps so the destination retains focus. The checked
294
- 1,000-page fixture mounts 15 thumbnails and seven main-view pages at
295
- readiness. Presentation decks above 60 slides use independent thumbnail-node
296
- and scene windows. The checked 1,000-slide, 9,000-element fixture mounts 18
297
- thumbnail buttons and 13 full thumbnail scenes, retains about 10.9 MiB of
298
- JavaScript heap, reaches slide 1,000 in 6.1–13.4 ms, and produces no Long
299
- Tasks. Design metadata is normalized once per controlled value and each
300
- visible thumbnail resolves only its own slide. The checked 100,000-block
301
- fixtures keep
302
- selection, editing, and export positions in the canonical model instead of
303
- replacing them with a React-only virtual list; rich and collaborative models
304
- deliberately retain the complete compatibility path. Consecutive controlled
305
- edits hash only changed lazy chunks and combine cached fingerprint segments,
306
- while cloned or persisted models still receive complete HTML verification.
307
- - **AI without UI scraping** — Typed agent ports and host-defined selection
308
- actions receive structured context and editing commands.
309
- - **Automation outside the browser** — The native Rust CLI, standard MCP
310
- server, and Office Skill share bounded mutation contracts. Coding agents can
311
- also keep a durable Yrs replica, exchange standard Yjs v1 updates and state
312
- vectors, perform authorized typed Markdown, Document, Spreadsheet cell/batch,
313
- Presentation scene-element and z-order, and PDF annotation, form-value, and
314
- review changes, including attributable Document selection comments, replies,
315
- text suggestions, and atomic final decisions, retain browser/native actor
316
- attribution, validate browser-created character- and paragraph-formatting
317
- revisions and their audit records, and checkpoint without replacing a whole
318
- Office file.
319
-
320
- ## Real-time collaboration
321
-
322
- Document, Markdown, Spreadsheet, Presentation, and PDF expose the same
323
- transport-neutral collaboration boundary. Two browser clients can edit one
324
- artifact live, render an accessible participant roster, and project remote
325
- text selections, cells, scene objects, pages, or annotations without moving
326
- the local user's viewport or focus. Native Yrs replicas join the same state
327
- through the CLI, standard MCP server, or A3S Code.
328
-
329
- The host owns rooms, authentication, authorization, network delivery, offline
330
- buffering, persistence, and the `Y.Doc`; A3S Office owns format-specific
331
- bindings, local undo, validated presence, and conflict-local typed mutations.
332
- Spreadsheet table state uses ordered, ID-keyed records with creation claims;
333
- independent table name, style, stripe, column, and filter fields can converge
334
- without replacing a serialized worksheet.
335
- An authenticated Document `comment` session can select text, create a durable
336
- thread, reply, resolve or reopen it, and delete only review records owned by
337
- its actor while canonical content remains read-only. The server independently
338
- validates that review-only boundary before persistence and broadcast. An
339
- authenticated Document `suggest` session can submit attributed insertions,
340
- deletions, and replacements while canonical text, structure, formatting,
341
- options, comments, and other actors' suggestions remain protected. An `edit`
342
- participant accepts or rejects a proposal and appends the final actor-attributed
343
- decision to the immutable `document.change-decisions` audit trail. The A3S Boot
344
- service also persists `edit`-mode character- and paragraph-formatting revisions
345
- and validates their bounded prior-format snapshots before broadcast. Character
346
- decisions keep or restore direct marks. Paragraph decisions keep or restore
347
- alignment, direction, indentation, spacing, pagination, outline, tab stops,
348
- borders, shading, and collapsed state without deleting text. Authenticated
349
- `suggest` updates must preserve both revision kinds and cannot rewrite their
350
- identity or snapshot. `suggest` on non-Document formats remains receive-only.
351
- See the bilingual [real-time collaboration guide](https://a3s-lab.github.io/Office/docs/components/collaboration.html)
352
- for React, Vue, Web Component, reconnect, security, and native-agent setup.
353
- The repository also ships a runnable
354
- [A3S Boot collaboration server](examples/collaboration-server/) with signed
355
- room tickets, Origin validation, durable Yrs storage, Awareness relay, a typed
356
- browser adapter, and actor-scoped browser or native room messages.
157
+ Neither plane requires an A3S backend. Read the
158
+ [browser architecture](./docs/latest/en/browser-editor-architecture.md) and
159
+ [native engine design](./docs/latest/en/native-office-engine.md) for the exact
160
+ boundaries.
357
161
 
358
162
  ## Quick start
359
163
 
360
- ### Try the product locally
164
+ ### Try the complete product
361
165
 
362
- Node.js 20+, Bun 1.3+, and Rust 1.85+ are required.
166
+ The fastest first success is the
167
+ [live Playground](https://a3s-lab.github.io/Office/playground/). It exposes
168
+ normal document templates, recent capabilities, file import, and every editor
169
+ without a local install.
170
+
171
+ To run the same Playground locally, use Node.js 20+, Bun 1.3+, and Rust 1.85+:
363
172
 
364
173
  ```bash
365
174
  git clone https://github.com/A3S-Lab/Office.git
@@ -368,21 +177,13 @@ bun install --frozen-lockfile
368
177
  bun run playground
369
178
  ```
370
179
 
371
- Then open the local URL printed by the development server. For a zero-install
372
- tour, use the [live Playground](https://a3s-lab.github.io/Office/playground/).
373
- Choose **体验格式修订**, open **审阅**, then **查看修订(2)** to inspect the
374
- independent Formatting and Paragraph Formatting cards and exercise accept or
375
- reject semantics.
376
-
377
180
  ### Embed a controlled React editor
378
181
 
379
- Install the public package with its React peers:
380
-
381
182
  ```bash
382
183
  bun add @a3s-lab/office react react-dom
383
184
  ```
384
185
 
385
- Import the stylesheet once, give the editor an explicit-height host, and store
186
+ Import the stylesheet once, give the editor an explicit-height host, and retain
386
187
  the complete value emitted by `onChange`:
387
188
 
388
189
  ```tsx
@@ -413,1208 +214,185 @@ export function ProjectBrief() {
413
214
  }
414
215
  ```
415
216
 
416
- The editor owns editing, layout, import/export, and browser rendering. The host
417
- owns persistence and decides when, where, and how the emitted content is saved.
217
+ The editor owns the editing transaction. Your application decides when, where,
218
+ and how the controlled value is stored.
418
219
 
419
- ### Preload an anticipated PDF
220
+ ### Choose an entry point
420
221
 
421
- Editor modules remain lazy. PDFium runtime loading is a separate, explicit
422
- choice because its unpacked WebAssembly binary is about 4.4 MiB. Warm both only
423
- from a high-confidence intent, and use the same URL when mounting `PdfViewer`:
222
+ | Entry point | Use it for |
223
+ | --- | --- |
224
+ | `@a3s-lab/office/react` | Lazy React editor components and preload helpers |
225
+ | `@a3s-lab/office/vue` | Vue 3 adapters with `v-model:content` |
226
+ | `@a3s-lab/office/web-component` | Framework-agnostic Custom Elements |
227
+ | `@a3s-lab/office/core` | Models, templates, import/export, file workflows, and Yjs bindings |
228
+ | `@a3s-lab/office/styles.css` | Shared editor and interaction-system styles |
424
229
 
425
- ```tsx
426
- import { PdfViewer, preloadOfficeEditor } from '@a3s-lab/office/react';
230
+ Copyable integrations live in the
231
+ [component documentation](https://a3s-lab.github.io/Office/docs/components/).
427
232
 
428
- const pdfiumUrl = '/assets/pdfium.wasm';
233
+ ## Files stay files
429
234
 
430
- void preloadOfficeEditor('pdf', {
431
- pdfWasmUrl: pdfiumUrl,
432
- preloadRuntimeAssets: true,
235
+ The Core API can import and export files without mounting an editor:
236
+
237
+ ```ts
238
+ import {
239
+ createArtifact,
240
+ createArtifactBlob,
241
+ importOfficeFile,
242
+ } from '@a3s-lab/office/core';
243
+
244
+ const shell = createArtifact('blank-document');
245
+ const artifact = await importOfficeFile(file, {
246
+ artifactId: shell.id,
247
+ onProgress: ({ stage, progress }) => {
248
+ console.info(stage, Math.round(progress * 100));
249
+ },
433
250
  });
434
251
 
435
- <PdfViewer loadSource={loadPdf} wasmUrl={pdfiumUrl} />;
252
+ const output = await createArtifactBlob(artifact);
436
253
  ```
437
254
 
438
- The preload caches the module and, when the request succeeds, the response
439
- body. Runtime warming is best effort: a network failure does not block editor
440
- opening, and a later call retries it. The helper does not create a hidden
441
- viewer or pre-initialize the PDFium Worker. On the local reference machine it
442
- improved median shell mount by 41.6 ms but did not improve the viewer-ready
443
- median, so Worker initialization remains the measured boundary.
255
+ Imported DOCX artifacts are source-backed. Safe, unedited package parts and
256
+ stable native identities are preserved under bounded rules; unsupported or
257
+ unsafe structures produce compatibility diagnostics or fail explicitly rather
258
+ than being attached to the wrong content. Structured Document values can also
259
+ cross process boundaries through the versioned snapshot codec.
444
260
 
445
- ### Organize and persist PDF pages
261
+ See the
262
+ [Document](./docs/latest/en/components/document.mdx),
263
+ [Spreadsheet](./docs/latest/en/components/spreadsheet.mdx),
264
+ [Presentation](./docs/latest/en/components/presentation.mdx), and
265
+ [PDF](./docs/latest/en/components/pdf.mdx) references for file-specific
266
+ contracts.
446
267
 
447
- Providing `onSave` enables the page organizer. Every insert, delete, rotate,
448
- reorder, or merge produces one replacement PDF `Blob` and one page-history
449
- record; extract and split return separate files without changing the source.
450
- Use `onPageExport` when the host should persist those derived files instead of
451
- letting the viewer download them:
268
+ ## Collaboration without a bundled cloud
452
269
 
453
- ```tsx
454
- import type { PdfPageOrganizationExport } from '@a3s-lab/office/react';
455
- import { PdfViewer } from '@a3s-lab/office/react';
456
-
457
- async function persistPageExports(
458
- files: readonly PdfPageOrganizationExport[],
459
- ): Promise<boolean> {
460
- await Promise.all(
461
- files.map(({ fileName, pageCount, pdf }) =>
462
- storage.put(fileName, pdf, { pageCount }),
463
- ),
464
- );
465
- return true;
466
- }
270
+ Every editor exposes the same transport-neutral collaboration boundary through
271
+ Yjs/Yrs content and Awareness. Browser users, native replicas, CLI sessions,
272
+ MCP clients, and A3S Code can participate in the same host-owned document.
467
273
 
468
- <PdfViewer
469
- fileName="contract.pdf"
470
- loadSource={() => storage.get('contract.pdf')}
471
- onSave={async (pdf) => {
472
- await storage.put('contract.pdf', pdf);
473
- return true;
474
- }}
475
- onPageExport={persistPageExports}
476
- />;
477
- ```
274
+ A3S Office provides format-specific bindings, local undo, validated presence,
275
+ remote selections or locations, comments, suggestions, and conflict-local
276
+ typed mutations. The host provides rooms, authentication, authorization,
277
+ delivery, offline buffering, persistence, and the `Y.Doc`.
478
278
 
479
- Page jobs load lazily in a dedicated Web Worker. The primary PDF is limited to
480
- 256 MiB, a merged PDF to 128 MiB, and every result to 4,096 pages. Toolbar
481
- Undo/Redo consumes native annotation or form history first, then page history.
482
- Signed or encrypted PDFs fail closed; delete, reorder, and merge also reject
483
- forms, outlines, or tagged structures whose page references cannot be safely
484
- rewritten. Extract and split surface a diagnostic when document-level catalog
485
- objects are intentionally not copied. Page organization is unavailable while
486
- `collaboration` or `evidenceOverlay` is active because those modes identify an
487
- immutable source PDF. See the complete
488
- [PDF page-organization contract](docs/latest/en/components/pdf.mdx#page-organization).
279
+ This separation makes collaboration optional infrastructure rather than a
280
+ mandatory account or storage service. Start with the
281
+ [collaboration guide](https://a3s-lab.github.io/Office/docs/components/collaboration.html)
282
+ or the runnable
283
+ [A3S Boot example](./examples/collaboration-server/).
489
284
 
490
- ### Persist a structured document snapshot
285
+ ## Automation without UI scraping
491
286
 
492
- Hosts that round-trip controlled document values across a process or language
493
- boundary should use the public versioned snapshot codec instead of converting
494
- the editor value to Markdown or treating HTML as the complete document:
287
+ The Rust CLI, standard MCP server, typed Rust API, and packaged Office Skill
288
+ share the same bounded file contracts:
495
289
 
496
- ```ts
497
- import {
498
- decodeDocumentSnapshot,
499
- encodeDocumentSnapshot,
500
- } from '@a3s-lab/office/core';
290
+ ```bash
291
+ # Validate and inspect a file.
292
+ cargo run -p a3s-office-cli -- validate report.docx --json
293
+ cargo run -p a3s-office-cli -- view report.docx outline --json
501
294
 
502
- const encoded = encodeDocumentSnapshot(content);
503
- await storage.put(documentId, encoded);
295
+ # Apply an exact guarded mutation.
296
+ cargo run -p a3s-office-cli -- set report.docx /body \
297
+ --find Draft --replace Final --json
504
298
 
505
- const restored = decodeDocumentSnapshot(await storage.get(documentId));
299
+ # Expose the same contracts over standard MCP.
300
+ cargo run -p a3s-office-cli -- mcp
506
301
  ```
507
302
 
508
- The v1 envelope uses the
509
- `application/vnd.a3s.office.document-snapshot+json;version=1` media type. It
510
- retains the synchronized HTML, structured ProseMirror model, page layout,
511
- comments, review state, and bibliography as deterministic bounded JSON. Decode
512
- fails closed for a different schema or version, malformed JSON, an oversized
513
- payload, or a model whose HTML fingerprint is stale. Optional `undefined`
514
- properties are omitted because they are outside the JSON data model.
303
+ Native collaboration replicas can exchange standard Yjs updates and state
304
+ vectors, then apply typed Document, Markdown, Spreadsheet, Presentation, and
305
+ PDF mutations without interpreting Office's private CRDT schema.
515
306
 
516
- ### Export the live Word layout to PDF
307
+ Read the [automation guide](https://a3s-lab.github.io/Office/docs/automation/)
308
+ and [CLI reference](./docs/latest/en/cli-reference.md).
517
309
 
518
- Give each mounted document a stable `artifactId`, then pass the matching,
519
- current artifact to `downloadArtifactPdf`. Export waits for the live pagination
520
- surface and crops the physical pages computed by the editor:
310
+ ## Current release
521
311
 
522
- ```tsx
523
- import { useState } from 'react';
524
- import {
525
- createArtifact,
526
- downloadArtifactPdf,
527
- } from '@a3s-lab/office/core';
528
- import { DocumentEditor } from '@a3s-lab/office/react';
312
+ Version `0.37.2` keeps the release surface focused on local, testable
313
+ workflows:
529
314
 
530
- export function DocumentWithPdfExport() {
531
- const [artifact, setArtifact] = useState(() =>
532
- createArtifact('blank-document'),
533
- );
315
+ - Document, visual Markdown, and Presentation text composition is safe for
316
+ Chinese and other IMEs: pre-edit text remains local, controlled replacement
317
+ waits for settlement, and only the committed value reaches the host.
318
+ - Spreadsheet sort and AutoFilter workflows run locally, including bounded
319
+ multi-key sorting, native wildcard filters, Top/Bottom filters, custom lists,
320
+ and Simplified Chinese collation choices.
321
+ - Structured-reference calculation, calculated-column fill, and native totals
322
+ rows share bounded Rust/WASM and JavaScript paths.
323
+ - The shared File menu now has explicit action icons, readable labels, bounded
324
+ keyboard navigation, and a distinct destructive-action treatment.
325
+ - PDF page organization performs insert, delete, rotate, reorder, extract,
326
+ merge, and split in a dedicated Worker with Blob-level Undo/Redo.
534
327
 
535
- if (artifact.content.type !== 'document') return null;
328
+ Release notes live in the [changelog](./CHANGELOG.md). The Playground exposes
329
+ recent workflows from one release-labelled capability gallery.
536
330
 
537
- return (
538
- <main style={{ display: 'flex', height: '100dvh', flexDirection: 'column' }}>
539
- <button
540
- type="button"
541
- onClick={() => void downloadArtifactPdf(artifact)}
542
- >
543
- Export PDF
544
- </button>
545
- <section style={{ flex: 1, minHeight: 0 }}>
546
- <DocumentEditor
547
- artifactId={artifact.id}
548
- content={artifact.content}
549
- onChange={(content) =>
550
- setArtifact((current) => ({
551
- ...current,
552
- content,
553
- revision: current.revision + 1,
554
- updatedAt: Date.now(),
555
- }))
556
- }
557
- />
558
- </section>
559
- </main>
560
- );
561
- }
562
- ```
331
+ ## Capabilities and boundaries
563
332
 
564
- The live path preserves automatic page-break decorations, shaped text, table
565
- continuations, and page chrome. It currently rasterizes each physical page
566
- into the PDF; searchable text and vector output remain future fidelity work.
333
+ A3S Office favors explicit fidelity boundaries over silent approximation.
334
+ `Supported` means a path has deterministic behavioral or native round-trip
335
+ evidence. `Partial` means a useful path exists with a documented boundary.
567
336
 
568
- ### Choose an entry point
337
+ ### Document
569
338
 
570
- - `@a3s-lab/office/react` Lazy React editor components and preload helpers.
571
- - `@a3s-lab/office/vue` Vue 3 adapters with `v-model:content`.
572
- - `@a3s-lab/office/web-component` — Custom Elements for framework-agnostic UI
573
- composition.
574
- - `@a3s-lab/office/core` — Typed models, templates, import, export, and browser
575
- file workflows, plus transport-neutral Yjs bindings for Markdown, Document,
576
- Spreadsheet, Presentation, and PDF collaboration.
577
- - `@a3s-lab/office/styles.css` — Shared editor and interaction-system styles.
339
+ **Strong paths:** structured authoring, pagination, tables, references, review,
340
+ large plain-document windows, and source-aware DOCX round trips.
578
341
 
579
- Copyable React, Vue, and Web Component examples live in the
580
- [component documentation](https://a3s-lab.github.io/Office/docs/components/).
342
+ **Boundary:** long-tail DrawingML, fields, exact layout parity, and searchable
343
+ vector PDF remain partial.
581
344
 
582
- ## Controlled by design
583
-
584
- A3S Office is headless at the product boundary, not at the UI boundary. The
585
- package includes complete toolbars, ribbons, panes, popovers, and dialogs while
586
- leaving product infrastructure to the host.
587
-
588
- **A3S Office owns:** editing models and commands; import, export, layout, and
589
- rendering; editor UI and responsive interactions; typed selection and agent
590
- ports.
591
-
592
- **Your host owns:** persistence and version history; identity, permissions,
593
- and collaboration; the application shell and navigation; AI providers,
594
- prompts, policy, and request lifecycle.
595
-
596
- For collaborative surfaces, pass the host-owned typed Presence controller as
597
- `presence` beside its exact `collaboration` session. Every editor projects the
598
- same responsive participant roster across editing and preview chrome, including
599
- human/agent identity, mode, activity, and a format-specific location summary.
600
- Editors publish their local location and project remote locations without
601
- writing them into canonical content: Document and Markdown render text
602
- selections/carets, Spreadsheet uses Fortune Sheet's native cell-presence layer,
603
- Presentation frames stable object IDs, and PDF identifies peers on the current
604
- page or annotation. A remote roster row explicitly navigates and focuses that
605
- location; passive Awareness updates never move the local selection, viewport,
606
- or focus. The host continues to synchronize Awareness and own both lifecycles.
607
-
608
- Document and Markdown selection menus can be replaced with host-defined typed
609
- actions. Each action receives an immutable selection snapshot, nearby text,
610
- the complete controlled content, and conflict-aware `replaceText`,
611
- `insertBefore`, `insertAfter`, and `copyText` commands. Markdown snapshots also
612
- identify whether the source or visual surface owns the selection. Async edits
613
- track unrelated visual-editor transactions and fail with `stale-selection`
614
- instead of changing the wrong text. The Playground's open-ended question action
615
- enters a focused draft before dispatch, so a host never receives an unfinished
616
- “Question:” request; attached context stays available without dominating the
617
- assistant surface.
618
-
619
- ## Browser file workflows
620
-
621
- The Core API creates typed blank artifacts and performs browser-side import or
622
- export without mounting an editor:
345
+ ### Spreadsheet
623
346
 
624
- ```ts
625
- import {
626
- createArtifact,
627
- createArtifactBlob,
628
- importOfficeFile,
629
- } from '@a3s-lab/office/core';
347
+ **Strong paths:** sparse editing, dependency-aware formulas, tables,
348
+ sort/filter, validation, charts, pivots, and XLSX round trips.
630
349
 
631
- const controller = new AbortController();
632
- const shell = createArtifact('blank-document');
633
- const imported = await importOfficeFile(file, {
634
- artifactId: shell.id,
635
- signal: controller.signal,
636
- onProgress: ({ stage, progress }) => {
637
- console.info(stage, `${Math.round(progress * 100)}%`);
638
- },
639
- });
640
- const output = await createArtifactBlob(imported);
641
- const blankDeck = createArtifact('blank-presentation');
350
+ **Boundary:** formula breadth, external data, macros, add-ins, and specialist
351
+ analysis remain incomplete.
642
352
 
643
- const workbookShell = createArtifact('blank-spreadsheet');
644
- if (workbookShell.content.type !== 'spreadsheet') {
645
- throw new Error('Expected a Spreadsheet shell.');
646
- }
647
- const workbook = await importOfficeFile(spreadsheetFile, {
648
- artifactId: workbookShell.id,
649
- spreadsheetSheetIds: workbookShell.content.sheets.flatMap((sheet) =>
650
- sheet.id ? [sheet.id] : [],
651
- ),
652
- });
653
- ```
353
+ ### Presentation
654
354
 
655
- Import progress advances monotonically through `reading`, `parsing`,
656
- `analyzing`, and `finalizing`. Calling `controller.abort()` rejects with an
657
- `AbortError`; large reads and parser checkpoints yield so a host can keep the
658
- progress and Cancel controls responsive. An optional host-reserved
659
- `artifactId` lets the UI mount an editor shell before parsing finishes and then
660
- apply the imported controlled value without remounting that surface. The
661
- Playground uses this boundary to overlap DOCX Worker parsing with editor
662
- initialization; source-backed export remains attached to the reserved ID. A
663
- Spreadsheet host can also reserve worksheet identities with
664
- `spreadsheetSheetIds`. Eligible structurally plain workbooks then replace the
665
- authenticated frozen matrix inside the mounted Fortune instance instead of
666
- cloning one million cells through a second mount. Sheet-count or identity
667
- changes, preview mode, charts, protection, merged or styled geometry, and other
668
- stateful workbook structures retain the complete remount path. The plain-OOXML
669
- Worker authenticates row and cell coordinates directly in its XML buffer, so a
670
- million-cell import does not allocate or regex-match a million address strings.
671
-
672
- Spreadsheet import and export preserve sparse worksheets up to the XLSX limit
673
- of 1,048,576 rows by 16,384 columns. The logical `data.length`, `row`, and
674
- `column` dimensions can be large while only populated indexes are materialized.
675
- Virtual scrolling never emits `onChange`, and editing a far blank row creates
676
- only that row. Data-validation regions remain compact in
677
- `dataValidationRanges`; direct `dataVerification` entries take precedence.
678
- Protection ranges, passwordless editable ranges, and conditional formatting
679
- also remain compact and round-trip through native XLSX records without
680
- allocating every covered cell.
681
-
682
- ### Complete Spreadsheet data-validation settings
683
-
684
- Data → Data Validation authors list, whole-number, decimal, date, and text-length
685
- rules across one or more selected ranges. The same dialog now owns the complete
686
- common input and error metadata: `allowBlank`, `showDropdownArrow`,
687
- `hintTitle`, `hintValue`, `prohibitInput`, `errorStyle`, `errorTitle`, and
688
- `errorMessage`. Titles are bounded to 32 Unicode code points, the input message
689
- to 255, and the error message to 225. Disabling a message keeps its text so a
690
- later re-enable does not discard the user's draft.
691
-
692
- The mounted grid reads compact rules without expanding blank cells, honors
693
- `allowBlank`, can hide the in-cell list arrow, shows the authored input title
694
- and message, and uses the authored error title and message when rejecting an
695
- invalid value. The current Fortune boundary still has one blocking browser
696
- alert path whenever error alerts are enabled. `stop`, `warning`, and
697
- `information` therefore round-trip as exact native file semantics, but the
698
- browser does not yet reproduce the separate warning/information confirmation
699
- branches of a desktop suite. Custom formulas and dependent lists also remain
700
- explicit gaps.
701
-
702
- XLSX import and export preserve `allowBlank`, `showErrorMessage`,
703
- `showInputMessage`, `errorStyle`, `errorTitle`, `error`, `promptTitle`, and
704
- `prompt`. The public `showDropdownArrow` name describes what users see, while
705
- SpreadsheetML stores the inverse in `showDropDown`. On the public Playground
706
- home page, choose **新建 → 数据验证** to inspect list, date, and priority
707
- examples with all three alert styles. This is a normal user-facing template,
708
- not an `?e2e=` fixture or a documentation-only example.
709
-
710
- Native XLSX pattern fills retain all 17 non-solid OOXML pattern identities plus
711
- their foreground and background RGB, theme, indexed, automatic, and tint color
712
- origins. Canvas draws them only for visible cells, behind text and below table
713
- or conditional-format fills. Format Painter, Paste Special Formats, unrelated
714
- formatting, Yjs collaboration, export, and reopen preserve the metadata; a new
715
- solid fill, No Fill, Clear Formats, or built-in Cell Style intentionally clears
716
- it. Malformed patterns fail closed, and semantic palette conflicts export
717
- literal RGB instead of a false theme or indexed reference.
718
-
719
- Format Cells now authors every native pattern through one typed fill model.
720
- Users can switch between none, solid, all 17 pattern types, and gradients while
721
- retaining inactive drafts, preview the exact Canvas result, and edit pattern
722
- foreground/background colors. Apply publishes one controlled workbook update
723
- and one Undo record; export and reopen retain the authored native pattern.
724
-
725
- Native XLSX gradient fills retain linear angles, path inner-rectangle geometry,
726
- two through 256 ordered stops, and each stop's RGB, theme, indexed, automatic,
727
- or tint identity. Fortune projects the first stop into `bg`; metadata remains
728
- active only while that projection matches. Visible linear fills use Canvas
729
- gradients, while path fills use at most 96 clipped rectangular contours, so
730
- off-viewport cells do no work and rendering stays bounded. Format Painter,
731
- Paste Special Formats, unrelated edits, Yjs collaboration, export, and reopen
732
- preserve the fill. Explicit fills and format resets clear it, malformed input
733
- fails closed, and semantic palette conflicts fall back to literal RGB.
734
-
735
- The same Format Cells Fill tab authors linear or path gradients without a
736
- second style state. It exposes exact angle or inner-rectangle geometry, 2–256
737
- ordered stops, midpoint insertion with interpolated color, stop removal and
738
- editing, mixed-selection safeguards, and a live native Canvas preview. Invalid
739
- stop order or path geometry blocks Apply before mutation; an accepted Apply
740
- remains one controlled update and one Undo record.
741
-
742
- Worksheet Tables/ListObjects live in `sheet.tables` as semantic records with
743
- stable IDs, workbook-unique names, zero-based ranges, ordered columns, filters,
744
- header/totals flags, and built-in style identity. XLSX import and export keep
745
- native table parts and relationships. Table styling is resolved only for the
746
- visible Canvas cells; converting a table to a range materializes the confirmed
747
- appearance without densifying unrelated worksheet space.
748
-
749
- The calculation kernel resolves a bounded common structured-reference subset:
750
- table names or `displayName`, worksheet-qualified tables, contiguous column
751
- ranges, `#All`, `#Headers`, `#Data`, `#Totals`, `#This Row`, and table-local
752
- `[@Column]` formulas. Rust/WASM and JavaScript fallback share the parser,
753
- catalog, dependency graph, and no-history projection path. Requests accept at
754
- most 1,024 tables and materialize at most 100,000 cells per structured range;
755
- whole-row/column, three-dimensional, external, disjoint, missing, or
756
- over-budget references fail closed. A validated calculated-column rule is
757
- inferred from matching current-row formulas and fills only newly inserted table
758
- body rows. Existing values, formulas, and manual exceptions always win; a
759
- conflicting column fails closed and drops its automatic rule. XLSX
760
- `<calculatedColumnFormula>` metadata round-trips with the leading `=` restored
761
- in the controlled model, while unsafe or external formulas are omitted.
762
- The Playground's **结构化引用** template shows a calculated `Revenue` column,
763
- an insertion hint, an editable totals row, and a worksheet-qualified summary.
764
- The Table Design totals menu enables or disables the row and assigns each
765
- column a label, one of ten native aggregate functions, or a bounded custom
766
- formula. Native aggregates emit filtered-row-aware `SUBTOTAL` formulas; direct
767
- cell edits reconcile back into table metadata, table structure changes move
768
- the row without overwriting manual cells, and table renames rewrite only
769
- generated formulas. Dense and sparse worksheets, Yjs collaboration, and XLSX
770
- `totalsRowFunction`, `totalsRowLabel`, and `totalsRowFormula` round trips share
771
- the same model. Slicers and external/query tables remain explicit boundaries.
772
-
773
- Use `downloadArtifact` to start a browser download or
774
- `createArtifactBlob` when your application owns upload and persistence.
775
- Imported DOCX artifacts are source-backed: safe source-only OPC parts,
776
- content-type registrations, and relationships survive a regenerated export.
777
- Persist the original Blob alongside the artifact and call `registerSourceBlob`
778
- after a browser reload. If that source is unavailable, DOCX export fails
779
- explicitly instead of silently dropping complex package state. The artifact's
780
- source metadata carries a SHA-256 fingerprint, so registering a different DOCX
781
- under the same artifact ID also fails. Generated core parts remain
782
- authoritative; compatibility diagnostics identify known inline OOXML
783
- normalization and the deliberate removal of invalid signatures, VBA, ActiveX,
784
- and custom-ribbon parts. Within `word/settings.xml`, relationship-free
785
- ignorable attributes, elements, and structurally valid, non-conflicting
786
- `mc:AlternateContent` blocks survive strict or transitional UTF-8/UTF-16
787
- sources. Generated Word settings still win, and this preservation does not yet
788
- restore behavior-changing settings. Regenerated `word/styles.xml` and
789
- `word/numbering.xml` also retain relationship-free passive extensions at the
790
- root and on uniquely matched identities. Styles match by type plus style ID;
791
- imported abstract-numbering, concrete-numbering, and level metadata follows
792
- regenerated IDs. Source-only or duplicate identities, malformed trees,
793
- relationship-bound content, and ambiguous one-to-many numbering mappings are
794
- dropped. Generated Word style and numbering semantics still win. In regenerated
795
- document, header, footer, footnote, and endnote parts, relationship-free passive
796
- extensions from non-OOXML ignorable namespaces also follow uniquely matched
797
- picture drawings, using normalized anchor and drawing-property IDs. Body,
798
- header, footer, footnote, and endnote imports retain those image identities in
799
- sanitized editable HTML. Passive extensions also follow uniquely matched,
800
- unchanged paragraphs and their paragraph properties by native `w14:paraId`
801
- plus `w14:textId`. Body and page-chrome HTML
802
- retain these identities; text edits rotate `textId`, formatting-only edits and
803
- moves keep it, and copies or splits receive new paragraph IDs. Source-only,
804
- duplicate, changed-text, relationship-bound, Microsoft/OOXML semantic, and
805
- ambiguous branches are dropped; generated paragraph and drawing semantics stay
806
- authoritative. Office 2013 `w15:collapsed` paragraph metadata also round-trips
807
- through body and page-chrome HTML as `data-office-default-collapsed`. Import
808
- accepts only an empty leaf or the exact core Word `w:val` lexicals `true`,
809
- `on`, `1`, `false`, `off`, and `0`; an omitted value means true, while a
810
- malformed or duplicated direct value fails closed instead of inheriting stale
811
- state. Export canonicalizes explicit states to `1` or `0`, declares the Word
812
- 2012 namespace, and adds its prefix to `mc:Ignorable`. This metadata remains
813
- native-only: browser content stays expanded and editable, without conflating
814
- Word's initial collapsed-heading view with navigation-pane state or hidden
815
- text. Stable table hierarchies use native row `w14:paraId` plus
816
- `w14:textId`, ordered directly owned row IDs for tables, and directly owned
817
- paragraph IDs for cells. Passive extensions on `w:tbl`/`w:tblPr`,
818
- `w:tr`/`w:trPr`, and `w:tc`/`w:tcPr` survive body or page-chrome regeneration.
819
- Row text or structural edits rotate the row version; formatting-only edits and
820
- moves retain it, copies receive independent IDs, and nested rows or cells are
821
- isolated from their outer table. Duplicate or cross-kind identities and unsafe
822
- extension branches fail closed, while generated table geometry and formatting
823
- win. Imported footnotes and endnotes now retain their native positive `w:id`
824
- across reorderings, while copies receive independent IDs. Signed native comment
825
- and reply IDs, reply parentage, and resolved state also survive regeneration.
826
- Native DrawingML pictures inside footnotes and endnotes retain their identity,
827
- layout, wrapping, crop, and layer metadata through public import and artifact
828
- export. Export repairs missing image relationships in generated note parts,
829
- allocates collision-free relationship IDs, and validates each media payload.
830
- Changed, duplicate, namespace-spoofed, relationship-bound, or semantic drawing
831
- branches stay disconnected; generated geometry and media remain authoritative,
832
- while legacy VML, shapes, and SmartArt normalize.
833
-
834
- Native Writer fonts retain the four independent WordprocessingML `w:rFonts`
835
- slots: `ascii`, `hAnsi`, `eastAsia`, and `cs`, together with their theme
836
- references and script hint. Mixed-script runs become bounded semantic spans so
837
- Latin, high ANSI, East Asian, and complex-script text each use the correct
838
- resolved browser family without rewriting the native source identity. The
839
- shared `Cmd/Ctrl+D` dialog exposes separate Latin, East Asian, and complex-text
840
- font controls, preserves untouched mixed selections, supports Follow style,
841
- uses one transaction and Undo record for combined character changes, and
842
- renders a script-aware preview. The Home font menu intentionally applies one
843
- all-text choice to all four slots. Body text, page chrome, notes, formatting
844
- revisions, strict/transitional import, exact export, and reopen share the typed
845
- model; malformed, duplicate, oversized, child-bearing, text-bearing, unknown,
846
- or namespace-spoofed `w:rFonts` data fails closed and is diagnosed.
847
-
848
- Native Writer text also authors and reopens all five WordprocessingML `w:em`
849
- values: `none`, `dot`, `comma`, `circle`, and `underDot`. The shared
850
- `Cmd/Ctrl+D` advanced font dialog keeps mixed selections untouched until an
851
- explicit choice, distinguishes removing direct formatting from writing an
852
- explicit `none` inheritance reset, restores focus and selection, and commits
853
- with the other character settings in one transaction and one Undo record. Body
854
- text, headers, footers, footnotes, endnotes, inherited styles, Format Painter,
855
- formatting revisions, strict/transitional import, export, and reopen retain the
856
- typed value. The DOM projects it through `data-office-emphasis-mark` and CSS
857
- `text-emphasis-*`; paragraphs with visible marks use browser-authoritative line
858
- measurement so their out-of-line glyph extents are not approximated by the
859
- Worker/WASM shaper. No dedicated shortcut is invented.
860
-
861
- Native Writer hidden text retains three distinct states: inherited formatting,
862
- native `w:vanish`, and an explicit `w:vanish w:val="0"` visible reset. The
863
- shared `Cmd/Ctrl+D` dialog preserves mixed selections until the checkbox is
864
- edited, while the standard `Cmd/Ctrl+Shift+H` command toggles the same typed
865
- mark and produces one Undo record. Body text, page chrome, footnotes, endnotes,
866
- Format Painter, formatting revisions, strict/transitional style inheritance,
867
- exact DOCX export, and reopen retain the value. Hidden text is suppressed by
868
- default; the View ribbon can reveal it only on editable Writer surfaces with a
869
- dotted underline. Read-only preview and detached PDF capture always suppress
870
- it. Unchanged comment XML remains source-preserved without claiming rich
871
- comment-text editing, and affected paragraphs use browser-authoritative line
872
- measurement so invisible glyphs never distort Worker/WASM pagination.
873
-
874
- Native Writer outline, shadow, emboss, and imprint retain four independent
875
- nullable TextStyle properties backed by exact `w:outline`, `w:shadow`,
876
- `w:emboss`, and `w:imprint` values. Missing properties continue style
877
- inheritance and explicit false values remain native resets. Outline and shadow
878
- can be enabled together; emboss and imprint are mutually exclusive with every
879
- other enabled effect. The shared `Cmd/Ctrl+D` dialog exposes four independently
880
- mixed checkboxes, clears conflicts in the same transaction, and creates one
881
- Undo record. Body text, page chrome, notes, Format Painter, formatting
882
- revisions, strict/transitional import, exact export, and reopen share the same
883
- model. CSS provides bounded browser and PDF paint projections while eligible
884
- paragraphs remain on the Worker/WASM layout path. The Playground's **文字效果**
885
- template demonstrates all four effects and the conflict-safe transition.
886
-
887
- Native Writer character borders retain all 25 visible WordprocessingML
888
- `w:bdr` line styles plus explicit `nil` and `none` resets. The typed model keeps
889
- direct or theme colors with tint and shade, widths from 2 through 96
890
- eighth-points, text spacing from 0 through 31 points, and explicit shadow and
891
- frame flags. The Home Font group exposes a direct Character Border toggle, and
892
- the shared `Cmd/Ctrl+D` Advanced Font Settings dialog distinguishes mixed,
893
- Follow style, explicit no-border, and editable border states. Line style,
894
- color, width, spacing, shadow, and frame changes apply through one transaction
895
- and one Undo record; Format Painter uses the same mark. Traditional Office
896
- defines no dedicated shortcut for this command, so A3S Office does not invent
897
- one.
898
-
899
- Document defaults, paragraph and character styles, body text, headers,
900
- footers, footnotes, endnotes, formatting revisions, strict or transitional
901
- DOCX import, exact export, and reopen share the model. Malformed, duplicated,
902
- misplaced, namespace-spoofed, child- or text-bearing, extra-attribute,
903
- art-style, out-of-range, and unresolved-theme input fails closed. The DOM uses
904
- `data-office-run-border`; CSS renders every edge with bounded line-style,
905
- padding, shadow, and cloned-fragment projections. Visible character borders use
906
- browser-authoritative line measurement because border and padding alter inline
907
- geometry, while explicit `nil` and `none` remain eligible for Worker/WASM
908
- layout. Browser and PDF paint are bounded visual approximations; the OOXML
909
- semantics remain exact. The Playground's **字符边框** template exercises the
910
- complete authoring and one-step Undo path.
911
-
912
- Native Writer character shading retains one exact `w:shd` value rather than a
913
- flattened CSS fill. The typed model preserves every WordprocessingML pattern,
914
- direct or automatic foreground/background colors, independent theme channels
915
- with tint and shade, and explicit `nil`. Document defaults, paragraph and
916
- character styles, conditional table styles, body, page chrome, notes,
917
- formatting revisions, strict/transitional import, exact export, and reopen use
918
- the same resolver. Invalid or spoofed leaves fail closed and are diagnosed.
919
-
920
- The shared `Cmd/Ctrl+D` Advanced Font Settings dialog distinguishes mixed,
921
- Follow style, explicit no-shading, and editable pattern/color states; changes
922
- commit with Format Painter and one-step Undo semantics. The DOM stores bounded
923
- JSON in `data-office-run-shading`, while CSS projects patterns without changing
924
- line geometry, so eligible content stays on the Worker/WASM path. Native
925
- `w:highlight` remains independent and takes display precedence without
926
- clobbering shading. The Playground's **字符底纹** template demonstrates the
927
- complete flow.
928
-
929
- Native Writer proofing languages retain the three independent WordprocessingML
930
- `w:lang` slots: Latin `w:val`, East Asian `w:eastAsia`, and bidi `w:bidi`.
931
- Native `w:noProof` remains an independent three-state property: inherited,
932
- explicitly checked with `w:val="false"`, or excluded from proofing. The Review
933
- ribbon's **设置校对语言** dialog accepts bounded BCP 47 language tags, keeps
934
- untouched mixed slots unchanged, exposes Follow style for each slot, and applies
935
- the touched language and proofing-state fields through one transaction and one
936
- Undo record. The same contract is available while editing headers and footers.
937
-
938
- Document defaults, paragraph and character styles, body text, headers,
939
- footers, footnotes, endnotes, formatting revisions, strict/transitional DOCX
940
- import, exact export, and reopen share the closed model. Malformed, duplicated,
941
- misplaced, namespace-spoofed, nested, text-bearing, extra-attribute, invalid-tag,
942
- or invalid on/off input fails closed and appears in compatibility diagnostics.
943
- The DOM stores canonical JSON in `data-office-proofing-languages`, stores an
944
- explicit Boolean in `data-office-no-proof`, and projects the effective `lang`
945
- and `spellcheck` attributes without claiming a bundled dictionary or grammar
946
- service. Valid effective languages also reach the Worker/WASM text-layout run
947
- and RustyBuzz shaping buffer. The Playground's **校对语言** template demonstrates
948
- Latin, East Asian, bidi, explicitly checked, and excluded states.
949
-
950
- Supported native OMML equations now survive as bounded structured objects in
951
- the document body, headers, footers, footnotes, and endnotes. Inline and display
952
- math, Unicode runs with literal/normal-text semantics, math script/style,
953
- manual-break, and alignment-point properties, common fractions, scripts,
954
- left-side pre-sub/superscripts with empty script slots, radicals with optional
955
- degrees, functions, n-ary operators, combining accents, overbars and underbars,
956
- group characters with
957
- explicit grouping-character placement and baseline justification, phantoms with
958
- visible or hidden bases, independently zeroed width, ascent, or descent, and
959
- transparent spacing, border boxes with independently visible edges and four
960
- strike directions, semantic boxes with
961
- operator-emulation, no-break, differential-spacing, manual-break, and alignment
962
- properties, bounded rectangular matrices with explicit column alignment,
963
- row-spacing and column-gap rules, and minimum column widths,
964
- equation arrays with 1–64 rows, vertical base alignment, maximum/object
965
- distribution, row-spacing rules, and `&` alignment/spacer markers, lower and
966
- upper limit objects, and delimiters regenerate as `m:oMath` or `m:oMathPara` and
967
- render an accessible MathML preview. Bar placement preserves the distinct OMML
968
- defaults for an omitted `barPr` and an omitted `pos`. Group-character
969
- normalization separately preserves an absent `chr` as U+23DF, an explicitly
970
- empty `chr`, bottom `pos`, and the absent-versus-empty `vertJc` defaults.
971
- Phantom normalization preserves the visible `show` default and disabled
972
- `zeroWid`, `zeroAsc`, `zeroDesc`, and `transp` defaults; MathML preview uses
973
- `mphantom` and `mpadded` without discarding the native spacing properties.
974
- Pre-scripts preserve required `sub`, `sup`, and `e` ordering and map empty left
975
- script slots to MathML `none` children after `mprescripts`.
976
- Right-side `sSup`, `sSub`, and `sSubSup` objects enforce their property-first
977
- argument order. `sSubSupPr` preserves `alnScr`, canonicalizes its absent or
978
- disabled value to unaligned scripts, and retains the enabled state through
979
- native export. Supported fraction, script, limit, radical, function, n-ary,
980
- accent, bar, group-character, phantom, border-box, box, matrix,
981
- equation-array, and delimiter property containers preserve one optional ordered
982
- `m:ctrlPr` control format through the same bounded Word run-property model.
983
- The control may contain a direct `w:rPr` or bounded tracked provenance rooted
984
- at `w:ins`, `w:del`, `w:moveFrom`, or `w:moveTo`. Each revision retains a
985
- non-negative 32-bit `w:id`, a bounded `w:author`, an optional validated
986
- `w:date`, and optional Microsoft 365 `w16du:dateUtc` with a UTC `Z` suffix.
987
- Word's legal `moveFrom/moveTo -> ins/del` and `ins -> del` chains are
988
- preserved, with the optional `w:rPr` at the deepest level. Every supported
989
- `deg`, `den`, `e`, `fName`, `lim`, `num`, `sub`, and `sup` argument slot
990
- preserves the same direct or revision-wrapped control format after its
991
- expressions. Empty `ctrlPr` or direct `w:rPr` values canonicalize away, while
992
- an empty revision remains native provenance. Safe object-control values project
993
- only onto separable MathML control/operator nodes; argument-slot formatting and
994
- all revision provenance remain native metadata because professional MathML has
995
- neither linear-build control characters nor Word review/move-range semantics.
996
- Document-level move-range pairing is not inferred from an isolated equation.
997
- Matrix properties follow the ordered
998
- `baseJc -> plcHide -> rSpRule -> cGpRule -> rSp -> cSp -> cGp -> mcs -> ctrlPr`
999
- grammar. Row and column rules accept single, 1.5, double, exact, and multiple
1000
- spacing. `rSp` and `cGp` are bounded to 65,535, while the minimum column width
1001
- `cSp` is bounded to 31,680 twips. If any spacing property is
1002
- present, omitted or attribute-free peers take their Word defaults and native
1003
- export emits a complete canonical spacing group. Row spacing and column gaps
1004
- project to MathML `rowspacing` and `columnspacing`; `cSp` remains native-only
1005
- for layout because MathML `columnwidth` is a fixed width rather than Word's
1006
- minimum.
1007
- Fractions enforce optional `fPr` before required `num` and `den` arguments.
1008
- An absent `type` or an attribute-free `type` canonicalizes to `bar`; `noBar`,
1009
- `skw`, and `lin` remain distinct through native export and MathML projection.
1010
- Radicals enforce `radPr`, optional `deg`, and `e` ordering. An omitted or empty
1011
- degree normalizes to a square root, while a visible nonempty degree remains an
1012
- nth root. Native export emits the canonical `radPr -> deg -> e` shape and uses
1013
- `degHide=1` with an empty degree slot for square roots.
1014
- Functions enforce optional `funcPr` before required `fName` and `e` slots. Both
1015
- required slots may be empty. Every supported `CT_OMathArg` slot may likewise be
1016
- empty and follows `argPr -> expressions -> ctrlPr`. Its optional trailing
1017
- `ctrlPr` retains one bounded direct or revision-wrapped Word control; fixed
1018
- slots use named metadata, while matrix cells, equation-array rows, and delimiter
1019
- arguments use strictly dimension-aligned metadata. Absent or empty
1020
- argument/control properties and
1021
- absent, empty, or zero `argSz` values normalize to the default. Bounded
1022
- `argSz` values from -2 through 2 round-trip as relative argument sizes. The
1023
- Word-effective `box/e`, `groupChr/e`, `limLow/lim`, `limUpp/lim`, `nary/sub`,
1024
- `nary/sup`, `rad/deg`, `sPre/sub`, `sPre/sup`, `sSub/sub`, `sSubSup/sub`,
1025
- `sSubSup/sup`, and `sSup/sup` pairs project to inverse-sign relative MathML
1026
- `scriptlevel`; valid sizes in other argument slots remain native metadata.
1027
- Out-of-range or malformed sizes, duplicate or misplaced properties, malformed
1028
- control-revision identities or nesting, and semantic argument properties fail
1029
- closed.
1030
- N-ary operators enforce optional `naryPr` before required `sub`, `sup`, and `e`
1031
- slots. An omitted `chr` defaults to U+222B, while an attribute-free `chr`
1032
- remains an explicitly empty unsupported operator; an attribute-free `limLoc`
1033
- defaults to `undOvr`. Omitted or disabled `grow` values normalize to the
1034
- non-growing default; an attribute-free or enabled `grow` round-trips and maps
1035
- to MathML `stretchy=true`. Native export always emits both limit slots with
1036
- `subHide` or `supHide` for absent scripts.
1037
- Delimiters require optional `dPr` before 1–32 `e` arguments and preserve empty
1038
- argument slots. Their properties follow
1039
- `begChr -> sepChr -> endChr -> grow -> shp -> ctrlPr`; omitted characters
1040
- normalize to `(`, U+2502, and `)`, while attribute-free character properties
1041
- remain explicitly empty. Omitted or enabled `grow` and omitted, attribute-free,
1042
- or `centered` shapes canonicalize to the growing centered defaults. Non-growing
1043
- and `match` shapes round-trip in schema order. MathML projects fixed delimiters
1044
- with `stretchy=false` and content-matched growing delimiters with
1045
- `symmetric=false`; Word ignores shape while delimiter growth is disabled.
1046
- Display equations preserve `left`, `right`, `center`, and `centerGroup`
1047
- paragraph justification. The bounded native grammar accepts one optional
1048
- `m:oMathParaPr` before one `m:oMath`, while absent properties, absent `m:jc`,
1049
- and an attribute-free `m:jc` all canonicalize to the `centerGroup` default.
1050
- Math-run properties preserve the ordered `lit`, `nor`, `scr`, `sty`, `brk`, and
1051
- `aln` grammar, canonicalize Roman/italic and disabled defaults, bound `alnAt` to
1052
- 1–255, and project supported script/style combinations through MathML
1053
- `mathvariant` while retaining native break and alignment metadata.
1054
- Math runs also preserve the native `m:rPr -> w:rPr -> m:t/w:t` order. The
1055
- bounded Word run-property subset covers direct and theme font references,
1056
- Latin and complex-script bold/italic flags, all-caps and small-caps
1057
- presentation, strike and double-strike, outline, shadow, emboss, imprint,
1058
- proofing/grid flags, hidden and web-hidden states, direct and theme colors with
1059
- tint/shade, signed character
1060
- spacing through 31,680 twips, 1–600% horizontal scaling, half-point kerning
1061
- thresholds and signed baseline positions, half-point font sizes, colored
1062
- underline styles, all seven legacy text-animation values, all 27 line-border
1063
- styles with direct/theme colors, 2–96 eighth-point widths, 0–31 point spacing,
1064
- and explicit shadow/frame flags, all named highlight colors, complete patterned
1065
- run shading with direct or theme foreground/background colors, manual run
1066
- widths from 0 through 31,680 twips with optional signed 32-bit grouping IDs,
1067
- explicit baseline/superscript/subscript run alignment, all five Word
1068
- emphasis-mark values (`none`, `dot`, `comma`, `circle`, and `underDot`),
1069
- RTL/complex-script flags, Latin, East Asian, and bidi language tags, and East
1070
- Asian typography metadata with optional signed 32-bit run IDs, two-lines-in-one
1071
- flags, all five enclosing-bracket styles, horizontal-in-vertical rotation, and
1072
- rotated-text compression, plus explicit paragraph-mark always-hidden/reset
1073
- flags and Office 2010 text glow, shadow, reflection, text-outline, text-fill,
1074
- 3D-scene, and 3D-property effects plus all 16 ligature combinations, all three
1075
- numeral forms, all three numeral-spacing modes, bounded lists of all 20
1076
- OpenType stylistic sets, and explicit contextual-alternate enable/reset values.
1077
- Glow preserves an optional
1078
- 0 through
1079
- 2,147,483,647 EMU
1080
- radius, exactly
1081
- one RGB or 17-slot theme color source, and up to 64 ordered, repeatable tint,
1082
- shade, alpha, hue-modulation, saturation, and luminance transform entries.
1083
- The distinct Office 2010 shadow effect preserves the same color model plus
1084
- optional 0 through 2,147,483,647 EMU blur and offset coordinates, a direction
1085
- from 0 inclusive to 360 degrees exclusive, signed horizontal and vertical
1086
- scales, skew angles strictly between -90 and 90 degrees, and all ten rectangle
1087
- alignments. Angles retain exact 1/60,000-degree units and scales retain exact
1088
- 1/1,000-percent units.
1089
- The leaf Office 2010 reflection effect preserves optional blur and distance
1090
- coordinates, start/end opacity and position from 0 through 100 percent,
1091
- direction and fade direction from 0 inclusive to 360 degrees exclusive,
1092
- signed horizontal and vertical scales, skew angles strictly between -90 and 90
1093
- degrees, and the same ten rectangle alignments. Angles retain exact
1094
- 1/60,000-degree units, while opacity, positions, and scales retain exact
1095
- 1/1,000-percent units.
1096
- The structured Office 2010 text-outline effect preserves an optional width from
1097
- 0 through 20,116,800 EMUs, all three line caps, five compound-line styles, and
1098
- both pen alignments. Its fill choice remains distinct among none, solid, and
1099
- gradient fills. Solid fills and optional lists of 2 through 10 gradient stops
1100
- retain RGB or theme colors and ordered transforms. Gradient shading retains an
1101
- optional exact linear angle and scale flag or a path shape with an optional
1102
- signed 32-bit relative fill rectangle. All 11 preset dashes and round, bevel,
1103
- or miter joins survive, including an optional exact nonnegative miter limit.
1104
- The Office 2010 text-fill effect reuses the same strict fill grammar without
1105
- outline geometry. It preserves explicit no-fill, empty or colored solid-fill,
1106
- and empty or bounded gradient-fill choices, including the same colors,
1107
- transforms, stop limits, shade geometry, and exact units.
1108
- The Office 2010 3D scene preserves all 62 camera presets, all 27 light-rig
1109
- presets, and all eight light directions. Its required camera then light-rig
1110
- structure remains exact; only the light rig may contain an optional rotation,
1111
- whose latitude, longitude, and revolution each retain exact 1/60,000-degree
1112
- units from 0 inclusive to 360 degrees exclusive.
1113
- The Office 2010 3D properties preserve optional extrusion height and contour
1114
- width from 0 through 2,147,483,647 EMUs, all 16 material presets, optional top
1115
- and bottom bevels with independently optional bounded width and height plus all
1116
- 12 bevel presets, and ordered extrusion and contour RGB/theme colors with the
1117
- same bounded transform chains. The exact
1118
- `bevelT -> bevelB -> extrusionClr -> contourClr` order remains intact.
1119
- The Office 2010 ligature leaf requires one exact value and preserves every
1120
- combination of standard, contextual, historical, and discretional OpenType
1121
- ligatures, including explicit `none` and `all` values.
1122
- The Office 2010 numeral-form leaf likewise requires one exact value and retains
1123
- the font default, lining numerals, or oldstyle numerals without conflating an
1124
- explicit default reset with omission.
1125
- The Office 2010 numeral-spacing leaf also requires one exact value and retains
1126
- the font default, proportional numerals, or tabular numerals without conflating
1127
- an explicit default reset with omission.
1128
- The Office 2010 stylistic-set container accepts up to 4,096 raw entries and
1129
- canonicalizes enabled IDs from 1 through 20 into a unique list in first-enabled
1130
- order. An omitted `w14:val`, `true`, or `1` enables an entry; `false` or `0`
1131
- does not enable it.
1132
- The leaf Office 2010 contextual-alternates property has no child content and
1133
- accepts only the exact `true`, `false`, `1`, or `0` lexical values.
1134
- Explicit zero/default geometry values remain present so they can reset
1135
- inherited formatting. Strict universal font-size and position measures are
1136
- accepted only when they convert exactly to the bounded half-point model. Strict
1137
- universal manual widths are accepted only when they convert exactly to bounded
1138
- whole twips; omitted
1139
- grouping IDs remain distinct from explicit zero. Explicit baseline alignment
1140
- remains present so inherited superscript or subscript formatting can be reset;
1141
- explicit `none` emphasis likewise removes inherited emphasis marks.
1142
- Empty `w:eastAsianLayout` elements canonicalize away, while omitted flags stay
1143
- distinct from explicit `false` resets and signed run IDs retain explicit zero.
1144
- An empty `w:specVanish` is canonicalized to `true`; omission remains distinct
1145
- from an explicit `false` inheritance reset.
1146
- An omitted `w14:glow/@w14:rad` retains the schema default of zero while an
1147
- explicit zero remains present. Glow export declares the Office 2010 namespace
1148
- and adds its prefix to `mc:Ignorable` without replacing existing tokens.
1149
- Omitted `w14:shadow` geometry retains its zero/`none` schema defaults while
1150
- explicit zero and `none` values remain present; this effect stays distinct from
1151
- the legacy `w:shadow` on/off property.
1152
- A present empty `w14:reflection` remains distinct from omission. Its omitted
1153
- geometry retains zero/`none` schema defaults while explicit zero and `none`
1154
- values remain present.
1155
- A present empty `w14:textOutline` also remains distinct from omission and keeps
1156
- the schema's bevel default. Omitted fill, dash, and join choices retain their
1157
- defaults, while explicit zero/default attributes and empty child choices remain
1158
- present.
1159
- A missing `w14:textFill` continues to use `w:color`. A present empty text fill,
1160
- an empty solid fill, or a gradient without a stop list remains distinct and
1161
- retains its schema-defined black default.
1162
- A present empty `w14:props3d` remains distinct from omission and retains zero
1163
- extrusion and contour geometry, warm-matte material, and black color defaults.
1164
- Attribute-free bevels likewise remain present with zero width/height and circle
1165
- defaults.
1166
- An omitted `w14:ligatures` uses Word's no-ligature default. A present leaf must
1167
- carry `w14:val`; explicit `none` remains present so it can reset inherited
1168
- formatting.
1169
- An omitted `w14:numForm` uses the font's default numeral form. A present leaf
1170
- must carry `w14:val`, and explicit `default` remains present as an inheritance
1171
- reset.
1172
- An omitted `w14:stylisticSets` enables no stylistic sets. A present empty
1173
- container remains explicit so it can reset inherited sets; export emits one
1174
- canonical attribute-free `w14:styleSet` child for each enabled ID.
1175
- An omitted `w14:cntxtAlts` uses Word's disabled default. A present leaf with no
1176
- `w14:val` means `true`; explicit `false` remains present as an inheritance
1177
- reset, and export canonicalizes both states to `1` or `0`.
1178
- Explicit on/off values remain distinct, export uses canonical
1179
- `m:rPr -> w:rPr -> m:t`, and the MathML preview projects safe direct color,
1180
- exact transform-free Office 2010 RGB text fills and black fill defaults,
1181
- background, size, font, direction, language, emphasis, decoration, character
1182
- spacing, width, effective kerning, baseline-shift,
1183
- baseline/superscript/subscript alignment, Word emphasis marks, all-caps, and
1184
- small-caps values without changing source Unicode text. Emphasis marks project
1185
- as filled dots, a literal comma, or an open circle above the text, or a filled
1186
- dot below it. Superscript and subscript also project the smaller rendered size
1187
- required by Word. When `w:position` and `w:vertAlign` coexist, both remain in
1188
- native schema order and the later explicit alignment controls the CSS vertical
1189
- position. All 16 explicit ligature values map exactly to the OpenType `liga`,
1190
- `clig`, `hlig`, and `dlig` tags. Those controls compose with stylistic-set IDs
1191
- in exactly one CSS `font-feature-settings` declaration, using `"ss01" 1`
1192
- through `"ss20" 1`; an explicit empty stylistic-set list emits `normal` when
1193
- there are no ligature controls. `w14:cntxtAlts` maps independently to CSS
1194
- `font-variant-ligatures: contextual` or `no-contextual`, which controls the
1195
- OpenType `calt` feature without conflating it with the `clig` contextual
1196
- ligature feature. Numeral forms and spacing
1197
- compose into exactly one CSS `font-variant-numeric` declaration: forms map to
1198
- `normal`, `lining-nums`, or `oldstyle-nums`, while spacing maps to `normal`,
1199
- `proportional-nums`, or `tabular-nums`. A default paired with a non-default
1200
- category emits only the non-default token; two explicit defaults emit `normal`.
1201
- `w:em` remains after `w:rtl`/`w:cs` and before
1202
- `w:lang`, while
1203
- `w:eastAsianLayout` remains after `w:lang`, `w:specVanish` follows it,
1204
- `w14:glow` follows `w:specVanish`, `w14:shadow` follows `w14:glow`, and
1205
- `w14:reflection` follows `w14:shadow`, followed by `w14:textOutline`,
1206
- `w14:textFill`, `w14:scene3d`, `w14:props3d`, `w14:ligatures`, `w14:numForm`,
1207
- `w14:numSpacing`, `w14:stylisticSets`, and `w14:cntxtAlts`. Simple
1208
- explicitly sized solid, double, dotted, dashed, inset, and outset line borders
1209
- project through CSS with direct or automatic color and point padding; explicit
1210
- `nil`/`none` resets also project. Outline, shadow, emboss, imprint, legacy text
1211
- animations, complex
1212
- multi-line, wavy, or 3D line borders, border shadow/frame, theme-only border
1213
- colors, hidden, and web-hidden values remain native-only because Word rendering
1214
- and view settings govern them. Manual run widths also remain native-only
1215
- because Word ignores `w:fitText` inside Office Math, so the MathML preview
1216
- deliberately does not emulate them.
1217
- East Asian two-lines-in-one, enclosing brackets, horizontal-in-vertical
1218
- rotation, and rotated-text compression also remain native-only. CSS
1219
- `text-combine-upright`, writing modes, and transforms do not preserve Word's
1220
- two-sub-line distribution or its left-rotated inline line box, so approximating
1221
- them would introduce layout drift.
1222
- `w:specVanish` also remains native-only and never hides an equation preview.
1223
- The standard limits its display semantics to paragraph marks and allows it to
1224
- be ignored on any other run; Word additionally ignores it unless `w:vanish` is
1225
- set. Schema-valid values are still retained without inventing that dependency.
1226
- Office 2010 glow, shadow, reflection, text-outline, 3D-scene, and 3D-property
1227
- effects also remain native-only. CSS `text-shadow`, reflection, opacity, perspective,
1228
- transform, text-stroke, paint-order, and border approximations cannot preserve
1229
- theme-bound colors,
1230
- ordered color transforms, exact blur and offset coordinates, reflection
1231
- opacity/position/fade geometry, signed scaling and skew, rectangle alignment,
1232
- gradient or compound strokes, preset dashes, caps, joins, or pen alignment, so
1233
- previews retain readable equation text without inventing a visually misleading
1234
- effect.
1235
- Text `noFill`, theme or transformed text-fill colors, and nonempty gradients
1236
- remain native-only when no exact MathML color exists. CSS transparent text or
1237
- background-clipped gradient approximations would make previews fragile, so the
1238
- underlying readable color remains the fallback.
1239
- `w:highlight` takes display precedence over `w:shd`; named highlights, explicit
1240
- highlight removal, clear direct fills, solid direct foregrounds, and nil
1241
- shading map to MathML `mathbackground`. Pattern masks and theme-only colors
1242
- remain native metadata when no exact browser color is available.
1243
- Enabled mutually exclusive all-caps/small-caps, strike/double-strike, or relief
1244
- combinations, invalid animation values, art-border styles, out-of-range border
1245
- width/spacing, malformed border colors/flags, missing, malformed, fractional,
1246
- or out-of-range manual widths and grouping IDs, missing or unknown
1247
- vertical-alignment or emphasis-mark values, malformed or out-of-range East
1248
- Asian layout IDs, flags, or bracket styles, malformed paragraph-mark visibility
1249
- flags, malformed glow radii, shadow or reflection geometry, text-outline
1250
- fill/gradient/dash/join structure, text-fill wrapper/fill/gradient structure,
1251
- color choices or transform chains, 3D-scene camera/light structure,
1252
- 3D-property extrusion/contour/bevel/color structure, bounded coordinates,
1253
- missing or malformed ligature values, non-leaf ligature content, preset values,
1254
- missing or malformed numeral-form values, non-leaf numeral-form content,
1255
- missing or malformed numeral-spacing values, non-leaf numeral-spacing content,
1256
- malformed or over-limit stylistic-set containers, entries, IDs, or on/off
1257
- values, malformed or non-leaf contextual-alternate values, directions, or
1258
- rotation angles, and unknown, duplicated, reordered,
1259
- namespace-spoofed, or relationship-bound Word run properties fail
1260
- closed instead of being silently discarded.
1261
- Border-box, box, and equation-array flags retain their semantic defaults, and
1262
- manual-break alignment indices are bounded to 1–255. Strict and transitional
1263
- UTF-8/UTF-16 math is normalized for editing. Invalid or non-combining accent
1264
- characters, malformed math-run or function structures, invalid or contradictory
1265
- fraction, radical, n-ary, delimiter, bar, group-character, phantom, border-box,
1266
- box, or equation-array properties,
1267
- malformed script-property, pre-script, math-paragraph, or lower/upper limit
1268
- structures,
1269
- malformed, duplicated, reordered, or out-of-range matrix spacing/gap
1270
- properties, ragged or over-limit matrices,
1271
- over-limit equation arrays,
1272
- malformed, misplaced, over-budget, namespace-spoofed, nested, or
1273
- relationship-bound math is flattened to bounded text and reported instead of
1274
- being trusted or silently attached to another equation.
1275
- Relationship-free passive extensions on uniquely matched `w:footnote`,
1276
- `w:endnote`, `w:comment`, and `w15:commentEx` roots are retained, and valid
1277
- `commentsIds` durable IDs are rebound to each regenerated final comment
1278
- paragraph. Duplicate or namespace-spoofed identities, deleted semantic records,
1279
- relationship-bound branches, and unsupported modern reaction/people sidecars
1280
- fail closed. Within uniquely matched note, comment, and reply records,
1281
- text-stable direct paragraphs and runs retain eligible passive extensions on
1282
- `w:p`, `w:r`, and `w:rPr`. Safe unmodeled note properties also survive, while
1283
- unchanged plain-text comments recover relationship-free source run boundaries
1284
- and formatting. Stable `w:hyperlink` wrappers now retain safe tooltips and
1285
- passive metadata. Generated note destinations remain authoritative; unchanged
1286
- comments and replies recover validated HTTP(S), `mailto`, or internal-anchor
1287
- destinations, with external relationship IDs deduplicated or rewritten after
1288
- collisions. Text-stable static rich-text and plain-text content controls also
1289
- recover eligible inline or contiguous block wrappers, aliases, tags, locking,
1290
- signed IDs, Word 2013 appearance and color, end-character formatting, passive
1291
- metadata, and stable runs. Editable footnote and endnote tables now regenerate
1292
- as native `w:tbl` blocks rather than flattened row text. Rich-text block
1293
- controls can safely span structurally stable paragraphs, tables, and nested
1294
- tables; matching includes row/cell shape, grid spans, merge state, nested block
1295
- shape, and exact paragraph text while generated table geometry wins. Colliding
1296
- control IDs are rewritten while unconflicted source IDs remain stable. Text or
1297
- table-structure edits, duplicate paragraphs or properties, missing or malformed
1298
- hyperlink relationships, wrong target types or modes, unsafe or relative
1299
- targets, combined external-plus-anchor destinations, namespace spoofing,
1300
- active data bindings or placeholder state, form or nested controls,
1301
- relationship-bound content, math, drawing-bearing control wrappers, and other
1302
- unsupported wrappers fail closed or normalize instead of being attached to the
1303
- wrong content. Source font-table metadata and source-only internal obfuscated
1304
- font payloads are also retained, with relationship references rewritten after
1305
- ID collisions. External fonts, wrong relationship or content types, duplicate
1306
- identities, and paths that collide with generated payloads are not reconnected.
1307
- Native DOCX consumers can use the retained embedded fonts; the browser editor,
1308
- preview, and PDF renderer do not load document-embedded font binaries and may
1309
- substitute fonts or wrap text differently.
1310
-
1311
- ## Native automation
1312
-
1313
- The repository also contains a native Rust engine for deterministic reads,
1314
- validation, mutation, batch operations, exact natural-unit inventories,
1315
- sibling-isolated semantic previews, screenshots, file watching, and a
1316
- source-bound exact-layout raster boundary across Office packages. The first
1317
- layout-authoritative route supports image-only PPTX slides whose single opaque
1318
- PNG exactly covers the declared slide surface. The optional Rust `pdfium`
1319
- feature adds bounded, one-based PDF page inventory and exact page PNGs through
1320
- an explicit host-supplied PDFium 7881 library. It records media/crop boxes,
1321
- rotation, physical and pixel geometry, source and engine hashes, and never
1322
- downloads a runtime or introduces a Browser dependency. Consumers can inspect
1323
- selected pages from one previously validated complete inventory without
1324
- rescanning the full document; render still revalidates the immutable source and
1325
- actual page profile before publication. The same retained inventory now
1326
- authorizes bounded native PDF text-layer extraction with source-order Unicode,
1327
- exact UTF-8/UTF-16 ranges, optional glyph boxes, and PDFium-native same-line,
1328
- same-style runs with exact PDF-coordinate bounds. Independent character and run
1329
- limits keep the result bounded. Document outlines retain exact page targets.
1330
- Text and outline calls revalidate
1331
- the immutable source, reuse inventory authority, and return typed limit or
1332
- unsupported failures without OCR or Browser access. Richer slides and formats
1333
- without an authoritative provider remain typed unsupported instead of being
1334
- relabeled semantic previews.
1335
- Native DOCX and PPTX table reads also normalize merged cells into one-based
1336
- logical row and column coordinates, row and column spans, and stable anchor
1337
- references for covered physical cells.
355
+ **Strong paths:** scene editing, masters/layouts, transitions, bounded entrance
356
+ animations, presenter workflows, and PPTX round trips.
1338
357
 
1339
- ```bash
1340
- # Run from the repository root
1341
- cargo run -p a3s-office-cli -- validate report.docx --json
1342
- cargo run -p a3s-office-cli -- view report.docx outline --json
1343
- cargo run -p a3s-office-cli -- set report.docx /body --find Draft --replace Final --json
358
+ **Boundary:** broader shapes, effects, media, animation families, and exact
359
+ print/video output remain partial or unsupported.
1344
360
 
1345
- # Start the standard MCP server
1346
- cargo run -p a3s-office-cli -- mcp
361
+ ### Markdown
1347
362
 
1348
- # Join a browser-owned Yjs document as a durable coding-agent replica.
1349
- cargo run -p a3s-office-cli -- collab join .a3s/report.replica \
1350
- --artifact-id report --kind document --actor-id agent-7 \
1351
- --operation-id join-1 --input browser.update --json
1352
-
1353
- # Export only the CRDT state missing from a remote state vector.
1354
- cargo run -p a3s-office-cli -- collab diff .a3s/report.replica \
1355
- --state-vector-input browser.state-vector --output agent.update --json
1356
-
1357
- # Bridge that replica to a host-owned room over machine-readable JSONL.
1358
- cargo run -p a3s-office-cli -- collab session .a3s/report.replica \
1359
- --poll-ms 100 --actor-name "A3S Agent" --json
1360
-
1361
- # Make a typed local change in an initialized Markdown replica. A running
1362
- # session publishes the resulting incremental Yjs update automatically.
1363
- cargo run -p a3s-office-cli -- collab mutate .a3s/notes.replica \
1364
- --artifact-id notes --kind markdown --actor-id agent-7 --mode edit \
1365
- --operation-id edit-42 \
1366
- --mutation '{"type":"markdown-replace","markdown":"# Shared notes"}' --json
1367
-
1368
- # Document text replacement is fail-closed: the shared XmlText must contain
1369
- # exactly the declared number of non-overlapping matches.
1370
- cargo run -p a3s-office-cli -- collab mutate .a3s/report.replica \
1371
- --artifact-id report --kind document --actor-id agent-7 --mode edit \
1372
- --operation-id edit-43 \
1373
- --mutation '{"type":"document-replace-text","search":"Draft","replacement":"Final","expectedMatches":1}' --json
1374
-
1375
- # Insert one plain paragraph beside a stable paragraph in a supported block
1376
- # container, including a nested list item or table cell.
1377
- cargo run -p a3s-office-cli -- collab mutate .a3s/report.replica \
1378
- --artifact-id report --kind document --actor-id agent-7 --mode edit \
1379
- --operation-id edit-44 \
1380
- --mutation '{"type":"document-insert-paragraph","anchorParagraphId":"00000001","position":"after","paragraphId":"00000012","textId":"00000013","text":"Native paragraph"}' --json
1381
-
1382
- # Add a durable selection comment from a comment-mode native replica. Read the
1383
- # projection first and use its exact paragraph/text IDs, anchor text, and UTF-16
1384
- # offsets. The author must match the authenticated actor display name.
1385
- cargo run -p a3s-office-cli -- collab join .a3s/report-review.replica \
1386
- --artifact-id report --kind document --actor-id agent-7 \
1387
- --actor-kind agent --mode comment --operation-id comment-join-1 \
1388
- --input browser.update --json
1389
- cargo run -p a3s-office-cli -- collab read .a3s/report-review.replica --json
1390
- cargo run -p a3s-office-cli -- collab mutate .a3s/report-review.replica \
1391
- --artifact-id report --kind document --actor-id agent-7 --mode comment \
1392
- --operation-id comment-45 \
1393
- --mutation '{"type":"document-comment-create","commentId":"comment-1","paragraphId":"00000001","expectedTextId":"00000002","startUtf16":6,"endUtf16":12,"expectedText":"review","author":"Ada Reviewer","createdAt":"2026-08-17T00:00:00.000Z","text":"Clarify this review point."}' --json
1394
-
1395
- # Propose an atomic replacement from an actor-scoped suggest replica. Read
1396
- # projection v3 immediately before writing and copy its exact paragraph/text
1397
- # identity, UTF-16 selection, and selected text.
1398
- cargo run -p a3s-office-cli -- collab join .a3s/report-suggest.replica \
1399
- --artifact-id report --kind document --actor-id agent-7 \
1400
- --actor-kind agent --mode suggest --operation-id suggestion-join-1 \
1401
- --input browser.update --json
1402
- cargo run -p a3s-office-cli -- collab read .a3s/report-suggest.replica --json
1403
- cargo run -p a3s-office-cli -- collab mutate .a3s/report-suggest.replica \
1404
- --artifact-id report --kind document --actor-id agent-7 --mode suggest \
1405
- --operation-id suggestion-create-1 \
1406
- --mutation '{"type":"document-suggestion-create","paragraphId":"00000001","expectedTextId":"00000002","startUtf16":6,"endUtf16":8,"expectedText":"😀","replacement":"reviewed","insertionId":"agent-7-insertion-1","deletionId":"agent-7-deletion-1","author":"A3S Agent","createdAt":"2026-08-17T11:00:00.000Z"}' --json
1407
- cargo run -p a3s-office-cli -- collab diff .a3s/report-suggest.replica \
1408
- --output agent-suggestion.update --json
1409
-
1410
- # An edit replica accepts or rejects one or more complete projected suggestion
1411
- # identities atomically and appends immutable actor-attributed decisions.
1412
- cargo run -p a3s-office-cli -- collab join .a3s/report-editor.replica \
1413
- --artifact-id report --kind document --actor-id editor-1 \
1414
- --actor-kind human --mode edit --operation-id editor-join-1 \
1415
- --input agent-suggestion.update --json
1416
- cargo run -p a3s-office-cli -- collab read .a3s/report-editor.replica --json
1417
- cargo run -p a3s-office-cli -- collab mutate .a3s/report-editor.replica \
1418
- --artifact-id report --kind document --actor-id editor-1 --mode edit \
1419
- --operation-id suggestion-accept-1 \
1420
- --mutation '{"type":"document-suggestion-decide","suggestions":[{"id":"agent-7-deletion-1","kind":"deletion","expectedActorId":"agent-7","expectedAuthor":"A3S Agent","expectedCreatedAt":"2026-08-17T11:00:00.000Z","expectedText":"😀"},{"id":"agent-7-insertion-1","kind":"insertion","expectedActorId":"agent-7","expectedAuthor":"A3S Agent","expectedCreatedAt":"2026-08-17T11:00:00.000Z","expectedText":"reviewed"}],"decision":"accept","decidedBy":"Grace Editor","decidedAt":"2026-08-17T11:01:00.000Z"}' --json
1421
-
1422
- # Recursively patch one Spreadsheet cell after matching the observed value.
1423
- # Zero-based row/column coordinates follow the browser collaboration model.
1424
- cargo run -p a3s-office-cli -- collab mutate .a3s/plan.replica \
1425
- --artifact-id plan --kind spreadsheet --actor-id agent-7 --mode edit \
1426
- --operation-id edit-45 \
1427
- --mutation '{"type":"spreadsheet-set-cell","sheetId":"sheet-data","row":1,"column":0,"expectedCell":{"v":10,"m":"10"},"nextCell":{"v":12,"m":"12","f":"=6*2"}}' --json
1428
-
1429
- # Apply one bounded Spreadsheet gesture atomically. Coordinates must be unique;
1430
- # nextCell:null is an exact guarded delete.
1431
- cargo run -p a3s-office-cli -- collab mutate .a3s/plan.replica \
1432
- --artifact-id plan --kind spreadsheet --actor-id agent-7 --mode edit \
1433
- --operation-id paste-46 \
1434
- --mutation '{"type":"spreadsheet-batch-cells","sheetId":"sheet-data","changes":[{"row":1,"column":0,"expectedCell":{"v":12,"m":"12","f":"=6*2"},"nextCell":{"v":14,"m":"14","f":"=7*2"}},{"row":1,"column":1,"expectedCell":null,"nextCell":{"v":20,"m":"20"}},{"row":2,"column":0,"expectedCell":{"v":"obsolete","m":"obsolete"},"nextCell":null}]}' --json
1435
-
1436
- # Update one Presentation scene element after matching the complete observed
1437
- # record. Create/delete use presentation-create/delete-element.
1438
- cargo run -p a3s-office-cli -- collab mutate .a3s/deck.replica \
1439
- --artifact-id deck --kind presentation --actor-id agent-7 --mode edit \
1440
- --operation-id edit-46 \
1441
- --mutation '{"type":"presentation-update-element","containerKind":"slide","containerId":"slide-1","elementId":"title-1","expectedElement":{"id":"title-1","type":"text","x":10,"y":10,"width":80,"height":20,"text":"Draft"},"nextElement":{"id":"title-1","type":"text","x":16,"y":10,"width":80,"height":20,"text":"Final"}}' --json
1442
-
1443
- # Move that element to the first order position after verifying its currently
1444
- # observed predecessor. Destination and source positions use stable IDs, not
1445
- # array indexes; null means no predecessor.
1446
- cargo run -p a3s-office-cli -- collab mutate .a3s/deck.replica \
1447
- --artifact-id deck --kind presentation --actor-id agent-7 --mode edit \
1448
- --operation-id move-46 \
1449
- --mutation '{"type":"presentation-move-element","containerKind":"slide","containerId":"slide-1","elementId":"title-1","expectedAfterElementId":"background-1","afterElementId":null}' --json
1450
-
1451
- # Set one PDF form value through its stable fully-qualified field name.
1452
- cargo run -p a3s-office-cli -- collab mutate .a3s/application.replica \
1453
- --artifact-id application --kind pdf --actor-id agent-7 --mode edit \
1454
- --operation-id edit-45 \
1455
- --mutation '{"type":"pdf-set-form-value","fieldId":"Applicant.Name","value":"Grace Hopper"}' --json
1456
-
1457
- # Create one portable highlight on source page 1. The nested rect and
1458
- # segmentRects use EmbedPDF's browser annotation geometry.
1459
- cargo run -p a3s-office-cli -- collab mutate .a3s/application.replica \
1460
- --artifact-id application --kind pdf --actor-id agent-7 --mode edit \
1461
- --operation-id annotation-create-1 \
1462
- --mutation '{"type":"pdf-create-annotation","annotationId":"annotation-1","pageIndex":0,"annotation":{"id":"annotation-1","pageIndex":0,"type":9,"rect":{"origin":{"x":68,"y":78},"size":{"width":300,"height":28}},"segmentRects":[{"origin":{"x":68,"y":78},"size":{"width":300,"height":28}}],"strokeColor":"#f59e0b","color":"#f59e0b","opacity":0.48,"contents":"Review this heading"}}' --json
1463
-
1464
- # Append one attributable redaction proposal. Geometry is expressed in source
1465
- # page coordinates and the replica actor becomes proposedBy.
1466
- cargo run -p a3s-office-cli -- collab mutate .a3s/application.replica \
1467
- --artifact-id application --kind pdf --actor-id agent-7 --mode edit \
1468
- --operation-id edit-46 \
1469
- --mutation '{"type":"pdf-propose-redaction","proposalId":"redaction-1","pageIndex":0,"rects":[{"left":10,"top":20,"right":80,"bottom":40}],"proposedAt":"2026-08-15T03:00:00.000Z","reason":"Personal data"}' --json
1470
-
1471
- # Append the one final decision for that review target. The replica actor
1472
- # becomes actorId; it is never accepted from caller-authored JSON.
1473
- cargo run -p a3s-office-cli -- collab mutate .a3s/application.replica \
1474
- --artifact-id application --kind pdf --actor-id agent-7 --mode edit \
1475
- --operation-id edit-47 \
1476
- --mutation '{"type":"pdf-decide-review","decisionId":"decision-1","targetKind":"redaction","targetId":"redaction-1","decision":"approve","createdAt":"2026-08-15T03:05:00.000Z"}' --json
1477
-
1478
- # Propose a clockwise rotation for selected immutable source pages. Deletion
1479
- # and complete reorder use pdf-propose-page-deletion/page-reorder.
1480
- cargo run -p a3s-office-cli -- collab mutate .a3s/application.replica \
1481
- --artifact-id application --kind pdf --actor-id agent-7 --mode edit \
1482
- --operation-id edit-48 \
1483
- --mutation '{"type":"pdf-propose-page-rotation","pageOperationId":"page-operation-1","pageIndices":[0,2],"degrees":90,"proposedAt":"2026-08-15T03:10:00.000Z"}' --json
1484
- ```
363
+ **Strong paths:** GFM source and visual editing, synchronized preview,
364
+ collaboration, direct round trips, and native automation.
1485
365
 
1486
- CLI, MCP, the typed Rust API, and the packaged Office Skill share the same
1487
- bounded contracts. They inspect and modify files without launching desktop
1488
- Office or scraping editor UI. The collaboration replica is transport-neutral:
1489
- the host still owns rooms, authentication, authorization, and delivery. Browser
1490
- Core also provides a bounded host-channel adapter for Yjs state-vector/update
1491
- sync and a typed, ephemeral Awareness controller for participants and
1492
- format-specific locations. React, Vue, and Web Components can project that
1493
- controller as a shared participant roster, remote canvas projection, and
1494
- participant-to-location navigation; neither component creates an account or
1495
- backend. The native CLI's JSONL session bridges the same host-channel envelope,
1496
- including reconnect handshakes, durable agent updates, and remote-echo
1497
- suppression, without opening its own network provider. With `--actor-name`, it
1498
- also emits standard, bounded `outbound-awareness` records for ephemeral agent
1499
- activity and format-specific locations, accepts remote Awareness and peer-left
1500
- records, and publishes participant snapshots without changing the durable
1501
- replica. Native Rust `project`,
1502
- `collab read`, and `office_collaboration_read` return the exact canonical
1503
- Markdown source or an Office-owned bounded Document projection with stable
1504
- paragraph/text identities, structural ancestry, option fields, subordinate
1505
- plain text, durable comments, replies, resolution and detached state, exact
1506
- paragraph-local UTF-16 anchors, live suggestions with exact placements,
1507
- immutable final decisions, and the current state vector. Projection schema
1508
- version 3 is the contract for these review fields. Product hosts therefore do
1509
- not need to interpret Office's private Yjs schema. Typed Markdown
1510
- replace/splice operations use browser UTF-16 offsets. Document mutations edit
1511
- ProseMirror `Y.XmlText` in place, rotate the affected Word `textId`, replace one
1512
- stable plain paragraph only after its `paragraphId`, `textId`, and complete
1513
- text still match, insert a
1514
- plain paragraph beside a stable identity in a bounded section, list-item,
1515
- table-cell/header, or blockquote container, or delete one only after its
1516
- complete text and `textId` still match. Required container blocks and each list
1517
- item's leading paragraph are preserved. Text or structural edits inside a
1518
- table rotate every identified ancestor row's `rowTextId`; incomplete row
1519
- identities fail before any write. Paragraphs containing inline atoms or review
1520
- marks remain guarded.
1521
- Page-color/track-changes sidecars remain independent conflict-local fields. All
1522
- mutations use the same durable event path. Spreadsheet set-cell mutations
1523
- recursively compare `expectedCell` with the current browser-compatible cell and
1524
- write only changed leaves, so unrelated concurrent value, formula, style,
1525
- hyperlink, note, and metadata edits merge. Use `expectedCell: null` only when
1526
- creating an observed blank coordinate. Spreadsheet deletion requires the exact
1527
- complete current cell, dense projections keep their dimensions, and sparse or
1528
- empty sheets remain sparse. `spreadsheet-batch-cells` applies 1 to 4,096
1529
- distinct coordinates in one sheet after checking every guard against the same
1530
- snapshot, then writes fields, presence markers, and dense dimensions in one
1531
- Yjs transaction. One conflict rejects the complete gesture without a durable
1532
- event. Presentation creation writes one complete element
1533
- plus a canonical immutable claim inside a slide, master, or layout and can
1534
- place it after a stable active element. Presentation update compares complete
1535
- expected/current/next elements and writes only changed top-level fields, so
1536
- unrelated concurrent geometry, text, or style changes merge while a stale
1537
- same-field edit fails. Presentation move compares the stable observed and
1538
- requested predecessor IDs instead of array indexes; `null` means the first
1539
- element-order position. An already-satisfied destination is idempotent, while
1540
- a stale source position or unavailable anchor fails before a durable update.
1541
- Only the moved element's order entry changes; no object fields, container, or
1542
- deck are replaced. Exact deletion writes a durable tombstone, and element IDs
1543
- and types never drift or become reusable. PDF annotation creation accepts the
1544
- portable browser record for FreeText, Highlight, Underline, StrikeOut, or Ink,
1545
- writes `source: created`, and commits its immutable claim atomically. An update
1546
- supplies complete `expectedAnnotation` and `nextAnnotation` values; recursive
1547
- optimistic matching merges unrelated concurrent leaves and rejects a stale
1548
- same-leaf edit. Deletion supplies expected source/page/type identity and writes
1549
- an irreversible tombstone. PDF form mutations update the same field-addressed
1550
- presence/fields/order roots as the browser binding. PDF redaction and
1551
- rotate/delete/reorder page-operation proposals plus final decisions append
1552
- immutable typed records and canonical claims in one transaction, derive actor
1553
- attribution from the replica, and reject invalid source-page sets, missing
1554
- targets, or a second final decision. None of these paths puts source or
1555
- signature bytes in Yjs. Validated browser source origins survive native
1556
- persistence and are re-emitted separately from host delivery IDs.
1557
-
1558
- Document review mutations use `document-comment-create`,
1559
- `document-comment-reply`, `document-comment-set-resolved`, and
1560
- `document-comment-delete`. Create validates an exact paragraph/text identity,
1561
- UTF-16 range, and selected text before writing both the thread and its
1562
- `documentComment` mark. Replies append to the stable thread; resolution can be
1563
- set or cleared; and `comment` mode can delete only records attributed to its
1564
- own actor. Removing selected text through a separately authorized edit keeps
1565
- the thread as a detached review record. Browser and native comment changes
1566
- share immutable claims and remain isolated from another participant's undo
1567
- history.
1568
-
1569
- Document suggestion mutations use `document-suggestion-create` in an
1570
- actor-scoped `suggest` replica and `document-suggestion-decide` in an `edit`
1571
- replica. Creation matches a stable plain paragraph, its current text identity,
1572
- an exact UTF-16 range, and selected text before writing an insertion, deletion,
1573
- or atomic replacement proposal. Decisions match every projected suggestion
1574
- identity and text in the batch, then accept or reject all of them in one
1575
- transaction and append immutable browser-compatible audit records. Actor IDs
1576
- come from replica manifests; authors and decision names must match the
1577
- authenticated display names. Stable-ID retries are idempotent, while stale
1578
- identities, overlapping proposals, incomplete replacement IDs, forged
1579
- attribution, or conflicting final decisions fail without a durable update.
1580
-
1581
- Read the [native engine design](docs/latest/en/native-office-engine.md), the
1582
- complete [CLI reference](docs/latest/en/cli-reference.md), or the published
1583
- [CLI and Skill guide](https://a3s-lab.github.io/Office/docs/automation/).
1584
-
1585
- ## Architecture
366
+ **Boundary:** Markdown remains format-native rather than acting as a conversion
367
+ layer for every rich-document construct.
1586
368
 
1587
- <p align="center">
1588
- <a href="assets/readme/architecture.svg">
1589
- <img src="assets/readme/architecture.svg" width="1200" alt="A3S Office architecture with browser editing and native automation planes controlled by the host product">
1590
- </a>
1591
- </p>
369
+ ### PDF
370
+
371
+ **Strong paths:** PDFium rendering, search, forms, annotations, save, and
372
+ bounded page organization.
1592
373
 
1593
- The browser plane combines controlled editor surfaces, framework adapters,
1594
- Workers, Rust WebAssembly, and PDFium. The native plane keeps filesystem and
1595
- OOXML package concerns in a separate Rust core, with a host-injected optional
1596
- PDFium provider for read-only PDF page evidence. Both planes expose typed
1597
- contracts; neither requires an A3S backend.
374
+ **Boundary:** existing content-stream editing, OCR, signatures, optimization,
375
+ and trustworthy redaction need explicit providers or future engines.
1598
376
 
1599
- For engine ownership, Worker/WASM boundaries, delivery stages, and performance
1600
- gates, see
1601
- [Browser editor architecture](docs/latest/en/browser-editor-architecture.md).
377
+ The complete capability inventory, priorities, and exit evidence live in the
378
+ [capability roadmap](./ROADMAP.md). Collaboration delivery has its own
379
+ [roadmap](./COLLABORATION_ROADMAP.md).
1602
380
 
1603
381
  ## Project status
1604
382
 
1605
- A3S Office is pre-1.0. Content models and component props are public, but a
383
+ A3S Office is pre-1.0. Public models and component props are usable, but a
1606
384
  minor release may still include breaking model changes. Required migrations
1607
- will be called out in the [changelog](CHANGELOG.md).
385
+ are documented in the [changelog](./CHANGELOG.md).
1608
386
 
1609
- The project targets predictable browser editing and file preservation, not
1610
- pixel parity with every Traditional Office feature. Unsupported OOXML semantics
1611
- and fidelity gaps remain explicit compatibility boundaries instead of being
1612
- silently approximated. Track product depth and release evidence in the
1613
- [editor quality roadmap](docs/latest/en/editor-quality-roadmap.md).
387
+ The goal is predictable browser editing and honest file preservation, not
388
+ pixel parity with every desktop-suite feature. Unsupported semantics remain
389
+ visible compatibility boundaries. The
390
+ [editor quality roadmap](./docs/latest/en/editor-quality-roadmap.md) records
391
+ the evidence required to move each boundary.
1614
392
 
1615
393
  ## Development
1616
394
 
1617
- Run focused checks from the repository root:
395
+ Run the standard checks from the repository root:
1618
396
 
1619
397
  ```bash
1620
398
  bun install --frozen-lockfile
@@ -1623,97 +401,52 @@ bun run lint
1623
401
  bun run typecheck
1624
402
  bun run test
1625
403
  bun run build
1626
- bun run test:e2e:pdf-page-organization:check
1627
- bun run test:e2e:pdf-page-organization
1628
- bun run playground:visual:pdf-page-organization
1629
- bun run test:e2e:large-pdf:check
1630
- bun run test:e2e:large-pdf
1631
- bun run performance:pdf
1632
- bun run test:e2e:large-presentation:check
1633
- bun run test:e2e:large-presentation
1634
- bun run performance:presentation
1635
404
  ```
1636
405
 
1637
- Start the integration Playground with `bun run playground`. The full pull
1638
- request checklist also covers the Rust workspace, browser bundle budget, and
1639
- committed visual contracts; see [CONTRIBUTING.md](CONTRIBUTING.md).
406
+ Focused local A3S Test gates cover first-open focus and IME composition:
1640
407
 
1641
- ## Documentation
408
+ ```bash
409
+ bun run test:e2e:initial-focus:check
410
+ bun run test:e2e:initial-focus
411
+ bun run test:e2e:presentation-chinese-ime:check
412
+ bun run test:e2e:presentation-chinese-ime
413
+ ```
1642
414
 
1643
- The published website follows the A3S UI documentation model: the searchable
1644
- Rspress documentation center owns the website root, while Playground is a
1645
- primary top-navigation route under `/playground/`. Simplified Chinese is the
1646
- stable default, English remains available from the language menu, and the
1647
- version menu switches between `latest` and frozen release documentation.
1648
- Search is scoped to the active language and version. Both surfaces derive
1649
- their paths from one deployment base, so preview, Pages, and fork deployments
1650
- keep working without hard-coded return URLs.
415
+ The controlled Document IME lifecycle also runs against Playwright's pinned
416
+ WebKit engine in CI:
417
+
418
+ ```bash
419
+ bun run playground:ime:webkit
420
+ ```
421
+
422
+ GitHub Actions does not require A3S Test. See
423
+ [CONTRIBUTING.md](./CONTRIBUTING.md),
424
+ [the E2E guide](./tests/e2e/README.md), and
425
+ [the visual-test guide](./visual-tests/README.md) for the complete validation
426
+ matrix.
427
+
428
+ ## Documentation
1651
429
 
1652
430
  - [Live Playground](https://a3s-lab.github.io/Office/playground/)
1653
431
  - [Documentation center](https://a3s-lab.github.io/Office/docs/)
1654
- - [A3S Office 0.37.1 documentation](https://a3s-lab.github.io/Office/docs/0.37.1/)
1655
- - [A3S Office 0.37.0 documentation](https://a3s-lab.github.io/Office/docs/0.37.0/)
1656
- - [A3S Office 0.36.0 documentation](https://a3s-lab.github.io/Office/docs/0.36.0/)
1657
- - [A3S Office 0.34.0 documentation](https://a3s-lab.github.io/Office/docs/0.34.0/)
1658
- - [A3S Office 0.33.0 documentation](https://a3s-lab.github.io/Office/docs/0.33.0/)
1659
- - [A3S Office 0.32.0 documentation](https://a3s-lab.github.io/Office/docs/0.32.0/)
1660
- - [A3S Office 0.31.0 documentation](https://a3s-lab.github.io/Office/docs/0.31.0/)
1661
- - [A3S Office 0.30.0 documentation](https://a3s-lab.github.io/Office/docs/0.30.0/)
1662
- - [A3S Office 0.29.0 documentation](https://a3s-lab.github.io/Office/docs/0.29.0/)
1663
- - [A3S Office 0.28.0 documentation](https://a3s-lab.github.io/Office/docs/0.28.0/)
1664
- - [A3S Office 0.27.0 documentation](https://a3s-lab.github.io/Office/docs/0.27.0/)
1665
- - [A3S Office 0.26.0 documentation](https://a3s-lab.github.io/Office/docs/0.26.0/)
1666
- - [A3S Office 0.25.0 documentation](https://a3s-lab.github.io/Office/docs/0.25.0/)
1667
- - [A3S Office 0.24.0 documentation](https://a3s-lab.github.io/Office/docs/0.24.0/)
1668
- - [A3S Office 0.23.0 documentation](https://a3s-lab.github.io/Office/docs/0.23.0/)
1669
- - [A3S Office 0.22.0 documentation](https://a3s-lab.github.io/Office/docs/0.22.0/)
1670
- - [A3S Office 0.21.0 documentation](https://a3s-lab.github.io/Office/docs/0.21.0/)
1671
- - [A3S Office 0.20.0 documentation](https://a3s-lab.github.io/Office/docs/0.20.0/)
1672
- - [A3S Office 0.19.0 documentation](https://a3s-lab.github.io/Office/docs/0.19.0/)
1673
- - [A3S Office 0.18.0 documentation](https://a3s-lab.github.io/Office/docs/0.18.0/)
1674
- - [A3S Office 0.17.0 documentation](https://a3s-lab.github.io/Office/docs/0.17.0/)
1675
- - [A3S Office 0.16.0 documentation](https://a3s-lab.github.io/Office/docs/0.16.0/)
1676
- - [A3S Office 0.15.0 documentation](https://a3s-lab.github.io/Office/docs/0.15.0/)
1677
- - [A3S Office 0.14.0 documentation](https://a3s-lab.github.io/Office/docs/0.14.0/)
1678
- - [A3S Office 0.13.1 documentation](https://a3s-lab.github.io/Office/docs/0.13.1/)
1679
- - [A3S Office 0.13.0 documentation](https://a3s-lab.github.io/Office/docs/0.13.0/)
1680
- - [A3S Office 0.12.0 documentation](https://a3s-lab.github.io/Office/docs/0.12.0/)
1681
- - [A3S Office 0.11.0 documentation](https://a3s-lab.github.io/Office/docs/0.11.0/)
1682
- - [A3S Office 0.10.0 documentation](https://a3s-lab.github.io/Office/docs/0.10.0/)
1683
- - [A3S Office 0.9.2 documentation](https://a3s-lab.github.io/Office/docs/0.9.2/)
1684
- - [A3S Office 0.9.1 documentation](https://a3s-lab.github.io/Office/docs/0.9.1/)
1685
- - [A3S Office 0.9.0 documentation](https://a3s-lab.github.io/Office/docs/0.9.0/)
1686
- - [A3S Office 0.8.1 documentation](https://a3s-lab.github.io/Office/docs/0.8.1/)
1687
- - [A3S Office 0.8.0 documentation](https://a3s-lab.github.io/Office/docs/0.8.0/)
1688
- - [A3S Office 0.7.3 documentation](https://a3s-lab.github.io/Office/docs/0.7.3/)
1689
- - [A3S Office 0.7.2 documentation](https://a3s-lab.github.io/Office/docs/0.7.2/)
1690
- - [A3S Office 0.7.1 documentation](https://a3s-lab.github.io/Office/docs/0.7.1/)
1691
- - [A3S Office 0.7.0 documentation](https://a3s-lab.github.io/Office/docs/0.7.0/)
1692
- - [A3S Office 0.6.0 documentation](https://a3s-lab.github.io/Office/docs/0.6.0/)
1693
- - [A3S Office 0.5.0 documentation](https://a3s-lab.github.io/Office/docs/0.5.0/)
1694
- - [A3S Office 0.4.0 documentation](https://a3s-lab.github.io/Office/docs/0.4.0/)
1695
- - [A3S Office 0.3.0 documentation](https://a3s-lab.github.io/Office/docs/0.3.0/)
1696
- - [A3S Office 0.2.0 documentation](https://a3s-lab.github.io/Office/docs/0.2.0/)
1697
- - [A3S Office 0.1.0 documentation](https://a3s-lab.github.io/Office/docs/0.1.0/)
1698
- - [React, Vue, and Web Component integration](https://a3s-lab.github.io/Office/docs/components/)
1699
- - [Real-time collaboration](https://a3s-lab.github.io/Office/docs/en/components/collaboration.html)
1700
- - [Collaboration delivery roadmap](COLLABORATION_ROADMAP.md)
1701
- - [Office CLI and coding-agent Skill](https://a3s-lab.github.io/Office/docs/automation/)
1702
- - [Browser editor architecture](docs/latest/en/browser-editor-architecture.md)
1703
- - [Native Office engine](docs/latest/en/native-office-engine.md)
1704
- - [CLI reference](docs/latest/en/cli-reference.md)
1705
- - [Editor quality roadmap](docs/latest/en/editor-quality-roadmap.md)
1706
- - [Changelog](CHANGELOG.md)
432
+ - [React, Vue, Web Component, and Core API](https://a3s-lab.github.io/Office/docs/components/)
433
+ - [Real-time collaboration](https://a3s-lab.github.io/Office/docs/components/collaboration.html)
434
+ - [CLI, MCP, and Office Skill](https://a3s-lab.github.io/Office/docs/automation/)
435
+ - [Browser editor architecture](./docs/latest/en/browser-editor-architecture.md)
436
+ - [Native Office engine](./docs/latest/en/native-office-engine.md)
437
+ - [Editor quality roadmap](./docs/latest/en/editor-quality-roadmap.md)
438
+ - [Changelog](./CHANGELOG.md)
1707
439
 
1708
440
  ## Community and security
1709
441
 
1710
- Contributions are welcome. Read the [contribution guide](CONTRIBUTING.md) and
1711
- [Code of Conduct](CODE_OF_CONDUCT.md) before opening a change. Report suspected
1712
- vulnerabilities through the private process in [SECURITY.md](SECURITY.md), not
1713
- through a public issue.
442
+ Contributions are welcome. Read the
443
+ [contribution guide](./CONTRIBUTING.md) and
444
+ [Code of Conduct](./CODE_OF_CONDUCT.md) before opening a change. Report
445
+ suspected vulnerabilities through the private process in
446
+ [SECURITY.md](./SECURITY.md), not through a public issue.
1714
447
 
1715
448
  ## License
1716
449
 
1717
- A3S Office is available under the [MIT License](LICENSE). Bundled PDFium and
450
+ A3S Office is available under the [MIT License](./LICENSE). Bundled PDFium and
1718
451
  other third-party assets carry additional notices in
1719
- [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md).
452
+ [THIRD_PARTY_NOTICES.md](./THIRD_PARTY_NOTICES.md).