@ansonlai/docx-redline-js 0.6.1 → 0.6.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.
@@ -23,7 +23,7 @@ It is a development sample, not a package API.
23
23
  docx-redline extract contract.docx --search "termination" --around 3
24
24
  ```
25
25
 
26
- Search is case-insensitive. Direct hits are capped; follow `selection.nextAfter` with `--after`, and cite `humanReference`, not `P42`.
26
+ Search is case-insensitive; follow `selection.hint` if 0 matches were found for restorable text. Direct hits are capped; follow `selection.nextAfter` with `--after`, and cite `humanReference`, not `P42`.
27
27
 
28
28
  2. Copy `exactText` with `paragraphId` or `fingerprint`. Use a UTF-8 operations
29
29
  file or serializer-backed stdin, then apply once:
@@ -575,12 +575,17 @@ normalize or reconstruct `exactText`. Operation files follow
575
575
  Paragraph indexes are 1-based. Inspection filters are `--index 12`,
576
576
  `--range 10:30`, `--indexes 2,5,8`, `--search text`, `--revised`, `--table`,
577
577
  `--body`, `--non-empty`, and `--view accepted|rejected|current`. Search is
578
- case-insensitive. Add `--around N` (`--context N` or `-C N`) to a search;
578
+ case-insensitive. When a search returns 0 matches in the active view but matches
579
+ exist in the alternate view (such as searching for a deleted clause to restore),
580
+ `selection.hint` provides immediate guidance to re-run with `--view rejected`.
581
+ Add `--around N` (`--context N` or `-C N`) to a search;
579
582
  context records are labeled separately and do not consume the direct-hit
580
583
  `--limit`. Continue a bounded result with `--after <paragraph-index>`. Ordinary
581
584
  unscoped CLI inspection defaults to 20 direct records and a 48 KiB soft budget;
582
585
  `--all` deliberately opts out. A malformed filter or unknown option is an error
583
- rather than an unfiltered fallback.
586
+ rather than an unfiltered fallback. CLI help commands (`apply --help`,
587
+ `extract --help`, `--help`) report canonical GitHub repository URLs in their
588
+ `documentation` array.
584
589
 
585
590
  Mutating commands use `--author`, operation-level authors, then
586
591
  `DOCX_REDLINE_AUTHOR`, falling back visibly to `AI Redliner`; review-resolution
@@ -87,9 +87,12 @@ focused contextual extraction:
87
87
  docx-redline extract input.docx --search "force majeure" --around 3
88
88
  ```
89
89
 
90
- Use `selection.nextAfter` with `--after` when truncated. Apply once per stable
91
- batch. Run `docx-redline apply --help` for canonical redline, whole-paragraph
92
- comment, and rejected-view restore shapes; the operation schema remains
90
+ Use `selection.nextAfter` with `--after` when truncated. When a search for
91
+ deleted or restorable content yields 0 matches in accepted view, follow
92
+ `selection.hint` and re-run with `--view rejected`. Apply once per stable batch.
93
+ Run `docx-redline apply --help` for canonical redline, whole-paragraph comment,
94
+ and rejected-view restore shapes; CLI help documentation fields return canonical
95
+ GitHub URLs. The operation schema remains
93
96
  [document-operations.schema.json](schemas/document-operations.schema.json).
94
97
 
95
98
  ## Recovery contract
package/node/cli-help.js CHANGED
@@ -182,6 +182,14 @@ export function commandOptionKeys(command) {
182
182
  return (CLI_COMMAND_HELP[command]?.options || []).map(item => item.key);
183
183
  }
184
184
 
