@eigenpal/docx-editor-agents 0.0.28 → 0.0.29
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/dist/bridge.js +3 -1
- package/dist/bridge.js.map +1 -1
- package/dist/bridge.mjs +8 -0
- package/dist/bridge.mjs.map +1 -0
- package/dist/index.js +22 -17
- package/dist/index.js.map +1 -1
- package/dist/{index.cjs → index.mjs} +19 -24
- package/dist/index.mjs.map +1 -0
- package/package.json +7 -8
- package/dist/bridge.cjs +0 -10
- package/dist/bridge.cjs.map +0 -1
- package/dist/index.cjs.map +0 -1
- /package/dist/{bridge.d.cts → bridge.d.mts} +0 -0
- /package/dist/{index.d.cts → index.d.mts} +0 -0
package/dist/bridge.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
1
3
|
// src/bridge.ts
|
|
2
4
|
function createReviewBridge(_editorRef) {
|
|
3
5
|
throw new Error("createReviewBridge is not yet implemented");
|
|
4
6
|
}
|
|
5
7
|
|
|
6
|
-
|
|
8
|
+
exports.createReviewBridge = createReviewBridge;
|
|
7
9
|
//# sourceMappingURL=bridge.js.map
|
|
8
10
|
//# sourceMappingURL=bridge.js.map
|
package/dist/bridge.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/bridge.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../src/bridge.ts"],"names":[],"mappings":";;;AASO,SAAS,mBAAmB,UAAA,EAA8C;AAC/E,EAAA,MAAM,IAAI,MAAM,2CAA2C,CAAA;AAC7D","file":"bridge.js","sourcesContent":["/**\n * Editor ref bridge — optional client-side integration.\n *\n * Separate entry point: import from '@eigenpal/docx-editor-agents/bridge'\n * This file may import React/ProseMirror — NOT included in the main headless bundle.\n *\n * TODO: Implement in task 9.1\n */\n\nexport function createReviewBridge(_editorRef: unknown): Record<string, unknown> {\n throw new Error('createReviewBridge is not yet implemented');\n}\n"]}
|
package/dist/bridge.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/bridge.ts"],"names":[],"mappings":";AASO,SAAS,mBAAmB,UAAA,EAA8C;AAC/E,EAAA,MAAM,IAAI,MAAM,2CAA2C,CAAA;AAC7D","file":"bridge.mjs","sourcesContent":["/**\n * Editor ref bridge — optional client-side integration.\n *\n * Separate entry point: import from '@eigenpal/docx-editor-agents/bridge'\n * This file may import React/ProseMirror — NOT included in the main headless bundle.\n *\n * TODO: Implement in task 9.1\n */\n\nexport function createReviewBridge(_editorRef: unknown): Record<string, unknown> {\n throw new Error('createReviewBridge is not yet implemented');\n}\n"]}
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var headless = require('@eigenpal/docx-core/headless');
|
|
2
4
|
|
|
3
5
|
// src/DocxReviewer.ts
|
|
4
6
|
function isTrackedChange(item) {
|
|
@@ -8,9 +10,9 @@ function getTrackedChangeText(content) {
|
|
|
8
10
|
const parts = [];
|
|
9
11
|
for (const item of content) {
|
|
10
12
|
if (item.type === "run") {
|
|
11
|
-
parts.push(getRunText(item));
|
|
13
|
+
parts.push(headless.getRunText(item));
|
|
12
14
|
} else if (item.type === "hyperlink") {
|
|
13
|
-
parts.push(getHyperlinkText(item));
|
|
15
|
+
parts.push(headless.getHyperlinkText(item));
|
|
14
16
|
}
|
|
15
17
|
}
|
|
16
18
|
return parts.join("");
|
|
@@ -104,11 +106,11 @@ function isInRange(index, from, to) {
|
|
|
104
106
|
function buildParagraphBlock(para, index, includeTrackedChanges, includeCommentAnchors) {
|
|
105
107
|
const text = buildParagraphText(para, includeTrackedChanges, includeCommentAnchors);
|
|
106
108
|
const styleId = para.formatting?.styleId;
|
|
107
|
-
if (isHeadingStyle(styleId)) {
|
|
109
|
+
if (headless.isHeadingStyle(styleId)) {
|
|
108
110
|
return {
|
|
109
111
|
type: "heading",
|
|
110
112
|
index,
|
|
111
|
-
level: parseHeadingLevel(styleId) ?? 1,
|
|
113
|
+
level: headless.parseHeadingLevel(styleId) ?? 1,
|
|
112
114
|
text
|
|
113
115
|
};
|
|
114
116
|
}
|
|
@@ -191,9 +193,9 @@ function buildParagraphText(para, includeTrackedChanges, includeCommentAnchors)
|
|
|
191
193
|
continue;
|
|
192
194
|
}
|
|
193
195
|
if (item.type === "run") {
|
|
194
|
-
parts.push(getRunText(item));
|
|
196
|
+
parts.push(headless.getRunText(item));
|
|
195
197
|
} else if (item.type === "hyperlink") {
|
|
196
|
-
parts.push(getHyperlinkText(item));
|
|
198
|
+
parts.push(headless.getHyperlinkText(item));
|
|
197
199
|
} else if (isTrackedChange(item)) {
|
|
198
200
|
const text = getTrackedChangeText(item.content);
|
|
199
201
|
if (item.type === "insertion" || item.type === "moveTo") {
|
|
@@ -240,14 +242,14 @@ function flattenRuns(paragraph) {
|
|
|
240
242
|
for (let ci = 0; ci < paragraph.content.length; ci++) {
|
|
241
243
|
const item = paragraph.content[ci];
|
|
242
244
|
if (item.type === "run") {
|
|
243
|
-
const text = getRunText(item);
|
|
245
|
+
const text = headless.getRunText(item);
|
|
244
246
|
result.push({ contentIndex: ci, run: item, text, startPos: pos });
|
|
245
247
|
pos += text.length;
|
|
246
248
|
} else if (item.type === "hyperlink") {
|
|
247
249
|
for (let hi = 0; hi < item.children.length; hi++) {
|
|
248
250
|
const child = item.children[hi];
|
|
249
251
|
if (child.type === "run") {
|
|
250
|
-
const text = getRunText(child);
|
|
252
|
+
const text = headless.getRunText(child);
|
|
251
253
|
result.push({ contentIndex: ci, run: child, text, startPos: pos });
|
|
252
254
|
pos += text.length;
|
|
253
255
|
}
|
|
@@ -256,13 +258,13 @@ function flattenRuns(paragraph) {
|
|
|
256
258
|
for (let ri = 0; ri < item.content.length; ri++) {
|
|
257
259
|
const child = item.content[ri];
|
|
258
260
|
if (child.type === "run") {
|
|
259
|
-
const text = getRunText(child);
|
|
261
|
+
const text = headless.getRunText(child);
|
|
260
262
|
result.push({ contentIndex: ci, run: child, text, startPos: pos });
|
|
261
263
|
pos += text.length;
|
|
262
264
|
} else if (child.type === "hyperlink") {
|
|
263
265
|
for (const hc of child.children) {
|
|
264
266
|
if (hc.type === "run") {
|
|
265
|
-
const text = getRunText(hc);
|
|
267
|
+
const text = headless.getRunText(hc);
|
|
266
268
|
result.push({ contentIndex: ci, run: hc, text, startPos: pos });
|
|
267
269
|
pos += text.length;
|
|
268
270
|
}
|
|
@@ -315,7 +317,7 @@ function isolateMatchedText(paragraph, search, paragraphIndex) {
|
|
|
315
317
|
const { startOffset, endOffset } = result;
|
|
316
318
|
const endItem = paragraph.content[endRunIndex];
|
|
317
319
|
if (endItem.type === "run") {
|
|
318
|
-
const endText = getRunText(endItem);
|
|
320
|
+
const endText = headless.getRunText(endItem);
|
|
319
321
|
if (endOffset < endText.length) {
|
|
320
322
|
const afterRun = makeRunWithText(endText.slice(endOffset), endItem);
|
|
321
323
|
setRunText(endItem, endText.slice(0, endOffset));
|
|
@@ -324,7 +326,7 @@ function isolateMatchedText(paragraph, search, paragraphIndex) {
|
|
|
324
326
|
}
|
|
325
327
|
const startItem = paragraph.content[startRunIndex];
|
|
326
328
|
if (startItem.type === "run" && startOffset > 0) {
|
|
327
|
-
const startText = getRunText(startItem);
|
|
329
|
+
const startText = headless.getRunText(startItem);
|
|
328
330
|
const beforeRun = makeRunWithText(startText.slice(0, startOffset), startItem);
|
|
329
331
|
setRunText(startItem, startText.slice(startOffset));
|
|
330
332
|
paragraph.content.splice(startRunIndex, 0, beforeRun);
|
|
@@ -497,12 +499,12 @@ function buildAnchoredTextMap(body) {
|
|
|
497
499
|
openRanges.delete(item.id);
|
|
498
500
|
}
|
|
499
501
|
} else if (item.type === "run") {
|
|
500
|
-
const text = getRunText(item);
|
|
502
|
+
const text = headless.getRunText(item);
|
|
501
503
|
for (const open of openRanges.values()) {
|
|
502
504
|
open.parts.push(text);
|
|
503
505
|
}
|
|
504
506
|
} else if (item.type === "hyperlink") {
|
|
505
|
-
const text = item.children.filter((c) => c.type === "run").map(getRunText).join("");
|
|
507
|
+
const text = item.children.filter((c) => c.type === "run").map(headless.getRunText).join("");
|
|
506
508
|
for (const open of openRanges.values()) {
|
|
507
509
|
open.parts.push(text);
|
|
508
510
|
}
|
|
@@ -772,7 +774,7 @@ var DocxReviewer = class _DocxReviewer {
|
|
|
772
774
|
* @param author - Default author name for comments and changes. (default: 'AI')
|
|
773
775
|
*/
|
|
774
776
|
static async fromBuffer(buffer, author = "AI") {
|
|
775
|
-
const doc = await parseDocx(buffer, { preloadFonts: false });
|
|
777
|
+
const doc = await headless.parseDocx(buffer, { preloadFonts: false });
|
|
776
778
|
return new _DocxReviewer(doc, author, buffer);
|
|
777
779
|
}
|
|
778
780
|
get body() {
|
|
@@ -891,6 +893,9 @@ var DocxReviewer = class _DocxReviewer {
|
|
|
891
893
|
}
|
|
892
894
|
};
|
|
893
895
|
|
|
894
|
-
|
|
896
|
+
exports.ChangeNotFoundError = ChangeNotFoundError;
|
|
897
|
+
exports.CommentNotFoundError = CommentNotFoundError;
|
|
898
|
+
exports.DocxReviewer = DocxReviewer;
|
|
899
|
+
exports.TextNotFoundError = TextNotFoundError;
|
|
895
900
|
//# sourceMappingURL=index.js.map
|
|
896
901
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils.ts","../src/content.ts","../src/errors.ts","../src/textSearch.ts","../src/discovery.ts","../src/comments.ts","../src/changes.ts","../src/batch.ts","../src/DocxReviewer.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Shared utilities for agent-use package.\n */\n\nimport type {\n DocumentBody,\n Paragraph,\n Run,\n Hyperlink,\n ParagraphContent,\n Insertion,\n Deletion,\n MoveFrom,\n MoveTo,\n} from '@eigenpal/docx-core/headless';\nimport {\n getRunText,\n getHyperlinkText,\n isHeadingStyle,\n parseHeadingLevel,\n} from '@eigenpal/docx-core/headless';\n\n// Re-export from core so other modules import from one place\nexport { getRunText, getHyperlinkText, isHeadingStyle, parseHeadingLevel };\n\n// ============================================================================\n// TRACKED CHANGE HELPERS\n// ============================================================================\n\nexport type TrackedChangeItem = Insertion | Deletion | MoveFrom | MoveTo;\n\nexport function isTrackedChange(item: ParagraphContent): item is TrackedChangeItem {\n return (\n item.type === 'insertion' ||\n item.type === 'deletion' ||\n item.type === 'moveFrom' ||\n item.type === 'moveTo'\n );\n}\n\nexport function getTrackedChangeText(content: (Run | Hyperlink)[]): string {\n const parts: string[] = [];\n for (const item of content) {\n if (item.type === 'run') {\n parts.push(getRunText(item));\n } else if (item.type === 'hyperlink') {\n parts.push(getHyperlinkText(item));\n }\n }\n return parts.join('');\n}\n\n// ============================================================================\n// DOCUMENT TRAVERSAL\n// ============================================================================\n\n/**\n * Get a paragraph by its document-wide index (counting into tables).\n * Throws on out-of-bounds.\n */\nexport function getParagraphAtIndex(body: DocumentBody, paragraphIndex: number): Paragraph {\n let index = 0;\n for (const block of body.content) {\n if (block.type === 'paragraph') {\n if (index === paragraphIndex) return block;\n index++;\n } else if (block.type === 'table') {\n for (const row of block.rows) {\n for (const cell of row.cells) {\n for (const cellBlock of cell.content) {\n if (cellBlock.type === 'paragraph') {\n if (index === paragraphIndex) return cellBlock;\n index++;\n }\n }\n }\n }\n } else {\n index++;\n }\n }\n throw new Error(`Paragraph index ${paragraphIndex} out of bounds (max: ${index - 1})`);\n}\n\n/**\n * Walk all paragraphs in the document body (including inside tables),\n * calling the callback with each paragraph and its document-wide index.\n */\nexport function forEachParagraph(\n body: DocumentBody,\n fn: (para: Paragraph, index: number) => void | boolean\n): void {\n let index = 0;\n for (const block of body.content) {\n if (block.type === 'paragraph') {\n if (fn(block, index) === false) return;\n index++;\n } else if (block.type === 'table') {\n for (const row of block.rows) {\n for (const cell of row.cells) {\n for (const cellBlock of cell.content) {\n if (cellBlock.type === 'paragraph') {\n if (fn(cellBlock, index) === false) return;\n index++;\n }\n }\n }\n }\n } else {\n index++;\n }\n }\n}\n","/**\n * getContent() — renders document as structured ContentBlock array for LLM consumption.\n * formatContentForLLM() — converts blocks to plain text (avoids JSON quote-escaping issues).\n */\n\nimport type { DocumentBody, Paragraph, Table } from '@eigenpal/docx-core/headless';\nimport type { ContentBlock, GetContentOptions } from './types';\nimport {\n getRunText,\n getHyperlinkText,\n getTrackedChangeText,\n isTrackedChange,\n isHeadingStyle,\n parseHeadingLevel,\n} from './utils';\n\n/**\n * Walk document body and produce ContentBlock array.\n */\nexport function getContent(body: DocumentBody, options: GetContentOptions = {}): ContentBlock[] {\n const {\n fromIndex,\n toIndex,\n includeTrackedChanges = true,\n includeCommentAnchors = true,\n } = options;\n\n const blocks: ContentBlock[] = [];\n let index = 0;\n\n for (const block of body.content) {\n if (block.type === 'paragraph') {\n if (isInRange(index, fromIndex, toIndex)) {\n blocks.push(\n buildParagraphBlock(block, index, includeTrackedChanges, includeCommentAnchors)\n );\n }\n index++;\n } else if (block.type === 'table') {\n if (isInRange(index, fromIndex, toIndex)) {\n blocks.push(buildTableBlock(block, index, includeTrackedChanges, includeCommentAnchors));\n }\n // Advance by number of cell paragraphs (matching getParagraphAtIndex counting)\n for (const row of block.rows) {\n for (const cell of row.cells) {\n for (const cellBlock of cell.content) {\n if (cellBlock.type === 'paragraph') {\n index++;\n }\n }\n }\n }\n } else {\n index++;\n }\n }\n\n return blocks;\n}\n\nfunction isInRange(index: number, from?: number, to?: number): boolean {\n return (from === undefined || index >= from) && (to === undefined || index <= to);\n}\n\nfunction buildParagraphBlock(\n para: Paragraph,\n index: number,\n includeTrackedChanges: boolean,\n includeCommentAnchors: boolean\n): ContentBlock {\n const text = buildParagraphText(para, includeTrackedChanges, includeCommentAnchors);\n const styleId = para.formatting?.styleId;\n\n if (isHeadingStyle(styleId)) {\n return {\n type: 'heading',\n index,\n level: parseHeadingLevel(styleId) ?? 1,\n text,\n };\n }\n\n if (para.listRendering) {\n return {\n type: 'list-item',\n index,\n text,\n listLevel: para.listRendering.level ?? 0,\n listType: para.listRendering.isBullet ? 'bullet' : 'number',\n };\n }\n\n return { type: 'paragraph', index, text };\n}\n\nfunction buildTableBlock(\n table: Table,\n index: number,\n includeTrackedChanges: boolean,\n includeCommentAnchors: boolean\n): ContentBlock {\n const rows: string[][] = [];\n for (const row of table.rows) {\n const cells: string[] = [];\n for (const cell of row.cells) {\n const cellTexts: string[] = [];\n for (const block of cell.content) {\n if (block.type === 'paragraph') {\n cellTexts.push(buildParagraphText(block, includeTrackedChanges, includeCommentAnchors));\n }\n }\n cells.push(cellTexts.join('\\n'));\n }\n rows.push(cells);\n }\n return { type: 'table', index, rows };\n}\n\n/**\n * Format content blocks as plain text for LLM prompts.\n * Every paragraph (including inside tables) gets its own [index].\n *\n * Output:\n * [0] (h1) Chapter Title\n * [1] Paragraph text here.\n * [2] • Bullet item\n * [3] (table, row 1, col 1) First cell\n * [4] (table, row 1, col 2) Second cell\n */\nexport function formatContentForLLM(blocks: ContentBlock[]): string {\n const lines: string[] = [];\n for (const block of blocks) {\n switch (block.type) {\n case 'heading':\n lines.push(`[${block.index}] (h${block.level}) ${block.text}`);\n break;\n case 'paragraph':\n lines.push(`[${block.index}] ${block.text}`);\n break;\n case 'list-item': {\n const indent = ' '.repeat(block.listLevel);\n const bullet = block.listType === 'bullet' ? '\\u2022' : '-';\n lines.push(`[${block.index}] ${indent}${bullet} ${block.text}`);\n break;\n }\n case 'table': {\n let idx = block.index;\n for (let r = 0; r < block.rows.length; r++) {\n for (let c = 0; c < block.rows[r].length; c++) {\n const cellText = block.rows[r][c];\n // A cell can have multiple paragraphs (joined by \\n in buildTableBlock)\n const paras = cellText.split('\\n');\n for (const para of paras) {\n lines.push(`[${idx}] (table, row ${r + 1}, col ${c + 1}) ${para}`);\n idx++;\n }\n }\n }\n break;\n }\n }\n }\n return lines.join('\\n');\n}\n\n/**\n * Build paragraph text with optional inline annotations for tracked changes and comments.\n */\nfunction buildParagraphText(\n para: Paragraph,\n includeTrackedChanges: boolean,\n includeCommentAnchors: boolean\n): string {\n const parts: string[] = [];\n const activeCommentIds = new Set<number>();\n\n for (const item of para.content) {\n if (item.type === 'commentRangeStart' && includeCommentAnchors) {\n activeCommentIds.add(item.id);\n parts.push(`[comment:${item.id}]`);\n continue;\n }\n if (item.type === 'commentRangeEnd' && includeCommentAnchors) {\n if (activeCommentIds.has(item.id)) {\n activeCommentIds.delete(item.id);\n parts.push('[/comment]');\n }\n continue;\n }\n\n if (item.type === 'run') {\n parts.push(getRunText(item));\n } else if (item.type === 'hyperlink') {\n parts.push(getHyperlinkText(item));\n } else if (isTrackedChange(item)) {\n const text = getTrackedChangeText(item.content);\n if (item.type === 'insertion' || item.type === 'moveTo') {\n if (includeTrackedChanges) {\n parts.push(`[+${text}+]{by:${item.info.author}}`);\n } else {\n parts.push(text);\n }\n } else {\n // deletion or moveFrom\n if (includeTrackedChanges) {\n parts.push(`[-${text}-]{by:${item.info.author}}`);\n }\n // When not annotating, hide deleted/moveFrom text\n }\n }\n }\n\n return parts.join('');\n}\n","/**\n * Error classes for @eigenpal/docx-editor-agents\n */\n\nexport class TextNotFoundError extends Error {\n constructor(search: string, paragraphIndex?: number) {\n const location =\n paragraphIndex !== undefined ? ` in paragraph ${paragraphIndex}` : ' in document';\n super(`Text not found${location}: \"${search}\"`);\n this.name = 'TextNotFoundError';\n }\n}\n\nexport class ChangeNotFoundError extends Error {\n constructor(id: number) {\n super(`Tracked change not found: id=${id}`);\n this.name = 'ChangeNotFoundError';\n }\n}\n\nexport class CommentNotFoundError extends Error {\n constructor(id: number) {\n super(`Comment not found: id=${id}`);\n this.name = 'CommentNotFoundError';\n }\n}\n","/**\n * Text search within paragraphs.\n * Handles text spanning multiple runs and tracked change wrappers.\n */\n\nimport type { Paragraph, Run } from '@eigenpal/docx-core/headless';\nimport { TextNotFoundError } from './errors';\nimport { getRunText, isTrackedChange } from './utils';\n\nexport interface TextSearchResult {\n startRunIndex: number;\n startOffset: number;\n endRunIndex: number;\n /** Character offset within the end run (exclusive) */\n endOffset: number;\n}\n\ninterface FlattenedRun {\n contentIndex: number;\n run: Run;\n text: string;\n startPos: number;\n}\n\n/**\n * Flatten paragraph content into runs with cumulative positions.\n */\nfunction flattenRuns(paragraph: Paragraph): FlattenedRun[] {\n const result: FlattenedRun[] = [];\n let pos = 0;\n\n for (let ci = 0; ci < paragraph.content.length; ci++) {\n const item = paragraph.content[ci];\n\n if (item.type === 'run') {\n const text = getRunText(item);\n result.push({ contentIndex: ci, run: item, text, startPos: pos });\n pos += text.length;\n } else if (item.type === 'hyperlink') {\n for (let hi = 0; hi < item.children.length; hi++) {\n const child = item.children[hi];\n if (child.type === 'run') {\n const text = getRunText(child);\n result.push({ contentIndex: ci, run: child, text, startPos: pos });\n pos += text.length;\n }\n }\n } else if (isTrackedChange(item)) {\n for (let ri = 0; ri < item.content.length; ri++) {\n const child = item.content[ri];\n if (child.type === 'run') {\n const text = getRunText(child);\n result.push({ contentIndex: ci, run: child, text, startPos: pos });\n pos += text.length;\n } else if (child.type === 'hyperlink') {\n for (const hc of child.children) {\n if (hc.type === 'run') {\n const text = getRunText(hc);\n result.push({ contentIndex: ci, run: hc, text, startPos: pos });\n pos += text.length;\n }\n }\n }\n }\n }\n }\n\n return result;\n}\n\nexport function getParagraphPlainText(paragraph: Paragraph): string {\n return flattenRuns(paragraph)\n .map((r) => r.text)\n .join('');\n}\n\n/**\n * Find text within a paragraph. Throws TextNotFoundError if not found.\n */\nexport function findTextInParagraph(\n paragraph: Paragraph,\n search: string,\n paragraphIndex?: number\n): TextSearchResult {\n const runs = flattenRuns(paragraph);\n const fullText = runs.map((r) => r.text).join('');\n\n const match = findMatch(fullText, search);\n if (!match) throw new TextNotFoundError(search, paragraphIndex);\n\n let startRunIdx = -1;\n let startOffset = 0;\n for (let i = 0; i < runs.length; i++) {\n if (match.start < runs[i].startPos + runs[i].text.length) {\n startRunIdx = i;\n startOffset = match.start - runs[i].startPos;\n break;\n }\n }\n\n let endRunIdx = -1;\n let endOffset = 0;\n for (let i = runs.length - 1; i >= 0; i--) {\n if (match.end > runs[i].startPos) {\n endRunIdx = i;\n endOffset = match.end - runs[i].startPos;\n break;\n }\n }\n\n if (startRunIdx === -1 || endRunIdx === -1) {\n throw new TextNotFoundError(search, paragraphIndex);\n }\n\n return {\n startRunIndex: runs[startRunIdx].contentIndex,\n startOffset,\n endRunIndex: runs[endRunIdx].contentIndex,\n endOffset,\n };\n}\n\n/**\n * Isolate matched text into its own runs by splitting at boundaries.\n * Mutates paragraph.content.\n */\nexport function isolateMatchedText(\n paragraph: Paragraph,\n search: string,\n paragraphIndex?: number\n): { startIndex: number; endIndex: number } {\n const result = findTextInParagraph(paragraph, search, paragraphIndex);\n let { startRunIndex, endRunIndex } = result;\n const { startOffset, endOffset } = result;\n\n // Split end run first (so indices don't shift for start)\n const endItem = paragraph.content[endRunIndex];\n if (endItem.type === 'run') {\n const endText = getRunText(endItem);\n if (endOffset < endText.length) {\n const afterRun = makeRunWithText(endText.slice(endOffset), endItem);\n setRunText(endItem, endText.slice(0, endOffset));\n paragraph.content.splice(endRunIndex + 1, 0, afterRun as Run);\n }\n }\n\n const startItem = paragraph.content[startRunIndex];\n if (startItem.type === 'run' && startOffset > 0) {\n const startText = getRunText(startItem);\n const beforeRun = makeRunWithText(startText.slice(0, startOffset), startItem);\n setRunText(startItem, startText.slice(startOffset));\n paragraph.content.splice(startRunIndex, 0, beforeRun as Run);\n startRunIndex++;\n endRunIndex++;\n }\n\n return { startIndex: startRunIndex, endIndex: endRunIndex };\n}\n\nfunction makeRunWithText(text: string, template: Run): Run {\n return {\n type: 'run',\n content: [{ type: 'text', text }],\n formatting: template.formatting ? { ...template.formatting } : undefined,\n } as Run;\n}\n\nfunction setRunText(run: Run, text: string): void {\n const textContent = run.content.find((c) => c.type === 'text');\n if (textContent) {\n (textContent as { type: 'text'; text: string }).text = text;\n }\n}\n\n// ============================================================================\n// MATCHING — exact, then normalized (case + quotes + whitespace)\n// ============================================================================\n\n/**\n * Normalize text for matching: lowercase, collapse whitespace,\n * straighten smart quotes/dashes, strip zero-width chars.\n */\nfunction normalize(original: string): { text: string; posMap: number[] } {\n const chars: string[] = [];\n const posMap: number[] = [];\n let prevSpace = true;\n\n for (let i = 0; i < original.length; i++) {\n let ch = original[i];\n\n // Skip zero-width chars\n if ('\\u200B\\u200C\\u200D\\uFEFF\\u00AD'.includes(ch)) continue;\n\n // Smart quotes → straight\n if ('\\u201C\\u201D\\u201E\\u201F'.includes(ch)) ch = '\"';\n if ('\\u2018\\u2019\\u201A\\u201B'.includes(ch)) ch = \"'\";\n\n // Dashes → hyphen\n if ('\\u2013\\u2014\\u2012\\u2015'.includes(ch)) ch = '-';\n\n // Ellipsis → dots\n if (ch === '\\u2026') {\n chars.push('.', '.', '.');\n posMap.push(i, i, i);\n prevSpace = false;\n continue;\n }\n\n // Collapse all whitespace (including \\n, \\t, non-breaking space)\n if (/\\s/.test(ch) || ch === '\\u00A0') {\n if (!prevSpace) {\n chars.push(' ');\n posMap.push(i);\n prevSpace = true;\n }\n continue;\n }\n\n chars.push(ch.toLowerCase());\n posMap.push(i);\n prevSpace = false;\n }\n\n // Trim trailing space\n if (chars.length > 0 && chars[chars.length - 1] === ' ') {\n chars.pop();\n posMap.pop();\n }\n\n return { text: chars.join(''), posMap };\n}\n\n/**\n * Map a normalized-space match back to original string positions.\n */\nfunction mapBack(\n norm: { posMap: number[] },\n idx: number,\n len: number,\n original: string\n): { start: number; end: number } {\n const start = norm.posMap[idx];\n let end = norm.posMap[idx + len - 1] + 1;\n while (end < original.length && '\\u200B\\u200C\\u200D\\uFEFF\\u00AD'.includes(original[end])) end++;\n return { start, end };\n}\n\n/**\n * Find search text within paragraph text.\n * 1. Exact match\n * 2. Normalized match (case-insensitive, smart quotes, collapsed whitespace)\n * 3. Trim trailing partial words (LLMs truncate mid-sentence)\n */\nfunction findMatch(text: string, search: string): { start: number; end: number } | null {\n if (!search || !text) return null;\n\n // 1. Exact\n const exact = text.indexOf(search);\n if (exact !== -1) return { start: exact, end: exact + search.length };\n\n // 2. Normalized\n const normText = normalize(text);\n const normSearch = normalize(search);\n if (!normSearch.text) return null;\n\n const idx = normText.text.indexOf(normSearch.text);\n if (idx !== -1) return mapBack(normText, idx, normSearch.text.length, text);\n\n // 3. Trim trailing partial words (LLM truncation: \"return HTTP 422. e.\" → \"return HTTP 422\")\n const words = normSearch.text.split(' ');\n if (words.length >= 3) {\n for (let drop = 1; drop <= Math.min(2, words.length - 2); drop++) {\n const trimmed = words.slice(0, -drop).join(' ');\n const trimIdx = normText.text.indexOf(trimmed);\n if (trimIdx !== -1) return mapBack(normText, trimIdx, trimmed.length, text);\n }\n }\n\n return null;\n}\n","/**\n * getChanges() and getComments() — discover tracked changes and comments in a document.\n */\n\nimport type { DocumentBody, Run, Comment } from '@eigenpal/docx-core/headless';\nimport type { ReviewChange, ReviewComment, ChangeFilter, CommentFilter } from './types';\nimport { getParagraphPlainText } from './textSearch';\nimport { getRunText, getTrackedChangeText, isTrackedChange, forEachParagraph } from './utils';\n\n/**\n * Collect all tracked changes from the document body.\n */\nexport function getChanges(body: DocumentBody, filter?: ChangeFilter): ReviewChange[] {\n const grouped = new Map<number, ReviewChange>();\n\n forEachParagraph(body, (para, paragraphIndex) => {\n let context: string | null = null;\n\n for (const item of para.content) {\n if (isTrackedChange(item)) {\n if (context === null) context = getParagraphPlainText(para);\n const text = getTrackedChangeText(item.content);\n const id = item.info.id;\n\n const existing = grouped.get(id);\n if (existing && existing.paragraphIndex === paragraphIndex) {\n existing.text += text;\n } else {\n grouped.set(id, {\n id,\n type: item.type,\n author: item.info.author,\n date: item.info.date ?? null,\n text,\n context,\n paragraphIndex,\n });\n }\n }\n }\n });\n\n const changes = Array.from(grouped.values());\n\n return changes.filter((c) => {\n if (filter?.author && c.author !== filter.author) return false;\n if (filter?.type && c.type !== filter.type) return false;\n return true;\n });\n}\n\n/**\n * Collect all comments from the document body.\n */\nexport function getComments(body: DocumentBody, filter?: CommentFilter): ReviewComment[] {\n const comments = body.comments ?? [];\n if (comments.length === 0) return [];\n\n const anchoredTextMap = buildAnchoredTextMap(body);\n\n const topLevel: Comment[] = [];\n const repliesByParent = new Map<number, Comment[]>();\n\n for (const c of comments) {\n if (c.parentId !== undefined) {\n const existing = repliesByParent.get(c.parentId) ?? [];\n existing.push(c);\n repliesByParent.set(c.parentId, existing);\n } else {\n topLevel.push(c);\n }\n }\n\n const result: ReviewComment[] = topLevel.map((c) => {\n const anchor = anchoredTextMap.get(c.id);\n const replies = (repliesByParent.get(c.id) ?? []).map((r) => ({\n id: r.id,\n author: r.author,\n date: r.date ?? null,\n text: getCommentText(r),\n }));\n\n return {\n id: c.id,\n author: c.author,\n date: c.date ?? null,\n text: getCommentText(c),\n anchoredText: anchor?.text ?? '',\n paragraphIndex: anchor?.paragraphIndex ?? -1,\n replies,\n done: c.done ?? false,\n };\n });\n\n return result.filter((c) => {\n if (filter?.author && c.author !== filter.author) return false;\n if (filter?.done !== undefined && c.done !== filter.done) return false;\n return true;\n });\n}\n\nfunction getCommentText(comment: Comment): string {\n return comment.content.map((para) => getParagraphPlainText(para)).join('\\n');\n}\n\ninterface AnchorInfo {\n text: string;\n paragraphIndex: number;\n}\n\nfunction buildAnchoredTextMap(body: DocumentBody): Map<number, AnchorInfo> {\n const result = new Map<number, AnchorInfo>();\n const openRanges = new Map<number, { paragraphIndex: number; parts: string[] }>();\n\n forEachParagraph(body, (para, paragraphIndex) => {\n for (const item of para.content) {\n if (item.type === 'commentRangeStart') {\n openRanges.set(item.id, { paragraphIndex, parts: [] });\n } else if (item.type === 'commentRangeEnd') {\n const open = openRanges.get(item.id);\n if (open) {\n result.set(item.id, { text: open.parts.join(''), paragraphIndex: open.paragraphIndex });\n openRanges.delete(item.id);\n }\n } else if (item.type === 'run') {\n const text = getRunText(item);\n for (const open of openRanges.values()) {\n open.parts.push(text);\n }\n } else if (item.type === 'hyperlink') {\n const text = item.children\n .filter((c): c is Run => c.type === 'run')\n .map(getRunText)\n .join('');\n for (const open of openRanges.values()) {\n open.parts.push(text);\n }\n } else if (isTrackedChange(item)) {\n const text = getTrackedChangeText(item.content);\n for (const open of openRanges.values()) {\n open.parts.push(text);\n }\n }\n }\n });\n\n return result;\n}\n","/**\n * Comment operations — addComment, replyTo\n */\n\nimport type { DocumentBody, Paragraph, Comment, Run } from '@eigenpal/docx-core/headless';\nimport type { AddCommentOptions, ReplyOptions } from './types';\nimport { CommentNotFoundError } from './errors';\nimport { findTextInParagraph } from './textSearch';\nimport { getParagraphAtIndex } from './utils';\n\n/**\n * Add a comment to a paragraph. Returns the new comment ID.\n */\nexport function addComment(body: DocumentBody, options: AddCommentOptions): number {\n const { paragraphIndex, author = 'AI', text, search } = options;\n const para = getParagraphAtIndex(body, paragraphIndex);\n\n const existingIds = (body.comments ?? []).map((c) => c.id);\n const newId = existingIds.length > 0 ? Math.max(...existingIds) + 1 : 1;\n\n const comment: Comment = {\n id: newId,\n author,\n date: new Date().toISOString(),\n content: [\n {\n type: 'paragraph',\n content: [{ type: 'run', content: [{ type: 'text', text }] } as Run],\n formatting: {},\n } as Paragraph,\n ],\n };\n\n if (!body.comments) {\n body.comments = [];\n }\n body.comments.push(comment);\n\n if (search) {\n const result = findTextInParagraph(para, search, paragraphIndex);\n // Insert end marker after end item, then start marker before start item\n para.content.splice(result.endRunIndex + 1, 0, { type: 'commentRangeEnd', id: newId });\n para.content.splice(result.startRunIndex, 0, { type: 'commentRangeStart', id: newId });\n } else {\n para.content.unshift({ type: 'commentRangeStart', id: newId });\n para.content.push({ type: 'commentRangeEnd', id: newId });\n }\n\n return newId;\n}\n\n/**\n * Reply to an existing comment. Returns the reply's comment ID.\n */\nexport function replyTo(body: DocumentBody, commentId: number, options: ReplyOptions): number {\n const comments = body.comments ?? [];\n const parent = comments.find((c) => c.id === commentId);\n if (!parent) {\n throw new CommentNotFoundError(commentId);\n }\n\n const existingIds = comments.map((c) => c.id);\n const newId = Math.max(...existingIds) + 1;\n\n const reply: Comment = {\n id: newId,\n author: options.author ?? 'AI',\n date: new Date().toISOString(),\n parentId: commentId,\n content: [\n {\n type: 'paragraph',\n content: [{ type: 'run', content: [{ type: 'text', text: options.text }] } as Run],\n formatting: {},\n } as Paragraph,\n ],\n };\n\n comments.push(reply);\n return newId;\n}\n","/**\n * Change operations — accept, reject, propose insertion/deletion/replacement.\n */\n\nimport type {\n DocumentBody,\n Paragraph,\n Run,\n Insertion,\n Deletion,\n ParagraphContent,\n} from '@eigenpal/docx-core/headless';\nimport type {\n ProposeReplacementOptions,\n ProposeInsertionOptions,\n ProposeDeletionOptions,\n} from './types';\nimport { ChangeNotFoundError } from './errors';\nimport { isolateMatchedText } from './textSearch';\nimport {\n isTrackedChange,\n getParagraphAtIndex,\n forEachParagraph,\n type TrackedChangeItem,\n} from './utils';\n\n// ============================================================================\n// ACCEPT / REJECT\n// ============================================================================\n\n/**\n * Accept a tracked change by ID.\n * Insertion: keep text, remove wrapper.\n * Deletion: remove text and wrapper.\n */\nexport function acceptChange(body: DocumentBody, id: number): void {\n if (!processChangeById(body, id, 'accept')) {\n throw new ChangeNotFoundError(id);\n }\n}\n\n/**\n * Reject a tracked change by ID.\n * Insertion: remove text and wrapper.\n * Deletion: keep text, remove wrapper.\n */\nexport function rejectChange(body: DocumentBody, id: number): void {\n if (!processChangeById(body, id, 'reject')) {\n throw new ChangeNotFoundError(id);\n }\n}\n\n/**\n * Accept all tracked changes. Returns count.\n */\nexport function acceptAll(body: DocumentBody): number {\n return processAllChanges(body, 'accept');\n}\n\n/**\n * Reject all tracked changes. Returns count.\n */\nexport function rejectAll(body: DocumentBody): number {\n return processAllChanges(body, 'reject');\n}\n\n/**\n * Process all tracked changes in a single pass (O(M) where M = total paragraphs).\n * Iterates backward within each paragraph so splice doesn't shift unprocessed indices.\n */\nfunction processAllChanges(body: DocumentBody, mode: 'accept' | 'reject'): number {\n let count = 0;\n forEachParagraph(body, (para) => {\n for (let i = para.content.length - 1; i >= 0; i--) {\n const item = para.content[i];\n if (isTrackedChange(item)) {\n applyChangeAtIndex(para, i, item, mode);\n count++;\n }\n }\n });\n return count;\n}\n\n/**\n * Find and process a tracked change by revision ID.\n * Processes ALL content items with matching ID (a revision can span multiple items).\n */\nfunction processChangeById(body: DocumentBody, id: number, mode: 'accept' | 'reject'): boolean {\n let found = false;\n forEachParagraph(body, (para) => {\n for (let i = para.content.length - 1; i >= 0; i--) {\n const item = para.content[i];\n if (isTrackedChange(item) && item.info.id === id) {\n applyChangeAtIndex(para, i, item, mode);\n found = true;\n }\n }\n // Stop traversal once we've found and processed the change\n if (found) return false;\n });\n return found;\n}\n\nfunction applyChangeAtIndex(\n para: Paragraph,\n index: number,\n item: TrackedChangeItem,\n mode: 'accept' | 'reject'\n) {\n const keepContent =\n (item.type === 'insertion' && mode === 'accept') ||\n (item.type === 'deletion' && mode === 'reject') ||\n (item.type === 'moveTo' && mode === 'accept') ||\n (item.type === 'moveFrom' && mode === 'reject');\n\n if (keepContent) {\n // Unwrap: replace the tracked change wrapper with its content runs\n const runs = item.content as ParagraphContent[];\n para.content.splice(index, 1, ...runs);\n } else {\n // Remove: delete the tracked change and its content\n para.content.splice(index, 1);\n }\n}\n\n// ============================================================================\n// PROPOSE CHANGES\n// ============================================================================\n\n/**\n * Propose a text replacement as a tracked change (deletion + insertion).\n */\nexport function proposeReplacement(body: DocumentBody, options: ProposeReplacementOptions): void {\n const { paragraphIndex, search, author = 'AI', replaceWith } = options;\n const para = getParagraphAtIndex(body, paragraphIndex);\n\n const { startIndex, endIndex } = isolateMatchedText(para, search, paragraphIndex);\n\n const now = new Date().toISOString();\n const baseId = nextRevisionId(body);\n\n const matchedContent = para.content.slice(startIndex, endIndex + 1);\n\n const deletion: Deletion = {\n type: 'deletion',\n info: { id: baseId, author, date: now },\n content: matchedContent as (Run | import('@eigenpal/docx-core/headless').Hyperlink)[],\n };\n\n const insertion: Insertion = {\n type: 'insertion',\n info: { id: baseId + 1, author, date: now },\n content: [{ type: 'run', content: [{ type: 'text', text: replaceWith }] } as Run],\n };\n\n para.content.splice(startIndex, endIndex - startIndex + 1, deletion, insertion);\n}\n\n/**\n * Propose an insertion as a tracked change.\n */\nexport function proposeInsertion(body: DocumentBody, options: ProposeInsertionOptions): void {\n const { paragraphIndex, author = 'AI', insertText, position = 'after', search } = options;\n const para = getParagraphAtIndex(body, paragraphIndex);\n\n const now = new Date().toISOString();\n const id = nextRevisionId(body);\n\n const insertion: Insertion = {\n type: 'insertion',\n info: { id, author, date: now },\n content: [{ type: 'run', content: [{ type: 'text', text: insertText }] } as Run],\n };\n\n if (search) {\n const { startIndex, endIndex } = isolateMatchedText(para, search, paragraphIndex);\n const insertAt = position === 'after' ? endIndex + 1 : startIndex;\n para.content.splice(insertAt, 0, insertion);\n } else {\n if (position === 'before') {\n para.content.unshift(insertion);\n } else {\n para.content.push(insertion);\n }\n }\n}\n\n/**\n * Propose a deletion as a tracked change.\n */\nexport function proposeDeletion(body: DocumentBody, options: ProposeDeletionOptions): void {\n const { paragraphIndex, search, author = 'AI' } = options;\n const para = getParagraphAtIndex(body, paragraphIndex);\n\n const { startIndex, endIndex } = isolateMatchedText(para, search, paragraphIndex);\n\n const now = new Date().toISOString();\n const id = nextRevisionId(body);\n\n const matchedContent = para.content.slice(startIndex, endIndex + 1);\n\n const deletion: Deletion = {\n type: 'deletion',\n info: { id, author, date: now },\n content: matchedContent as (Run | import('@eigenpal/docx-core/headless').Hyperlink)[],\n };\n\n para.content.splice(startIndex, endIndex - startIndex + 1, deletion);\n}\n\n// ============================================================================\n// HELPERS\n// ============================================================================\n\n/** Cached max revision ID per body — avoids O(N) scan on every proposal. */\nconst revisionIdCache = new WeakMap<DocumentBody, number>();\n\nfunction nextRevisionId(body: DocumentBody): number {\n let maxId = revisionIdCache.get(body);\n if (maxId === undefined) {\n maxId = 0;\n forEachParagraph(body, (para) => {\n for (const item of para.content) {\n if (isTrackedChange(item)) {\n maxId = Math.max(maxId!, item.info.id);\n }\n }\n });\n }\n const next = maxId + 1;\n // Reserve both next and next+1 (replacement uses two IDs)\n revisionIdCache.set(body, next + 1);\n return next;\n}\n","/**\n * applyReview() — batch review operations in a single call.\n */\n\nimport type { DocumentBody } from '@eigenpal/docx-core/headless';\nimport type { BatchReviewOptions, BatchResult, BatchError } from './types';\nimport { acceptChange, rejectChange, proposeReplacement } from './changes';\nimport { addComment, replyTo } from './comments';\n\n/**\n * Apply multiple review operations in a single call.\n * Order: accept/reject → comments → replies → proposals.\n * Individual failures are collected, not thrown.\n * defaultAuthor is used when individual items don't specify an author.\n */\nexport function applyReview(\n body: DocumentBody,\n ops: BatchReviewOptions,\n defaultAuthor = 'AI'\n): BatchResult {\n const errors: BatchError[] = [];\n let accepted = 0;\n let rejected = 0;\n let commentsAdded = 0;\n let repliesAdded = 0;\n let proposalsAdded = 0;\n\n for (const id of ops.accept ?? []) {\n try {\n acceptChange(body, id);\n accepted++;\n } catch (e) {\n errors.push({ operation: 'accept', id, error: (e as Error).message });\n }\n }\n\n for (const id of ops.reject ?? []) {\n try {\n rejectChange(body, id);\n rejected++;\n } catch (e) {\n errors.push({ operation: 'reject', id, error: (e as Error).message });\n }\n }\n\n for (const opts of ops.comments ?? []) {\n try {\n addComment(body, { ...opts, author: opts.author ?? defaultAuthor });\n commentsAdded++;\n } catch (e) {\n errors.push({ operation: 'comment', search: opts.search, error: (e as Error).message });\n }\n }\n\n for (const opts of ops.replies ?? []) {\n try {\n replyTo(body, opts.commentId, { author: opts.author ?? defaultAuthor, text: opts.text });\n repliesAdded++;\n } catch (e) {\n errors.push({ operation: 'reply', id: opts.commentId, error: (e as Error).message });\n }\n }\n\n for (const opts of ops.proposals ?? []) {\n try {\n proposeReplacement(body, { ...opts, author: opts.author ?? defaultAuthor });\n proposalsAdded++;\n } catch (e) {\n errors.push({ operation: 'proposal', search: opts.search, error: (e as Error).message });\n }\n }\n\n return { accepted, rejected, commentsAdded, repliesAdded, proposalsAdded, errors };\n}\n","/**\n * DocxReviewer — Word-like API for AI document review.\n *\n * @example\n * ```ts\n * const reviewer = await DocxReviewer.fromBuffer(buffer, 'AI Reviewer');\n * const text = reviewer.getContentAsText();\n * reviewer.addComment(5, 'Fix this paragraph.');\n * reviewer.replace(5, '$50k', '$500k');\n * const output = await reviewer.toBuffer();\n * ```\n */\n\nimport type { Document, DocumentBody } from '@eigenpal/docx-core/headless';\nimport { parseDocx } from '@eigenpal/docx-core/headless';\nimport type {\n ContentBlock,\n GetContentOptions,\n ReviewChange,\n ReviewComment,\n ChangeFilter,\n CommentFilter,\n AddCommentOptions,\n ReplyOptions,\n ProposeReplacementOptions,\n ProposeInsertionOptions,\n ProposeDeletionOptions,\n BatchReviewOptions,\n BatchResult,\n} from './types';\nimport { getContent as getContentImpl, formatContentForLLM } from './content';\nimport { getChanges as getChangesImpl, getComments as getCommentsImpl } from './discovery';\nimport { addComment as addCommentImpl, replyTo as replyToImpl } from './comments';\nimport {\n acceptChange as acceptChangeImpl,\n rejectChange as rejectChangeImpl,\n acceptAll as acceptAllImpl,\n rejectAll as rejectAllImpl,\n proposeReplacement as proposeReplacementImpl,\n proposeInsertion as proposeInsertionImpl,\n proposeDeletion as proposeDeletionImpl,\n} from './changes';\nimport { applyReview as applyReviewImpl } from './batch';\n\nexport class DocxReviewer {\n private doc: Document;\n /** Default author for comments and tracked changes. Set once, used everywhere. */\n readonly author: string;\n\n /**\n * Create a reviewer from a parsed Document.\n * @param document - Parsed Document from @eigenpal/docx-core\n * @param author - Default author name for comments and changes. (default: 'AI')\n * @param originalBuffer - Original DOCX buffer, needed for toBuffer()\n */\n constructor(document: Document, author = 'AI', originalBuffer?: ArrayBuffer) {\n // Strip originalBuffer before cloning to avoid deep-copying potentially large ArrayBuffer\n const savedBuffer = originalBuffer ?? document.originalBuffer;\n const { originalBuffer: _discard, ...rest } = document;\n this.doc = structuredClone(rest) as Document;\n if (savedBuffer) this.doc.originalBuffer = savedBuffer;\n this.author = author;\n }\n\n /**\n * Create a reviewer from a DOCX file buffer.\n * @param buffer - ArrayBuffer of the DOCX file\n * @param author - Default author name for comments and changes. (default: 'AI')\n */\n static async fromBuffer(buffer: ArrayBuffer, author = 'AI'): Promise<DocxReviewer> {\n const doc = await parseDocx(buffer, { preloadFonts: false });\n return new DocxReviewer(doc, author, buffer);\n }\n\n private get body(): DocumentBody {\n return this.doc.package.document;\n }\n\n private resolveAuthor(author?: string): string {\n return author ?? this.author;\n }\n\n // ==========================================================================\n // READ\n // ==========================================================================\n\n /** Get document content as structured blocks (headings, paragraphs, tables, lists). */\n getContent(options?: GetContentOptions): ContentBlock[] {\n return getContentImpl(this.body, options);\n }\n\n /**\n * Get document content as plain text for LLM prompts.\n * Each paragraph is prefixed with its index: `[0] text`, `[1] text`, etc.\n * Table cells include position: `[5] (table, row 1, col 2) cell text`.\n * Avoids JSON quote-escaping issues — LLMs can copy text verbatim.\n */\n getContentAsText(options?: GetContentOptions): string {\n return formatContentForLLM(getContentImpl(this.body, options));\n }\n\n // ==========================================================================\n // DISCOVER\n // ==========================================================================\n\n /** Get all tracked changes in the document. */\n getChanges(filter?: ChangeFilter): ReviewChange[] {\n return getChangesImpl(this.body, filter);\n }\n\n /** Get all comments with their replies. */\n getComments(filter?: CommentFilter): ReviewComment[] {\n return getCommentsImpl(this.body, filter);\n }\n\n // ==========================================================================\n // COMMENT\n // ==========================================================================\n\n /**\n * Add a comment on a paragraph.\n * @param paragraphIndex - Index of the paragraph to comment on\n * @param text - Comment text\n * @returns The new comment ID\n */\n addComment(paragraphIndex: number, text: string): number;\n /**\n * Add a comment with full options (custom author, anchored to specific text).\n * @param options - Comment options\n * @returns The new comment ID\n */\n addComment(options: AddCommentOptions): number;\n addComment(indexOrOptions: number | AddCommentOptions, text?: string): number {\n const opts =\n typeof indexOrOptions === 'number'\n ? { paragraphIndex: indexOrOptions, text: text!, author: this.author }\n : { ...indexOrOptions, author: this.resolveAuthor(indexOrOptions.author) };\n return addCommentImpl(this.body, opts);\n }\n\n /**\n * Reply to an existing comment.\n * @param commentId - ID of the comment to reply to\n * @param text - Reply text\n * @returns The new reply comment ID\n */\n replyTo(commentId: number, text: string): number;\n /** Reply to an existing comment with full options. */\n replyTo(commentId: number, options: ReplyOptions): number;\n replyTo(commentId: number, textOrOptions: string | ReplyOptions): number {\n const opts =\n typeof textOrOptions === 'string'\n ? { text: textOrOptions, author: this.author }\n : { ...textOrOptions, author: this.resolveAuthor(textOrOptions.author) };\n return replyToImpl(this.body, commentId, opts);\n }\n\n // ==========================================================================\n // PROPOSE CHANGES\n // ==========================================================================\n\n /**\n * Replace text in a paragraph. Creates a tracked change (deletion + insertion).\n * @param paragraphIndex - Index of the paragraph\n * @param search - Short phrase to find within the paragraph\n * @param replaceWith - Replacement text\n */\n replace(paragraphIndex: number, search: string, replaceWith: string): void;\n /** Replace text with full options. */\n replace(options: ProposeReplacementOptions): void;\n replace(\n indexOrOptions: number | ProposeReplacementOptions,\n search?: string,\n replaceWith?: string\n ): void {\n const opts =\n typeof indexOrOptions === 'number'\n ? {\n paragraphIndex: indexOrOptions,\n search: search!,\n replaceWith: replaceWith!,\n author: this.author,\n }\n : { ...indexOrOptions, author: this.resolveAuthor(indexOrOptions.author) };\n proposeReplacementImpl(this.body, opts);\n }\n\n /** @deprecated Use replace() instead. */\n proposeReplacement(options: ProposeReplacementOptions): void {\n this.replace(options);\n }\n\n /** Insert text as a tracked change. */\n proposeInsertion(options: ProposeInsertionOptions): void {\n proposeInsertionImpl(this.body, {\n ...options,\n author: this.resolveAuthor(options.author),\n });\n }\n\n /** Delete text as a tracked change. */\n proposeDeletion(options: ProposeDeletionOptions): void {\n proposeDeletionImpl(this.body, {\n ...options,\n author: this.resolveAuthor(options.author),\n });\n }\n\n // ==========================================================================\n // RESOLVE\n // ==========================================================================\n\n /** Accept a tracked change by its revision ID. */\n acceptChange(id: number): void {\n acceptChangeImpl(this.body, id);\n }\n\n /** Reject a tracked change by its revision ID. */\n rejectChange(id: number): void {\n rejectChangeImpl(this.body, id);\n }\n\n /** Accept all tracked changes. Returns count accepted. */\n acceptAll(): number {\n return acceptAllImpl(this.body);\n }\n\n /** Reject all tracked changes. Returns count rejected. */\n rejectAll(): number {\n return rejectAllImpl(this.body);\n }\n\n // ==========================================================================\n // BATCH\n // ==========================================================================\n\n /**\n * Apply multiple review operations in one call.\n * Uses the reviewer's default author. Individual failures are collected, not thrown.\n */\n applyReview(ops: BatchReviewOptions): BatchResult {\n return applyReviewImpl(this.body, ops, this.author);\n }\n\n // ==========================================================================\n // EXPORT\n // ==========================================================================\n\n /** Get the modified Document model. */\n toDocument(): Document {\n return this.doc;\n }\n\n /** Serialize back to a DOCX buffer. Requires the original buffer. */\n async toBuffer(): Promise<ArrayBuffer> {\n if (!this.doc.originalBuffer) {\n throw new Error(\n 'Cannot create buffer: no original DOCX buffer was provided. ' +\n 'Use DocxReviewer.fromBuffer() or pass originalBuffer to the constructor.'\n );\n }\n const { repackDocx } = await import('@eigenpal/docx-core/headless');\n return repackDocx(this.doc);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/utils.ts","../src/content.ts","../src/errors.ts","../src/textSearch.ts","../src/discovery.ts","../src/comments.ts","../src/changes.ts","../src/batch.ts","../src/DocxReviewer.ts"],"names":["getRunText","getHyperlinkText","isHeadingStyle","parseHeadingLevel","parseDocx"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Shared utilities for agent-use package.\n */\n\nimport type {\n DocumentBody,\n Paragraph,\n Run,\n Hyperlink,\n ParagraphContent,\n Insertion,\n Deletion,\n MoveFrom,\n MoveTo,\n} from '@eigenpal/docx-core/headless';\nimport {\n getRunText,\n getHyperlinkText,\n isHeadingStyle,\n parseHeadingLevel,\n} from '@eigenpal/docx-core/headless';\n\n// Re-export from core so other modules import from one place\nexport { getRunText, getHyperlinkText, isHeadingStyle, parseHeadingLevel };\n\n// ============================================================================\n// TRACKED CHANGE HELPERS\n// ============================================================================\n\nexport type TrackedChangeItem = Insertion | Deletion | MoveFrom | MoveTo;\n\nexport function isTrackedChange(item: ParagraphContent): item is TrackedChangeItem {\n return (\n item.type === 'insertion' ||\n item.type === 'deletion' ||\n item.type === 'moveFrom' ||\n item.type === 'moveTo'\n );\n}\n\nexport function getTrackedChangeText(content: (Run | Hyperlink)[]): string {\n const parts: string[] = [];\n for (const item of content) {\n if (item.type === 'run') {\n parts.push(getRunText(item));\n } else if (item.type === 'hyperlink') {\n parts.push(getHyperlinkText(item));\n }\n }\n return parts.join('');\n}\n\n// ============================================================================\n// DOCUMENT TRAVERSAL\n// ============================================================================\n\n/**\n * Get a paragraph by its document-wide index (counting into tables).\n * Throws on out-of-bounds.\n */\nexport function getParagraphAtIndex(body: DocumentBody, paragraphIndex: number): Paragraph {\n let index = 0;\n for (const block of body.content) {\n if (block.type === 'paragraph') {\n if (index === paragraphIndex) return block;\n index++;\n } else if (block.type === 'table') {\n for (const row of block.rows) {\n for (const cell of row.cells) {\n for (const cellBlock of cell.content) {\n if (cellBlock.type === 'paragraph') {\n if (index === paragraphIndex) return cellBlock;\n index++;\n }\n }\n }\n }\n } else {\n index++;\n }\n }\n throw new Error(`Paragraph index ${paragraphIndex} out of bounds (max: ${index - 1})`);\n}\n\n/**\n * Walk all paragraphs in the document body (including inside tables),\n * calling the callback with each paragraph and its document-wide index.\n */\nexport function forEachParagraph(\n body: DocumentBody,\n fn: (para: Paragraph, index: number) => void | boolean\n): void {\n let index = 0;\n for (const block of body.content) {\n if (block.type === 'paragraph') {\n if (fn(block, index) === false) return;\n index++;\n } else if (block.type === 'table') {\n for (const row of block.rows) {\n for (const cell of row.cells) {\n for (const cellBlock of cell.content) {\n if (cellBlock.type === 'paragraph') {\n if (fn(cellBlock, index) === false) return;\n index++;\n }\n }\n }\n }\n } else {\n index++;\n }\n }\n}\n","/**\n * getContent() — renders document as structured ContentBlock array for LLM consumption.\n * formatContentForLLM() — converts blocks to plain text (avoids JSON quote-escaping issues).\n */\n\nimport type { DocumentBody, Paragraph, Table } from '@eigenpal/docx-core/headless';\nimport type { ContentBlock, GetContentOptions } from './types';\nimport {\n getRunText,\n getHyperlinkText,\n getTrackedChangeText,\n isTrackedChange,\n isHeadingStyle,\n parseHeadingLevel,\n} from './utils';\n\n/**\n * Walk document body and produce ContentBlock array.\n */\nexport function getContent(body: DocumentBody, options: GetContentOptions = {}): ContentBlock[] {\n const {\n fromIndex,\n toIndex,\n includeTrackedChanges = true,\n includeCommentAnchors = true,\n } = options;\n\n const blocks: ContentBlock[] = [];\n let index = 0;\n\n for (const block of body.content) {\n if (block.type === 'paragraph') {\n if (isInRange(index, fromIndex, toIndex)) {\n blocks.push(\n buildParagraphBlock(block, index, includeTrackedChanges, includeCommentAnchors)\n );\n }\n index++;\n } else if (block.type === 'table') {\n if (isInRange(index, fromIndex, toIndex)) {\n blocks.push(buildTableBlock(block, index, includeTrackedChanges, includeCommentAnchors));\n }\n // Advance by number of cell paragraphs (matching getParagraphAtIndex counting)\n for (const row of block.rows) {\n for (const cell of row.cells) {\n for (const cellBlock of cell.content) {\n if (cellBlock.type === 'paragraph') {\n index++;\n }\n }\n }\n }\n } else {\n index++;\n }\n }\n\n return blocks;\n}\n\nfunction isInRange(index: number, from?: number, to?: number): boolean {\n return (from === undefined || index >= from) && (to === undefined || index <= to);\n}\n\nfunction buildParagraphBlock(\n para: Paragraph,\n index: number,\n includeTrackedChanges: boolean,\n includeCommentAnchors: boolean\n): ContentBlock {\n const text = buildParagraphText(para, includeTrackedChanges, includeCommentAnchors);\n const styleId = para.formatting?.styleId;\n\n if (isHeadingStyle(styleId)) {\n return {\n type: 'heading',\n index,\n level: parseHeadingLevel(styleId) ?? 1,\n text,\n };\n }\n\n if (para.listRendering) {\n return {\n type: 'list-item',\n index,\n text,\n listLevel: para.listRendering.level ?? 0,\n listType: para.listRendering.isBullet ? 'bullet' : 'number',\n };\n }\n\n return { type: 'paragraph', index, text };\n}\n\nfunction buildTableBlock(\n table: Table,\n index: number,\n includeTrackedChanges: boolean,\n includeCommentAnchors: boolean\n): ContentBlock {\n const rows: string[][] = [];\n for (const row of table.rows) {\n const cells: string[] = [];\n for (const cell of row.cells) {\n const cellTexts: string[] = [];\n for (const block of cell.content) {\n if (block.type === 'paragraph') {\n cellTexts.push(buildParagraphText(block, includeTrackedChanges, includeCommentAnchors));\n }\n }\n cells.push(cellTexts.join('\\n'));\n }\n rows.push(cells);\n }\n return { type: 'table', index, rows };\n}\n\n/**\n * Format content blocks as plain text for LLM prompts.\n * Every paragraph (including inside tables) gets its own [index].\n *\n * Output:\n * [0] (h1) Chapter Title\n * [1] Paragraph text here.\n * [2] • Bullet item\n * [3] (table, row 1, col 1) First cell\n * [4] (table, row 1, col 2) Second cell\n */\nexport function formatContentForLLM(blocks: ContentBlock[]): string {\n const lines: string[] = [];\n for (const block of blocks) {\n switch (block.type) {\n case 'heading':\n lines.push(`[${block.index}] (h${block.level}) ${block.text}`);\n break;\n case 'paragraph':\n lines.push(`[${block.index}] ${block.text}`);\n break;\n case 'list-item': {\n const indent = ' '.repeat(block.listLevel);\n const bullet = block.listType === 'bullet' ? '\\u2022' : '-';\n lines.push(`[${block.index}] ${indent}${bullet} ${block.text}`);\n break;\n }\n case 'table': {\n let idx = block.index;\n for (let r = 0; r < block.rows.length; r++) {\n for (let c = 0; c < block.rows[r].length; c++) {\n const cellText = block.rows[r][c];\n // A cell can have multiple paragraphs (joined by \\n in buildTableBlock)\n const paras = cellText.split('\\n');\n for (const para of paras) {\n lines.push(`[${idx}] (table, row ${r + 1}, col ${c + 1}) ${para}`);\n idx++;\n }\n }\n }\n break;\n }\n }\n }\n return lines.join('\\n');\n}\n\n/**\n * Build paragraph text with optional inline annotations for tracked changes and comments.\n */\nfunction buildParagraphText(\n para: Paragraph,\n includeTrackedChanges: boolean,\n includeCommentAnchors: boolean\n): string {\n const parts: string[] = [];\n const activeCommentIds = new Set<number>();\n\n for (const item of para.content) {\n if (item.type === 'commentRangeStart' && includeCommentAnchors) {\n activeCommentIds.add(item.id);\n parts.push(`[comment:${item.id}]`);\n continue;\n }\n if (item.type === 'commentRangeEnd' && includeCommentAnchors) {\n if (activeCommentIds.has(item.id)) {\n activeCommentIds.delete(item.id);\n parts.push('[/comment]');\n }\n continue;\n }\n\n if (item.type === 'run') {\n parts.push(getRunText(item));\n } else if (item.type === 'hyperlink') {\n parts.push(getHyperlinkText(item));\n } else if (isTrackedChange(item)) {\n const text = getTrackedChangeText(item.content);\n if (item.type === 'insertion' || item.type === 'moveTo') {\n if (includeTrackedChanges) {\n parts.push(`[+${text}+]{by:${item.info.author}}`);\n } else {\n parts.push(text);\n }\n } else {\n // deletion or moveFrom\n if (includeTrackedChanges) {\n parts.push(`[-${text}-]{by:${item.info.author}}`);\n }\n // When not annotating, hide deleted/moveFrom text\n }\n }\n }\n\n return parts.join('');\n}\n","/**\n * Error classes for @eigenpal/docx-editor-agents\n */\n\nexport class TextNotFoundError extends Error {\n constructor(search: string, paragraphIndex?: number) {\n const location =\n paragraphIndex !== undefined ? ` in paragraph ${paragraphIndex}` : ' in document';\n super(`Text not found${location}: \"${search}\"`);\n this.name = 'TextNotFoundError';\n }\n}\n\nexport class ChangeNotFoundError extends Error {\n constructor(id: number) {\n super(`Tracked change not found: id=${id}`);\n this.name = 'ChangeNotFoundError';\n }\n}\n\nexport class CommentNotFoundError extends Error {\n constructor(id: number) {\n super(`Comment not found: id=${id}`);\n this.name = 'CommentNotFoundError';\n }\n}\n","/**\n * Text search within paragraphs.\n * Handles text spanning multiple runs and tracked change wrappers.\n */\n\nimport type { Paragraph, Run } from '@eigenpal/docx-core/headless';\nimport { TextNotFoundError } from './errors';\nimport { getRunText, isTrackedChange } from './utils';\n\nexport interface TextSearchResult {\n startRunIndex: number;\n startOffset: number;\n endRunIndex: number;\n /** Character offset within the end run (exclusive) */\n endOffset: number;\n}\n\ninterface FlattenedRun {\n contentIndex: number;\n run: Run;\n text: string;\n startPos: number;\n}\n\n/**\n * Flatten paragraph content into runs with cumulative positions.\n */\nfunction flattenRuns(paragraph: Paragraph): FlattenedRun[] {\n const result: FlattenedRun[] = [];\n let pos = 0;\n\n for (let ci = 0; ci < paragraph.content.length; ci++) {\n const item = paragraph.content[ci];\n\n if (item.type === 'run') {\n const text = getRunText(item);\n result.push({ contentIndex: ci, run: item, text, startPos: pos });\n pos += text.length;\n } else if (item.type === 'hyperlink') {\n for (let hi = 0; hi < item.children.length; hi++) {\n const child = item.children[hi];\n if (child.type === 'run') {\n const text = getRunText(child);\n result.push({ contentIndex: ci, run: child, text, startPos: pos });\n pos += text.length;\n }\n }\n } else if (isTrackedChange(item)) {\n for (let ri = 0; ri < item.content.length; ri++) {\n const child = item.content[ri];\n if (child.type === 'run') {\n const text = getRunText(child);\n result.push({ contentIndex: ci, run: child, text, startPos: pos });\n pos += text.length;\n } else if (child.type === 'hyperlink') {\n for (const hc of child.children) {\n if (hc.type === 'run') {\n const text = getRunText(hc);\n result.push({ contentIndex: ci, run: hc, text, startPos: pos });\n pos += text.length;\n }\n }\n }\n }\n }\n }\n\n return result;\n}\n\nexport function getParagraphPlainText(paragraph: Paragraph): string {\n return flattenRuns(paragraph)\n .map((r) => r.text)\n .join('');\n}\n\n/**\n * Find text within a paragraph. Throws TextNotFoundError if not found.\n */\nexport function findTextInParagraph(\n paragraph: Paragraph,\n search: string,\n paragraphIndex?: number\n): TextSearchResult {\n const runs = flattenRuns(paragraph);\n const fullText = runs.map((r) => r.text).join('');\n\n const match = findMatch(fullText, search);\n if (!match) throw new TextNotFoundError(search, paragraphIndex);\n\n let startRunIdx = -1;\n let startOffset = 0;\n for (let i = 0; i < runs.length; i++) {\n if (match.start < runs[i].startPos + runs[i].text.length) {\n startRunIdx = i;\n startOffset = match.start - runs[i].startPos;\n break;\n }\n }\n\n let endRunIdx = -1;\n let endOffset = 0;\n for (let i = runs.length - 1; i >= 0; i--) {\n if (match.end > runs[i].startPos) {\n endRunIdx = i;\n endOffset = match.end - runs[i].startPos;\n break;\n }\n }\n\n if (startRunIdx === -1 || endRunIdx === -1) {\n throw new TextNotFoundError(search, paragraphIndex);\n }\n\n return {\n startRunIndex: runs[startRunIdx].contentIndex,\n startOffset,\n endRunIndex: runs[endRunIdx].contentIndex,\n endOffset,\n };\n}\n\n/**\n * Isolate matched text into its own runs by splitting at boundaries.\n * Mutates paragraph.content.\n */\nexport function isolateMatchedText(\n paragraph: Paragraph,\n search: string,\n paragraphIndex?: number\n): { startIndex: number; endIndex: number } {\n const result = findTextInParagraph(paragraph, search, paragraphIndex);\n let { startRunIndex, endRunIndex } = result;\n const { startOffset, endOffset } = result;\n\n // Split end run first (so indices don't shift for start)\n const endItem = paragraph.content[endRunIndex];\n if (endItem.type === 'run') {\n const endText = getRunText(endItem);\n if (endOffset < endText.length) {\n const afterRun = makeRunWithText(endText.slice(endOffset), endItem);\n setRunText(endItem, endText.slice(0, endOffset));\n paragraph.content.splice(endRunIndex + 1, 0, afterRun as Run);\n }\n }\n\n const startItem = paragraph.content[startRunIndex];\n if (startItem.type === 'run' && startOffset > 0) {\n const startText = getRunText(startItem);\n const beforeRun = makeRunWithText(startText.slice(0, startOffset), startItem);\n setRunText(startItem, startText.slice(startOffset));\n paragraph.content.splice(startRunIndex, 0, beforeRun as Run);\n startRunIndex++;\n endRunIndex++;\n }\n\n return { startIndex: startRunIndex, endIndex: endRunIndex };\n}\n\nfunction makeRunWithText(text: string, template: Run): Run {\n return {\n type: 'run',\n content: [{ type: 'text', text }],\n formatting: template.formatting ? { ...template.formatting } : undefined,\n } as Run;\n}\n\nfunction setRunText(run: Run, text: string): void {\n const textContent = run.content.find((c) => c.type === 'text');\n if (textContent) {\n (textContent as { type: 'text'; text: string }).text = text;\n }\n}\n\n// ============================================================================\n// MATCHING — exact, then normalized (case + quotes + whitespace)\n// ============================================================================\n\n/**\n * Normalize text for matching: lowercase, collapse whitespace,\n * straighten smart quotes/dashes, strip zero-width chars.\n */\nfunction normalize(original: string): { text: string; posMap: number[] } {\n const chars: string[] = [];\n const posMap: number[] = [];\n let prevSpace = true;\n\n for (let i = 0; i < original.length; i++) {\n let ch = original[i];\n\n // Skip zero-width chars\n if ('\\u200B\\u200C\\u200D\\uFEFF\\u00AD'.includes(ch)) continue;\n\n // Smart quotes → straight\n if ('\\u201C\\u201D\\u201E\\u201F'.includes(ch)) ch = '\"';\n if ('\\u2018\\u2019\\u201A\\u201B'.includes(ch)) ch = \"'\";\n\n // Dashes → hyphen\n if ('\\u2013\\u2014\\u2012\\u2015'.includes(ch)) ch = '-';\n\n // Ellipsis → dots\n if (ch === '\\u2026') {\n chars.push('.', '.', '.');\n posMap.push(i, i, i);\n prevSpace = false;\n continue;\n }\n\n // Collapse all whitespace (including \\n, \\t, non-breaking space)\n if (/\\s/.test(ch) || ch === '\\u00A0') {\n if (!prevSpace) {\n chars.push(' ');\n posMap.push(i);\n prevSpace = true;\n }\n continue;\n }\n\n chars.push(ch.toLowerCase());\n posMap.push(i);\n prevSpace = false;\n }\n\n // Trim trailing space\n if (chars.length > 0 && chars[chars.length - 1] === ' ') {\n chars.pop();\n posMap.pop();\n }\n\n return { text: chars.join(''), posMap };\n}\n\n/**\n * Map a normalized-space match back to original string positions.\n */\nfunction mapBack(\n norm: { posMap: number[] },\n idx: number,\n len: number,\n original: string\n): { start: number; end: number } {\n const start = norm.posMap[idx];\n let end = norm.posMap[idx + len - 1] + 1;\n while (end < original.length && '\\u200B\\u200C\\u200D\\uFEFF\\u00AD'.includes(original[end])) end++;\n return { start, end };\n}\n\n/**\n * Find search text within paragraph text.\n * 1. Exact match\n * 2. Normalized match (case-insensitive, smart quotes, collapsed whitespace)\n * 3. Trim trailing partial words (LLMs truncate mid-sentence)\n */\nfunction findMatch(text: string, search: string): { start: number; end: number } | null {\n if (!search || !text) return null;\n\n // 1. Exact\n const exact = text.indexOf(search);\n if (exact !== -1) return { start: exact, end: exact + search.length };\n\n // 2. Normalized\n const normText = normalize(text);\n const normSearch = normalize(search);\n if (!normSearch.text) return null;\n\n const idx = normText.text.indexOf(normSearch.text);\n if (idx !== -1) return mapBack(normText, idx, normSearch.text.length, text);\n\n // 3. Trim trailing partial words (LLM truncation: \"return HTTP 422. e.\" → \"return HTTP 422\")\n const words = normSearch.text.split(' ');\n if (words.length >= 3) {\n for (let drop = 1; drop <= Math.min(2, words.length - 2); drop++) {\n const trimmed = words.slice(0, -drop).join(' ');\n const trimIdx = normText.text.indexOf(trimmed);\n if (trimIdx !== -1) return mapBack(normText, trimIdx, trimmed.length, text);\n }\n }\n\n return null;\n}\n","/**\n * getChanges() and getComments() — discover tracked changes and comments in a document.\n */\n\nimport type { DocumentBody, Run, Comment } from '@eigenpal/docx-core/headless';\nimport type { ReviewChange, ReviewComment, ChangeFilter, CommentFilter } from './types';\nimport { getParagraphPlainText } from './textSearch';\nimport { getRunText, getTrackedChangeText, isTrackedChange, forEachParagraph } from './utils';\n\n/**\n * Collect all tracked changes from the document body.\n */\nexport function getChanges(body: DocumentBody, filter?: ChangeFilter): ReviewChange[] {\n const grouped = new Map<number, ReviewChange>();\n\n forEachParagraph(body, (para, paragraphIndex) => {\n let context: string | null = null;\n\n for (const item of para.content) {\n if (isTrackedChange(item)) {\n if (context === null) context = getParagraphPlainText(para);\n const text = getTrackedChangeText(item.content);\n const id = item.info.id;\n\n const existing = grouped.get(id);\n if (existing && existing.paragraphIndex === paragraphIndex) {\n existing.text += text;\n } else {\n grouped.set(id, {\n id,\n type: item.type,\n author: item.info.author,\n date: item.info.date ?? null,\n text,\n context,\n paragraphIndex,\n });\n }\n }\n }\n });\n\n const changes = Array.from(grouped.values());\n\n return changes.filter((c) => {\n if (filter?.author && c.author !== filter.author) return false;\n if (filter?.type && c.type !== filter.type) return false;\n return true;\n });\n}\n\n/**\n * Collect all comments from the document body.\n */\nexport function getComments(body: DocumentBody, filter?: CommentFilter): ReviewComment[] {\n const comments = body.comments ?? [];\n if (comments.length === 0) return [];\n\n const anchoredTextMap = buildAnchoredTextMap(body);\n\n const topLevel: Comment[] = [];\n const repliesByParent = new Map<number, Comment[]>();\n\n for (const c of comments) {\n if (c.parentId !== undefined) {\n const existing = repliesByParent.get(c.parentId) ?? [];\n existing.push(c);\n repliesByParent.set(c.parentId, existing);\n } else {\n topLevel.push(c);\n }\n }\n\n const result: ReviewComment[] = topLevel.map((c) => {\n const anchor = anchoredTextMap.get(c.id);\n const replies = (repliesByParent.get(c.id) ?? []).map((r) => ({\n id: r.id,\n author: r.author,\n date: r.date ?? null,\n text: getCommentText(r),\n }));\n\n return {\n id: c.id,\n author: c.author,\n date: c.date ?? null,\n text: getCommentText(c),\n anchoredText: anchor?.text ?? '',\n paragraphIndex: anchor?.paragraphIndex ?? -1,\n replies,\n done: c.done ?? false,\n };\n });\n\n return result.filter((c) => {\n if (filter?.author && c.author !== filter.author) return false;\n if (filter?.done !== undefined && c.done !== filter.done) return false;\n return true;\n });\n}\n\nfunction getCommentText(comment: Comment): string {\n return comment.content.map((para) => getParagraphPlainText(para)).join('\\n');\n}\n\ninterface AnchorInfo {\n text: string;\n paragraphIndex: number;\n}\n\nfunction buildAnchoredTextMap(body: DocumentBody): Map<number, AnchorInfo> {\n const result = new Map<number, AnchorInfo>();\n const openRanges = new Map<number, { paragraphIndex: number; parts: string[] }>();\n\n forEachParagraph(body, (para, paragraphIndex) => {\n for (const item of para.content) {\n if (item.type === 'commentRangeStart') {\n openRanges.set(item.id, { paragraphIndex, parts: [] });\n } else if (item.type === 'commentRangeEnd') {\n const open = openRanges.get(item.id);\n if (open) {\n result.set(item.id, { text: open.parts.join(''), paragraphIndex: open.paragraphIndex });\n openRanges.delete(item.id);\n }\n } else if (item.type === 'run') {\n const text = getRunText(item);\n for (const open of openRanges.values()) {\n open.parts.push(text);\n }\n } else if (item.type === 'hyperlink') {\n const text = item.children\n .filter((c): c is Run => c.type === 'run')\n .map(getRunText)\n .join('');\n for (const open of openRanges.values()) {\n open.parts.push(text);\n }\n } else if (isTrackedChange(item)) {\n const text = getTrackedChangeText(item.content);\n for (const open of openRanges.values()) {\n open.parts.push(text);\n }\n }\n }\n });\n\n return result;\n}\n","/**\n * Comment operations — addComment, replyTo\n */\n\nimport type { DocumentBody, Paragraph, Comment, Run } from '@eigenpal/docx-core/headless';\nimport type { AddCommentOptions, ReplyOptions } from './types';\nimport { CommentNotFoundError } from './errors';\nimport { findTextInParagraph } from './textSearch';\nimport { getParagraphAtIndex } from './utils';\n\n/**\n * Add a comment to a paragraph. Returns the new comment ID.\n */\nexport function addComment(body: DocumentBody, options: AddCommentOptions): number {\n const { paragraphIndex, author = 'AI', text, search } = options;\n const para = getParagraphAtIndex(body, paragraphIndex);\n\n const existingIds = (body.comments ?? []).map((c) => c.id);\n const newId = existingIds.length > 0 ? Math.max(...existingIds) + 1 : 1;\n\n const comment: Comment = {\n id: newId,\n author,\n date: new Date().toISOString(),\n content: [\n {\n type: 'paragraph',\n content: [{ type: 'run', content: [{ type: 'text', text }] } as Run],\n formatting: {},\n } as Paragraph,\n ],\n };\n\n if (!body.comments) {\n body.comments = [];\n }\n body.comments.push(comment);\n\n if (search) {\n const result = findTextInParagraph(para, search, paragraphIndex);\n // Insert end marker after end item, then start marker before start item\n para.content.splice(result.endRunIndex + 1, 0, { type: 'commentRangeEnd', id: newId });\n para.content.splice(result.startRunIndex, 0, { type: 'commentRangeStart', id: newId });\n } else {\n para.content.unshift({ type: 'commentRangeStart', id: newId });\n para.content.push({ type: 'commentRangeEnd', id: newId });\n }\n\n return newId;\n}\n\n/**\n * Reply to an existing comment. Returns the reply's comment ID.\n */\nexport function replyTo(body: DocumentBody, commentId: number, options: ReplyOptions): number {\n const comments = body.comments ?? [];\n const parent = comments.find((c) => c.id === commentId);\n if (!parent) {\n throw new CommentNotFoundError(commentId);\n }\n\n const existingIds = comments.map((c) => c.id);\n const newId = Math.max(...existingIds) + 1;\n\n const reply: Comment = {\n id: newId,\n author: options.author ?? 'AI',\n date: new Date().toISOString(),\n parentId: commentId,\n content: [\n {\n type: 'paragraph',\n content: [{ type: 'run', content: [{ type: 'text', text: options.text }] } as Run],\n formatting: {},\n } as Paragraph,\n ],\n };\n\n comments.push(reply);\n return newId;\n}\n","/**\n * Change operations — accept, reject, propose insertion/deletion/replacement.\n */\n\nimport type {\n DocumentBody,\n Paragraph,\n Run,\n Insertion,\n Deletion,\n ParagraphContent,\n} from '@eigenpal/docx-core/headless';\nimport type {\n ProposeReplacementOptions,\n ProposeInsertionOptions,\n ProposeDeletionOptions,\n} from './types';\nimport { ChangeNotFoundError } from './errors';\nimport { isolateMatchedText } from './textSearch';\nimport {\n isTrackedChange,\n getParagraphAtIndex,\n forEachParagraph,\n type TrackedChangeItem,\n} from './utils';\n\n// ============================================================================\n// ACCEPT / REJECT\n// ============================================================================\n\n/**\n * Accept a tracked change by ID.\n * Insertion: keep text, remove wrapper.\n * Deletion: remove text and wrapper.\n */\nexport function acceptChange(body: DocumentBody, id: number): void {\n if (!processChangeById(body, id, 'accept')) {\n throw new ChangeNotFoundError(id);\n }\n}\n\n/**\n * Reject a tracked change by ID.\n * Insertion: remove text and wrapper.\n * Deletion: keep text, remove wrapper.\n */\nexport function rejectChange(body: DocumentBody, id: number): void {\n if (!processChangeById(body, id, 'reject')) {\n throw new ChangeNotFoundError(id);\n }\n}\n\n/**\n * Accept all tracked changes. Returns count.\n */\nexport function acceptAll(body: DocumentBody): number {\n return processAllChanges(body, 'accept');\n}\n\n/**\n * Reject all tracked changes. Returns count.\n */\nexport function rejectAll(body: DocumentBody): number {\n return processAllChanges(body, 'reject');\n}\n\n/**\n * Process all tracked changes in a single pass (O(M) where M = total paragraphs).\n * Iterates backward within each paragraph so splice doesn't shift unprocessed indices.\n */\nfunction processAllChanges(body: DocumentBody, mode: 'accept' | 'reject'): number {\n let count = 0;\n forEachParagraph(body, (para) => {\n for (let i = para.content.length - 1; i >= 0; i--) {\n const item = para.content[i];\n if (isTrackedChange(item)) {\n applyChangeAtIndex(para, i, item, mode);\n count++;\n }\n }\n });\n return count;\n}\n\n/**\n * Find and process a tracked change by revision ID.\n * Processes ALL content items with matching ID (a revision can span multiple items).\n */\nfunction processChangeById(body: DocumentBody, id: number, mode: 'accept' | 'reject'): boolean {\n let found = false;\n forEachParagraph(body, (para) => {\n for (let i = para.content.length - 1; i >= 0; i--) {\n const item = para.content[i];\n if (isTrackedChange(item) && item.info.id === id) {\n applyChangeAtIndex(para, i, item, mode);\n found = true;\n }\n }\n // Stop traversal once we've found and processed the change\n if (found) return false;\n });\n return found;\n}\n\nfunction applyChangeAtIndex(\n para: Paragraph,\n index: number,\n item: TrackedChangeItem,\n mode: 'accept' | 'reject'\n) {\n const keepContent =\n (item.type === 'insertion' && mode === 'accept') ||\n (item.type === 'deletion' && mode === 'reject') ||\n (item.type === 'moveTo' && mode === 'accept') ||\n (item.type === 'moveFrom' && mode === 'reject');\n\n if (keepContent) {\n // Unwrap: replace the tracked change wrapper with its content runs\n const runs = item.content as ParagraphContent[];\n para.content.splice(index, 1, ...runs);\n } else {\n // Remove: delete the tracked change and its content\n para.content.splice(index, 1);\n }\n}\n\n// ============================================================================\n// PROPOSE CHANGES\n// ============================================================================\n\n/**\n * Propose a text replacement as a tracked change (deletion + insertion).\n */\nexport function proposeReplacement(body: DocumentBody, options: ProposeReplacementOptions): void {\n const { paragraphIndex, search, author = 'AI', replaceWith } = options;\n const para = getParagraphAtIndex(body, paragraphIndex);\n\n const { startIndex, endIndex } = isolateMatchedText(para, search, paragraphIndex);\n\n const now = new Date().toISOString();\n const baseId = nextRevisionId(body);\n\n const matchedContent = para.content.slice(startIndex, endIndex + 1);\n\n const deletion: Deletion = {\n type: 'deletion',\n info: { id: baseId, author, date: now },\n content: matchedContent as (Run | import('@eigenpal/docx-core/headless').Hyperlink)[],\n };\n\n const insertion: Insertion = {\n type: 'insertion',\n info: { id: baseId + 1, author, date: now },\n content: [{ type: 'run', content: [{ type: 'text', text: replaceWith }] } as Run],\n };\n\n para.content.splice(startIndex, endIndex - startIndex + 1, deletion, insertion);\n}\n\n/**\n * Propose an insertion as a tracked change.\n */\nexport function proposeInsertion(body: DocumentBody, options: ProposeInsertionOptions): void {\n const { paragraphIndex, author = 'AI', insertText, position = 'after', search } = options;\n const para = getParagraphAtIndex(body, paragraphIndex);\n\n const now = new Date().toISOString();\n const id = nextRevisionId(body);\n\n const insertion: Insertion = {\n type: 'insertion',\n info: { id, author, date: now },\n content: [{ type: 'run', content: [{ type: 'text', text: insertText }] } as Run],\n };\n\n if (search) {\n const { startIndex, endIndex } = isolateMatchedText(para, search, paragraphIndex);\n const insertAt = position === 'after' ? endIndex + 1 : startIndex;\n para.content.splice(insertAt, 0, insertion);\n } else {\n if (position === 'before') {\n para.content.unshift(insertion);\n } else {\n para.content.push(insertion);\n }\n }\n}\n\n/**\n * Propose a deletion as a tracked change.\n */\nexport function proposeDeletion(body: DocumentBody, options: ProposeDeletionOptions): void {\n const { paragraphIndex, search, author = 'AI' } = options;\n const para = getParagraphAtIndex(body, paragraphIndex);\n\n const { startIndex, endIndex } = isolateMatchedText(para, search, paragraphIndex);\n\n const now = new Date().toISOString();\n const id = nextRevisionId(body);\n\n const matchedContent = para.content.slice(startIndex, endIndex + 1);\n\n const deletion: Deletion = {\n type: 'deletion',\n info: { id, author, date: now },\n content: matchedContent as (Run | import('@eigenpal/docx-core/headless').Hyperlink)[],\n };\n\n para.content.splice(startIndex, endIndex - startIndex + 1, deletion);\n}\n\n// ============================================================================\n// HELPERS\n// ============================================================================\n\n/** Cached max revision ID per body — avoids O(N) scan on every proposal. */\nconst revisionIdCache = new WeakMap<DocumentBody, number>();\n\nfunction nextRevisionId(body: DocumentBody): number {\n let maxId = revisionIdCache.get(body);\n if (maxId === undefined) {\n maxId = 0;\n forEachParagraph(body, (para) => {\n for (const item of para.content) {\n if (isTrackedChange(item)) {\n maxId = Math.max(maxId!, item.info.id);\n }\n }\n });\n }\n const next = maxId + 1;\n // Reserve both next and next+1 (replacement uses two IDs)\n revisionIdCache.set(body, next + 1);\n return next;\n}\n","/**\n * applyReview() — batch review operations in a single call.\n */\n\nimport type { DocumentBody } from '@eigenpal/docx-core/headless';\nimport type { BatchReviewOptions, BatchResult, BatchError } from './types';\nimport { acceptChange, rejectChange, proposeReplacement } from './changes';\nimport { addComment, replyTo } from './comments';\n\n/**\n * Apply multiple review operations in a single call.\n * Order: accept/reject → comments → replies → proposals.\n * Individual failures are collected, not thrown.\n * defaultAuthor is used when individual items don't specify an author.\n */\nexport function applyReview(\n body: DocumentBody,\n ops: BatchReviewOptions,\n defaultAuthor = 'AI'\n): BatchResult {\n const errors: BatchError[] = [];\n let accepted = 0;\n let rejected = 0;\n let commentsAdded = 0;\n let repliesAdded = 0;\n let proposalsAdded = 0;\n\n for (const id of ops.accept ?? []) {\n try {\n acceptChange(body, id);\n accepted++;\n } catch (e) {\n errors.push({ operation: 'accept', id, error: (e as Error).message });\n }\n }\n\n for (const id of ops.reject ?? []) {\n try {\n rejectChange(body, id);\n rejected++;\n } catch (e) {\n errors.push({ operation: 'reject', id, error: (e as Error).message });\n }\n }\n\n for (const opts of ops.comments ?? []) {\n try {\n addComment(body, { ...opts, author: opts.author ?? defaultAuthor });\n commentsAdded++;\n } catch (e) {\n errors.push({ operation: 'comment', search: opts.search, error: (e as Error).message });\n }\n }\n\n for (const opts of ops.replies ?? []) {\n try {\n replyTo(body, opts.commentId, { author: opts.author ?? defaultAuthor, text: opts.text });\n repliesAdded++;\n } catch (e) {\n errors.push({ operation: 'reply', id: opts.commentId, error: (e as Error).message });\n }\n }\n\n for (const opts of ops.proposals ?? []) {\n try {\n proposeReplacement(body, { ...opts, author: opts.author ?? defaultAuthor });\n proposalsAdded++;\n } catch (e) {\n errors.push({ operation: 'proposal', search: opts.search, error: (e as Error).message });\n }\n }\n\n return { accepted, rejected, commentsAdded, repliesAdded, proposalsAdded, errors };\n}\n","/**\n * DocxReviewer — Word-like API for AI document review.\n *\n * @example\n * ```ts\n * const reviewer = await DocxReviewer.fromBuffer(buffer, 'AI Reviewer');\n * const text = reviewer.getContentAsText();\n * reviewer.addComment(5, 'Fix this paragraph.');\n * reviewer.replace(5, '$50k', '$500k');\n * const output = await reviewer.toBuffer();\n * ```\n */\n\nimport type { Document, DocumentBody } from '@eigenpal/docx-core/headless';\nimport { parseDocx } from '@eigenpal/docx-core/headless';\nimport type {\n ContentBlock,\n GetContentOptions,\n ReviewChange,\n ReviewComment,\n ChangeFilter,\n CommentFilter,\n AddCommentOptions,\n ReplyOptions,\n ProposeReplacementOptions,\n ProposeInsertionOptions,\n ProposeDeletionOptions,\n BatchReviewOptions,\n BatchResult,\n} from './types';\nimport { getContent as getContentImpl, formatContentForLLM } from './content';\nimport { getChanges as getChangesImpl, getComments as getCommentsImpl } from './discovery';\nimport { addComment as addCommentImpl, replyTo as replyToImpl } from './comments';\nimport {\n acceptChange as acceptChangeImpl,\n rejectChange as rejectChangeImpl,\n acceptAll as acceptAllImpl,\n rejectAll as rejectAllImpl,\n proposeReplacement as proposeReplacementImpl,\n proposeInsertion as proposeInsertionImpl,\n proposeDeletion as proposeDeletionImpl,\n} from './changes';\nimport { applyReview as applyReviewImpl } from './batch';\n\nexport class DocxReviewer {\n private doc: Document;\n /** Default author for comments and tracked changes. Set once, used everywhere. */\n readonly author: string;\n\n /**\n * Create a reviewer from a parsed Document.\n * @param document - Parsed Document from @eigenpal/docx-core\n * @param author - Default author name for comments and changes. (default: 'AI')\n * @param originalBuffer - Original DOCX buffer, needed for toBuffer()\n */\n constructor(document: Document, author = 'AI', originalBuffer?: ArrayBuffer) {\n // Strip originalBuffer before cloning to avoid deep-copying potentially large ArrayBuffer\n const savedBuffer = originalBuffer ?? document.originalBuffer;\n const { originalBuffer: _discard, ...rest } = document;\n this.doc = structuredClone(rest) as Document;\n if (savedBuffer) this.doc.originalBuffer = savedBuffer;\n this.author = author;\n }\n\n /**\n * Create a reviewer from a DOCX file buffer.\n * @param buffer - ArrayBuffer of the DOCX file\n * @param author - Default author name for comments and changes. (default: 'AI')\n */\n static async fromBuffer(buffer: ArrayBuffer, author = 'AI'): Promise<DocxReviewer> {\n const doc = await parseDocx(buffer, { preloadFonts: false });\n return new DocxReviewer(doc, author, buffer);\n }\n\n private get body(): DocumentBody {\n return this.doc.package.document;\n }\n\n private resolveAuthor(author?: string): string {\n return author ?? this.author;\n }\n\n // ==========================================================================\n // READ\n // ==========================================================================\n\n /** Get document content as structured blocks (headings, paragraphs, tables, lists). */\n getContent(options?: GetContentOptions): ContentBlock[] {\n return getContentImpl(this.body, options);\n }\n\n /**\n * Get document content as plain text for LLM prompts.\n * Each paragraph is prefixed with its index: `[0] text`, `[1] text`, etc.\n * Table cells include position: `[5] (table, row 1, col 2) cell text`.\n * Avoids JSON quote-escaping issues — LLMs can copy text verbatim.\n */\n getContentAsText(options?: GetContentOptions): string {\n return formatContentForLLM(getContentImpl(this.body, options));\n }\n\n // ==========================================================================\n // DISCOVER\n // ==========================================================================\n\n /** Get all tracked changes in the document. */\n getChanges(filter?: ChangeFilter): ReviewChange[] {\n return getChangesImpl(this.body, filter);\n }\n\n /** Get all comments with their replies. */\n getComments(filter?: CommentFilter): ReviewComment[] {\n return getCommentsImpl(this.body, filter);\n }\n\n // ==========================================================================\n // COMMENT\n // ==========================================================================\n\n /**\n * Add a comment on a paragraph.\n * @param paragraphIndex - Index of the paragraph to comment on\n * @param text - Comment text\n * @returns The new comment ID\n */\n addComment(paragraphIndex: number, text: string): number;\n /**\n * Add a comment with full options (custom author, anchored to specific text).\n * @param options - Comment options\n * @returns The new comment ID\n */\n addComment(options: AddCommentOptions): number;\n addComment(indexOrOptions: number | AddCommentOptions, text?: string): number {\n const opts =\n typeof indexOrOptions === 'number'\n ? { paragraphIndex: indexOrOptions, text: text!, author: this.author }\n : { ...indexOrOptions, author: this.resolveAuthor(indexOrOptions.author) };\n return addCommentImpl(this.body, opts);\n }\n\n /**\n * Reply to an existing comment.\n * @param commentId - ID of the comment to reply to\n * @param text - Reply text\n * @returns The new reply comment ID\n */\n replyTo(commentId: number, text: string): number;\n /** Reply to an existing comment with full options. */\n replyTo(commentId: number, options: ReplyOptions): number;\n replyTo(commentId: number, textOrOptions: string | ReplyOptions): number {\n const opts =\n typeof textOrOptions === 'string'\n ? { text: textOrOptions, author: this.author }\n : { ...textOrOptions, author: this.resolveAuthor(textOrOptions.author) };\n return replyToImpl(this.body, commentId, opts);\n }\n\n // ==========================================================================\n // PROPOSE CHANGES\n // ==========================================================================\n\n /**\n * Replace text in a paragraph. Creates a tracked change (deletion + insertion).\n * @param paragraphIndex - Index of the paragraph\n * @param search - Short phrase to find within the paragraph\n * @param replaceWith - Replacement text\n */\n replace(paragraphIndex: number, search: string, replaceWith: string): void;\n /** Replace text with full options. */\n replace(options: ProposeReplacementOptions): void;\n replace(\n indexOrOptions: number | ProposeReplacementOptions,\n search?: string,\n replaceWith?: string\n ): void {\n const opts =\n typeof indexOrOptions === 'number'\n ? {\n paragraphIndex: indexOrOptions,\n search: search!,\n replaceWith: replaceWith!,\n author: this.author,\n }\n : { ...indexOrOptions, author: this.resolveAuthor(indexOrOptions.author) };\n proposeReplacementImpl(this.body, opts);\n }\n\n /** @deprecated Use replace() instead. */\n proposeReplacement(options: ProposeReplacementOptions): void {\n this.replace(options);\n }\n\n /** Insert text as a tracked change. */\n proposeInsertion(options: ProposeInsertionOptions): void {\n proposeInsertionImpl(this.body, {\n ...options,\n author: this.resolveAuthor(options.author),\n });\n }\n\n /** Delete text as a tracked change. */\n proposeDeletion(options: ProposeDeletionOptions): void {\n proposeDeletionImpl(this.body, {\n ...options,\n author: this.resolveAuthor(options.author),\n });\n }\n\n // ==========================================================================\n // RESOLVE\n // ==========================================================================\n\n /** Accept a tracked change by its revision ID. */\n acceptChange(id: number): void {\n acceptChangeImpl(this.body, id);\n }\n\n /** Reject a tracked change by its revision ID. */\n rejectChange(id: number): void {\n rejectChangeImpl(this.body, id);\n }\n\n /** Accept all tracked changes. Returns count accepted. */\n acceptAll(): number {\n return acceptAllImpl(this.body);\n }\n\n /** Reject all tracked changes. Returns count rejected. */\n rejectAll(): number {\n return rejectAllImpl(this.body);\n }\n\n // ==========================================================================\n // BATCH\n // ==========================================================================\n\n /**\n * Apply multiple review operations in one call.\n * Uses the reviewer's default author. Individual failures are collected, not thrown.\n */\n applyReview(ops: BatchReviewOptions): BatchResult {\n return applyReviewImpl(this.body, ops, this.author);\n }\n\n // ==========================================================================\n // EXPORT\n // ==========================================================================\n\n /** Get the modified Document model. */\n toDocument(): Document {\n return this.doc;\n }\n\n /** Serialize back to a DOCX buffer. Requires the original buffer. */\n async toBuffer(): Promise<ArrayBuffer> {\n if (!this.doc.originalBuffer) {\n throw new Error(\n 'Cannot create buffer: no original DOCX buffer was provided. ' +\n 'Use DocxReviewer.fromBuffer() or pass originalBuffer to the constructor.'\n );\n }\n const { repackDocx } = await import('@eigenpal/docx-core/headless');\n return repackDocx(this.doc);\n }\n}\n"]}
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
var headless = require('@eigenpal/docx-core/headless');
|
|
1
|
+
import { parseDocx, isHeadingStyle, parseHeadingLevel, getRunText, getHyperlinkText } from '@eigenpal/docx-core/headless';
|
|
4
2
|
|
|
5
3
|
// src/DocxReviewer.ts
|
|
6
4
|
function isTrackedChange(item) {
|
|
@@ -10,9 +8,9 @@ function getTrackedChangeText(content) {
|
|
|
10
8
|
const parts = [];
|
|
11
9
|
for (const item of content) {
|
|
12
10
|
if (item.type === "run") {
|
|
13
|
-
parts.push(
|
|
11
|
+
parts.push(getRunText(item));
|
|
14
12
|
} else if (item.type === "hyperlink") {
|
|
15
|
-
parts.push(
|
|
13
|
+
parts.push(getHyperlinkText(item));
|
|
16
14
|
}
|
|
17
15
|
}
|
|
18
16
|
return parts.join("");
|
|
@@ -106,11 +104,11 @@ function isInRange(index, from, to) {
|
|
|
106
104
|
function buildParagraphBlock(para, index, includeTrackedChanges, includeCommentAnchors) {
|
|
107
105
|
const text = buildParagraphText(para, includeTrackedChanges, includeCommentAnchors);
|
|
108
106
|
const styleId = para.formatting?.styleId;
|
|
109
|
-
if (
|
|
107
|
+
if (isHeadingStyle(styleId)) {
|
|
110
108
|
return {
|
|
111
109
|
type: "heading",
|
|
112
110
|
index,
|
|
113
|
-
level:
|
|
111
|
+
level: parseHeadingLevel(styleId) ?? 1,
|
|
114
112
|
text
|
|
115
113
|
};
|
|
116
114
|
}
|
|
@@ -193,9 +191,9 @@ function buildParagraphText(para, includeTrackedChanges, includeCommentAnchors)
|
|
|
193
191
|
continue;
|
|
194
192
|
}
|
|
195
193
|
if (item.type === "run") {
|
|
196
|
-
parts.push(
|
|
194
|
+
parts.push(getRunText(item));
|
|
197
195
|
} else if (item.type === "hyperlink") {
|
|
198
|
-
parts.push(
|
|
196
|
+
parts.push(getHyperlinkText(item));
|
|
199
197
|
} else if (isTrackedChange(item)) {
|
|
200
198
|
const text = getTrackedChangeText(item.content);
|
|
201
199
|
if (item.type === "insertion" || item.type === "moveTo") {
|
|
@@ -242,14 +240,14 @@ function flattenRuns(paragraph) {
|
|
|
242
240
|
for (let ci = 0; ci < paragraph.content.length; ci++) {
|
|
243
241
|
const item = paragraph.content[ci];
|
|
244
242
|
if (item.type === "run") {
|
|
245
|
-
const text =
|
|
243
|
+
const text = getRunText(item);
|
|
246
244
|
result.push({ contentIndex: ci, run: item, text, startPos: pos });
|
|
247
245
|
pos += text.length;
|
|
248
246
|
} else if (item.type === "hyperlink") {
|
|
249
247
|
for (let hi = 0; hi < item.children.length; hi++) {
|
|
250
248
|
const child = item.children[hi];
|
|
251
249
|
if (child.type === "run") {
|
|
252
|
-
const text =
|
|
250
|
+
const text = getRunText(child);
|
|
253
251
|
result.push({ contentIndex: ci, run: child, text, startPos: pos });
|
|
254
252
|
pos += text.length;
|
|
255
253
|
}
|
|
@@ -258,13 +256,13 @@ function flattenRuns(paragraph) {
|
|
|
258
256
|
for (let ri = 0; ri < item.content.length; ri++) {
|
|
259
257
|
const child = item.content[ri];
|
|
260
258
|
if (child.type === "run") {
|
|
261
|
-
const text =
|
|
259
|
+
const text = getRunText(child);
|
|
262
260
|
result.push({ contentIndex: ci, run: child, text, startPos: pos });
|
|
263
261
|
pos += text.length;
|
|
264
262
|
} else if (child.type === "hyperlink") {
|
|
265
263
|
for (const hc of child.children) {
|
|
266
264
|
if (hc.type === "run") {
|
|
267
|
-
const text =
|
|
265
|
+
const text = getRunText(hc);
|
|
268
266
|
result.push({ contentIndex: ci, run: hc, text, startPos: pos });
|
|
269
267
|
pos += text.length;
|
|
270
268
|
}
|
|
@@ -317,7 +315,7 @@ function isolateMatchedText(paragraph, search, paragraphIndex) {
|
|
|
317
315
|
const { startOffset, endOffset } = result;
|
|
318
316
|
const endItem = paragraph.content[endRunIndex];
|
|
319
317
|
if (endItem.type === "run") {
|
|
320
|
-
const endText =
|
|
318
|
+
const endText = getRunText(endItem);
|
|
321
319
|
if (endOffset < endText.length) {
|
|
322
320
|
const afterRun = makeRunWithText(endText.slice(endOffset), endItem);
|
|
323
321
|
setRunText(endItem, endText.slice(0, endOffset));
|
|
@@ -326,7 +324,7 @@ function isolateMatchedText(paragraph, search, paragraphIndex) {
|
|
|
326
324
|
}
|
|
327
325
|
const startItem = paragraph.content[startRunIndex];
|
|
328
326
|
if (startItem.type === "run" && startOffset > 0) {
|
|
329
|
-
const startText =
|
|
327
|
+
const startText = getRunText(startItem);
|
|
330
328
|
const beforeRun = makeRunWithText(startText.slice(0, startOffset), startItem);
|
|
331
329
|
setRunText(startItem, startText.slice(startOffset));
|
|
332
330
|
paragraph.content.splice(startRunIndex, 0, beforeRun);
|
|
@@ -499,12 +497,12 @@ function buildAnchoredTextMap(body) {
|
|
|
499
497
|
openRanges.delete(item.id);
|
|
500
498
|
}
|
|
501
499
|
} else if (item.type === "run") {
|
|
502
|
-
const text =
|
|
500
|
+
const text = getRunText(item);
|
|
503
501
|
for (const open of openRanges.values()) {
|
|
504
502
|
open.parts.push(text);
|
|
505
503
|
}
|
|
506
504
|
} else if (item.type === "hyperlink") {
|
|
507
|
-
const text = item.children.filter((c) => c.type === "run").map(
|
|
505
|
+
const text = item.children.filter((c) => c.type === "run").map(getRunText).join("");
|
|
508
506
|
for (const open of openRanges.values()) {
|
|
509
507
|
open.parts.push(text);
|
|
510
508
|
}
|
|
@@ -774,7 +772,7 @@ var DocxReviewer = class _DocxReviewer {
|
|
|
774
772
|
* @param author - Default author name for comments and changes. (default: 'AI')
|
|
775
773
|
*/
|
|
776
774
|
static async fromBuffer(buffer, author = "AI") {
|
|
777
|
-
const doc = await
|
|
775
|
+
const doc = await parseDocx(buffer, { preloadFonts: false });
|
|
778
776
|
return new _DocxReviewer(doc, author, buffer);
|
|
779
777
|
}
|
|
780
778
|
get body() {
|
|
@@ -893,9 +891,6 @@ var DocxReviewer = class _DocxReviewer {
|
|
|
893
891
|
}
|
|
894
892
|
};
|
|
895
893
|
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
exports.TextNotFoundError = TextNotFoundError;
|
|
900
|
-
//# sourceMappingURL=index.cjs.map
|
|
901
|
-
//# sourceMappingURL=index.cjs.map
|
|
894
|
+
export { ChangeNotFoundError, CommentNotFoundError, DocxReviewer, TextNotFoundError };
|
|
895
|
+
//# sourceMappingURL=index.mjs.map
|
|
896
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils.ts","../src/content.ts","../src/errors.ts","../src/textSearch.ts","../src/discovery.ts","../src/comments.ts","../src/changes.ts","../src/batch.ts","../src/DocxReviewer.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Shared utilities for agent-use package.\n */\n\nimport type {\n DocumentBody,\n Paragraph,\n Run,\n Hyperlink,\n ParagraphContent,\n Insertion,\n Deletion,\n MoveFrom,\n MoveTo,\n} from '@eigenpal/docx-core/headless';\nimport {\n getRunText,\n getHyperlinkText,\n isHeadingStyle,\n parseHeadingLevel,\n} from '@eigenpal/docx-core/headless';\n\n// Re-export from core so other modules import from one place\nexport { getRunText, getHyperlinkText, isHeadingStyle, parseHeadingLevel };\n\n// ============================================================================\n// TRACKED CHANGE HELPERS\n// ============================================================================\n\nexport type TrackedChangeItem = Insertion | Deletion | MoveFrom | MoveTo;\n\nexport function isTrackedChange(item: ParagraphContent): item is TrackedChangeItem {\n return (\n item.type === 'insertion' ||\n item.type === 'deletion' ||\n item.type === 'moveFrom' ||\n item.type === 'moveTo'\n );\n}\n\nexport function getTrackedChangeText(content: (Run | Hyperlink)[]): string {\n const parts: string[] = [];\n for (const item of content) {\n if (item.type === 'run') {\n parts.push(getRunText(item));\n } else if (item.type === 'hyperlink') {\n parts.push(getHyperlinkText(item));\n }\n }\n return parts.join('');\n}\n\n// ============================================================================\n// DOCUMENT TRAVERSAL\n// ============================================================================\n\n/**\n * Get a paragraph by its document-wide index (counting into tables).\n * Throws on out-of-bounds.\n */\nexport function getParagraphAtIndex(body: DocumentBody, paragraphIndex: number): Paragraph {\n let index = 0;\n for (const block of body.content) {\n if (block.type === 'paragraph') {\n if (index === paragraphIndex) return block;\n index++;\n } else if (block.type === 'table') {\n for (const row of block.rows) {\n for (const cell of row.cells) {\n for (const cellBlock of cell.content) {\n if (cellBlock.type === 'paragraph') {\n if (index === paragraphIndex) return cellBlock;\n index++;\n }\n }\n }\n }\n } else {\n index++;\n }\n }\n throw new Error(`Paragraph index ${paragraphIndex} out of bounds (max: ${index - 1})`);\n}\n\n/**\n * Walk all paragraphs in the document body (including inside tables),\n * calling the callback with each paragraph and its document-wide index.\n */\nexport function forEachParagraph(\n body: DocumentBody,\n fn: (para: Paragraph, index: number) => void | boolean\n): void {\n let index = 0;\n for (const block of body.content) {\n if (block.type === 'paragraph') {\n if (fn(block, index) === false) return;\n index++;\n } else if (block.type === 'table') {\n for (const row of block.rows) {\n for (const cell of row.cells) {\n for (const cellBlock of cell.content) {\n if (cellBlock.type === 'paragraph') {\n if (fn(cellBlock, index) === false) return;\n index++;\n }\n }\n }\n }\n } else {\n index++;\n }\n }\n}\n","/**\n * getContent() — renders document as structured ContentBlock array for LLM consumption.\n * formatContentForLLM() — converts blocks to plain text (avoids JSON quote-escaping issues).\n */\n\nimport type { DocumentBody, Paragraph, Table } from '@eigenpal/docx-core/headless';\nimport type { ContentBlock, GetContentOptions } from './types';\nimport {\n getRunText,\n getHyperlinkText,\n getTrackedChangeText,\n isTrackedChange,\n isHeadingStyle,\n parseHeadingLevel,\n} from './utils';\n\n/**\n * Walk document body and produce ContentBlock array.\n */\nexport function getContent(body: DocumentBody, options: GetContentOptions = {}): ContentBlock[] {\n const {\n fromIndex,\n toIndex,\n includeTrackedChanges = true,\n includeCommentAnchors = true,\n } = options;\n\n const blocks: ContentBlock[] = [];\n let index = 0;\n\n for (const block of body.content) {\n if (block.type === 'paragraph') {\n if (isInRange(index, fromIndex, toIndex)) {\n blocks.push(\n buildParagraphBlock(block, index, includeTrackedChanges, includeCommentAnchors)\n );\n }\n index++;\n } else if (block.type === 'table') {\n if (isInRange(index, fromIndex, toIndex)) {\n blocks.push(buildTableBlock(block, index, includeTrackedChanges, includeCommentAnchors));\n }\n // Advance by number of cell paragraphs (matching getParagraphAtIndex counting)\n for (const row of block.rows) {\n for (const cell of row.cells) {\n for (const cellBlock of cell.content) {\n if (cellBlock.type === 'paragraph') {\n index++;\n }\n }\n }\n }\n } else {\n index++;\n }\n }\n\n return blocks;\n}\n\nfunction isInRange(index: number, from?: number, to?: number): boolean {\n return (from === undefined || index >= from) && (to === undefined || index <= to);\n}\n\nfunction buildParagraphBlock(\n para: Paragraph,\n index: number,\n includeTrackedChanges: boolean,\n includeCommentAnchors: boolean\n): ContentBlock {\n const text = buildParagraphText(para, includeTrackedChanges, includeCommentAnchors);\n const styleId = para.formatting?.styleId;\n\n if (isHeadingStyle(styleId)) {\n return {\n type: 'heading',\n index,\n level: parseHeadingLevel(styleId) ?? 1,\n text,\n };\n }\n\n if (para.listRendering) {\n return {\n type: 'list-item',\n index,\n text,\n listLevel: para.listRendering.level ?? 0,\n listType: para.listRendering.isBullet ? 'bullet' : 'number',\n };\n }\n\n return { type: 'paragraph', index, text };\n}\n\nfunction buildTableBlock(\n table: Table,\n index: number,\n includeTrackedChanges: boolean,\n includeCommentAnchors: boolean\n): ContentBlock {\n const rows: string[][] = [];\n for (const row of table.rows) {\n const cells: string[] = [];\n for (const cell of row.cells) {\n const cellTexts: string[] = [];\n for (const block of cell.content) {\n if (block.type === 'paragraph') {\n cellTexts.push(buildParagraphText(block, includeTrackedChanges, includeCommentAnchors));\n }\n }\n cells.push(cellTexts.join('\\n'));\n }\n rows.push(cells);\n }\n return { type: 'table', index, rows };\n}\n\n/**\n * Format content blocks as plain text for LLM prompts.\n * Every paragraph (including inside tables) gets its own [index].\n *\n * Output:\n * [0] (h1) Chapter Title\n * [1] Paragraph text here.\n * [2] • Bullet item\n * [3] (table, row 1, col 1) First cell\n * [4] (table, row 1, col 2) Second cell\n */\nexport function formatContentForLLM(blocks: ContentBlock[]): string {\n const lines: string[] = [];\n for (const block of blocks) {\n switch (block.type) {\n case 'heading':\n lines.push(`[${block.index}] (h${block.level}) ${block.text}`);\n break;\n case 'paragraph':\n lines.push(`[${block.index}] ${block.text}`);\n break;\n case 'list-item': {\n const indent = ' '.repeat(block.listLevel);\n const bullet = block.listType === 'bullet' ? '\\u2022' : '-';\n lines.push(`[${block.index}] ${indent}${bullet} ${block.text}`);\n break;\n }\n case 'table': {\n let idx = block.index;\n for (let r = 0; r < block.rows.length; r++) {\n for (let c = 0; c < block.rows[r].length; c++) {\n const cellText = block.rows[r][c];\n // A cell can have multiple paragraphs (joined by \\n in buildTableBlock)\n const paras = cellText.split('\\n');\n for (const para of paras) {\n lines.push(`[${idx}] (table, row ${r + 1}, col ${c + 1}) ${para}`);\n idx++;\n }\n }\n }\n break;\n }\n }\n }\n return lines.join('\\n');\n}\n\n/**\n * Build paragraph text with optional inline annotations for tracked changes and comments.\n */\nfunction buildParagraphText(\n para: Paragraph,\n includeTrackedChanges: boolean,\n includeCommentAnchors: boolean\n): string {\n const parts: string[] = [];\n const activeCommentIds = new Set<number>();\n\n for (const item of para.content) {\n if (item.type === 'commentRangeStart' && includeCommentAnchors) {\n activeCommentIds.add(item.id);\n parts.push(`[comment:${item.id}]`);\n continue;\n }\n if (item.type === 'commentRangeEnd' && includeCommentAnchors) {\n if (activeCommentIds.has(item.id)) {\n activeCommentIds.delete(item.id);\n parts.push('[/comment]');\n }\n continue;\n }\n\n if (item.type === 'run') {\n parts.push(getRunText(item));\n } else if (item.type === 'hyperlink') {\n parts.push(getHyperlinkText(item));\n } else if (isTrackedChange(item)) {\n const text = getTrackedChangeText(item.content);\n if (item.type === 'insertion' || item.type === 'moveTo') {\n if (includeTrackedChanges) {\n parts.push(`[+${text}+]{by:${item.info.author}}`);\n } else {\n parts.push(text);\n }\n } else {\n // deletion or moveFrom\n if (includeTrackedChanges) {\n parts.push(`[-${text}-]{by:${item.info.author}}`);\n }\n // When not annotating, hide deleted/moveFrom text\n }\n }\n }\n\n return parts.join('');\n}\n","/**\n * Error classes for @eigenpal/docx-editor-agents\n */\n\nexport class TextNotFoundError extends Error {\n constructor(search: string, paragraphIndex?: number) {\n const location =\n paragraphIndex !== undefined ? ` in paragraph ${paragraphIndex}` : ' in document';\n super(`Text not found${location}: \"${search}\"`);\n this.name = 'TextNotFoundError';\n }\n}\n\nexport class ChangeNotFoundError extends Error {\n constructor(id: number) {\n super(`Tracked change not found: id=${id}`);\n this.name = 'ChangeNotFoundError';\n }\n}\n\nexport class CommentNotFoundError extends Error {\n constructor(id: number) {\n super(`Comment not found: id=${id}`);\n this.name = 'CommentNotFoundError';\n }\n}\n","/**\n * Text search within paragraphs.\n * Handles text spanning multiple runs and tracked change wrappers.\n */\n\nimport type { Paragraph, Run } from '@eigenpal/docx-core/headless';\nimport { TextNotFoundError } from './errors';\nimport { getRunText, isTrackedChange } from './utils';\n\nexport interface TextSearchResult {\n startRunIndex: number;\n startOffset: number;\n endRunIndex: number;\n /** Character offset within the end run (exclusive) */\n endOffset: number;\n}\n\ninterface FlattenedRun {\n contentIndex: number;\n run: Run;\n text: string;\n startPos: number;\n}\n\n/**\n * Flatten paragraph content into runs with cumulative positions.\n */\nfunction flattenRuns(paragraph: Paragraph): FlattenedRun[] {\n const result: FlattenedRun[] = [];\n let pos = 0;\n\n for (let ci = 0; ci < paragraph.content.length; ci++) {\n const item = paragraph.content[ci];\n\n if (item.type === 'run') {\n const text = getRunText(item);\n result.push({ contentIndex: ci, run: item, text, startPos: pos });\n pos += text.length;\n } else if (item.type === 'hyperlink') {\n for (let hi = 0; hi < item.children.length; hi++) {\n const child = item.children[hi];\n if (child.type === 'run') {\n const text = getRunText(child);\n result.push({ contentIndex: ci, run: child, text, startPos: pos });\n pos += text.length;\n }\n }\n } else if (isTrackedChange(item)) {\n for (let ri = 0; ri < item.content.length; ri++) {\n const child = item.content[ri];\n if (child.type === 'run') {\n const text = getRunText(child);\n result.push({ contentIndex: ci, run: child, text, startPos: pos });\n pos += text.length;\n } else if (child.type === 'hyperlink') {\n for (const hc of child.children) {\n if (hc.type === 'run') {\n const text = getRunText(hc);\n result.push({ contentIndex: ci, run: hc, text, startPos: pos });\n pos += text.length;\n }\n }\n }\n }\n }\n }\n\n return result;\n}\n\nexport function getParagraphPlainText(paragraph: Paragraph): string {\n return flattenRuns(paragraph)\n .map((r) => r.text)\n .join('');\n}\n\n/**\n * Find text within a paragraph. Throws TextNotFoundError if not found.\n */\nexport function findTextInParagraph(\n paragraph: Paragraph,\n search: string,\n paragraphIndex?: number\n): TextSearchResult {\n const runs = flattenRuns(paragraph);\n const fullText = runs.map((r) => r.text).join('');\n\n const match = findMatch(fullText, search);\n if (!match) throw new TextNotFoundError(search, paragraphIndex);\n\n let startRunIdx = -1;\n let startOffset = 0;\n for (let i = 0; i < runs.length; i++) {\n if (match.start < runs[i].startPos + runs[i].text.length) {\n startRunIdx = i;\n startOffset = match.start - runs[i].startPos;\n break;\n }\n }\n\n let endRunIdx = -1;\n let endOffset = 0;\n for (let i = runs.length - 1; i >= 0; i--) {\n if (match.end > runs[i].startPos) {\n endRunIdx = i;\n endOffset = match.end - runs[i].startPos;\n break;\n }\n }\n\n if (startRunIdx === -1 || endRunIdx === -1) {\n throw new TextNotFoundError(search, paragraphIndex);\n }\n\n return {\n startRunIndex: runs[startRunIdx].contentIndex,\n startOffset,\n endRunIndex: runs[endRunIdx].contentIndex,\n endOffset,\n };\n}\n\n/**\n * Isolate matched text into its own runs by splitting at boundaries.\n * Mutates paragraph.content.\n */\nexport function isolateMatchedText(\n paragraph: Paragraph,\n search: string,\n paragraphIndex?: number\n): { startIndex: number; endIndex: number } {\n const result = findTextInParagraph(paragraph, search, paragraphIndex);\n let { startRunIndex, endRunIndex } = result;\n const { startOffset, endOffset } = result;\n\n // Split end run first (so indices don't shift for start)\n const endItem = paragraph.content[endRunIndex];\n if (endItem.type === 'run') {\n const endText = getRunText(endItem);\n if (endOffset < endText.length) {\n const afterRun = makeRunWithText(endText.slice(endOffset), endItem);\n setRunText(endItem, endText.slice(0, endOffset));\n paragraph.content.splice(endRunIndex + 1, 0, afterRun as Run);\n }\n }\n\n const startItem = paragraph.content[startRunIndex];\n if (startItem.type === 'run' && startOffset > 0) {\n const startText = getRunText(startItem);\n const beforeRun = makeRunWithText(startText.slice(0, startOffset), startItem);\n setRunText(startItem, startText.slice(startOffset));\n paragraph.content.splice(startRunIndex, 0, beforeRun as Run);\n startRunIndex++;\n endRunIndex++;\n }\n\n return { startIndex: startRunIndex, endIndex: endRunIndex };\n}\n\nfunction makeRunWithText(text: string, template: Run): Run {\n return {\n type: 'run',\n content: [{ type: 'text', text }],\n formatting: template.formatting ? { ...template.formatting } : undefined,\n } as Run;\n}\n\nfunction setRunText(run: Run, text: string): void {\n const textContent = run.content.find((c) => c.type === 'text');\n if (textContent) {\n (textContent as { type: 'text'; text: string }).text = text;\n }\n}\n\n// ============================================================================\n// MATCHING — exact, then normalized (case + quotes + whitespace)\n// ============================================================================\n\n/**\n * Normalize text for matching: lowercase, collapse whitespace,\n * straighten smart quotes/dashes, strip zero-width chars.\n */\nfunction normalize(original: string): { text: string; posMap: number[] } {\n const chars: string[] = [];\n const posMap: number[] = [];\n let prevSpace = true;\n\n for (let i = 0; i < original.length; i++) {\n let ch = original[i];\n\n // Skip zero-width chars\n if ('\\u200B\\u200C\\u200D\\uFEFF\\u00AD'.includes(ch)) continue;\n\n // Smart quotes → straight\n if ('\\u201C\\u201D\\u201E\\u201F'.includes(ch)) ch = '\"';\n if ('\\u2018\\u2019\\u201A\\u201B'.includes(ch)) ch = \"'\";\n\n // Dashes → hyphen\n if ('\\u2013\\u2014\\u2012\\u2015'.includes(ch)) ch = '-';\n\n // Ellipsis → dots\n if (ch === '\\u2026') {\n chars.push('.', '.', '.');\n posMap.push(i, i, i);\n prevSpace = false;\n continue;\n }\n\n // Collapse all whitespace (including \\n, \\t, non-breaking space)\n if (/\\s/.test(ch) || ch === '\\u00A0') {\n if (!prevSpace) {\n chars.push(' ');\n posMap.push(i);\n prevSpace = true;\n }\n continue;\n }\n\n chars.push(ch.toLowerCase());\n posMap.push(i);\n prevSpace = false;\n }\n\n // Trim trailing space\n if (chars.length > 0 && chars[chars.length - 1] === ' ') {\n chars.pop();\n posMap.pop();\n }\n\n return { text: chars.join(''), posMap };\n}\n\n/**\n * Map a normalized-space match back to original string positions.\n */\nfunction mapBack(\n norm: { posMap: number[] },\n idx: number,\n len: number,\n original: string\n): { start: number; end: number } {\n const start = norm.posMap[idx];\n let end = norm.posMap[idx + len - 1] + 1;\n while (end < original.length && '\\u200B\\u200C\\u200D\\uFEFF\\u00AD'.includes(original[end])) end++;\n return { start, end };\n}\n\n/**\n * Find search text within paragraph text.\n * 1. Exact match\n * 2. Normalized match (case-insensitive, smart quotes, collapsed whitespace)\n * 3. Trim trailing partial words (LLMs truncate mid-sentence)\n */\nfunction findMatch(text: string, search: string): { start: number; end: number } | null {\n if (!search || !text) return null;\n\n // 1. Exact\n const exact = text.indexOf(search);\n if (exact !== -1) return { start: exact, end: exact + search.length };\n\n // 2. Normalized\n const normText = normalize(text);\n const normSearch = normalize(search);\n if (!normSearch.text) return null;\n\n const idx = normText.text.indexOf(normSearch.text);\n if (idx !== -1) return mapBack(normText, idx, normSearch.text.length, text);\n\n // 3. Trim trailing partial words (LLM truncation: \"return HTTP 422. e.\" → \"return HTTP 422\")\n const words = normSearch.text.split(' ');\n if (words.length >= 3) {\n for (let drop = 1; drop <= Math.min(2, words.length - 2); drop++) {\n const trimmed = words.slice(0, -drop).join(' ');\n const trimIdx = normText.text.indexOf(trimmed);\n if (trimIdx !== -1) return mapBack(normText, trimIdx, trimmed.length, text);\n }\n }\n\n return null;\n}\n","/**\n * getChanges() and getComments() — discover tracked changes and comments in a document.\n */\n\nimport type { DocumentBody, Run, Comment } from '@eigenpal/docx-core/headless';\nimport type { ReviewChange, ReviewComment, ChangeFilter, CommentFilter } from './types';\nimport { getParagraphPlainText } from './textSearch';\nimport { getRunText, getTrackedChangeText, isTrackedChange, forEachParagraph } from './utils';\n\n/**\n * Collect all tracked changes from the document body.\n */\nexport function getChanges(body: DocumentBody, filter?: ChangeFilter): ReviewChange[] {\n const grouped = new Map<number, ReviewChange>();\n\n forEachParagraph(body, (para, paragraphIndex) => {\n let context: string | null = null;\n\n for (const item of para.content) {\n if (isTrackedChange(item)) {\n if (context === null) context = getParagraphPlainText(para);\n const text = getTrackedChangeText(item.content);\n const id = item.info.id;\n\n const existing = grouped.get(id);\n if (existing && existing.paragraphIndex === paragraphIndex) {\n existing.text += text;\n } else {\n grouped.set(id, {\n id,\n type: item.type,\n author: item.info.author,\n date: item.info.date ?? null,\n text,\n context,\n paragraphIndex,\n });\n }\n }\n }\n });\n\n const changes = Array.from(grouped.values());\n\n return changes.filter((c) => {\n if (filter?.author && c.author !== filter.author) return false;\n if (filter?.type && c.type !== filter.type) return false;\n return true;\n });\n}\n\n/**\n * Collect all comments from the document body.\n */\nexport function getComments(body: DocumentBody, filter?: CommentFilter): ReviewComment[] {\n const comments = body.comments ?? [];\n if (comments.length === 0) return [];\n\n const anchoredTextMap = buildAnchoredTextMap(body);\n\n const topLevel: Comment[] = [];\n const repliesByParent = new Map<number, Comment[]>();\n\n for (const c of comments) {\n if (c.parentId !== undefined) {\n const existing = repliesByParent.get(c.parentId) ?? [];\n existing.push(c);\n repliesByParent.set(c.parentId, existing);\n } else {\n topLevel.push(c);\n }\n }\n\n const result: ReviewComment[] = topLevel.map((c) => {\n const anchor = anchoredTextMap.get(c.id);\n const replies = (repliesByParent.get(c.id) ?? []).map((r) => ({\n id: r.id,\n author: r.author,\n date: r.date ?? null,\n text: getCommentText(r),\n }));\n\n return {\n id: c.id,\n author: c.author,\n date: c.date ?? null,\n text: getCommentText(c),\n anchoredText: anchor?.text ?? '',\n paragraphIndex: anchor?.paragraphIndex ?? -1,\n replies,\n done: c.done ?? false,\n };\n });\n\n return result.filter((c) => {\n if (filter?.author && c.author !== filter.author) return false;\n if (filter?.done !== undefined && c.done !== filter.done) return false;\n return true;\n });\n}\n\nfunction getCommentText(comment: Comment): string {\n return comment.content.map((para) => getParagraphPlainText(para)).join('\\n');\n}\n\ninterface AnchorInfo {\n text: string;\n paragraphIndex: number;\n}\n\nfunction buildAnchoredTextMap(body: DocumentBody): Map<number, AnchorInfo> {\n const result = new Map<number, AnchorInfo>();\n const openRanges = new Map<number, { paragraphIndex: number; parts: string[] }>();\n\n forEachParagraph(body, (para, paragraphIndex) => {\n for (const item of para.content) {\n if (item.type === 'commentRangeStart') {\n openRanges.set(item.id, { paragraphIndex, parts: [] });\n } else if (item.type === 'commentRangeEnd') {\n const open = openRanges.get(item.id);\n if (open) {\n result.set(item.id, { text: open.parts.join(''), paragraphIndex: open.paragraphIndex });\n openRanges.delete(item.id);\n }\n } else if (item.type === 'run') {\n const text = getRunText(item);\n for (const open of openRanges.values()) {\n open.parts.push(text);\n }\n } else if (item.type === 'hyperlink') {\n const text = item.children\n .filter((c): c is Run => c.type === 'run')\n .map(getRunText)\n .join('');\n for (const open of openRanges.values()) {\n open.parts.push(text);\n }\n } else if (isTrackedChange(item)) {\n const text = getTrackedChangeText(item.content);\n for (const open of openRanges.values()) {\n open.parts.push(text);\n }\n }\n }\n });\n\n return result;\n}\n","/**\n * Comment operations — addComment, replyTo\n */\n\nimport type { DocumentBody, Paragraph, Comment, Run } from '@eigenpal/docx-core/headless';\nimport type { AddCommentOptions, ReplyOptions } from './types';\nimport { CommentNotFoundError } from './errors';\nimport { findTextInParagraph } from './textSearch';\nimport { getParagraphAtIndex } from './utils';\n\n/**\n * Add a comment to a paragraph. Returns the new comment ID.\n */\nexport function addComment(body: DocumentBody, options: AddCommentOptions): number {\n const { paragraphIndex, author = 'AI', text, search } = options;\n const para = getParagraphAtIndex(body, paragraphIndex);\n\n const existingIds = (body.comments ?? []).map((c) => c.id);\n const newId = existingIds.length > 0 ? Math.max(...existingIds) + 1 : 1;\n\n const comment: Comment = {\n id: newId,\n author,\n date: new Date().toISOString(),\n content: [\n {\n type: 'paragraph',\n content: [{ type: 'run', content: [{ type: 'text', text }] } as Run],\n formatting: {},\n } as Paragraph,\n ],\n };\n\n if (!body.comments) {\n body.comments = [];\n }\n body.comments.push(comment);\n\n if (search) {\n const result = findTextInParagraph(para, search, paragraphIndex);\n // Insert end marker after end item, then start marker before start item\n para.content.splice(result.endRunIndex + 1, 0, { type: 'commentRangeEnd', id: newId });\n para.content.splice(result.startRunIndex, 0, { type: 'commentRangeStart', id: newId });\n } else {\n para.content.unshift({ type: 'commentRangeStart', id: newId });\n para.content.push({ type: 'commentRangeEnd', id: newId });\n }\n\n return newId;\n}\n\n/**\n * Reply to an existing comment. Returns the reply's comment ID.\n */\nexport function replyTo(body: DocumentBody, commentId: number, options: ReplyOptions): number {\n const comments = body.comments ?? [];\n const parent = comments.find((c) => c.id === commentId);\n if (!parent) {\n throw new CommentNotFoundError(commentId);\n }\n\n const existingIds = comments.map((c) => c.id);\n const newId = Math.max(...existingIds) + 1;\n\n const reply: Comment = {\n id: newId,\n author: options.author ?? 'AI',\n date: new Date().toISOString(),\n parentId: commentId,\n content: [\n {\n type: 'paragraph',\n content: [{ type: 'run', content: [{ type: 'text', text: options.text }] } as Run],\n formatting: {},\n } as Paragraph,\n ],\n };\n\n comments.push(reply);\n return newId;\n}\n","/**\n * Change operations — accept, reject, propose insertion/deletion/replacement.\n */\n\nimport type {\n DocumentBody,\n Paragraph,\n Run,\n Insertion,\n Deletion,\n ParagraphContent,\n} from '@eigenpal/docx-core/headless';\nimport type {\n ProposeReplacementOptions,\n ProposeInsertionOptions,\n ProposeDeletionOptions,\n} from './types';\nimport { ChangeNotFoundError } from './errors';\nimport { isolateMatchedText } from './textSearch';\nimport {\n isTrackedChange,\n getParagraphAtIndex,\n forEachParagraph,\n type TrackedChangeItem,\n} from './utils';\n\n// ============================================================================\n// ACCEPT / REJECT\n// ============================================================================\n\n/**\n * Accept a tracked change by ID.\n * Insertion: keep text, remove wrapper.\n * Deletion: remove text and wrapper.\n */\nexport function acceptChange(body: DocumentBody, id: number): void {\n if (!processChangeById(body, id, 'accept')) {\n throw new ChangeNotFoundError(id);\n }\n}\n\n/**\n * Reject a tracked change by ID.\n * Insertion: remove text and wrapper.\n * Deletion: keep text, remove wrapper.\n */\nexport function rejectChange(body: DocumentBody, id: number): void {\n if (!processChangeById(body, id, 'reject')) {\n throw new ChangeNotFoundError(id);\n }\n}\n\n/**\n * Accept all tracked changes. Returns count.\n */\nexport function acceptAll(body: DocumentBody): number {\n return processAllChanges(body, 'accept');\n}\n\n/**\n * Reject all tracked changes. Returns count.\n */\nexport function rejectAll(body: DocumentBody): number {\n return processAllChanges(body, 'reject');\n}\n\n/**\n * Process all tracked changes in a single pass (O(M) where M = total paragraphs).\n * Iterates backward within each paragraph so splice doesn't shift unprocessed indices.\n */\nfunction processAllChanges(body: DocumentBody, mode: 'accept' | 'reject'): number {\n let count = 0;\n forEachParagraph(body, (para) => {\n for (let i = para.content.length - 1; i >= 0; i--) {\n const item = para.content[i];\n if (isTrackedChange(item)) {\n applyChangeAtIndex(para, i, item, mode);\n count++;\n }\n }\n });\n return count;\n}\n\n/**\n * Find and process a tracked change by revision ID.\n * Processes ALL content items with matching ID (a revision can span multiple items).\n */\nfunction processChangeById(body: DocumentBody, id: number, mode: 'accept' | 'reject'): boolean {\n let found = false;\n forEachParagraph(body, (para) => {\n for (let i = para.content.length - 1; i >= 0; i--) {\n const item = para.content[i];\n if (isTrackedChange(item) && item.info.id === id) {\n applyChangeAtIndex(para, i, item, mode);\n found = true;\n }\n }\n // Stop traversal once we've found and processed the change\n if (found) return false;\n });\n return found;\n}\n\nfunction applyChangeAtIndex(\n para: Paragraph,\n index: number,\n item: TrackedChangeItem,\n mode: 'accept' | 'reject'\n) {\n const keepContent =\n (item.type === 'insertion' && mode === 'accept') ||\n (item.type === 'deletion' && mode === 'reject') ||\n (item.type === 'moveTo' && mode === 'accept') ||\n (item.type === 'moveFrom' && mode === 'reject');\n\n if (keepContent) {\n // Unwrap: replace the tracked change wrapper with its content runs\n const runs = item.content as ParagraphContent[];\n para.content.splice(index, 1, ...runs);\n } else {\n // Remove: delete the tracked change and its content\n para.content.splice(index, 1);\n }\n}\n\n// ============================================================================\n// PROPOSE CHANGES\n// ============================================================================\n\n/**\n * Propose a text replacement as a tracked change (deletion + insertion).\n */\nexport function proposeReplacement(body: DocumentBody, options: ProposeReplacementOptions): void {\n const { paragraphIndex, search, author = 'AI', replaceWith } = options;\n const para = getParagraphAtIndex(body, paragraphIndex);\n\n const { startIndex, endIndex } = isolateMatchedText(para, search, paragraphIndex);\n\n const now = new Date().toISOString();\n const baseId = nextRevisionId(body);\n\n const matchedContent = para.content.slice(startIndex, endIndex + 1);\n\n const deletion: Deletion = {\n type: 'deletion',\n info: { id: baseId, author, date: now },\n content: matchedContent as (Run | import('@eigenpal/docx-core/headless').Hyperlink)[],\n };\n\n const insertion: Insertion = {\n type: 'insertion',\n info: { id: baseId + 1, author, date: now },\n content: [{ type: 'run', content: [{ type: 'text', text: replaceWith }] } as Run],\n };\n\n para.content.splice(startIndex, endIndex - startIndex + 1, deletion, insertion);\n}\n\n/**\n * Propose an insertion as a tracked change.\n */\nexport function proposeInsertion(body: DocumentBody, options: ProposeInsertionOptions): void {\n const { paragraphIndex, author = 'AI', insertText, position = 'after', search } = options;\n const para = getParagraphAtIndex(body, paragraphIndex);\n\n const now = new Date().toISOString();\n const id = nextRevisionId(body);\n\n const insertion: Insertion = {\n type: 'insertion',\n info: { id, author, date: now },\n content: [{ type: 'run', content: [{ type: 'text', text: insertText }] } as Run],\n };\n\n if (search) {\n const { startIndex, endIndex } = isolateMatchedText(para, search, paragraphIndex);\n const insertAt = position === 'after' ? endIndex + 1 : startIndex;\n para.content.splice(insertAt, 0, insertion);\n } else {\n if (position === 'before') {\n para.content.unshift(insertion);\n } else {\n para.content.push(insertion);\n }\n }\n}\n\n/**\n * Propose a deletion as a tracked change.\n */\nexport function proposeDeletion(body: DocumentBody, options: ProposeDeletionOptions): void {\n const { paragraphIndex, search, author = 'AI' } = options;\n const para = getParagraphAtIndex(body, paragraphIndex);\n\n const { startIndex, endIndex } = isolateMatchedText(para, search, paragraphIndex);\n\n const now = new Date().toISOString();\n const id = nextRevisionId(body);\n\n const matchedContent = para.content.slice(startIndex, endIndex + 1);\n\n const deletion: Deletion = {\n type: 'deletion',\n info: { id, author, date: now },\n content: matchedContent as (Run | import('@eigenpal/docx-core/headless').Hyperlink)[],\n };\n\n para.content.splice(startIndex, endIndex - startIndex + 1, deletion);\n}\n\n// ============================================================================\n// HELPERS\n// ============================================================================\n\n/** Cached max revision ID per body — avoids O(N) scan on every proposal. */\nconst revisionIdCache = new WeakMap<DocumentBody, number>();\n\nfunction nextRevisionId(body: DocumentBody): number {\n let maxId = revisionIdCache.get(body);\n if (maxId === undefined) {\n maxId = 0;\n forEachParagraph(body, (para) => {\n for (const item of para.content) {\n if (isTrackedChange(item)) {\n maxId = Math.max(maxId!, item.info.id);\n }\n }\n });\n }\n const next = maxId + 1;\n // Reserve both next and next+1 (replacement uses two IDs)\n revisionIdCache.set(body, next + 1);\n return next;\n}\n","/**\n * applyReview() — batch review operations in a single call.\n */\n\nimport type { DocumentBody } from '@eigenpal/docx-core/headless';\nimport type { BatchReviewOptions, BatchResult, BatchError } from './types';\nimport { acceptChange, rejectChange, proposeReplacement } from './changes';\nimport { addComment, replyTo } from './comments';\n\n/**\n * Apply multiple review operations in a single call.\n * Order: accept/reject → comments → replies → proposals.\n * Individual failures are collected, not thrown.\n * defaultAuthor is used when individual items don't specify an author.\n */\nexport function applyReview(\n body: DocumentBody,\n ops: BatchReviewOptions,\n defaultAuthor = 'AI'\n): BatchResult {\n const errors: BatchError[] = [];\n let accepted = 0;\n let rejected = 0;\n let commentsAdded = 0;\n let repliesAdded = 0;\n let proposalsAdded = 0;\n\n for (const id of ops.accept ?? []) {\n try {\n acceptChange(body, id);\n accepted++;\n } catch (e) {\n errors.push({ operation: 'accept', id, error: (e as Error).message });\n }\n }\n\n for (const id of ops.reject ?? []) {\n try {\n rejectChange(body, id);\n rejected++;\n } catch (e) {\n errors.push({ operation: 'reject', id, error: (e as Error).message });\n }\n }\n\n for (const opts of ops.comments ?? []) {\n try {\n addComment(body, { ...opts, author: opts.author ?? defaultAuthor });\n commentsAdded++;\n } catch (e) {\n errors.push({ operation: 'comment', search: opts.search, error: (e as Error).message });\n }\n }\n\n for (const opts of ops.replies ?? []) {\n try {\n replyTo(body, opts.commentId, { author: opts.author ?? defaultAuthor, text: opts.text });\n repliesAdded++;\n } catch (e) {\n errors.push({ operation: 'reply', id: opts.commentId, error: (e as Error).message });\n }\n }\n\n for (const opts of ops.proposals ?? []) {\n try {\n proposeReplacement(body, { ...opts, author: opts.author ?? defaultAuthor });\n proposalsAdded++;\n } catch (e) {\n errors.push({ operation: 'proposal', search: opts.search, error: (e as Error).message });\n }\n }\n\n return { accepted, rejected, commentsAdded, repliesAdded, proposalsAdded, errors };\n}\n","/**\n * DocxReviewer — Word-like API for AI document review.\n *\n * @example\n * ```ts\n * const reviewer = await DocxReviewer.fromBuffer(buffer, 'AI Reviewer');\n * const text = reviewer.getContentAsText();\n * reviewer.addComment(5, 'Fix this paragraph.');\n * reviewer.replace(5, '$50k', '$500k');\n * const output = await reviewer.toBuffer();\n * ```\n */\n\nimport type { Document, DocumentBody } from '@eigenpal/docx-core/headless';\nimport { parseDocx } from '@eigenpal/docx-core/headless';\nimport type {\n ContentBlock,\n GetContentOptions,\n ReviewChange,\n ReviewComment,\n ChangeFilter,\n CommentFilter,\n AddCommentOptions,\n ReplyOptions,\n ProposeReplacementOptions,\n ProposeInsertionOptions,\n ProposeDeletionOptions,\n BatchReviewOptions,\n BatchResult,\n} from './types';\nimport { getContent as getContentImpl, formatContentForLLM } from './content';\nimport { getChanges as getChangesImpl, getComments as getCommentsImpl } from './discovery';\nimport { addComment as addCommentImpl, replyTo as replyToImpl } from './comments';\nimport {\n acceptChange as acceptChangeImpl,\n rejectChange as rejectChangeImpl,\n acceptAll as acceptAllImpl,\n rejectAll as rejectAllImpl,\n proposeReplacement as proposeReplacementImpl,\n proposeInsertion as proposeInsertionImpl,\n proposeDeletion as proposeDeletionImpl,\n} from './changes';\nimport { applyReview as applyReviewImpl } from './batch';\n\nexport class DocxReviewer {\n private doc: Document;\n /** Default author for comments and tracked changes. Set once, used everywhere. */\n readonly author: string;\n\n /**\n * Create a reviewer from a parsed Document.\n * @param document - Parsed Document from @eigenpal/docx-core\n * @param author - Default author name for comments and changes. (default: 'AI')\n * @param originalBuffer - Original DOCX buffer, needed for toBuffer()\n */\n constructor(document: Document, author = 'AI', originalBuffer?: ArrayBuffer) {\n // Strip originalBuffer before cloning to avoid deep-copying potentially large ArrayBuffer\n const savedBuffer = originalBuffer ?? document.originalBuffer;\n const { originalBuffer: _discard, ...rest } = document;\n this.doc = structuredClone(rest) as Document;\n if (savedBuffer) this.doc.originalBuffer = savedBuffer;\n this.author = author;\n }\n\n /**\n * Create a reviewer from a DOCX file buffer.\n * @param buffer - ArrayBuffer of the DOCX file\n * @param author - Default author name for comments and changes. (default: 'AI')\n */\n static async fromBuffer(buffer: ArrayBuffer, author = 'AI'): Promise<DocxReviewer> {\n const doc = await parseDocx(buffer, { preloadFonts: false });\n return new DocxReviewer(doc, author, buffer);\n }\n\n private get body(): DocumentBody {\n return this.doc.package.document;\n }\n\n private resolveAuthor(author?: string): string {\n return author ?? this.author;\n }\n\n // ==========================================================================\n // READ\n // ==========================================================================\n\n /** Get document content as structured blocks (headings, paragraphs, tables, lists). */\n getContent(options?: GetContentOptions): ContentBlock[] {\n return getContentImpl(this.body, options);\n }\n\n /**\n * Get document content as plain text for LLM prompts.\n * Each paragraph is prefixed with its index: `[0] text`, `[1] text`, etc.\n * Table cells include position: `[5] (table, row 1, col 2) cell text`.\n * Avoids JSON quote-escaping issues — LLMs can copy text verbatim.\n */\n getContentAsText(options?: GetContentOptions): string {\n return formatContentForLLM(getContentImpl(this.body, options));\n }\n\n // ==========================================================================\n // DISCOVER\n // ==========================================================================\n\n /** Get all tracked changes in the document. */\n getChanges(filter?: ChangeFilter): ReviewChange[] {\n return getChangesImpl(this.body, filter);\n }\n\n /** Get all comments with their replies. */\n getComments(filter?: CommentFilter): ReviewComment[] {\n return getCommentsImpl(this.body, filter);\n }\n\n // ==========================================================================\n // COMMENT\n // ==========================================================================\n\n /**\n * Add a comment on a paragraph.\n * @param paragraphIndex - Index of the paragraph to comment on\n * @param text - Comment text\n * @returns The new comment ID\n */\n addComment(paragraphIndex: number, text: string): number;\n /**\n * Add a comment with full options (custom author, anchored to specific text).\n * @param options - Comment options\n * @returns The new comment ID\n */\n addComment(options: AddCommentOptions): number;\n addComment(indexOrOptions: number | AddCommentOptions, text?: string): number {\n const opts =\n typeof indexOrOptions === 'number'\n ? { paragraphIndex: indexOrOptions, text: text!, author: this.author }\n : { ...indexOrOptions, author: this.resolveAuthor(indexOrOptions.author) };\n return addCommentImpl(this.body, opts);\n }\n\n /**\n * Reply to an existing comment.\n * @param commentId - ID of the comment to reply to\n * @param text - Reply text\n * @returns The new reply comment ID\n */\n replyTo(commentId: number, text: string): number;\n /** Reply to an existing comment with full options. */\n replyTo(commentId: number, options: ReplyOptions): number;\n replyTo(commentId: number, textOrOptions: string | ReplyOptions): number {\n const opts =\n typeof textOrOptions === 'string'\n ? { text: textOrOptions, author: this.author }\n : { ...textOrOptions, author: this.resolveAuthor(textOrOptions.author) };\n return replyToImpl(this.body, commentId, opts);\n }\n\n // ==========================================================================\n // PROPOSE CHANGES\n // ==========================================================================\n\n /**\n * Replace text in a paragraph. Creates a tracked change (deletion + insertion).\n * @param paragraphIndex - Index of the paragraph\n * @param search - Short phrase to find within the paragraph\n * @param replaceWith - Replacement text\n */\n replace(paragraphIndex: number, search: string, replaceWith: string): void;\n /** Replace text with full options. */\n replace(options: ProposeReplacementOptions): void;\n replace(\n indexOrOptions: number | ProposeReplacementOptions,\n search?: string,\n replaceWith?: string\n ): void {\n const opts =\n typeof indexOrOptions === 'number'\n ? {\n paragraphIndex: indexOrOptions,\n search: search!,\n replaceWith: replaceWith!,\n author: this.author,\n }\n : { ...indexOrOptions, author: this.resolveAuthor(indexOrOptions.author) };\n proposeReplacementImpl(this.body, opts);\n }\n\n /** @deprecated Use replace() instead. */\n proposeReplacement(options: ProposeReplacementOptions): void {\n this.replace(options);\n }\n\n /** Insert text as a tracked change. */\n proposeInsertion(options: ProposeInsertionOptions): void {\n proposeInsertionImpl(this.body, {\n ...options,\n author: this.resolveAuthor(options.author),\n });\n }\n\n /** Delete text as a tracked change. */\n proposeDeletion(options: ProposeDeletionOptions): void {\n proposeDeletionImpl(this.body, {\n ...options,\n author: this.resolveAuthor(options.author),\n });\n }\n\n // ==========================================================================\n // RESOLVE\n // ==========================================================================\n\n /** Accept a tracked change by its revision ID. */\n acceptChange(id: number): void {\n acceptChangeImpl(this.body, id);\n }\n\n /** Reject a tracked change by its revision ID. */\n rejectChange(id: number): void {\n rejectChangeImpl(this.body, id);\n }\n\n /** Accept all tracked changes. Returns count accepted. */\n acceptAll(): number {\n return acceptAllImpl(this.body);\n }\n\n /** Reject all tracked changes. Returns count rejected. */\n rejectAll(): number {\n return rejectAllImpl(this.body);\n }\n\n // ==========================================================================\n // BATCH\n // ==========================================================================\n\n /**\n * Apply multiple review operations in one call.\n * Uses the reviewer's default author. Individual failures are collected, not thrown.\n */\n applyReview(ops: BatchReviewOptions): BatchResult {\n return applyReviewImpl(this.body, ops, this.author);\n }\n\n // ==========================================================================\n // EXPORT\n // ==========================================================================\n\n /** Get the modified Document model. */\n toDocument(): Document {\n return this.doc;\n }\n\n /** Serialize back to a DOCX buffer. Requires the original buffer. */\n async toBuffer(): Promise<ArrayBuffer> {\n if (!this.doc.originalBuffer) {\n throw new Error(\n 'Cannot create buffer: no original DOCX buffer was provided. ' +\n 'Use DocxReviewer.fromBuffer() or pass originalBuffer to the constructor.'\n );\n }\n const { repackDocx } = await import('@eigenpal/docx-core/headless');\n return repackDocx(this.doc);\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,21 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eigenpal/docx-editor-agents",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.29",
|
|
4
4
|
"description": "Agent-friendly API for DOCX document review — read, comment, propose changes, accept/reject tracked changes",
|
|
5
|
-
"
|
|
6
|
-
"
|
|
7
|
-
"module": "./dist/index.js",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"module": "./dist/index.mjs",
|
|
8
7
|
"types": "./dist/index.d.ts",
|
|
9
8
|
"exports": {
|
|
10
9
|
".": {
|
|
11
10
|
"types": "./dist/index.d.ts",
|
|
12
|
-
"import": "./dist/index.
|
|
13
|
-
"require": "./dist/index.
|
|
11
|
+
"import": "./dist/index.mjs",
|
|
12
|
+
"require": "./dist/index.js"
|
|
14
13
|
},
|
|
15
14
|
"./bridge": {
|
|
16
15
|
"types": "./dist/bridge.d.ts",
|
|
17
|
-
"import": "./dist/bridge.
|
|
18
|
-
"require": "./dist/bridge.
|
|
16
|
+
"import": "./dist/bridge.mjs",
|
|
17
|
+
"require": "./dist/bridge.js"
|
|
19
18
|
}
|
|
20
19
|
},
|
|
21
20
|
"typesVersions": {
|
package/dist/bridge.cjs
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
// src/bridge.ts
|
|
4
|
-
function createReviewBridge(_editorRef) {
|
|
5
|
-
throw new Error("createReviewBridge is not yet implemented");
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
exports.createReviewBridge = createReviewBridge;
|
|
9
|
-
//# sourceMappingURL=bridge.cjs.map
|
|
10
|
-
//# sourceMappingURL=bridge.cjs.map
|
package/dist/bridge.cjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/bridge.ts"],"names":[],"mappings":";;;AASO,SAAS,mBAAmB,UAAA,EAA8C;AAC/E,EAAA,MAAM,IAAI,MAAM,2CAA2C,CAAA;AAC7D","file":"bridge.cjs","sourcesContent":["/**\n * Editor ref bridge — optional client-side integration.\n *\n * Separate entry point: import from '@eigenpal/docx-editor-agents/bridge'\n * This file may import React/ProseMirror — NOT included in the main headless bundle.\n *\n * TODO: Implement in task 9.1\n */\n\nexport function createReviewBridge(_editorRef: unknown): Record<string, unknown> {\n throw new Error('createReviewBridge is not yet implemented');\n}\n"]}
|
package/dist/index.cjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils.ts","../src/content.ts","../src/errors.ts","../src/textSearch.ts","../src/discovery.ts","../src/comments.ts","../src/changes.ts","../src/batch.ts","../src/DocxReviewer.ts"],"names":["getRunText","getHyperlinkText","isHeadingStyle","parseHeadingLevel","parseDocx"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Shared utilities for agent-use package.\n */\n\nimport type {\n DocumentBody,\n Paragraph,\n Run,\n Hyperlink,\n ParagraphContent,\n Insertion,\n Deletion,\n MoveFrom,\n MoveTo,\n} from '@eigenpal/docx-core/headless';\nimport {\n getRunText,\n getHyperlinkText,\n isHeadingStyle,\n parseHeadingLevel,\n} from '@eigenpal/docx-core/headless';\n\n// Re-export from core so other modules import from one place\nexport { getRunText, getHyperlinkText, isHeadingStyle, parseHeadingLevel };\n\n// ============================================================================\n// TRACKED CHANGE HELPERS\n// ============================================================================\n\nexport type TrackedChangeItem = Insertion | Deletion | MoveFrom | MoveTo;\n\nexport function isTrackedChange(item: ParagraphContent): item is TrackedChangeItem {\n return (\n item.type === 'insertion' ||\n item.type === 'deletion' ||\n item.type === 'moveFrom' ||\n item.type === 'moveTo'\n );\n}\n\nexport function getTrackedChangeText(content: (Run | Hyperlink)[]): string {\n const parts: string[] = [];\n for (const item of content) {\n if (item.type === 'run') {\n parts.push(getRunText(item));\n } else if (item.type === 'hyperlink') {\n parts.push(getHyperlinkText(item));\n }\n }\n return parts.join('');\n}\n\n// ============================================================================\n// DOCUMENT TRAVERSAL\n// ============================================================================\n\n/**\n * Get a paragraph by its document-wide index (counting into tables).\n * Throws on out-of-bounds.\n */\nexport function getParagraphAtIndex(body: DocumentBody, paragraphIndex: number): Paragraph {\n let index = 0;\n for (const block of body.content) {\n if (block.type === 'paragraph') {\n if (index === paragraphIndex) return block;\n index++;\n } else if (block.type === 'table') {\n for (const row of block.rows) {\n for (const cell of row.cells) {\n for (const cellBlock of cell.content) {\n if (cellBlock.type === 'paragraph') {\n if (index === paragraphIndex) return cellBlock;\n index++;\n }\n }\n }\n }\n } else {\n index++;\n }\n }\n throw new Error(`Paragraph index ${paragraphIndex} out of bounds (max: ${index - 1})`);\n}\n\n/**\n * Walk all paragraphs in the document body (including inside tables),\n * calling the callback with each paragraph and its document-wide index.\n */\nexport function forEachParagraph(\n body: DocumentBody,\n fn: (para: Paragraph, index: number) => void | boolean\n): void {\n let index = 0;\n for (const block of body.content) {\n if (block.type === 'paragraph') {\n if (fn(block, index) === false) return;\n index++;\n } else if (block.type === 'table') {\n for (const row of block.rows) {\n for (const cell of row.cells) {\n for (const cellBlock of cell.content) {\n if (cellBlock.type === 'paragraph') {\n if (fn(cellBlock, index) === false) return;\n index++;\n }\n }\n }\n }\n } else {\n index++;\n }\n }\n}\n","/**\n * getContent() — renders document as structured ContentBlock array for LLM consumption.\n * formatContentForLLM() — converts blocks to plain text (avoids JSON quote-escaping issues).\n */\n\nimport type { DocumentBody, Paragraph, Table } from '@eigenpal/docx-core/headless';\nimport type { ContentBlock, GetContentOptions } from './types';\nimport {\n getRunText,\n getHyperlinkText,\n getTrackedChangeText,\n isTrackedChange,\n isHeadingStyle,\n parseHeadingLevel,\n} from './utils';\n\n/**\n * Walk document body and produce ContentBlock array.\n */\nexport function getContent(body: DocumentBody, options: GetContentOptions = {}): ContentBlock[] {\n const {\n fromIndex,\n toIndex,\n includeTrackedChanges = true,\n includeCommentAnchors = true,\n } = options;\n\n const blocks: ContentBlock[] = [];\n let index = 0;\n\n for (const block of body.content) {\n if (block.type === 'paragraph') {\n if (isInRange(index, fromIndex, toIndex)) {\n blocks.push(\n buildParagraphBlock(block, index, includeTrackedChanges, includeCommentAnchors)\n );\n }\n index++;\n } else if (block.type === 'table') {\n if (isInRange(index, fromIndex, toIndex)) {\n blocks.push(buildTableBlock(block, index, includeTrackedChanges, includeCommentAnchors));\n }\n // Advance by number of cell paragraphs (matching getParagraphAtIndex counting)\n for (const row of block.rows) {\n for (const cell of row.cells) {\n for (const cellBlock of cell.content) {\n if (cellBlock.type === 'paragraph') {\n index++;\n }\n }\n }\n }\n } else {\n index++;\n }\n }\n\n return blocks;\n}\n\nfunction isInRange(index: number, from?: number, to?: number): boolean {\n return (from === undefined || index >= from) && (to === undefined || index <= to);\n}\n\nfunction buildParagraphBlock(\n para: Paragraph,\n index: number,\n includeTrackedChanges: boolean,\n includeCommentAnchors: boolean\n): ContentBlock {\n const text = buildParagraphText(para, includeTrackedChanges, includeCommentAnchors);\n const styleId = para.formatting?.styleId;\n\n if (isHeadingStyle(styleId)) {\n return {\n type: 'heading',\n index,\n level: parseHeadingLevel(styleId) ?? 1,\n text,\n };\n }\n\n if (para.listRendering) {\n return {\n type: 'list-item',\n index,\n text,\n listLevel: para.listRendering.level ?? 0,\n listType: para.listRendering.isBullet ? 'bullet' : 'number',\n };\n }\n\n return { type: 'paragraph', index, text };\n}\n\nfunction buildTableBlock(\n table: Table,\n index: number,\n includeTrackedChanges: boolean,\n includeCommentAnchors: boolean\n): ContentBlock {\n const rows: string[][] = [];\n for (const row of table.rows) {\n const cells: string[] = [];\n for (const cell of row.cells) {\n const cellTexts: string[] = [];\n for (const block of cell.content) {\n if (block.type === 'paragraph') {\n cellTexts.push(buildParagraphText(block, includeTrackedChanges, includeCommentAnchors));\n }\n }\n cells.push(cellTexts.join('\\n'));\n }\n rows.push(cells);\n }\n return { type: 'table', index, rows };\n}\n\n/**\n * Format content blocks as plain text for LLM prompts.\n * Every paragraph (including inside tables) gets its own [index].\n *\n * Output:\n * [0] (h1) Chapter Title\n * [1] Paragraph text here.\n * [2] • Bullet item\n * [3] (table, row 1, col 1) First cell\n * [4] (table, row 1, col 2) Second cell\n */\nexport function formatContentForLLM(blocks: ContentBlock[]): string {\n const lines: string[] = [];\n for (const block of blocks) {\n switch (block.type) {\n case 'heading':\n lines.push(`[${block.index}] (h${block.level}) ${block.text}`);\n break;\n case 'paragraph':\n lines.push(`[${block.index}] ${block.text}`);\n break;\n case 'list-item': {\n const indent = ' '.repeat(block.listLevel);\n const bullet = block.listType === 'bullet' ? '\\u2022' : '-';\n lines.push(`[${block.index}] ${indent}${bullet} ${block.text}`);\n break;\n }\n case 'table': {\n let idx = block.index;\n for (let r = 0; r < block.rows.length; r++) {\n for (let c = 0; c < block.rows[r].length; c++) {\n const cellText = block.rows[r][c];\n // A cell can have multiple paragraphs (joined by \\n in buildTableBlock)\n const paras = cellText.split('\\n');\n for (const para of paras) {\n lines.push(`[${idx}] (table, row ${r + 1}, col ${c + 1}) ${para}`);\n idx++;\n }\n }\n }\n break;\n }\n }\n }\n return lines.join('\\n');\n}\n\n/**\n * Build paragraph text with optional inline annotations for tracked changes and comments.\n */\nfunction buildParagraphText(\n para: Paragraph,\n includeTrackedChanges: boolean,\n includeCommentAnchors: boolean\n): string {\n const parts: string[] = [];\n const activeCommentIds = new Set<number>();\n\n for (const item of para.content) {\n if (item.type === 'commentRangeStart' && includeCommentAnchors) {\n activeCommentIds.add(item.id);\n parts.push(`[comment:${item.id}]`);\n continue;\n }\n if (item.type === 'commentRangeEnd' && includeCommentAnchors) {\n if (activeCommentIds.has(item.id)) {\n activeCommentIds.delete(item.id);\n parts.push('[/comment]');\n }\n continue;\n }\n\n if (item.type === 'run') {\n parts.push(getRunText(item));\n } else if (item.type === 'hyperlink') {\n parts.push(getHyperlinkText(item));\n } else if (isTrackedChange(item)) {\n const text = getTrackedChangeText(item.content);\n if (item.type === 'insertion' || item.type === 'moveTo') {\n if (includeTrackedChanges) {\n parts.push(`[+${text}+]{by:${item.info.author}}`);\n } else {\n parts.push(text);\n }\n } else {\n // deletion or moveFrom\n if (includeTrackedChanges) {\n parts.push(`[-${text}-]{by:${item.info.author}}`);\n }\n // When not annotating, hide deleted/moveFrom text\n }\n }\n }\n\n return parts.join('');\n}\n","/**\n * Error classes for @eigenpal/docx-editor-agents\n */\n\nexport class TextNotFoundError extends Error {\n constructor(search: string, paragraphIndex?: number) {\n const location =\n paragraphIndex !== undefined ? ` in paragraph ${paragraphIndex}` : ' in document';\n super(`Text not found${location}: \"${search}\"`);\n this.name = 'TextNotFoundError';\n }\n}\n\nexport class ChangeNotFoundError extends Error {\n constructor(id: number) {\n super(`Tracked change not found: id=${id}`);\n this.name = 'ChangeNotFoundError';\n }\n}\n\nexport class CommentNotFoundError extends Error {\n constructor(id: number) {\n super(`Comment not found: id=${id}`);\n this.name = 'CommentNotFoundError';\n }\n}\n","/**\n * Text search within paragraphs.\n * Handles text spanning multiple runs and tracked change wrappers.\n */\n\nimport type { Paragraph, Run } from '@eigenpal/docx-core/headless';\nimport { TextNotFoundError } from './errors';\nimport { getRunText, isTrackedChange } from './utils';\n\nexport interface TextSearchResult {\n startRunIndex: number;\n startOffset: number;\n endRunIndex: number;\n /** Character offset within the end run (exclusive) */\n endOffset: number;\n}\n\ninterface FlattenedRun {\n contentIndex: number;\n run: Run;\n text: string;\n startPos: number;\n}\n\n/**\n * Flatten paragraph content into runs with cumulative positions.\n */\nfunction flattenRuns(paragraph: Paragraph): FlattenedRun[] {\n const result: FlattenedRun[] = [];\n let pos = 0;\n\n for (let ci = 0; ci < paragraph.content.length; ci++) {\n const item = paragraph.content[ci];\n\n if (item.type === 'run') {\n const text = getRunText(item);\n result.push({ contentIndex: ci, run: item, text, startPos: pos });\n pos += text.length;\n } else if (item.type === 'hyperlink') {\n for (let hi = 0; hi < item.children.length; hi++) {\n const child = item.children[hi];\n if (child.type === 'run') {\n const text = getRunText(child);\n result.push({ contentIndex: ci, run: child, text, startPos: pos });\n pos += text.length;\n }\n }\n } else if (isTrackedChange(item)) {\n for (let ri = 0; ri < item.content.length; ri++) {\n const child = item.content[ri];\n if (child.type === 'run') {\n const text = getRunText(child);\n result.push({ contentIndex: ci, run: child, text, startPos: pos });\n pos += text.length;\n } else if (child.type === 'hyperlink') {\n for (const hc of child.children) {\n if (hc.type === 'run') {\n const text = getRunText(hc);\n result.push({ contentIndex: ci, run: hc, text, startPos: pos });\n pos += text.length;\n }\n }\n }\n }\n }\n }\n\n return result;\n}\n\nexport function getParagraphPlainText(paragraph: Paragraph): string {\n return flattenRuns(paragraph)\n .map((r) => r.text)\n .join('');\n}\n\n/**\n * Find text within a paragraph. Throws TextNotFoundError if not found.\n */\nexport function findTextInParagraph(\n paragraph: Paragraph,\n search: string,\n paragraphIndex?: number\n): TextSearchResult {\n const runs = flattenRuns(paragraph);\n const fullText = runs.map((r) => r.text).join('');\n\n const match = findMatch(fullText, search);\n if (!match) throw new TextNotFoundError(search, paragraphIndex);\n\n let startRunIdx = -1;\n let startOffset = 0;\n for (let i = 0; i < runs.length; i++) {\n if (match.start < runs[i].startPos + runs[i].text.length) {\n startRunIdx = i;\n startOffset = match.start - runs[i].startPos;\n break;\n }\n }\n\n let endRunIdx = -1;\n let endOffset = 0;\n for (let i = runs.length - 1; i >= 0; i--) {\n if (match.end > runs[i].startPos) {\n endRunIdx = i;\n endOffset = match.end - runs[i].startPos;\n break;\n }\n }\n\n if (startRunIdx === -1 || endRunIdx === -1) {\n throw new TextNotFoundError(search, paragraphIndex);\n }\n\n return {\n startRunIndex: runs[startRunIdx].contentIndex,\n startOffset,\n endRunIndex: runs[endRunIdx].contentIndex,\n endOffset,\n };\n}\n\n/**\n * Isolate matched text into its own runs by splitting at boundaries.\n * Mutates paragraph.content.\n */\nexport function isolateMatchedText(\n paragraph: Paragraph,\n search: string,\n paragraphIndex?: number\n): { startIndex: number; endIndex: number } {\n const result = findTextInParagraph(paragraph, search, paragraphIndex);\n let { startRunIndex, endRunIndex } = result;\n const { startOffset, endOffset } = result;\n\n // Split end run first (so indices don't shift for start)\n const endItem = paragraph.content[endRunIndex];\n if (endItem.type === 'run') {\n const endText = getRunText(endItem);\n if (endOffset < endText.length) {\n const afterRun = makeRunWithText(endText.slice(endOffset), endItem);\n setRunText(endItem, endText.slice(0, endOffset));\n paragraph.content.splice(endRunIndex + 1, 0, afterRun as Run);\n }\n }\n\n const startItem = paragraph.content[startRunIndex];\n if (startItem.type === 'run' && startOffset > 0) {\n const startText = getRunText(startItem);\n const beforeRun = makeRunWithText(startText.slice(0, startOffset), startItem);\n setRunText(startItem, startText.slice(startOffset));\n paragraph.content.splice(startRunIndex, 0, beforeRun as Run);\n startRunIndex++;\n endRunIndex++;\n }\n\n return { startIndex: startRunIndex, endIndex: endRunIndex };\n}\n\nfunction makeRunWithText(text: string, template: Run): Run {\n return {\n type: 'run',\n content: [{ type: 'text', text }],\n formatting: template.formatting ? { ...template.formatting } : undefined,\n } as Run;\n}\n\nfunction setRunText(run: Run, text: string): void {\n const textContent = run.content.find((c) => c.type === 'text');\n if (textContent) {\n (textContent as { type: 'text'; text: string }).text = text;\n }\n}\n\n// ============================================================================\n// MATCHING — exact, then normalized (case + quotes + whitespace)\n// ============================================================================\n\n/**\n * Normalize text for matching: lowercase, collapse whitespace,\n * straighten smart quotes/dashes, strip zero-width chars.\n */\nfunction normalize(original: string): { text: string; posMap: number[] } {\n const chars: string[] = [];\n const posMap: number[] = [];\n let prevSpace = true;\n\n for (let i = 0; i < original.length; i++) {\n let ch = original[i];\n\n // Skip zero-width chars\n if ('\\u200B\\u200C\\u200D\\uFEFF\\u00AD'.includes(ch)) continue;\n\n // Smart quotes → straight\n if ('\\u201C\\u201D\\u201E\\u201F'.includes(ch)) ch = '\"';\n if ('\\u2018\\u2019\\u201A\\u201B'.includes(ch)) ch = \"'\";\n\n // Dashes → hyphen\n if ('\\u2013\\u2014\\u2012\\u2015'.includes(ch)) ch = '-';\n\n // Ellipsis → dots\n if (ch === '\\u2026') {\n chars.push('.', '.', '.');\n posMap.push(i, i, i);\n prevSpace = false;\n continue;\n }\n\n // Collapse all whitespace (including \\n, \\t, non-breaking space)\n if (/\\s/.test(ch) || ch === '\\u00A0') {\n if (!prevSpace) {\n chars.push(' ');\n posMap.push(i);\n prevSpace = true;\n }\n continue;\n }\n\n chars.push(ch.toLowerCase());\n posMap.push(i);\n prevSpace = false;\n }\n\n // Trim trailing space\n if (chars.length > 0 && chars[chars.length - 1] === ' ') {\n chars.pop();\n posMap.pop();\n }\n\n return { text: chars.join(''), posMap };\n}\n\n/**\n * Map a normalized-space match back to original string positions.\n */\nfunction mapBack(\n norm: { posMap: number[] },\n idx: number,\n len: number,\n original: string\n): { start: number; end: number } {\n const start = norm.posMap[idx];\n let end = norm.posMap[idx + len - 1] + 1;\n while (end < original.length && '\\u200B\\u200C\\u200D\\uFEFF\\u00AD'.includes(original[end])) end++;\n return { start, end };\n}\n\n/**\n * Find search text within paragraph text.\n * 1. Exact match\n * 2. Normalized match (case-insensitive, smart quotes, collapsed whitespace)\n * 3. Trim trailing partial words (LLMs truncate mid-sentence)\n */\nfunction findMatch(text: string, search: string): { start: number; end: number } | null {\n if (!search || !text) return null;\n\n // 1. Exact\n const exact = text.indexOf(search);\n if (exact !== -1) return { start: exact, end: exact + search.length };\n\n // 2. Normalized\n const normText = normalize(text);\n const normSearch = normalize(search);\n if (!normSearch.text) return null;\n\n const idx = normText.text.indexOf(normSearch.text);\n if (idx !== -1) return mapBack(normText, idx, normSearch.text.length, text);\n\n // 3. Trim trailing partial words (LLM truncation: \"return HTTP 422. e.\" → \"return HTTP 422\")\n const words = normSearch.text.split(' ');\n if (words.length >= 3) {\n for (let drop = 1; drop <= Math.min(2, words.length - 2); drop++) {\n const trimmed = words.slice(0, -drop).join(' ');\n const trimIdx = normText.text.indexOf(trimmed);\n if (trimIdx !== -1) return mapBack(normText, trimIdx, trimmed.length, text);\n }\n }\n\n return null;\n}\n","/**\n * getChanges() and getComments() — discover tracked changes and comments in a document.\n */\n\nimport type { DocumentBody, Run, Comment } from '@eigenpal/docx-core/headless';\nimport type { ReviewChange, ReviewComment, ChangeFilter, CommentFilter } from './types';\nimport { getParagraphPlainText } from './textSearch';\nimport { getRunText, getTrackedChangeText, isTrackedChange, forEachParagraph } from './utils';\n\n/**\n * Collect all tracked changes from the document body.\n */\nexport function getChanges(body: DocumentBody, filter?: ChangeFilter): ReviewChange[] {\n const grouped = new Map<number, ReviewChange>();\n\n forEachParagraph(body, (para, paragraphIndex) => {\n let context: string | null = null;\n\n for (const item of para.content) {\n if (isTrackedChange(item)) {\n if (context === null) context = getParagraphPlainText(para);\n const text = getTrackedChangeText(item.content);\n const id = item.info.id;\n\n const existing = grouped.get(id);\n if (existing && existing.paragraphIndex === paragraphIndex) {\n existing.text += text;\n } else {\n grouped.set(id, {\n id,\n type: item.type,\n author: item.info.author,\n date: item.info.date ?? null,\n text,\n context,\n paragraphIndex,\n });\n }\n }\n }\n });\n\n const changes = Array.from(grouped.values());\n\n return changes.filter((c) => {\n if (filter?.author && c.author !== filter.author) return false;\n if (filter?.type && c.type !== filter.type) return false;\n return true;\n });\n}\n\n/**\n * Collect all comments from the document body.\n */\nexport function getComments(body: DocumentBody, filter?: CommentFilter): ReviewComment[] {\n const comments = body.comments ?? [];\n if (comments.length === 0) return [];\n\n const anchoredTextMap = buildAnchoredTextMap(body);\n\n const topLevel: Comment[] = [];\n const repliesByParent = new Map<number, Comment[]>();\n\n for (const c of comments) {\n if (c.parentId !== undefined) {\n const existing = repliesByParent.get(c.parentId) ?? [];\n existing.push(c);\n repliesByParent.set(c.parentId, existing);\n } else {\n topLevel.push(c);\n }\n }\n\n const result: ReviewComment[] = topLevel.map((c) => {\n const anchor = anchoredTextMap.get(c.id);\n const replies = (repliesByParent.get(c.id) ?? []).map((r) => ({\n id: r.id,\n author: r.author,\n date: r.date ?? null,\n text: getCommentText(r),\n }));\n\n return {\n id: c.id,\n author: c.author,\n date: c.date ?? null,\n text: getCommentText(c),\n anchoredText: anchor?.text ?? '',\n paragraphIndex: anchor?.paragraphIndex ?? -1,\n replies,\n done: c.done ?? false,\n };\n });\n\n return result.filter((c) => {\n if (filter?.author && c.author !== filter.author) return false;\n if (filter?.done !== undefined && c.done !== filter.done) return false;\n return true;\n });\n}\n\nfunction getCommentText(comment: Comment): string {\n return comment.content.map((para) => getParagraphPlainText(para)).join('\\n');\n}\n\ninterface AnchorInfo {\n text: string;\n paragraphIndex: number;\n}\n\nfunction buildAnchoredTextMap(body: DocumentBody): Map<number, AnchorInfo> {\n const result = new Map<number, AnchorInfo>();\n const openRanges = new Map<number, { paragraphIndex: number; parts: string[] }>();\n\n forEachParagraph(body, (para, paragraphIndex) => {\n for (const item of para.content) {\n if (item.type === 'commentRangeStart') {\n openRanges.set(item.id, { paragraphIndex, parts: [] });\n } else if (item.type === 'commentRangeEnd') {\n const open = openRanges.get(item.id);\n if (open) {\n result.set(item.id, { text: open.parts.join(''), paragraphIndex: open.paragraphIndex });\n openRanges.delete(item.id);\n }\n } else if (item.type === 'run') {\n const text = getRunText(item);\n for (const open of openRanges.values()) {\n open.parts.push(text);\n }\n } else if (item.type === 'hyperlink') {\n const text = item.children\n .filter((c): c is Run => c.type === 'run')\n .map(getRunText)\n .join('');\n for (const open of openRanges.values()) {\n open.parts.push(text);\n }\n } else if (isTrackedChange(item)) {\n const text = getTrackedChangeText(item.content);\n for (const open of openRanges.values()) {\n open.parts.push(text);\n }\n }\n }\n });\n\n return result;\n}\n","/**\n * Comment operations — addComment, replyTo\n */\n\nimport type { DocumentBody, Paragraph, Comment, Run } from '@eigenpal/docx-core/headless';\nimport type { AddCommentOptions, ReplyOptions } from './types';\nimport { CommentNotFoundError } from './errors';\nimport { findTextInParagraph } from './textSearch';\nimport { getParagraphAtIndex } from './utils';\n\n/**\n * Add a comment to a paragraph. Returns the new comment ID.\n */\nexport function addComment(body: DocumentBody, options: AddCommentOptions): number {\n const { paragraphIndex, author = 'AI', text, search } = options;\n const para = getParagraphAtIndex(body, paragraphIndex);\n\n const existingIds = (body.comments ?? []).map((c) => c.id);\n const newId = existingIds.length > 0 ? Math.max(...existingIds) + 1 : 1;\n\n const comment: Comment = {\n id: newId,\n author,\n date: new Date().toISOString(),\n content: [\n {\n type: 'paragraph',\n content: [{ type: 'run', content: [{ type: 'text', text }] } as Run],\n formatting: {},\n } as Paragraph,\n ],\n };\n\n if (!body.comments) {\n body.comments = [];\n }\n body.comments.push(comment);\n\n if (search) {\n const result = findTextInParagraph(para, search, paragraphIndex);\n // Insert end marker after end item, then start marker before start item\n para.content.splice(result.endRunIndex + 1, 0, { type: 'commentRangeEnd', id: newId });\n para.content.splice(result.startRunIndex, 0, { type: 'commentRangeStart', id: newId });\n } else {\n para.content.unshift({ type: 'commentRangeStart', id: newId });\n para.content.push({ type: 'commentRangeEnd', id: newId });\n }\n\n return newId;\n}\n\n/**\n * Reply to an existing comment. Returns the reply's comment ID.\n */\nexport function replyTo(body: DocumentBody, commentId: number, options: ReplyOptions): number {\n const comments = body.comments ?? [];\n const parent = comments.find((c) => c.id === commentId);\n if (!parent) {\n throw new CommentNotFoundError(commentId);\n }\n\n const existingIds = comments.map((c) => c.id);\n const newId = Math.max(...existingIds) + 1;\n\n const reply: Comment = {\n id: newId,\n author: options.author ?? 'AI',\n date: new Date().toISOString(),\n parentId: commentId,\n content: [\n {\n type: 'paragraph',\n content: [{ type: 'run', content: [{ type: 'text', text: options.text }] } as Run],\n formatting: {},\n } as Paragraph,\n ],\n };\n\n comments.push(reply);\n return newId;\n}\n","/**\n * Change operations — accept, reject, propose insertion/deletion/replacement.\n */\n\nimport type {\n DocumentBody,\n Paragraph,\n Run,\n Insertion,\n Deletion,\n ParagraphContent,\n} from '@eigenpal/docx-core/headless';\nimport type {\n ProposeReplacementOptions,\n ProposeInsertionOptions,\n ProposeDeletionOptions,\n} from './types';\nimport { ChangeNotFoundError } from './errors';\nimport { isolateMatchedText } from './textSearch';\nimport {\n isTrackedChange,\n getParagraphAtIndex,\n forEachParagraph,\n type TrackedChangeItem,\n} from './utils';\n\n// ============================================================================\n// ACCEPT / REJECT\n// ============================================================================\n\n/**\n * Accept a tracked change by ID.\n * Insertion: keep text, remove wrapper.\n * Deletion: remove text and wrapper.\n */\nexport function acceptChange(body: DocumentBody, id: number): void {\n if (!processChangeById(body, id, 'accept')) {\n throw new ChangeNotFoundError(id);\n }\n}\n\n/**\n * Reject a tracked change by ID.\n * Insertion: remove text and wrapper.\n * Deletion: keep text, remove wrapper.\n */\nexport function rejectChange(body: DocumentBody, id: number): void {\n if (!processChangeById(body, id, 'reject')) {\n throw new ChangeNotFoundError(id);\n }\n}\n\n/**\n * Accept all tracked changes. Returns count.\n */\nexport function acceptAll(body: DocumentBody): number {\n return processAllChanges(body, 'accept');\n}\n\n/**\n * Reject all tracked changes. Returns count.\n */\nexport function rejectAll(body: DocumentBody): number {\n return processAllChanges(body, 'reject');\n}\n\n/**\n * Process all tracked changes in a single pass (O(M) where M = total paragraphs).\n * Iterates backward within each paragraph so splice doesn't shift unprocessed indices.\n */\nfunction processAllChanges(body: DocumentBody, mode: 'accept' | 'reject'): number {\n let count = 0;\n forEachParagraph(body, (para) => {\n for (let i = para.content.length - 1; i >= 0; i--) {\n const item = para.content[i];\n if (isTrackedChange(item)) {\n applyChangeAtIndex(para, i, item, mode);\n count++;\n }\n }\n });\n return count;\n}\n\n/**\n * Find and process a tracked change by revision ID.\n * Processes ALL content items with matching ID (a revision can span multiple items).\n */\nfunction processChangeById(body: DocumentBody, id: number, mode: 'accept' | 'reject'): boolean {\n let found = false;\n forEachParagraph(body, (para) => {\n for (let i = para.content.length - 1; i >= 0; i--) {\n const item = para.content[i];\n if (isTrackedChange(item) && item.info.id === id) {\n applyChangeAtIndex(para, i, item, mode);\n found = true;\n }\n }\n // Stop traversal once we've found and processed the change\n if (found) return false;\n });\n return found;\n}\n\nfunction applyChangeAtIndex(\n para: Paragraph,\n index: number,\n item: TrackedChangeItem,\n mode: 'accept' | 'reject'\n) {\n const keepContent =\n (item.type === 'insertion' && mode === 'accept') ||\n (item.type === 'deletion' && mode === 'reject') ||\n (item.type === 'moveTo' && mode === 'accept') ||\n (item.type === 'moveFrom' && mode === 'reject');\n\n if (keepContent) {\n // Unwrap: replace the tracked change wrapper with its content runs\n const runs = item.content as ParagraphContent[];\n para.content.splice(index, 1, ...runs);\n } else {\n // Remove: delete the tracked change and its content\n para.content.splice(index, 1);\n }\n}\n\n// ============================================================================\n// PROPOSE CHANGES\n// ============================================================================\n\n/**\n * Propose a text replacement as a tracked change (deletion + insertion).\n */\nexport function proposeReplacement(body: DocumentBody, options: ProposeReplacementOptions): void {\n const { paragraphIndex, search, author = 'AI', replaceWith } = options;\n const para = getParagraphAtIndex(body, paragraphIndex);\n\n const { startIndex, endIndex } = isolateMatchedText(para, search, paragraphIndex);\n\n const now = new Date().toISOString();\n const baseId = nextRevisionId(body);\n\n const matchedContent = para.content.slice(startIndex, endIndex + 1);\n\n const deletion: Deletion = {\n type: 'deletion',\n info: { id: baseId, author, date: now },\n content: matchedContent as (Run | import('@eigenpal/docx-core/headless').Hyperlink)[],\n };\n\n const insertion: Insertion = {\n type: 'insertion',\n info: { id: baseId + 1, author, date: now },\n content: [{ type: 'run', content: [{ type: 'text', text: replaceWith }] } as Run],\n };\n\n para.content.splice(startIndex, endIndex - startIndex + 1, deletion, insertion);\n}\n\n/**\n * Propose an insertion as a tracked change.\n */\nexport function proposeInsertion(body: DocumentBody, options: ProposeInsertionOptions): void {\n const { paragraphIndex, author = 'AI', insertText, position = 'after', search } = options;\n const para = getParagraphAtIndex(body, paragraphIndex);\n\n const now = new Date().toISOString();\n const id = nextRevisionId(body);\n\n const insertion: Insertion = {\n type: 'insertion',\n info: { id, author, date: now },\n content: [{ type: 'run', content: [{ type: 'text', text: insertText }] } as Run],\n };\n\n if (search) {\n const { startIndex, endIndex } = isolateMatchedText(para, search, paragraphIndex);\n const insertAt = position === 'after' ? endIndex + 1 : startIndex;\n para.content.splice(insertAt, 0, insertion);\n } else {\n if (position === 'before') {\n para.content.unshift(insertion);\n } else {\n para.content.push(insertion);\n }\n }\n}\n\n/**\n * Propose a deletion as a tracked change.\n */\nexport function proposeDeletion(body: DocumentBody, options: ProposeDeletionOptions): void {\n const { paragraphIndex, search, author = 'AI' } = options;\n const para = getParagraphAtIndex(body, paragraphIndex);\n\n const { startIndex, endIndex } = isolateMatchedText(para, search, paragraphIndex);\n\n const now = new Date().toISOString();\n const id = nextRevisionId(body);\n\n const matchedContent = para.content.slice(startIndex, endIndex + 1);\n\n const deletion: Deletion = {\n type: 'deletion',\n info: { id, author, date: now },\n content: matchedContent as (Run | import('@eigenpal/docx-core/headless').Hyperlink)[],\n };\n\n para.content.splice(startIndex, endIndex - startIndex + 1, deletion);\n}\n\n// ============================================================================\n// HELPERS\n// ============================================================================\n\n/** Cached max revision ID per body — avoids O(N) scan on every proposal. */\nconst revisionIdCache = new WeakMap<DocumentBody, number>();\n\nfunction nextRevisionId(body: DocumentBody): number {\n let maxId = revisionIdCache.get(body);\n if (maxId === undefined) {\n maxId = 0;\n forEachParagraph(body, (para) => {\n for (const item of para.content) {\n if (isTrackedChange(item)) {\n maxId = Math.max(maxId!, item.info.id);\n }\n }\n });\n }\n const next = maxId + 1;\n // Reserve both next and next+1 (replacement uses two IDs)\n revisionIdCache.set(body, next + 1);\n return next;\n}\n","/**\n * applyReview() — batch review operations in a single call.\n */\n\nimport type { DocumentBody } from '@eigenpal/docx-core/headless';\nimport type { BatchReviewOptions, BatchResult, BatchError } from './types';\nimport { acceptChange, rejectChange, proposeReplacement } from './changes';\nimport { addComment, replyTo } from './comments';\n\n/**\n * Apply multiple review operations in a single call.\n * Order: accept/reject → comments → replies → proposals.\n * Individual failures are collected, not thrown.\n * defaultAuthor is used when individual items don't specify an author.\n */\nexport function applyReview(\n body: DocumentBody,\n ops: BatchReviewOptions,\n defaultAuthor = 'AI'\n): BatchResult {\n const errors: BatchError[] = [];\n let accepted = 0;\n let rejected = 0;\n let commentsAdded = 0;\n let repliesAdded = 0;\n let proposalsAdded = 0;\n\n for (const id of ops.accept ?? []) {\n try {\n acceptChange(body, id);\n accepted++;\n } catch (e) {\n errors.push({ operation: 'accept', id, error: (e as Error).message });\n }\n }\n\n for (const id of ops.reject ?? []) {\n try {\n rejectChange(body, id);\n rejected++;\n } catch (e) {\n errors.push({ operation: 'reject', id, error: (e as Error).message });\n }\n }\n\n for (const opts of ops.comments ?? []) {\n try {\n addComment(body, { ...opts, author: opts.author ?? defaultAuthor });\n commentsAdded++;\n } catch (e) {\n errors.push({ operation: 'comment', search: opts.search, error: (e as Error).message });\n }\n }\n\n for (const opts of ops.replies ?? []) {\n try {\n replyTo(body, opts.commentId, { author: opts.author ?? defaultAuthor, text: opts.text });\n repliesAdded++;\n } catch (e) {\n errors.push({ operation: 'reply', id: opts.commentId, error: (e as Error).message });\n }\n }\n\n for (const opts of ops.proposals ?? []) {\n try {\n proposeReplacement(body, { ...opts, author: opts.author ?? defaultAuthor });\n proposalsAdded++;\n } catch (e) {\n errors.push({ operation: 'proposal', search: opts.search, error: (e as Error).message });\n }\n }\n\n return { accepted, rejected, commentsAdded, repliesAdded, proposalsAdded, errors };\n}\n","/**\n * DocxReviewer — Word-like API for AI document review.\n *\n * @example\n * ```ts\n * const reviewer = await DocxReviewer.fromBuffer(buffer, 'AI Reviewer');\n * const text = reviewer.getContentAsText();\n * reviewer.addComment(5, 'Fix this paragraph.');\n * reviewer.replace(5, '$50k', '$500k');\n * const output = await reviewer.toBuffer();\n * ```\n */\n\nimport type { Document, DocumentBody } from '@eigenpal/docx-core/headless';\nimport { parseDocx } from '@eigenpal/docx-core/headless';\nimport type {\n ContentBlock,\n GetContentOptions,\n ReviewChange,\n ReviewComment,\n ChangeFilter,\n CommentFilter,\n AddCommentOptions,\n ReplyOptions,\n ProposeReplacementOptions,\n ProposeInsertionOptions,\n ProposeDeletionOptions,\n BatchReviewOptions,\n BatchResult,\n} from './types';\nimport { getContent as getContentImpl, formatContentForLLM } from './content';\nimport { getChanges as getChangesImpl, getComments as getCommentsImpl } from './discovery';\nimport { addComment as addCommentImpl, replyTo as replyToImpl } from './comments';\nimport {\n acceptChange as acceptChangeImpl,\n rejectChange as rejectChangeImpl,\n acceptAll as acceptAllImpl,\n rejectAll as rejectAllImpl,\n proposeReplacement as proposeReplacementImpl,\n proposeInsertion as proposeInsertionImpl,\n proposeDeletion as proposeDeletionImpl,\n} from './changes';\nimport { applyReview as applyReviewImpl } from './batch';\n\nexport class DocxReviewer {\n private doc: Document;\n /** Default author for comments and tracked changes. Set once, used everywhere. */\n readonly author: string;\n\n /**\n * Create a reviewer from a parsed Document.\n * @param document - Parsed Document from @eigenpal/docx-core\n * @param author - Default author name for comments and changes. (default: 'AI')\n * @param originalBuffer - Original DOCX buffer, needed for toBuffer()\n */\n constructor(document: Document, author = 'AI', originalBuffer?: ArrayBuffer) {\n // Strip originalBuffer before cloning to avoid deep-copying potentially large ArrayBuffer\n const savedBuffer = originalBuffer ?? document.originalBuffer;\n const { originalBuffer: _discard, ...rest } = document;\n this.doc = structuredClone(rest) as Document;\n if (savedBuffer) this.doc.originalBuffer = savedBuffer;\n this.author = author;\n }\n\n /**\n * Create a reviewer from a DOCX file buffer.\n * @param buffer - ArrayBuffer of the DOCX file\n * @param author - Default author name for comments and changes. (default: 'AI')\n */\n static async fromBuffer(buffer: ArrayBuffer, author = 'AI'): Promise<DocxReviewer> {\n const doc = await parseDocx(buffer, { preloadFonts: false });\n return new DocxReviewer(doc, author, buffer);\n }\n\n private get body(): DocumentBody {\n return this.doc.package.document;\n }\n\n private resolveAuthor(author?: string): string {\n return author ?? this.author;\n }\n\n // ==========================================================================\n // READ\n // ==========================================================================\n\n /** Get document content as structured blocks (headings, paragraphs, tables, lists). */\n getContent(options?: GetContentOptions): ContentBlock[] {\n return getContentImpl(this.body, options);\n }\n\n /**\n * Get document content as plain text for LLM prompts.\n * Each paragraph is prefixed with its index: `[0] text`, `[1] text`, etc.\n * Table cells include position: `[5] (table, row 1, col 2) cell text`.\n * Avoids JSON quote-escaping issues — LLMs can copy text verbatim.\n */\n getContentAsText(options?: GetContentOptions): string {\n return formatContentForLLM(getContentImpl(this.body, options));\n }\n\n // ==========================================================================\n // DISCOVER\n // ==========================================================================\n\n /** Get all tracked changes in the document. */\n getChanges(filter?: ChangeFilter): ReviewChange[] {\n return getChangesImpl(this.body, filter);\n }\n\n /** Get all comments with their replies. */\n getComments(filter?: CommentFilter): ReviewComment[] {\n return getCommentsImpl(this.body, filter);\n }\n\n // ==========================================================================\n // COMMENT\n // ==========================================================================\n\n /**\n * Add a comment on a paragraph.\n * @param paragraphIndex - Index of the paragraph to comment on\n * @param text - Comment text\n * @returns The new comment ID\n */\n addComment(paragraphIndex: number, text: string): number;\n /**\n * Add a comment with full options (custom author, anchored to specific text).\n * @param options - Comment options\n * @returns The new comment ID\n */\n addComment(options: AddCommentOptions): number;\n addComment(indexOrOptions: number | AddCommentOptions, text?: string): number {\n const opts =\n typeof indexOrOptions === 'number'\n ? { paragraphIndex: indexOrOptions, text: text!, author: this.author }\n : { ...indexOrOptions, author: this.resolveAuthor(indexOrOptions.author) };\n return addCommentImpl(this.body, opts);\n }\n\n /**\n * Reply to an existing comment.\n * @param commentId - ID of the comment to reply to\n * @param text - Reply text\n * @returns The new reply comment ID\n */\n replyTo(commentId: number, text: string): number;\n /** Reply to an existing comment with full options. */\n replyTo(commentId: number, options: ReplyOptions): number;\n replyTo(commentId: number, textOrOptions: string | ReplyOptions): number {\n const opts =\n typeof textOrOptions === 'string'\n ? { text: textOrOptions, author: this.author }\n : { ...textOrOptions, author: this.resolveAuthor(textOrOptions.author) };\n return replyToImpl(this.body, commentId, opts);\n }\n\n // ==========================================================================\n // PROPOSE CHANGES\n // ==========================================================================\n\n /**\n * Replace text in a paragraph. Creates a tracked change (deletion + insertion).\n * @param paragraphIndex - Index of the paragraph\n * @param search - Short phrase to find within the paragraph\n * @param replaceWith - Replacement text\n */\n replace(paragraphIndex: number, search: string, replaceWith: string): void;\n /** Replace text with full options. */\n replace(options: ProposeReplacementOptions): void;\n replace(\n indexOrOptions: number | ProposeReplacementOptions,\n search?: string,\n replaceWith?: string\n ): void {\n const opts =\n typeof indexOrOptions === 'number'\n ? {\n paragraphIndex: indexOrOptions,\n search: search!,\n replaceWith: replaceWith!,\n author: this.author,\n }\n : { ...indexOrOptions, author: this.resolveAuthor(indexOrOptions.author) };\n proposeReplacementImpl(this.body, opts);\n }\n\n /** @deprecated Use replace() instead. */\n proposeReplacement(options: ProposeReplacementOptions): void {\n this.replace(options);\n }\n\n /** Insert text as a tracked change. */\n proposeInsertion(options: ProposeInsertionOptions): void {\n proposeInsertionImpl(this.body, {\n ...options,\n author: this.resolveAuthor(options.author),\n });\n }\n\n /** Delete text as a tracked change. */\n proposeDeletion(options: ProposeDeletionOptions): void {\n proposeDeletionImpl(this.body, {\n ...options,\n author: this.resolveAuthor(options.author),\n });\n }\n\n // ==========================================================================\n // RESOLVE\n // ==========================================================================\n\n /** Accept a tracked change by its revision ID. */\n acceptChange(id: number): void {\n acceptChangeImpl(this.body, id);\n }\n\n /** Reject a tracked change by its revision ID. */\n rejectChange(id: number): void {\n rejectChangeImpl(this.body, id);\n }\n\n /** Accept all tracked changes. Returns count accepted. */\n acceptAll(): number {\n return acceptAllImpl(this.body);\n }\n\n /** Reject all tracked changes. Returns count rejected. */\n rejectAll(): number {\n return rejectAllImpl(this.body);\n }\n\n // ==========================================================================\n // BATCH\n // ==========================================================================\n\n /**\n * Apply multiple review operations in one call.\n * Uses the reviewer's default author. Individual failures are collected, not thrown.\n */\n applyReview(ops: BatchReviewOptions): BatchResult {\n return applyReviewImpl(this.body, ops, this.author);\n }\n\n // ==========================================================================\n // EXPORT\n // ==========================================================================\n\n /** Get the modified Document model. */\n toDocument(): Document {\n return this.doc;\n }\n\n /** Serialize back to a DOCX buffer. Requires the original buffer. */\n async toBuffer(): Promise<ArrayBuffer> {\n if (!this.doc.originalBuffer) {\n throw new Error(\n 'Cannot create buffer: no original DOCX buffer was provided. ' +\n 'Use DocxReviewer.fromBuffer() or pass originalBuffer to the constructor.'\n );\n }\n const { repackDocx } = await import('@eigenpal/docx-core/headless');\n return repackDocx(this.doc);\n }\n}\n"]}
|
|
File without changes
|
|
File without changes
|