@ansonlai/docx-redline-js 0.6.1 → 0.7.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 +19 -8
- package/CHANGELOG.md +43 -0
- package/README.md +57 -18
- package/dist/docx-redline-js.esm.js +29 -1
- package/dist/docx-redline-js.esm.js.map +2 -2
- package/dist/docx-redline-js.esm.min.js +66 -66
- package/dist/docx-redline-js.esm.min.js.map +3 -3
- package/docs/AGENT_FAST_START.md +22 -24
- package/docs/AGENT_KNOWLEDGE_BASE.md +33 -16
- package/docs/SKILL_AUTHORING.md +61 -22
- package/docs/releases/0.7.0.md +199 -0
- package/docs/schemas/document-operations.schema.json +13 -0
- package/docs/validation-reports/2026-09-14-localized-patching-rollout.md +90 -0
- package/index.d.ts +2 -0
- package/node/cli-help.js +30 -3
- package/node/cli.js +259 -34
- package/package.json +5 -1
- package/services/batch-operation-orchestrator.js +25 -16
- package/services/document-inspection.js +30 -0
- package/services/document-operation-applier.js +68 -9
- package/services/document-operation-contract.js +56 -5
- package/services/localized-replacement-compiler.js +304 -0
- package/services/operation-batch-compiler.js +33 -1
- package/services/operation-preflight.js +10 -6
- package/services/standalone-operation-runner.d.ts +55 -3
package/AGENTS.md
CHANGED
|
@@ -21,9 +21,16 @@ specific advanced operation, API, or recovery topic you need.
|
|
|
21
21
|
|
|
22
22
|
## Ordinary document edits
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
For a literal mechanical edit with known old and new text, try one fail-closed
|
|
25
|
+
apply call. Use a visible heading plus a directional range when global matching
|
|
26
|
+
is too broad:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
docx-redline apply contract.docx --search "Section 4.1" --context-range 1:3 --find "thirty (30) days" --replace "sixty (60) days" --profile agent --output reviewed.docx
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
For semantic drafting, inspect once and apply once. With a structured wrapper,
|
|
33
|
+
use revision-bound handles. For shell-only work, use serializer-backed stdin:
|
|
27
34
|
|
|
28
35
|
```bash
|
|
29
36
|
docx-redline extract contract.docx --search "termination" --around 3
|
|
@@ -38,10 +45,12 @@ Consolidate incompatible writes to the same source; use captures for intentional
|
|
|
38
45
|
created-content dependencies.
|
|
39
46
|
|
|
40
47
|
Require `completion: true`, `written: true`, a non-null output path, and no
|
|
41
|
-
per-operation errors.
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
48
|
+
per-operation errors. Localized edits also require `change.committed: true` and
|
|
49
|
+
`change.verification.acceptedViewMatchesCompiledText: true`. Follow
|
|
50
|
+
`error.recovery.action` and `retryPlan`; never retry unchanged failed arguments.
|
|
51
|
+
Follow `selection.hint` for restorable text. Do not accept/reject another
|
|
52
|
+
reviewer's work or remove comments without explicit user authorization. The
|
|
53
|
+
source is never overwritten unless `--in-place` is explicit.
|
|
45
54
|
|
|
46
55
|
The agent profile preserves progressive execution and the ordinary revision
|
|
47
56
|
policy. Add `--atomic` or `--existing-revisions slice-cross-author` only when
|
|
@@ -63,7 +72,9 @@ targeting, revision allocation, comments, numbering, validation, or rollback.
|
|
|
63
72
|
The stateful wrapper in `examples/agent-session-wrapper.mjs` is a testable
|
|
64
73
|
development demonstration only. It is excluded from package files and exports.
|
|
65
74
|
Production harnesses own their transport and negotiate the minimum CLI
|
|
66
|
-
`contractVersion`/capabilities they use.
|
|
75
|
+
`contractVersion`/capabilities they use. The 0.7.0 localized fast path requires
|
|
76
|
+
contract 8 and its localized replacement, speculative apply, and change-summary
|
|
77
|
+
capabilities.
|
|
67
78
|
|
|
68
79
|
## Code map
|
|
69
80
|
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,49 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 0.7.0
|
|
6
|
+
|
|
7
|
+
### Agent Performance and Localized Editing
|
|
8
|
+
|
|
9
|
+
- **Localized exact replacements:** `redline`/`replace` operations may provide
|
|
10
|
+
`replacements: [{ find, replace, occurrence? }]` instead of a complete
|
|
11
|
+
`modified` paragraph. The compiler resolves the accepted-view source once,
|
|
12
|
+
applies non-overlapping exact replacements simultaneously, synthesizes the
|
|
13
|
+
canonical desired paragraph, and delegates to the unchanged OOXML engine.
|
|
14
|
+
- **One-turn speculative apply:** `docx-redline apply --find ... --replace ...`
|
|
15
|
+
can resolve a globally unique source literal without preliminary extraction.
|
|
16
|
+
`--search` plus signed `--context-range START:END` scopes visible headings and
|
|
17
|
+
multi-paragraph provisions; `--around N` is symmetric shorthand.
|
|
18
|
+
- **Fail-closed selection:** Missing anchors and patch sources, multiple eligible
|
|
19
|
+
paragraphs, ambiguous occurrences, overlaps, conflicts, and unsupported
|
|
20
|
+
localized shapes refuse mutation. A failed speculative command never writes
|
|
21
|
+
or truncates its output path.
|
|
22
|
+
- **Verified change evidence:** Localized operation results include a compact
|
|
23
|
+
`change` object with target location, contextual anchor/range, exact
|
|
24
|
+
replacement entries, bounded before/after excerpts, commit disposition, and
|
|
25
|
+
post-mutation accepted-view verification. Atomic rollback marks the evidence
|
|
26
|
+
non-committed and `rolled_back`.
|
|
27
|
+
- **CLI contract version 8:** Adds `localized-replacements-v1`,
|
|
28
|
+
`speculative-search-apply-v1`, and `localized-change-summary-v1`. Skills and
|
|
29
|
+
harnesses should pin version 0.7.0 and negotiate only the capabilities used.
|
|
30
|
+
- **Measured workflow reduction:** The checked benchmark records 50% fewer tool
|
|
31
|
+
turns and a 64.77%–78.98% smaller deterministic request-token proxy across
|
|
32
|
+
three literal-edit cases. Median native engine/I/O time remained effectively
|
|
33
|
+
neutral; provider reasoning and network latency were not estimated.
|
|
34
|
+
|
|
35
|
+
### Compatibility
|
|
36
|
+
|
|
37
|
+
- Existing `modified` operations, strong targets, operations files/stdin,
|
|
38
|
+
tracked-change generation, package validation, rollback, comments,
|
|
39
|
+
Accept/Reject, and revision policies remain supported.
|
|
40
|
+
- Localized replacement fields and successful `change` evidence are additive.
|
|
41
|
+
Wrappers that adopt them must require CLI contract 8; integrations using only
|
|
42
|
+
earlier capabilities can continue using their existing operation shapes.
|
|
43
|
+
- The implementation remains OOXML-only and adds no runtime dependency or Word,
|
|
44
|
+
Office automation, COM, or proprietary document API requirement.
|
|
45
|
+
|
|
46
|
+
## 0.6.0–0.6.2
|
|
47
|
+
|
|
5
48
|
### Safety Fixes
|
|
6
49
|
|
|
7
50
|
- **Foreign deleted-paragraph resurrection guard**: Refuses non-empty same-paragraph edits when another author owns the paragraph-mark deletion and all existing paragraph content is deleted. The operation now returns `FOREIGN_PARAGRAPH_MARK_DELETION` with the owning author instead of emitting lifecycle-unsafe OOXML; atomic document operations roll back byte-for-byte. `validateRedlineOoxml` reports already-authored instances as warnings.
|
package/README.md
CHANGED
|
@@ -15,9 +15,25 @@ Converts AI-generated or programmatic text/markdown edits into valid Office Open
|
|
|
15
15
|
- Comment management: delete comments by author or for all authors
|
|
16
16
|
- Highlights: apply highlight colors to runs
|
|
17
17
|
- Markdown and OOXML conversion in both directions
|
|
18
|
-
- Status/error result fields for parse, targeting, and existing-revision failures
|
|
19
|
-
-
|
|
20
|
-
-
|
|
18
|
+
- Status/error result fields for parse, targeting, and existing-revision failures
|
|
19
|
+
- Localized exact replacements and fail-closed one-turn CLI edits with verified before/after evidence
|
|
20
|
+
- Package plumbing helpers for numbering.xml, comments.xml, content types, and relationships
|
|
21
|
+
- Zero host dependencies: works in Node.js, browsers, Deno, and similar JS runtimes with DOM parsing support
|
|
22
|
+
|
|
23
|
+
## What's New in 0.7.0
|
|
24
|
+
|
|
25
|
+
Version 0.7.0 adds a contract-8 fast path for exact mechanical edits. Agents can
|
|
26
|
+
send a small `find`/`replace` request instead of reproducing a complete legal
|
|
27
|
+
paragraph, and may omit a strong target when the source literal resolves to one
|
|
28
|
+
accepted-view paragraph. Visible headings can narrow the attempt with a signed
|
|
29
|
+
directional window such as `--search "Section 4.1" --context-range 1:3`.
|
|
30
|
+
|
|
31
|
+
Speculative edits fail without writing when the anchor, paragraph, or source
|
|
32
|
+
span is missing or ambiguous. Successful localized results include a committed
|
|
33
|
+
`change` object with the selected legal location, bounded before/after excerpts,
|
|
34
|
+
and actual accepted-view verification. Existing full-paragraph operations,
|
|
35
|
+
tracked-change semantics, validation, rollback, and review policies remain
|
|
36
|
+
available unchanged. See the [complete 0.7.0 release notes](./docs/releases/0.7.0.md).
|
|
21
37
|
## Documentation Index
|
|
22
38
|
|
|
23
39
|
| Document | Description |
|
|
@@ -147,10 +163,13 @@ const inventory = inspectDocumentParts({ documentXml, commentsXml, numberingXml
|
|
|
147
163
|
Inspection returns exact paragraph text, target IDs/fingerprints, headings,
|
|
148
164
|
table/list context, revision authors, and joined comment anchors. Filters such
|
|
149
165
|
as `search`, `indexes`, `range`, `revisedOnly`, `inTable`, and `skipEmpty`
|
|
150
|
-
limit output. Search is a case-insensitive substring match; `around` adds nearby
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
166
|
+
limit output. Search is a case-insensitive substring match; `around` adds nearby drafting
|
|
167
|
+
context, while `limit` and `after` page direct hits. When a search yields 0
|
|
168
|
+
matches in the active view, `selection.hint` provides guidance if matches exist
|
|
169
|
+
in the alternate revision view (such as searching for deleted text to restore).
|
|
170
|
+
`revisionView` accepts `accepted`, `rejected`, or `current`. Returned
|
|
171
|
+
paragraphs identify matches versus context and include `humanReference` for
|
|
172
|
+
user-facing summaries.
|
|
154
173
|
|
|
155
174
|
For complete `.docx` buffers in Node:
|
|
156
175
|
|
|
@@ -212,9 +231,23 @@ benchmark explicitly does not claim to measure LLM reasoning or provider/tool
|
|
|
212
231
|
latency. Checked comparative results are in the
|
|
213
232
|
[agent protocol rollout audit](./docs/validation-reports/2026-09-12-agent-protocol-rollout.md).
|
|
214
233
|
|
|
234
|
+
> **Pre-1.0 integration warning:** Agent skills, MCP servers, and harnesses
|
|
235
|
+
> should pin the exact `@ansonlai/docx-redline-js` release they were tested
|
|
236
|
+
> against and declare the CLI contract version/capabilities they require. Do
|
|
237
|
+
> not treat a newly installed release or contract as verified until the
|
|
238
|
+
> integration's compatibility tests pass. See the
|
|
239
|
+
> [skill-authoring contract](./docs/SKILL_AUTHORING.md#runtime-negotiation).
|
|
240
|
+
|
|
215
241
|
### Agent CLI
|
|
216
|
-
|
|
242
|
+
|
|
217
243
|
```bash
|
|
244
|
+
# One-turn exact mechanical edit; fails closed unless one paragraph matches
|
|
245
|
+
docx-redline apply contract.docx --find "thirty (30) days" --replace "sixty (60) days" --profile agent --output reviewed.docx
|
|
246
|
+
|
|
247
|
+
# Directional context after a visible heading; repeated cross-references are safe
|
|
248
|
+
docx-redline apply contract.docx --search "Section 4.1" --context-range 1:3 --find "thirty (30) days" --replace "sixty (60) days" --profile agent --output reviewed.docx
|
|
249
|
+
|
|
250
|
+
# Semantic drafting still starts with focused context
|
|
218
251
|
docx-redline extract contract.docx --search "termination" --around 3
|
|
219
252
|
docx-redline preflight contract.docx --operations operations.json --author "Editor"
|
|
220
253
|
docx-redline apply contract.docx --operations operations.json --author "Editor" --output reviewed.docx
|
|
@@ -249,25 +282,31 @@ All commands emit JSON on stdout. `apply` defaults:
|
|
|
249
282
|
- **Compact stdout**: `--compact` emits one-line mutation JSON. It changes serialization only, not operation semantics.
|
|
250
283
|
- **Tracked changes**: Defaults to `generateRedlines: true`. Pass `--no-redlines` when clean direct text edits are desired.
|
|
251
284
|
- **Inline edits**: Use `--target <text>` with `--modified <text>` or `--comment <text>` for quick one-liners without creating a JSON file.
|
|
285
|
+
- **Localized edits**: Use `--find`/`--replace` with a known strong target, or omit the target for fail-closed global resolution. Add `--search` with `--context-range 1:3` for text strictly after a visible heading; `--around 3` is symmetric. Successful localized results include bounded before/after excerpts and post-mutation accepted-view verification in `results[i].change`.
|
|
252
286
|
- **Compact mutation results**: `apply`, `accept`, `reject`, and `delete-comments` omit full OOXML/package payloads and inspection text from stdout. CLI operation results omit duplicate nested receipt bodies; the ordered top-level `receipts` array is authoritative. Successful exact target-match diagnostics are omitted and equivalent-whitespace matches retain only mode/count. Node and standalone-runner results remain unchanged. Use `validate` when full issue arrays are needed.
|
|
253
287
|
|
|
254
288
|
Inspection commands default to 20 direct matches and a 48 KiB soft response
|
|
255
|
-
budget when no explicit positional scope is supplied.
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
289
|
+
budget when no explicit positional scope is supplied. When a search returns 0
|
|
290
|
+
matches in the requested view, `selection.hint` provides immediate guidance if
|
|
291
|
+
matches exist in the alternate view (such as searching for a deleted clause to
|
|
292
|
+
restore). Use `--limit` with `--after <paragraph-index>` to continue, `--around N`
|
|
293
|
+
(aliases `--context` and `-C`) to include nearby paragraphs, and `--all` only
|
|
294
|
+
for deliberate unbounded inspection. Every retained target is complete; an
|
|
295
|
+
individually oversized paragraph is returned whole with an `oversizeItem`
|
|
296
|
+
marker. Machine `index` and `ref` fields are for targeting and pagination, not
|
|
297
|
+
user-facing Word locations; use `humanReference`, `provision`, or
|
|
298
|
+
`nearestHeading` in reports.
|
|
262
299
|
|
|
263
|
-
`docx-redline version` reports contract version
|
|
300
|
+
`docx-redline version` reports contract version 8 and the additive
|
|
264
301
|
`command-help-v1`, `inspection-context-v1`, `bounded-inspection-v1`,
|
|
265
302
|
`human-document-references-v1`, `batch-start-source-binding`,
|
|
266
303
|
`recovery-envelope-v1`, `require-complete-exit`, `operations-stdin`,
|
|
267
304
|
`agent-safety-profile-v2`, `deduplicated-cli-receipts`, and
|
|
268
|
-
`compact-cli-json-v1`
|
|
305
|
+
`compact-cli-json-v1`, `localized-replacements-v1`,
|
|
306
|
+
`speculative-search-apply-v1`, and `localized-change-summary-v1` capabilities.
|
|
307
|
+
Wrappers should negotiate only the
|
|
269
308
|
capabilities they use. Run `docx-redline <command> --help` for that command's
|
|
270
|
-
machine-readable options, behavior, exit codes, and compact examples.
|
|
309
|
+
machine-readable options, behavior, exit codes, canonical GitHub documentation links, and compact examples.
|
|
271
310
|
|
|
272
311
|
See the [compact agent fast start](./docs/AGENT_FAST_START.md), the
|
|
273
312
|
[skill/harness authoring contract](./docs/SKILL_AUTHORING.md), and the
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// @ansonlai/docx-redline-js v0.
|
|
1
|
+
// @ansonlai/docx-redline-js v0.7.0 — https://github.com/AnsonLai/docx-redline-js
|
|
2
2
|
var __create = Object.create;
|
|
3
3
|
var __defProp = Object.defineProperty;
|
|
4
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
@@ -11594,6 +11594,34 @@ function inspectDocumentParts(parts, options = {}) {
|
|
|
11594
11594
|
comments.set(id, definition);
|
|
11595
11595
|
}
|
|
11596
11596
|
const selected = selectInspectionParagraphs(paragraphs, options);
|
|
11597
|
+
if (options.search && selected.selection && selected.selection.totalMatches === 0) {
|
|
11598
|
+
const needle = String(options.search).toLowerCase();
|
|
11599
|
+
const alternateView = revisionView === "accepted" ? "rejected" : "accepted";
|
|
11600
|
+
let rangeStart = 1;
|
|
11601
|
+
let rangeEnd = paragraphNodes.length;
|
|
11602
|
+
if (options.range) {
|
|
11603
|
+
rangeStart = Number(options.range.start ?? options.range[0]);
|
|
11604
|
+
rangeEnd = Number(options.range.end ?? options.range[1]);
|
|
11605
|
+
}
|
|
11606
|
+
let alternateMatches = 0;
|
|
11607
|
+
for (let i = 0; i < paragraphNodes.length; i++) {
|
|
11608
|
+
const index = i + 1;
|
|
11609
|
+
if (options.range && (index < rangeStart || index > rangeEnd)) continue;
|
|
11610
|
+
if (Array.isArray(options.indexes) && !options.indexes.includes(index)) continue;
|
|
11611
|
+
const pNode = paragraphNodes[i];
|
|
11612
|
+
if (options.table && !hasAncestor(pNode, "tc")) continue;
|
|
11613
|
+
if (options.body && hasAncestor(pNode, "tc")) continue;
|
|
11614
|
+
if (options.revised && revisionAuthors(pNode).length === 0) continue;
|
|
11615
|
+
const altText = extractCanonicalParagraphText(pNode, { revisionView: alternateView });
|
|
11616
|
+
if (options.skipEmpty && altText.length === 0) continue;
|
|
11617
|
+
if (altText.toLowerCase().includes(needle)) {
|
|
11618
|
+
alternateMatches++;
|
|
11619
|
+
}
|
|
11620
|
+
}
|
|
11621
|
+
if (alternateMatches > 0) {
|
|
11622
|
+
selected.selection.hint = revisionView === "accepted" ? `0 matches in accepted view, but ${alternateMatches} match${alternateMatches === 1 ? "" : "es"} found in --view rejected. If searching for deleted text to restore, re-run with --view rejected.` : `0 matches in rejected view, but ${alternateMatches} match${alternateMatches === 1 ? "" : "es"} found in --view accepted. Re-run with --view accepted.`;
|
|
11623
|
+
}
|
|
11624
|
+
}
|
|
11597
11625
|
paragraphs = selected.paragraphs;
|
|
11598
11626
|
const allRevisionAuthors = [...new Set(paragraphs.flatMap((item) => item.revisionAuthors))].sort();
|
|
11599
11627
|
const coveredEntries = extractDocumentPartsEntries(parts);
|