185
+ const DOCS_BASE_URL = 'https://github.com/AnsonLai/docx-redline-js/blob/main/';
186
+ export const CLI_DOCUMENTATION_URLS = Object.freeze([
187
+ `${DOCS_BASE_URL}AGENTS.md`,
188
+ `${DOCS_BASE_URL}docs/AGENT_FAST_START.md`,
189
+ `${DOCS_BASE_URL}docs/SKILL_AUTHORING.md`,
190
+ `${DOCS_BASE_URL}docs/schemas/document-operations.schema.json`
191
+ ]);
192
+
185
193
  export function buildCliHelp(command = null) {
186
194
  if (!command) {
187
195
  return {
@@ -190,7 +198,7 @@ export function buildCliHelp(command = null) {
190
198
  usage: 'docx-redline <command> [file.docx] [options]',
191
199
  commands: CLI_COMMANDS.map(name => ({ name, summary: CLI_COMMAND_HELP[name].summary })),
192
200
  notes: ['Run docx-redline <command> --help for flags, semantics, and bounded examples.'],
193
- documentation: ['AGENTS.md', 'docs/AGENT_FAST_START.md', 'docs/SKILL_AUTHORING.md', 'docs/schemas/document-operations.schema.json']
201
+ documentation: [...CLI_DOCUMENTATION_URLS]
194
202
  };
195
203
  }
196
204
  const entry = CLI_COMMAND_HELP[command];
@@ -204,6 +212,7 @@ export function buildCliHelp(command = null) {
204
212
  options: entry.options.map(({ key: _key, ...publicOption }) => publicOption),
205
213
  notes: entry.notes,
206
214
  examples: entry.examples,
207
- documentation: ['AGENTS.md', 'docs/AGENT_FAST_START.md', 'docs/SKILL_AUTHORING.md', 'docs/schemas/document-operations.schema.json']
215
+ documentation: [...CLI_DOCUMENTATION_URLS]
208
216
  };
209
217
  }
218
+
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ansonlai/docx-redline-js",
3
- "version": "0.6.1",
3
+ "version": "0.6.2",
4
4
  "description": "Host-independent OOXML reconciliation engine for .docx manipulation with track changes",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -309,6 +309,36 @@ export function inspectDocumentParts(parts, options = {}) {
309
309
  comments.set(id, definition);
310
310
  }
311
311
  const selected = selectInspectionParagraphs(paragraphs, options);
312
+ if (options.search && selected.selection && selected.selection.totalMatches === 0) {
313
+ const needle = String(options.search).toLowerCase();
314
+ const alternateView = revisionView === 'accepted' ? 'rejected' : 'accepted';
315
+ let rangeStart = 1;
316
+ let rangeEnd = paragraphNodes.length;
317
+ if (options.range) {
318
+ rangeStart = Number(options.range.start ?? options.range[0]);
319
+ rangeEnd = Number(options.range.end ?? options.range[1]);
320
+ }
321
+ let alternateMatches = 0;
322
+ for (let i = 0; i < paragraphNodes.length; i++) {
323
+ const index = i + 1;
324
+ if (options.range && (index < rangeStart || index > rangeEnd)) continue;
325
+ if (Array.isArray(options.indexes) && !options.indexes.includes(index)) continue;
326
+ const pNode = paragraphNodes[i];
327
+ if (options.table && !hasAncestor(pNode, 'tc')) continue;
328
+ if (options.body && hasAncestor(pNode, 'tc')) continue;
329
+ if (options.revised && revisionAuthors(pNode).length === 0) continue;
330
+ const altText = extractCanonicalParagraphText(pNode, { revisionView: alternateView });
331
+ if (options.skipEmpty && altText.length === 0) continue;
332
+ if (altText.toLowerCase().includes(needle)) {
333
+ alternateMatches++;
334
+ }
335
+ }
336
+ if (alternateMatches > 0) {
337
+ selected.selection.hint = revisionView === 'accepted'
338
+ ? `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.`
339
+ : `0 matches in rejected view, but ${alternateMatches} match${alternateMatches === 1 ? '' : 'es'} found in --view accepted. Re-run with --view accepted.`;
340
+ }
341
+ }
312
342
  paragraphs = selected.paragraphs;
313
343
  const allRevisionAuthors = [...new Set(paragraphs.flatMap(item => item.revisionAuthors))].sort();
314
344
  const coveredEntries = extractDocumentPartsEntries(parts);