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