@ansonlai/docx-redline-js 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +36 -10
- package/README.md +83 -6
- package/adapters/xml-adapter.js +73 -10
- package/core/list-targeting.js +3 -0
- package/core/paragraph-targeting.js +33 -7
- package/core/redline-validation.js +22 -0
- package/core/types.js +122 -27
- package/core/xml-query.js +3 -1
- package/dist/docx-redline-js.esm.js +1148 -572
- package/dist/docx-redline-js.esm.js.map +4 -4
- package/dist/docx-redline-js.esm.min.js +79 -78
- package/dist/docx-redline-js.esm.min.js.map +4 -4
- package/docs/TESTING.md +687 -0
- package/docs/VALIDATION.md +81 -2
- package/docs/WORD-MANUAL-REVIEW.md +138 -0
- package/docs/plans/2026-08-30-reliability-testing-improvements.md +488 -0
- package/docs/plans/2026-09-01-performance-and-complexity-reduction.md +210 -0
- package/docs/plans/{2026-03-01-release-0.1.4-design.md → completed/2026-03-01-release-0.1.4-design.md} +2 -0
- package/docs/plans/{2026-03-01-release-0.1.4.md → completed/2026-03-01-release-0.1.4.md} +5 -3
- package/docs/plans/{2026-05-31-architectural changes.md → completed/2026-05-31-architectural changes.md } +2 -0
- package/docs/plans/completed/2026-08-02-reliability-improvements.md +1155 -0
- package/docs/test-comparison-dashboard.html +95 -0
- package/docs/validation-reports/2026-08-30-phase-1-word-visual-preflight.md +22 -0
- package/docs/validation-reports/2026-08-30-phase-2-word-visual-preflight.md +24 -0
- package/docs/validation-reports/2026-08-30-phase-3-coverage.md +73 -0
- package/docs/validation-reports/2026-09-02-multilevel-bullets-visual-review.md +82 -0
- package/docs/validation-reports/2026-09-02-multimodal-visual-samples.md +114 -0
- package/docs/validation-reports/2026-09-02-visual-failures-preflight.md +79 -0
- package/engine/format-extraction.js +1 -1
- package/engine/formatting-removal.js +95 -104
- package/engine/oxml-engine.js +176 -83
- package/engine/reconstruction-mapper.js +276 -79
- package/engine/reconstruction-mode.js +20 -6
- package/engine/reconstruction-writer.js +117 -72
- package/engine/run-builders.js +17 -13
- package/engine/surgical-diff-application.js +7 -21
- package/engine/surgical-mode.js +3 -2
- package/engine/table-mode.js +27 -16
- package/index.d.ts +95 -3
- package/index.js +14 -13
- package/orchestration/list-structural-fallback.js +16 -39
- package/package.json +23 -5
- package/pipeline/diff-engine.js +174 -55
- package/pipeline/ingestion-export.js +39 -24
- package/pipeline/ingestion-paragraph.js +7 -5
- package/pipeline/list-generation.js +27 -18
- package/pipeline/patching.js +2 -3
- package/pipeline/pipeline.js +65 -36
- package/pipeline/serialization.js +13 -5
- package/scripts/build-test-dashboard.mjs +43 -0
- package/scripts/check-types.mjs +16 -24
- package/scripts/export-validation-fixtures.mjs +191 -45
- package/scripts/fetch-superdoc-corpus.mjs +61 -0
- package/scripts/generate-test-dashboard.mjs +199 -0
- package/scripts/inspect-visual-evidence.mjs +271 -0
- package/scripts/lib/minimal-zip.mjs +199 -18
- package/scripts/lib/word-coverage-catalogue.mjs +207 -0
- package/scripts/lib/word-coverage-metadata.mjs +93 -0
- package/scripts/lib/zip-reader.mjs +64 -0
- package/scripts/package-superdoc-word-fixtures.ps1 +64 -0
- package/scripts/prepare-corpus-word-visual-review.mjs +84 -0
- package/scripts/prepare-superdoc-word-corpus.mjs +284 -0
- package/scripts/prepare-word-review.mjs +77 -0
- package/scripts/prepare-word-visual-review.mjs +90 -0
- package/scripts/render-agenda-multilevel.mjs +70 -0
- package/scripts/render-case22.mjs +73 -0
- package/scripts/render-case40.ps1 +35 -0
- package/scripts/render-multilevel-bullet-images.py +58 -0
- package/scripts/render-multilevel-bullet-visual.ps1 +32 -0
- package/scripts/render-multilevel-cases.mjs +80 -0
- package/scripts/report-coverage-gaps.mjs +103 -0
- package/scripts/report-word-coverage.mjs +71 -0
- package/scripts/sample-multimodal-visual-check.mjs +221 -0
- package/scripts/test-multilevel-bullet-visual.mjs +187 -0
- package/scripts/word-com-corpus-suite.ps1 +43 -0
- package/scripts/word-com-corpus-visual-suite.ps1 +116 -0
- package/scripts/word-com-differential.ps1 +158 -16
- package/scripts/word-com-suite.ps1 +19 -0
- package/scripts/word-com-visual-suite.ps1 +132 -0
- package/services/comment-engine.js +51 -46
- package/services/comment-locator.js +0 -1
- package/services/comment-package.js +11 -10
- package/services/numbering-service.js +1 -1
- package/services/revision-comment-management.js +31 -10
- package/services/standalone-docx-plumbing.js +45 -34
- package/services/standalone-operation-runner.js +315 -75
- package/services/table-reconciliation.js +23 -11
package/docs/VALIDATION.md
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# Validation
|
|
2
2
|
|
|
3
|
+
This document is the release-validation reference. For the testing model and
|
|
4
|
+
step-by-step instructions for adding cases, see [TESTING.md](./TESTING.md).
|
|
5
|
+
|
|
3
6
|
This package works on OOXML strings and intentionally leaves `.docx` zip
|
|
4
7
|
packaging to consumers (release *tooling* assembles minimal `.docx` fixtures
|
|
5
8
|
with a script-local zip writer; the published library still has no zip
|
|
@@ -52,8 +55,7 @@ Writes to `tmp/validation-docx/`, per case:
|
|
|
52
55
|
## Word Differential Check (Windows, desktop Word)
|
|
53
56
|
|
|
54
57
|
```bash
|
|
55
|
-
|
|
56
|
-
npm run smoke:word:diff
|
|
58
|
+
npm run test:word
|
|
57
59
|
```
|
|
58
60
|
|
|
59
61
|
For each fixture, desktop Word opens the `.docx`, confirms revisions are
|
|
@@ -62,6 +64,21 @@ expected modified text; then reopens and runs **RejectAllRevisions** and
|
|
|
62
64
|
compares to the original text. This is the strongest check available: Word
|
|
63
65
|
itself resolves the revisions this library generated.
|
|
64
66
|
|
|
67
|
+
`npm run test:word` exports the current English legal/administrative task
|
|
68
|
+
catalogue to `tmp/word-validation/` before running the differential. Expected
|
|
69
|
+
text is compared exactly by default; only Word's paragraph terminators are
|
|
70
|
+
normalized. The 33-case catalogue includes reliability regressions for literal
|
|
71
|
+
dollar/escape content, inline assistant-like text, leading whitespace,
|
|
72
|
+
multi-paragraph replacement, preserving prior revisions on no-op, and atomic
|
|
73
|
+
batch rollback after a later target failure. It also verifies that a document
|
|
74
|
+
with a near-limit prior revision ID produces safe low-range IDs, and exercises
|
|
75
|
+
bookmark/hyperlink adjacency, mixed formatted runs, content controls, table
|
|
76
|
+
cells, structural tabs, locked complex fields, comments, footnotes/endnotes,
|
|
77
|
+
headers/footers, and external hyperlinks with explicit structural-preservation
|
|
78
|
+
assertions. The
|
|
79
|
+
lower-level `npm run smoke:word:diff` remains available for an
|
|
80
|
+
already-exported fixture directory.
|
|
81
|
+
|
|
65
82
|
The older `npm run smoke:word -- path/to/file.docx` open-only smoke check
|
|
66
83
|
remains available for ad-hoc files.
|
|
67
84
|
|
|
@@ -102,3 +119,65 @@ A second independent OOXML consumer parsing the fixtures without error.
|
|
|
102
119
|
|
|
103
120
|
The Word differential check stays manual because it requires desktop Word;
|
|
104
121
|
run it before tagging a release.
|
|
122
|
+
|
|
123
|
+
## JavaScript Coverage Baseline
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
npm run test:coverage
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
The command runs the complete JavaScript test suite under c8 and prints a
|
|
130
|
+
per-file report. Coverage answers “which implementation paths did the automated
|
|
131
|
+
JavaScript tests execute?” It does not prove that executed paths are correct,
|
|
132
|
+
that generated OOXML opens in Word, or that the real-document corpus is broad
|
|
133
|
+
enough. Treat it as a map for finding thinly tested code; Word, schema,
|
|
134
|
+
LibreOffice, fuzz, and corpus checks provide different evidence.
|
|
135
|
+
|
|
136
|
+
The initial Phase 7 baseline recorded on 2026-08-29 was:
|
|
137
|
+
|
|
138
|
+
| Metric | Coverage |
|
|
139
|
+
|---|---:|
|
|
140
|
+
| Lines / statements | 79.57% |
|
|
141
|
+
| Functions | 80.07% |
|
|
142
|
+
| Branches | 69.22% |
|
|
143
|
+
|
|
144
|
+
This is a visibility baseline, not a CI threshold. Notable opportunities from
|
|
145
|
+
the baseline are `services/numbering-helpers.js` (23.55% lines),
|
|
146
|
+
`orchestration/route-plan.js` (23.75%), and
|
|
147
|
+
`orchestration/list-structural-fallback.js` (57.19%).
|
|
148
|
+
|
|
149
|
+
The post-Phase-5 snapshot recorded on 2026-08-30 is 79.96% lines/statements,
|
|
150
|
+
80.95% functions, and 69.52% branches. Preserve both snapshots so changes are
|
|
151
|
+
visible over time rather than presenting coverage as a pass/fail quality score.
|
|
152
|
+
|
|
153
|
+
## Pinned SuperDoc Corpus References
|
|
154
|
+
|
|
155
|
+
The real-document lane uses explicitly selected references from
|
|
156
|
+
[SuperDoc's docx-corpus](https://docxcorp.us/) (ODC-By 1.0). It does not consume
|
|
157
|
+
a floating or bulk manifest. The reviewed reference set contains 10 English
|
|
158
|
+
legal and 10 English administrative documents. Run the complete local lane on
|
|
159
|
+
Windows with desktop Word installed:
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
npm run test:corpus:word
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
To fetch only particular reviewed sources:
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
npm run corpus:fetch:superdoc -- --id <pinned-sha256>
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
Valid IDs and provenance are recorded in
|
|
172
|
+
`tests/corpus/superdoc-english-legal-administrative.json`. The fetcher refuses
|
|
173
|
+
unknown IDs, verifies downloaded bytes against a separately pinned observed
|
|
174
|
+
SHA-256, and writes `.docx` plus attribution metadata under
|
|
175
|
+
`tmp/superdoc-corpus/`. The separate digest is intentional: on 2026-08-29 the
|
|
176
|
+
service returned valid DOCX bytes that did not hash to its advertised corpus
|
|
177
|
+
IDs. Deterministic reviewed operations live in
|
|
178
|
+
`tests/corpus/superdoc-word-scenarios.json`.
|
|
179
|
+
|
|
180
|
+
The corpus suite replaces only `word/document.xml`, proves that the uncompressed
|
|
181
|
+
bytes of every untouched package part remain identical, opens each result in
|
|
182
|
+
Word without a repair dialog, and checks both Accept All and Reject All. Do not
|
|
183
|
+
commit downloaded documents.
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
# Microsoft Word Manual Review
|
|
2
|
+
|
|
3
|
+
This checklist is the human visual companion to `npm run test:word` and
|
|
4
|
+
`npm run test:corpus:word`. The automated differential proves Word revision
|
|
5
|
+
semantics by comparing text after Accept All and Reject All. This review checks
|
|
6
|
+
the layout and interaction details that `Document.Content.Text` cannot see.
|
|
7
|
+
|
|
8
|
+
An AI agent may use this same checklist as a visual preflight by controlling the
|
|
9
|
+
local Word UI and inspecting screenshots. Mark that report **AI visual
|
|
10
|
+
preflight**; it helps select and triage cases but does not replace the human
|
|
11
|
+
release sign-off described below.
|
|
12
|
+
|
|
13
|
+
## Prepare the review set
|
|
14
|
+
|
|
15
|
+
Run the automated lane first:
|
|
16
|
+
|
|
17
|
+
```powershell
|
|
18
|
+
npm run test:word
|
|
19
|
+
npm run test:corpus:word
|
|
20
|
+
npm run report:word:coverage
|
|
21
|
+
npm run review:word:prepare -- --cycle=0
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
The last command writes a pending review manifest under ignored
|
|
25
|
+
`tmp/word-manual-review/` containing changed catalogue families, the rotating
|
|
26
|
+
20% synthetic release sample, and legal/administrative corpus representatives.
|
|
27
|
+
It only prepares the selection: it never records a visual pass or human
|
|
28
|
+
sign-off. Use a new cycle number for each release rotation.
|
|
29
|
+
|
|
30
|
+
Synthetic documents are generated under `tmp/word-validation/`; reviewed
|
|
31
|
+
SuperDoc results are under `tmp/superdoc-word-fixtures/`. Do not commit generated
|
|
32
|
+
or downloaded `.docx` files.
|
|
33
|
+
|
|
34
|
+
Select:
|
|
35
|
+
|
|
36
|
+
- every new or changed case;
|
|
37
|
+
- every case required by the triggers in `docs/TESTING.md`;
|
|
38
|
+
- at least 20% of unchanged synthetic cases, rotating from the prior release;
|
|
39
|
+
- at least one legal and one administrative SuperDoc result; and
|
|
40
|
+
- representative list, table, formatted-run, and anchor/field/content-control
|
|
41
|
+
structures.
|
|
42
|
+
|
|
43
|
+
Record the installed Word version and build from **File → Account → About
|
|
44
|
+
Word**. Differences in rendering can be version-specific.
|
|
45
|
+
|
|
46
|
+
## Configure Word
|
|
47
|
+
|
|
48
|
+
For the tracked-change inspection:
|
|
49
|
+
|
|
50
|
+
1. Open the generated fixture directly in desktop Word.
|
|
51
|
+
2. On **Review**, select **All Markup**.
|
|
52
|
+
3. Under **Show Markup**, enable insertions/deletions, formatting, comments, and
|
|
53
|
+
all reviewers relevant to the case.
|
|
54
|
+
4. Use the expected balloons/inline display for the document and enable
|
|
55
|
+
paragraph marks when checking whitespace, tabs, breaks, lists, and empty
|
|
56
|
+
paragraphs.
|
|
57
|
+
5. Do not overwrite the generated fixture. Work on disposable copies if a
|
|
58
|
+
saved accepted or rejected view is useful.
|
|
59
|
+
|
|
60
|
+
## Inspect each case
|
|
61
|
+
|
|
62
|
+
### Tracked-change view
|
|
63
|
+
|
|
64
|
+
- The document opens without a repair, conversion, or unreadable-content prompt.
|
|
65
|
+
- Word shows the expected revision count and author attribution.
|
|
66
|
+
- Insertions and deletions are anchored at the intended words or paragraph
|
|
67
|
+
marks; a small edit has not become an unexplained whole-paragraph rewrite.
|
|
68
|
+
- Untargeted text and surrounding revisions remain unchanged.
|
|
69
|
+
- Existing bold, italic, underline, highlighting, fonts, styles, and language
|
|
70
|
+
settings remain visually consistent.
|
|
71
|
+
- Spaces, tabs, manual breaks, paragraph spacing, indentation, and alignment
|
|
72
|
+
look intentional with formatting marks visible.
|
|
73
|
+
- Lists retain numbering, levels, continuation, indentation, and marker style.
|
|
74
|
+
- Tables retain widths, borders, merged cells, row heights, and alignment.
|
|
75
|
+
- Bookmarks, hyperlinks, fields, content controls, comments, and note references
|
|
76
|
+
remain in the correct visible location and still behave when activated.
|
|
77
|
+
- Headers, footers, section boundaries, page breaks, and pagination remain
|
|
78
|
+
stable around the edit.
|
|
79
|
+
- Revision balloons and comment balloons point to the correct content and do
|
|
80
|
+
not obscure or displace unrelated layout unexpectedly.
|
|
81
|
+
|
|
82
|
+
### Accept All view
|
|
83
|
+
|
|
84
|
+
On a disposable copy, choose **Accept All Changes** and verify:
|
|
85
|
+
|
|
86
|
+
- the resulting visible text expresses the intended edit;
|
|
87
|
+
- no deletion residue, empty revision wrapper, unexpected blank line, or stale
|
|
88
|
+
formatting remains;
|
|
89
|
+
- lists, tables, fields, links, comments, notes, and page layout still work; and
|
|
90
|
+
- untargeted content is visually unchanged.
|
|
91
|
+
|
|
92
|
+
Close the copy without replacing the generated fixture.
|
|
93
|
+
|
|
94
|
+
### Reject All view
|
|
95
|
+
|
|
96
|
+
Reopen a fresh copy, choose **Reject All Changes**, and verify:
|
|
97
|
+
|
|
98
|
+
- the original visible text and formatting are restored;
|
|
99
|
+
- original list numbering, table layout, fields, anchors, and pagination return;
|
|
100
|
+
and
|
|
101
|
+
- no content introduced by the edit remains.
|
|
102
|
+
|
|
103
|
+
## Record the result
|
|
104
|
+
|
|
105
|
+
Keep the review report with the release-validation artifacts. Screenshots may be
|
|
106
|
+
stored under ignored `tmp/word-manual-review/<date>/` when useful, but do not
|
|
107
|
+
commit corpus document images or document contents without checking their
|
|
108
|
+
rights and sensitivity.
|
|
109
|
+
|
|
110
|
+
Suggested report:
|
|
111
|
+
|
|
112
|
+
```markdown
|
|
113
|
+
# Word visual review — <release/date>
|
|
114
|
+
|
|
115
|
+
- Reviewer:
|
|
116
|
+
- Review date:
|
|
117
|
+
- Word version/build:
|
|
118
|
+
- Automated synthetic result:
|
|
119
|
+
- Automated corpus result:
|
|
120
|
+
- Review type: Human sign-off | AI visual preflight
|
|
121
|
+
|
|
122
|
+
| Case | Why selected | All Markup | Accept All | Reject All | Result | Notes |
|
|
123
|
+
|---|---|---|---|---|---|---|
|
|
124
|
+
| example-case | New table structure | Pass | Pass | Pass | Pass | No layout shift |
|
|
125
|
+
|
|
126
|
+
## Failures or follow-ups
|
|
127
|
+
|
|
128
|
+
- None.
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
A **Pass** requires all three views to pass. Record **Fail** if the rendering or
|
|
132
|
+
interaction is wrong even when automated text comparison passes. Turn a failure
|
|
133
|
+
into a fixed regression case when possible; otherwise record the exact harness
|
|
134
|
+
or Word-version limitation in the active reliability plan.
|
|
135
|
+
|
|
136
|
+
For an AI preflight, also record screenshot paths and confidence/uncertainty in
|
|
137
|
+
the notes. A human reviewer should revisit every AI failure or uncertain result
|
|
138
|
+
and must still complete the release sample independently.
|