@ansonlai/docx-redline-js 0.1.4 → 0.2.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.
Files changed (47) hide show
  1. package/AGENTS.md +53 -4
  2. package/ARCHITECTURE.md +75 -11
  3. package/README.md +62 -3
  4. package/core/redline-validation.js +156 -0
  5. package/core/types.js +35 -8
  6. package/core/word-xml.js +90 -0
  7. package/dist/docx-redline-js.esm.js +3195 -2592
  8. package/dist/docx-redline-js.esm.js.map +4 -4
  9. package/dist/docx-redline-js.esm.min.js +71 -67
  10. package/dist/docx-redline-js.esm.min.js.map +4 -4
  11. package/docs/VALIDATION.md +104 -0
  12. package/docs/plans/2026-03-01-release-0.1.4-design.md +31 -0
  13. package/docs/plans/2026-03-01-release-0.1.4.md +108 -0
  14. package/docs/plans/2026-05-31-architectural changes.md +591 -0
  15. package/engine/format-application.js +13 -14
  16. package/engine/format-span-application.js +7 -6
  17. package/engine/formatting-removal.js +15 -12
  18. package/engine/oxml-engine.js +146 -55
  19. package/engine/reconstruction-mapper.js +35 -8
  20. package/engine/reconstruction-mode.js +14 -13
  21. package/engine/reconstruction-writer.js +97 -78
  22. package/engine/rpr-helpers.js +34 -32
  23. package/engine/run-builders.js +150 -39
  24. package/engine/surgical-diff-application.js +216 -0
  25. package/engine/surgical-mode.js +84 -519
  26. package/engine/surgical-run-splitting.js +96 -0
  27. package/engine/surgical-spans.js +169 -0
  28. package/engine/table-cell-context.js +15 -13
  29. package/engine/table-mode.js +39 -35
  30. package/index.d.ts +172 -0
  31. package/index.js +50 -47
  32. package/package.json +10 -2
  33. package/pipeline/ingestion-export.js +1 -0
  34. package/pipeline/ingestion-paragraph.js +37 -12
  35. package/pipeline/ingestion-table.js +11 -8
  36. package/scripts/build.mjs +40 -0
  37. package/scripts/check-types.mjs +29 -0
  38. package/scripts/export-validation-fixtures.mjs +125 -0
  39. package/scripts/lib/minimal-zip.mjs +155 -0
  40. package/scripts/run-tests.mjs +43 -0
  41. package/scripts/validate-fixtures-xsd.sh +37 -0
  42. package/scripts/word-com-differential.ps1 +133 -0
  43. package/scripts/word-com-smoke.ps1 +48 -0
  44. package/services/comment-locator.js +10 -9
  45. package/services/revision-comment-management.js +115 -1
  46. package/services/standalone-operation-runner.js +119 -69
  47. package/services/table-reconciliation.js +7 -8
@@ -0,0 +1,104 @@
1
+ # Validation
2
+
3
+ This package works on OOXML strings and intentionally leaves `.docx` zip
4
+ packaging to consumers (release *tooling* assembles minimal `.docx` fixtures
5
+ with a script-local zip writer; the published library still has no zip
6
+ dependency).
7
+
8
+ The test suite verifies the accept/reject round-trip invariant using the
9
+ library's own transforms. Because a shared misconception between the
10
+ generator and the resolver would pass those tests silently, release
11
+ validation adds **independent oracles**: Microsoft Word, LibreOffice, and
12
+ the ECMA-376 schemas.
13
+
14
+ ## Automated Checks (every `npm test`)
15
+
16
+ ```bash
17
+ npm test # includes tests/roundtrip_fuzz_tests.mjs (seeded, deterministic)
18
+ npm run test:isolation
19
+ npm run check:types
20
+ ```
21
+
22
+ The fuzz harness generates random paragraph structures and edits, then
23
+ asserts the round-trip invariant plus `validateRedlineOoxml` on each case.
24
+ Tune or reproduce with:
25
+
26
+ ```bash
27
+ FUZZ_SEED=<seed> FUZZ_ITERATIONS=<n> node tests/roundtrip_fuzz_tests.mjs
28
+ ```
29
+
30
+ A failing case prints its exact reproduction command.
31
+
32
+ ## Runtime Guardrail
33
+
34
+ `validateRedlineOoxml(oxml)` (exported from `index.js`) runs the structural
35
+ invariants at runtime and returns `{ valid, issues }`. Downstream packagers
36
+ should call it before writing engine output into `word/document.xml`.
37
+
38
+ ## Export Fixtures
39
+
40
+ ```bash
41
+ node scripts/export-validation-fixtures.mjs
42
+ ```
43
+
44
+ Writes to `tmp/validation-docx/`, per case:
45
+
46
+ - `<name>.document.xml` — generated `word/document.xml` payload
47
+ - `<name>.docx` — minimal assembled package
48
+ - `<name>.expected.json` — expected accept-all / reject-all plain text,
49
+ derived from edit *intent* (not from this library's transforms), so
50
+ external consumers act as independent oracles
51
+
52
+ ## Word Differential Check (Windows, desktop Word)
53
+
54
+ ```bash
55
+ node scripts/export-validation-fixtures.mjs
56
+ npm run smoke:word:diff
57
+ ```
58
+
59
+ For each fixture, desktop Word opens the `.docx`, confirms revisions are
60
+ visible, runs **AcceptAllRevisions**, and compares the document text to the
61
+ expected modified text; then reopens and runs **RejectAllRevisions** and
62
+ compares to the original text. This is the strongest check available: Word
63
+ itself resolves the revisions this library generated.
64
+
65
+ The older `npm run smoke:word -- path/to/file.docx` open-only smoke check
66
+ remains available for ad-hoc files.
67
+
68
+ ## Schema Validation (ECMA-376 transitional XSD)
69
+
70
+ ```bash
71
+ node scripts/export-validation-fixtures.mjs
72
+ bash scripts/validate-fixtures-xsd.sh
73
+ ```
74
+
75
+ Downloads (and caches in `.cache/ooxml-schemas/`) the transitional
76
+ wordprocessingml schemas from ECMA-376 Part 4, patches the `xml:` namespace
77
+ import to resolve offline, and validates every `*.document.xml` fixture with
78
+ `xmllint`. Requires `curl`, `unzip`, and `xmllint` (`libxml2-utils` on
79
+ Debian/Ubuntu; available on Windows via conda/msys).
80
+
81
+ ## LibreOffice Consumer Check
82
+
83
+ ```bash
84
+ cd tmp/validation-docx
85
+ soffice --headless --convert-to pdf --outdir converted *.docx
86
+ ```
87
+
88
+ A second independent OOXML consumer parsing the fixtures without error.
89
+
90
+ ## Continuous Validation
91
+
92
+ `.github/workflows/validation.yml` runs nightly (and on demand via
93
+ `workflow_dispatch`):
94
+
95
+ 1. **xsd-schema** — exports fixtures and validates them against the
96
+ ECMA-376 transitional `wml.xsd`.
97
+ 2. **libreoffice** — exports fixtures and converts them with headless
98
+ LibreOffice.
99
+ 3. **fuzz-extended** — 20,000 fuzz round-trip cases with a date-derived
100
+ seed, so every night explores new inputs. A failure log includes the
101
+ exact `FUZZ_SEED` reproduction command.
102
+
103
+ The Word differential check stays manual because it requires desktop Word;
104
+ run it before tagging a release.
@@ -0,0 +1,31 @@
1
+ # 0.1.4 Release Prep Design
2
+
3
+ **Objective:** Prepare the repository for a `0.1.4` patch release without publishing from this session.
4
+
5
+ ## Scope
6
+
7
+ - Bump the package version from `0.1.3` to `0.1.4` in release metadata.
8
+ - Update local release-note examples that are pinned to the prior version.
9
+ - Run release preflight verification locally after the version bump.
10
+ - Hand off the exact npm commands for the manual publish step.
11
+
12
+ ## Approach
13
+
14
+ Use minimal, explicit edits so the release prep is easy to review. Keep the release workflow local and manual, consistent with the existing policy in `.anson/release-ci-cd-notes.md`.
15
+
16
+ ## Verification
17
+
18
+ Run the same preflight commands documented in the local release notes:
19
+
20
+ - `npm test:isolation`
21
+ - `npm test`
22
+ - `npm run build`
23
+ - `npm pack --dry-run`
24
+
25
+ ## Manual Handoff
26
+
27
+ After verification, provide the exact commands for:
28
+
29
+ - `npm whoami`
30
+ - `npm publish --access public`
31
+ - `npm view @ansonlai/docx-redline-js version`
@@ -0,0 +1,108 @@
1
+ # 0.1.4 Release Prep Implementation Plan
2
+
3
+ > **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
4
+
5
+ **Goal:** Prepare the repository for a local/manual `0.1.4` release and verify it is ready to publish.
6
+
7
+ **Architecture:** Keep the release prep narrowly scoped to version metadata, local release instructions, and preflight verification. Do not publish from the implementation step; instead, leave the workspace in a verified, reviewable state and hand off the final npm commands.
8
+
9
+ **Tech Stack:** Node.js, npm, PowerShell, package metadata files
10
+
11
+ ---
12
+
13
+ ### Task 1: Update Release Metadata
14
+
15
+ **Files:**
16
+ - Create: `docs/plans/2026-03-01-release-0.1.4-design.md`
17
+ - Create: `docs/plans/2026-03-01-release-0.1.4.md`
18
+ - Modify: `package.json`
19
+ - Modify: `package-lock.json`
20
+ - Modify: `.anson/release-ci-cd-notes.md`
21
+
22
+ **Step 1: Write the failing test**
23
+
24
+ Inspect the current version references and confirm they still show `0.1.3`.
25
+
26
+ **Step 2: Run test to verify it fails**
27
+
28
+ Run: `rg -uu -n "0\\.1\\.3|0\\.1\\.4" .`
29
+ Expected: package metadata and local release-note examples still point to `0.1.3`.
30
+
31
+ **Step 3: Write minimal implementation**
32
+
33
+ - Change package version fields to `0.1.4`.
34
+ - Update local release-note example commands and CDN URLs to `0.1.4`.
35
+ - Save the release design and implementation plan docs.
36
+
37
+ **Step 4: Run test to verify it passes**
38
+
39
+ Run: `rg -uu -n "0\\.1\\.3|0\\.1\\.4" package.json package-lock.json .anson/release-ci-cd-notes.md`
40
+ Expected: only `0.1.4` appears in those release-facing files.
41
+
42
+ **Step 5: Commit**
43
+
44
+ ```bash
45
+ git add docs/plans/2026-03-01-release-0.1.4-design.md docs/plans/2026-03-01-release-0.1.4.md package.json package-lock.json .anson/release-ci-cd-notes.md
46
+ git commit -m "release: prep v0.1.4"
47
+ ```
48
+
49
+ ### Task 2: Run Release Preflight
50
+
51
+ **Files:**
52
+ - Modify: `dist/docx-redline-js.esm.js`
53
+
54
+ **Step 1: Write the failing test**
55
+
56
+ Assume the built artifact banner still reflects the previous version until the build runs.
57
+
58
+ **Step 2: Run test to verify it fails**
59
+
60
+ Run: `rg -n "v0\\.1\\.3|v0\\.1\\.4" dist/docx-redline-js.esm.js`
61
+ Expected: the banner still shows `v0.1.3` before rebuilding.
62
+
63
+ **Step 3: Write minimal implementation**
64
+
65
+ Run the documented preflight:
66
+
67
+ - `npm test:isolation`
68
+ - `npm test`
69
+ - `npm run build`
70
+ - `npm pack --dry-run`
71
+
72
+ **Step 4: Run test to verify it passes**
73
+
74
+ Run: `rg -n "v0\\.1\\.3|v0\\.1\\.4" dist/docx-redline-js.esm.js`
75
+ Expected: the banner shows `v0.1.4`, and the preflight commands complete successfully.
76
+
77
+ **Step 5: Commit**
78
+
79
+ ```bash
80
+ git add dist/docx-redline-js.esm.js
81
+ git commit -m "build: refresh dist for v0.1.4"
82
+ ```
83
+
84
+ ### Task 3: Publish Handoff
85
+
86
+ **Files:**
87
+ - No file changes
88
+
89
+ **Step 1: Write the failing test**
90
+
91
+ Confirm the package is not yet published from this session.
92
+
93
+ **Step 2: Run test to verify it fails**
94
+
95
+ Run: `npm view @ansonlai/docx-redline-js version`
96
+ Expected: the registry version may still report the prior published release until you publish manually.
97
+
98
+ **Step 3: Write minimal implementation**
99
+
100
+ Provide the exact local commands for npm auth check, publish, optional tag push, and post-publish verification.
101
+
102
+ **Step 4: Run test to verify it passes**
103
+
104
+ User runs the publish commands locally and confirms `npm view @ansonlai/docx-redline-js version` returns `0.1.4`.
105
+
106
+ **Step 5: Commit**
107
+
108
+ No additional commit required.