@superdoc-dev/sdk 1.19.2 → 1.20.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. package/dist/action-primitives/doc-index.cjs +215 -0
  2. package/dist/action-primitives/doc-index.d.ts +83 -0
  3. package/dist/action-primitives/doc-index.d.ts.map +1 -0
  4. package/dist/action-primitives/doc-index.js +211 -0
  5. package/dist/action-primitives/engine.cjs +204 -0
  6. package/dist/action-primitives/engine.d.ts +71 -0
  7. package/dist/action-primitives/engine.d.ts.map +1 -0
  8. package/dist/action-primitives/engine.js +196 -0
  9. package/dist/action-primitives/receipt.cjs +39 -0
  10. package/dist/action-primitives/receipt.d.ts +49 -0
  11. package/dist/action-primitives/receipt.d.ts.map +1 -0
  12. package/dist/action-primitives/receipt.js +32 -0
  13. package/dist/action-primitives/resolve.cjs +252 -0
  14. package/dist/action-primitives/resolve.d.ts +56 -0
  15. package/dist/action-primitives/resolve.d.ts.map +1 -0
  16. package/dist/action-primitives/resolve.js +246 -0
  17. package/dist/action-primitives/session-cache.cjs +43 -0
  18. package/dist/action-primitives/session-cache.d.ts +19 -0
  19. package/dist/action-primitives/session-cache.d.ts.map +1 -0
  20. package/dist/action-primitives/session-cache.js +37 -0
  21. package/dist/action-primitives/tools/list-transform.cjs +661 -0
  22. package/dist/action-primitives/tools/list-transform.d.ts +98 -0
  23. package/dist/action-primitives/tools/list-transform.d.ts.map +1 -0
  24. package/dist/action-primitives/tools/list-transform.js +656 -0
  25. package/dist/action-primitives/tools/structure-insert.cjs +1343 -0
  26. package/dist/action-primitives/tools/structure-insert.d.ts +183 -0
  27. package/dist/action-primitives/tools/structure-insert.d.ts.map +1 -0
  28. package/dist/action-primitives/tools/structure-insert.js +1338 -0
  29. package/dist/action-primitives/tools/text-transform.cjs +669 -0
  30. package/dist/action-primitives/tools/text-transform.d.ts +64 -0
  31. package/dist/action-primitives/tools/text-transform.d.ts.map +1 -0
  32. package/dist/action-primitives/tools/text-transform.js +664 -0
  33. package/dist/action-primitives/types.d.ts +36 -0
  34. package/dist/action-primitives/types.d.ts.map +1 -0
  35. package/dist/action-primitives/types.js +15 -0
  36. package/dist/agent/actions.cjs +5381 -0
  37. package/dist/agent/actions.d.ts +404 -0
  38. package/dist/agent/actions.d.ts.map +1 -0
  39. package/dist/agent/actions.js +5373 -0
  40. package/dist/agent/catalog.cjs +483 -0
  41. package/dist/agent/catalog.d.ts +103 -0
  42. package/dist/agent/catalog.d.ts.map +1 -0
  43. package/dist/agent/catalog.js +471 -0
  44. package/dist/agent/doc-snapshot.cjs +663 -0
  45. package/dist/agent/doc-snapshot.d.ts +247 -0
  46. package/dist/agent/doc-snapshot.d.ts.map +1 -0
  47. package/dist/agent/doc-snapshot.js +657 -0
  48. package/dist/agent/index.d.ts +16 -0
  49. package/dist/agent/index.d.ts.map +1 -0
  50. package/dist/agent/index.js +15 -0
  51. package/dist/agent/ir.cjs +170 -0
  52. package/dist/agent/ir.d.ts +216 -0
  53. package/dist/agent/ir.d.ts.map +1 -0
  54. package/dist/agent/ir.js +181 -0
  55. package/dist/agent/operation-catalog.cjs +418 -0
  56. package/dist/agent/operation-catalog.d.ts +36 -0
  57. package/dist/agent/operation-catalog.d.ts.map +1 -0
  58. package/dist/agent/operation-catalog.js +446 -0
  59. package/dist/agent/runtime.cjs +501 -0
  60. package/dist/agent/runtime.d.ts +120 -0
  61. package/dist/agent/runtime.d.ts.map +1 -0
  62. package/dist/agent/runtime.js +493 -0
  63. package/dist/embedded-prompts.generated.cjs +13 -0
  64. package/dist/embedded-prompts.generated.d.ts +4 -0
  65. package/dist/embedded-prompts.generated.d.ts.map +1 -0
  66. package/dist/embedded-prompts.generated.js +9 -0
  67. package/dist/generated/client.cjs +18 -0
  68. package/dist/generated/client.d.ts +134 -0
  69. package/dist/generated/client.d.ts.map +1 -1
  70. package/dist/generated/client.js +18 -0
  71. package/dist/generated/contract.cjs +622 -3
  72. package/dist/generated/contract.d.ts.map +1 -1
  73. package/dist/generated/contract.js +622 -3
  74. package/dist/index.cjs +3 -7
  75. package/dist/index.d.ts +8 -6
  76. package/dist/index.d.ts.map +1 -1
  77. package/dist/index.js +2 -8
  78. package/dist/presets/core.cjs +454 -0
  79. package/dist/presets/core.d.ts +20 -0
  80. package/dist/presets/core.d.ts.map +1 -0
  81. package/dist/presets/core.js +447 -0
  82. package/dist/presets.cjs +55 -8
  83. package/dist/presets.d.ts +39 -8
  84. package/dist/presets.d.ts.map +1 -1
  85. package/dist/presets.js +53 -8
  86. package/dist/prompts/mcp-prompt.md +23 -0
  87. package/dist/prompts/system-prompt.md +108 -0
  88. package/dist/runtime/transport-common.cjs +8 -0
  89. package/dist/runtime/transport-common.d.ts.map +1 -1
  90. package/dist/runtime/transport-common.js +8 -0
  91. package/dist/tools.cjs +46 -11
  92. package/dist/tools.d.ts +55 -8
  93. package/dist/tools.d.ts.map +1 -1
  94. package/dist/tools.js +45 -13
  95. package/package.json +9 -8
  96. package/tools/__pycache__/__init__.cpython-312.pyc +0 -0
  97. package/tools/__pycache__/intent_dispatch_generated.cpython-312.pyc +0 -0
  98. package/tools/catalog.json +14 -0
  99. package/tools/tools-policy.json +1 -1
  100. package/tools/tools.anthropic.json +14 -0
  101. package/tools/tools.generic.json +14 -0
  102. package/tools/tools.openai.json +14 -0
  103. package/tools/tools.vercel.json +14 -0
@@ -0,0 +1,657 @@
1
+ function asString(v, fallback = '') {
2
+ return typeof v === 'string' ? v : fallback;
3
+ }
4
+ function asNumber(v, fallback = 0) {
5
+ return typeof v === 'number' && Number.isFinite(v) ? v : fallback;
6
+ }
7
+ function asRecord(v) {
8
+ return typeof v === 'object' && v !== null && !Array.isArray(v) ? v : null;
9
+ }
10
+ async function safeCall(thunk, fallback, onError) {
11
+ try {
12
+ return await thunk();
13
+ }
14
+ catch (err) {
15
+ onError(err);
16
+ return fallback;
17
+ }
18
+ }
19
+ function maybeMethod(api, path) {
20
+ let cursor = api;
21
+ for (const token of path) {
22
+ // Function-shaped intermediates are legal: RPC/proxy document handles
23
+ // (e.g. the browser doc-bridge) expose namespaces as callables.
24
+ if (!cursor || (typeof cursor !== 'object' && typeof cursor !== 'function'))
25
+ return null;
26
+ cursor = cursor[token];
27
+ }
28
+ return typeof cursor === 'function' ? cursor : null;
29
+ }
30
+ function explicitCount(counts, ...keys) {
31
+ for (const key of keys) {
32
+ const value = counts[key];
33
+ if (typeof value === 'number' && Number.isFinite(value))
34
+ return value;
35
+ }
36
+ return null;
37
+ }
38
+ function includesDomain(requested, domain) {
39
+ return requested == null || requested.has(domain);
40
+ }
41
+ /**
42
+ * Build a deterministic snapshot of a document. The snapshot uses only
43
+ * read-mode operations from the generated contract — it never mutates state,
44
+ * and any individual section that fails is captured as a diagnostic so the
45
+ * rest of the snapshot remains usable.
46
+ */
47
+ export async function buildDocumentSnapshot(doc, options = {}) {
48
+ const diagnostics = [];
49
+ const recordError = (section) => (err) => {
50
+ diagnostics.push({ section, message: err instanceof Error ? err.message : String(err) });
51
+ };
52
+ const blockOffset = Math.max(0, options.blockOffset ?? 0);
53
+ const blockLimit = options.blockLimit ?? options.blockTextLimit ?? 1000;
54
+ const listLimit = options.listLimit ?? 1000;
55
+ const tableLimit = options.tableLimit ?? 500;
56
+ const commentLimit = options.commentLimit ?? 500;
57
+ const trackedChangeLimit = options.trackedChangeLimit ?? 500;
58
+ const requestedDomains = Array.isArray(options.includeDomains) && options.includeDomains.length > 0 ? new Set(options.includeDomains) : null;
59
+ const blockNodeTypes = new Set(Array.isArray(options.blockNodeTypes)
60
+ ? options.blockNodeTypes.filter((value) => typeof value === 'string' && value.length > 0)
61
+ : []);
62
+ const infoFn = maybeMethod(doc, ['info']);
63
+ const info = infoFn ? await safeCall(() => infoFn({}), null, recordError('info')) : null;
64
+ const infoRec = asRecord(info);
65
+ const counts = asRecord(infoRec?.counts) ?? {};
66
+ const revision = asString(infoRec?.revision, 'unknown');
67
+ const countsFromInfo = {
68
+ blocks: explicitCount(counts, 'blocks') ?? 0,
69
+ paragraphs: explicitCount(counts, 'paragraphs') ?? 0,
70
+ headings: explicitCount(counts, 'headings') ?? 0,
71
+ tables: explicitCount(counts, 'tables') ?? 0,
72
+ lists: explicitCount(counts, 'lists') ?? 0,
73
+ images: explicitCount(counts, 'images') ?? 0,
74
+ comments: explicitCount(counts, 'comments') ?? 0,
75
+ trackedChanges: explicitCount(counts, 'trackedChanges') ?? 0,
76
+ sections: explicitCount(counts, 'sections') ?? 0,
77
+ fields: explicitCount(counts, 'fields') ?? 0,
78
+ hyperlinks: explicitCount(counts, 'hyperlinks') ?? 0,
79
+ bookmarks: explicitCount(counts, 'bookmarks') ?? 0,
80
+ contentControls: explicitCount(counts, 'contentControls', 'sdtFields') ?? 0,
81
+ permissionRanges: explicitCount(counts, 'permissionRanges') ?? 0,
82
+ styles: explicitCount(counts, 'styles') ?? 0,
83
+ headers: explicitCount(counts, 'headers') ?? 0,
84
+ footers: explicitCount(counts, 'footers') ?? 0,
85
+ };
86
+ if (options.countsOnly === true) {
87
+ return {
88
+ revision,
89
+ counts: countsFromInfo,
90
+ blocks: [],
91
+ lists: [],
92
+ tables: [],
93
+ comments: [],
94
+ trackedChanges: [],
95
+ sections: [],
96
+ headerFooters: [],
97
+ styles: [],
98
+ contentControls: [],
99
+ fields: [],
100
+ hyperlinks: [],
101
+ bookmarks: [],
102
+ permissionRanges: [],
103
+ images: [],
104
+ diagnostics,
105
+ };
106
+ }
107
+ // Blocks
108
+ const includeBlocksInSnapshot = includesDomain(requestedDomains, 'blocks');
109
+ const needBlocksRead = includeBlocksInSnapshot || includesDomain(requestedDomains, 'tables');
110
+ const blocksFn = maybeMethod(doc, ['blocks', 'list']);
111
+ const blocksRaw = needBlocksRead && blocksFn
112
+ ? await safeCall(() => blocksFn({ offset: blockOffset, limit: blockLimit, includeText: includeBlocksInSnapshot }), null, recordError('blocks.list'))
113
+ : null;
114
+ const blocksRec = asRecord(blocksRaw);
115
+ const totalBlocks = explicitCount(blocksRec ?? {}, 'total') ?? countsFromInfo.blocks;
116
+ const rawBlocks = Array.isArray(blocksRec?.blocks) ? blocksRec.blocks : [];
117
+ const normalizedBlocks = rawBlocks.map((b, index) => {
118
+ const rec = asRecord(b) ?? {};
119
+ return {
120
+ // doc-api block.ordinal is 0-based; the model-facing convention is
121
+ // 1-based (matches paragraphOrdinal/tableOrdinal and ordinal selectors).
122
+ ordinal: asNumber(rec.ordinal, blockOffset + index) + 1,
123
+ nodeId: asString(rec.nodeId),
124
+ nodeType: asString(rec.nodeType, 'paragraph'),
125
+ text: asString(rec.text),
126
+ textPreview: typeof rec.textPreview === 'string' ? rec.textPreview : null,
127
+ styleId: typeof rec.styleId === 'string' ? rec.styleId : null,
128
+ headingLevel: typeof rec.headingLevel === 'number' ? rec.headingLevel : undefined,
129
+ ...(asRecord(rec.numbering)
130
+ ? {
131
+ numbering: {
132
+ marker: asString(asRecord(rec.numbering).marker) || null,
133
+ path: Array.isArray(asRecord(rec.numbering).path) ? asRecord(rec.numbering).path : null,
134
+ kind: asString(asRecord(rec.numbering).kind) || null,
135
+ },
136
+ }
137
+ : {}),
138
+ };
139
+ });
140
+ let blocks = includeBlocksInSnapshot && blockNodeTypes.size > 0
141
+ ? normalizedBlocks.filter((block) => blockNodeTypes.has(block.nodeType))
142
+ : includeBlocksInSnapshot
143
+ ? normalizedBlocks
144
+ : [];
145
+ if (includeBlocksInSnapshot && options.omitEmptyBlocks === true) {
146
+ // Drop empty paragraphs/list-items only; structural blocks (tables) keep
147
+ // their slot even with empty text.
148
+ blocks = blocks.filter((block) => block.text.trim().length > 0 || (block.nodeType !== 'paragraph' && block.nodeType !== 'listItem'));
149
+ }
150
+ if (includeBlocksInSnapshot && options.dropTextPreview === true) {
151
+ blocks = blocks.map((block) => ({ ...block, textPreview: null }));
152
+ }
153
+ // Lists
154
+ const listsFn = maybeMethod(doc, ['lists', 'list']);
155
+ const listsRaw = includesDomain(requestedDomains, 'lists') && listsFn
156
+ ? await safeCall(() => listsFn({ offset: 0, limit: listLimit }), null, recordError('lists.list'))
157
+ : null;
158
+ const listsRec = asRecord(listsRaw);
159
+ const listItemsArr = Array.isArray(listsRec?.items) ? listsRec.items : [];
160
+ const listsById = new Map();
161
+ for (const item of listItemsArr) {
162
+ const rec = asRecord(item);
163
+ if (!rec)
164
+ continue;
165
+ const listId = asString(rec.listId, 'list:unknown');
166
+ if (!listsById.has(listId)) {
167
+ listsById.set(listId, {
168
+ listId,
169
+ kind: asString(rec.kind, 'ordered'),
170
+ items: [],
171
+ });
172
+ }
173
+ const addr = asRecord(rec.address);
174
+ listsById.get(listId).items.push({
175
+ nodeId: asString(addr?.nodeId),
176
+ ordinal: asNumber(rec.ordinal),
177
+ level: asNumber(rec.level),
178
+ text: asString(rec.text),
179
+ });
180
+ }
181
+ const lists = [...listsById.values()];
182
+ // Tables: derive table block list from `blocks`, then query shape per table.
183
+ const tableBlocks = normalizedBlocks.filter((b) => b.nodeType === 'table');
184
+ const tablesFn = maybeMethod(doc, ['tables', 'get']);
185
+ const tables = [];
186
+ if (includesDomain(requestedDomains, 'tables')) {
187
+ for (let i = 0; i < Math.min(tableBlocks.length, tableLimit); i += 1) {
188
+ const block = tableBlocks[i];
189
+ if (!tablesFn) {
190
+ tables.push({ nodeId: block.nodeId, ordinal: i + 1, rows: 0, columns: 0, cells: [] });
191
+ continue;
192
+ }
193
+ const tableRaw = await safeCall(() => tablesFn({ nodeId: block.nodeId }), null, recordError(`tables.get:${block.nodeId}`));
194
+ const rec = asRecord(tableRaw);
195
+ tables.push({
196
+ nodeId: block.nodeId,
197
+ ordinal: i + 1,
198
+ rows: asNumber(rec?.rows),
199
+ columns: asNumber(rec?.columns),
200
+ cells: [],
201
+ });
202
+ }
203
+ }
204
+ const extractFn = maybeMethod(doc, ['extract']);
205
+ if (tables.length > 0 && extractFn) {
206
+ const extractRaw = await safeCall(() => extractFn({}), null, recordError('extract'));
207
+ const extractRec = asRecord(extractRaw);
208
+ const extractBlocks = Array.isArray(extractRec?.blocks) ? extractRec.blocks : [];
209
+ const cellsByTableNodeId = new Map();
210
+ for (const block of extractBlocks) {
211
+ const rec = asRecord(block);
212
+ const tableContext = asRecord(rec?.tableContext);
213
+ if (!rec || !tableContext)
214
+ continue;
215
+ const tableOrdinal = asNumber(tableContext.tableOrdinal, -1);
216
+ const rowIndex = asNumber(tableContext.rowIndex, -1);
217
+ const columnIndex = asNumber(tableContext.columnIndex, -1);
218
+ if (tableOrdinal < 0 || rowIndex < 0 || columnIndex < 0)
219
+ continue;
220
+ const table = tables[tableOrdinal];
221
+ if (!table)
222
+ continue;
223
+ const key = `${rowIndex}:${columnIndex}`;
224
+ const text = asString(rec.text);
225
+ const nodeId = asString(rec.nodeId) || undefined;
226
+ const cellMap = cellsByTableNodeId.get(table.nodeId) ??
227
+ new Map();
228
+ const existing = cellMap.get(key);
229
+ cellMap.set(key, {
230
+ rowIndex,
231
+ columnIndex,
232
+ text: existing == null || text.length === 0
233
+ ? (existing?.text ?? text)
234
+ : existing.text.length === 0
235
+ ? text
236
+ : `${existing.text}\n${text}`,
237
+ nodeId: existing?.nodeId ?? nodeId,
238
+ });
239
+ cellsByTableNodeId.set(table.nodeId, cellMap);
240
+ }
241
+ for (const table of tables) {
242
+ const cellMap = cellsByTableNodeId.get(table.nodeId);
243
+ if (!cellMap)
244
+ continue;
245
+ table.cells = [...cellMap.values()].sort((left, right) => left.rowIndex - right.rowIndex || left.columnIndex - right.columnIndex);
246
+ }
247
+ }
248
+ // Comments
249
+ const commentsFn = maybeMethod(doc, ['comments', 'list']);
250
+ const commentsRaw = includesDomain(requestedDomains, 'comments') && commentsFn
251
+ ? await safeCall(() => commentsFn({ includeResolved: true, offset: 0, limit: commentLimit }), null, recordError('comments.list'))
252
+ : null;
253
+ const commentsRec = asRecord(commentsRaw);
254
+ const commentItems = Array.isArray(commentsRec?.items) ? commentsRec.items : [];
255
+ const comments = commentItems.map((c) => {
256
+ const rec = asRecord(c) ?? {};
257
+ const target = asRecord(rec.target);
258
+ const segments = Array.isArray(target?.segments) ? target.segments : [];
259
+ return {
260
+ id: asString(rec.id),
261
+ text: asString(rec.text),
262
+ status: asString(rec.status, 'open'),
263
+ anchoredText: typeof rec.anchoredText === 'string' ? rec.anchoredText : undefined,
264
+ segments: segments.flatMap((seg) => {
265
+ const segRec = asRecord(seg);
266
+ const range = asRecord(segRec?.range);
267
+ if (!segRec)
268
+ return [];
269
+ return [
270
+ {
271
+ blockId: asString(segRec.blockId),
272
+ start: asNumber(range?.start),
273
+ end: asNumber(range?.end),
274
+ },
275
+ ];
276
+ }),
277
+ };
278
+ });
279
+ // Tracked changes
280
+ const trackedFn = maybeMethod(doc, ['trackChanges', 'list']);
281
+ const trackedRaw = includesDomain(requestedDomains, 'trackedChanges') && trackedFn
282
+ ? await safeCall(() => trackedFn({ offset: 0, limit: trackedChangeLimit }), null, recordError('trackChanges.list'))
283
+ : null;
284
+ const trackedRec = asRecord(trackedRaw);
285
+ const trackedItems = Array.isArray(trackedRec?.items) ? trackedRec.items : [];
286
+ const trackedChanges = trackedItems.map((t) => {
287
+ const rec = asRecord(t) ?? {};
288
+ const addr = asRecord(rec.address);
289
+ const story = asRecord(addr?.story);
290
+ return {
291
+ id: asString(rec.id),
292
+ type: asString(rec.type, 'insert'),
293
+ excerpt: typeof rec.excerpt === 'string' ? rec.excerpt : undefined,
294
+ author: typeof rec.author === 'string' ? rec.author : undefined,
295
+ date: typeof rec.date === 'string' ? rec.date : undefined,
296
+ story: typeof story?.storyType === 'string' ? story.storyType : undefined,
297
+ };
298
+ });
299
+ // Sections (best effort; not all SDK builds expose a sections.list)
300
+ const sectionsFn = maybeMethod(doc, ['sections', 'list']);
301
+ let sections = [];
302
+ if (includesDomain(requestedDomains, 'sections') && sectionsFn) {
303
+ const sectionsRaw = await safeCall(() => sectionsFn({}), null, recordError('sections.list'));
304
+ const rec = asRecord(sectionsRaw);
305
+ const items = Array.isArray(rec?.items) ? rec.items : [];
306
+ sections = items.map((s, index) => {
307
+ const srec = asRecord(s) ?? {};
308
+ const pageSize = asRecord(srec.pageSize);
309
+ return {
310
+ ordinal: asNumber(srec.ordinal, index + 1),
311
+ sectionId: typeof srec.sectionId === 'string' ? srec.sectionId : undefined,
312
+ startNodeId: typeof srec.startNodeId === 'string' ? srec.startNodeId : undefined,
313
+ endNodeId: typeof srec.endNodeId === 'string' ? srec.endNodeId : undefined,
314
+ pageSize: pageSize ? { width: asNumber(pageSize.width), height: asNumber(pageSize.height) } : undefined,
315
+ };
316
+ });
317
+ }
318
+ // Header / footer (best effort)
319
+ const headerFooterFn = maybeMethod(doc, ['headerFooters', 'list']);
320
+ let headerFooters = [];
321
+ if (includesDomain(requestedDomains, 'headerFooters') && headerFooterFn) {
322
+ const raw = await safeCall(() => headerFooterFn({}), null, recordError('headerFooters.list'));
323
+ const rec = asRecord(raw);
324
+ const items = Array.isArray(rec?.items) ? rec.items : [];
325
+ headerFooters = items.flatMap((hf) => {
326
+ const r = asRecord(hf);
327
+ if (!r)
328
+ return [];
329
+ const kind = asString(r.kind, 'header');
330
+ return [
331
+ {
332
+ kind: kind === 'footer' ? 'footer' : 'header',
333
+ sectionId: typeof r.sectionId === 'string' ? r.sectionId : undefined,
334
+ sectionIndex: typeof r.sectionIndex === 'number' ? r.sectionIndex : undefined,
335
+ variant: typeof r.variant === 'string' ? r.variant : undefined,
336
+ blocks: [],
337
+ },
338
+ ];
339
+ });
340
+ }
341
+ // Styles
342
+ const stylesFn = maybeMethod(doc, ['styles', 'list']);
343
+ let styles = [];
344
+ if (includesDomain(requestedDomains, 'styles') && stylesFn) {
345
+ const raw = await safeCall(() => stylesFn({}), null, recordError('styles.list'));
346
+ const rec = asRecord(raw);
347
+ const items = Array.isArray(rec?.items) ? rec.items : [];
348
+ styles = items.flatMap((it) => {
349
+ const r = asRecord(it);
350
+ if (!r)
351
+ return [];
352
+ return [
353
+ {
354
+ styleId: asString(r.styleId),
355
+ name: asString(r.name, asString(r.styleId)),
356
+ type: typeof r.type === 'string' ? r.type : undefined,
357
+ basedOn: typeof r.basedOn === 'string' ? r.basedOn : undefined,
358
+ },
359
+ ];
360
+ });
361
+ }
362
+ // Content controls
363
+ const contentControlsFn = maybeMethod(doc, ['contentControls', 'list']);
364
+ let contentControls = [];
365
+ if (includesDomain(requestedDomains, 'contentControls') && contentControlsFn) {
366
+ const raw = await safeCall(() => contentControlsFn({}), null, recordError('contentControls.list'));
367
+ const rec = asRecord(raw);
368
+ const items = Array.isArray(rec?.items) ? rec.items : [];
369
+ contentControls = items.flatMap((it) => {
370
+ const r = asRecord(it);
371
+ if (!r)
372
+ return [];
373
+ return [
374
+ {
375
+ id: asString(r.id),
376
+ type: typeof r.type === 'string' ? r.type : undefined,
377
+ alias: typeof r.alias === 'string' ? r.alias : undefined,
378
+ tag: typeof r.tag === 'string' ? r.tag : undefined,
379
+ text: typeof r.text === 'string' ? r.text : undefined,
380
+ },
381
+ ];
382
+ });
383
+ }
384
+ // Fields
385
+ const fieldsFn = maybeMethod(doc, ['fields', 'list']);
386
+ let fields = [];
387
+ if (includesDomain(requestedDomains, 'fields') && fieldsFn) {
388
+ const raw = await safeCall(() => fieldsFn({}), null, recordError('fields.list'));
389
+ const rec = asRecord(raw);
390
+ const items = Array.isArray(rec?.items) ? rec.items : [];
391
+ fields = items.flatMap((it) => {
392
+ const r = asRecord(it);
393
+ if (!r)
394
+ return [];
395
+ return [
396
+ {
397
+ id: asString(r.id),
398
+ type: typeof r.type === 'string' ? r.type : undefined,
399
+ result: typeof r.result === 'string' ? r.result : undefined,
400
+ },
401
+ ];
402
+ });
403
+ }
404
+ // Hyperlinks
405
+ const hyperlinksFn = maybeMethod(doc, ['hyperlinks', 'list']);
406
+ let hyperlinks = [];
407
+ if (includesDomain(requestedDomains, 'hyperlinks') && hyperlinksFn) {
408
+ const raw = await safeCall(() => hyperlinksFn({}), null, recordError('hyperlinks.list'));
409
+ const rec = asRecord(raw);
410
+ const items = Array.isArray(rec?.items) ? rec.items : [];
411
+ hyperlinks = items.flatMap((it) => {
412
+ const r = asRecord(it);
413
+ if (!r)
414
+ return [];
415
+ return [
416
+ {
417
+ id: asString(r.id),
418
+ url: asString(r.url),
419
+ display: typeof r.display === 'string' ? r.display : undefined,
420
+ nodeId: typeof r.nodeId === 'string' ? r.nodeId : undefined,
421
+ },
422
+ ];
423
+ });
424
+ }
425
+ // Bookmarks
426
+ const bookmarksFn = maybeMethod(doc, ['bookmarks', 'list']);
427
+ let bookmarks = [];
428
+ if (includesDomain(requestedDomains, 'bookmarks') && bookmarksFn) {
429
+ const raw = await safeCall(() => bookmarksFn({}), null, recordError('bookmarks.list'));
430
+ const rec = asRecord(raw);
431
+ const items = Array.isArray(rec?.items) ? rec.items : [];
432
+ bookmarks = items.flatMap((it) => {
433
+ const r = asRecord(it);
434
+ if (!r)
435
+ return [];
436
+ return [
437
+ {
438
+ id: asString(r.id),
439
+ name: asString(r.name, asString(r.id)),
440
+ startNodeId: typeof r.startNodeId === 'string' ? r.startNodeId : undefined,
441
+ endNodeId: typeof r.endNodeId === 'string' ? r.endNodeId : undefined,
442
+ },
443
+ ];
444
+ });
445
+ }
446
+ // Permission ranges
447
+ const prFn = maybeMethod(doc, ['permissionRanges', 'list']);
448
+ let permissionRanges = [];
449
+ if (includesDomain(requestedDomains, 'permissionRanges') && prFn) {
450
+ const raw = await safeCall(() => prFn({}), null, recordError('permissionRanges.list'));
451
+ const rec = asRecord(raw);
452
+ const items = Array.isArray(rec?.items) ? rec.items : [];
453
+ permissionRanges = items.flatMap((it) => {
454
+ const r = asRecord(it);
455
+ if (!r)
456
+ return [];
457
+ return [
458
+ {
459
+ id: asString(r.id),
460
+ startNodeId: typeof r.startNodeId === 'string' ? r.startNodeId : undefined,
461
+ endNodeId: typeof r.endNodeId === 'string' ? r.endNodeId : undefined,
462
+ editorOrEditorGroup: typeof r.editorOrEditorGroup === 'string' ? r.editorOrEditorGroup : undefined,
463
+ },
464
+ ];
465
+ });
466
+ }
467
+ // Images
468
+ const imagesFn = maybeMethod(doc, ['images', 'list']);
469
+ let images = [];
470
+ if (includesDomain(requestedDomains, 'images') && imagesFn) {
471
+ const raw = await safeCall(() => imagesFn({}), null, recordError('images.list'));
472
+ const rec = asRecord(raw);
473
+ const items = Array.isArray(rec?.items) ? rec.items : [];
474
+ images = items.flatMap((it) => {
475
+ const r = asRecord(it);
476
+ if (!r)
477
+ return [];
478
+ return [
479
+ {
480
+ imageId: asString(r.imageId, asString(r.id)),
481
+ nodeId: typeof r.nodeId === 'string' ? r.nodeId : undefined,
482
+ alt: typeof r.alt === 'string' ? r.alt : undefined,
483
+ caption: typeof r.caption === 'string' ? r.caption : undefined,
484
+ },
485
+ ];
486
+ });
487
+ }
488
+ return {
489
+ revision,
490
+ counts: {
491
+ blocks: countsFromInfo.blocks || totalBlocks || normalizedBlocks.length,
492
+ paragraphs: countsFromInfo.paragraphs || normalizedBlocks.filter((b) => b.nodeType === 'paragraph').length,
493
+ headings: countsFromInfo.headings || normalizedBlocks.filter((b) => b.nodeType === 'heading').length,
494
+ tables: countsFromInfo.tables || tableBlocks.length,
495
+ lists: countsFromInfo.lists || lists.length,
496
+ images: countsFromInfo.images || images.length,
497
+ comments: countsFromInfo.comments || comments.length,
498
+ trackedChanges: countsFromInfo.trackedChanges || trackedChanges.length,
499
+ sections: countsFromInfo.sections || sections.length,
500
+ fields: countsFromInfo.fields || fields.length,
501
+ hyperlinks: countsFromInfo.hyperlinks || hyperlinks.length,
502
+ bookmarks: countsFromInfo.bookmarks || bookmarks.length,
503
+ contentControls: countsFromInfo.contentControls || contentControls.length,
504
+ permissionRanges: countsFromInfo.permissionRanges || permissionRanges.length,
505
+ styles: countsFromInfo.styles || styles.length,
506
+ headers: countsFromInfo.headers || headerFooters.filter((h) => h.kind === 'header').length,
507
+ footers: countsFromInfo.footers || headerFooters.filter((h) => h.kind === 'footer').length,
508
+ },
509
+ blocks,
510
+ lists,
511
+ tables,
512
+ comments,
513
+ trackedChanges,
514
+ sections,
515
+ headerFooters,
516
+ styles,
517
+ contentControls,
518
+ fields,
519
+ hyperlinks,
520
+ bookmarks,
521
+ permissionRanges,
522
+ images,
523
+ diagnostics,
524
+ };
525
+ }
526
+ /**
527
+ * Structured ambiguity error returned when multiple candidates match a
528
+ * selector and the plan required uniqueness.
529
+ */
530
+ export class AmbiguousSelectorError extends Error {
531
+ code = 'AMBIGUOUS_SELECTOR';
532
+ candidates;
533
+ constructor(message, candidates) {
534
+ super(message);
535
+ this.name = 'AmbiguousSelectorError';
536
+ this.candidates = candidates;
537
+ }
538
+ }
539
+ /**
540
+ * Resolve a deterministic selector against the snapshot. Returns the matching
541
+ * block ids in document order. Selectors that target entities return
542
+ * entity-domain matches by id.
543
+ */
544
+ export function resolveSnapshotSelector(snapshot, selector) {
545
+ const nonEmptyParagraphs = snapshot.blocks.filter((block) => block.nodeType === 'paragraph' && block.text.trim().length > 0);
546
+ const firstHeading = snapshot.blocks.find((block) => block.nodeType === 'heading');
547
+ const bodyParagraphs = firstHeading == null
548
+ ? nonEmptyParagraphs
549
+ : snapshot.blocks.filter((block) => block.nodeType === 'paragraph' && block.text.trim().length > 0 && block.ordinal > firstHeading.ordinal);
550
+ switch (selector.kind) {
551
+ case 'ref':
552
+ return snapshot.blocks.filter((b) => b.nodeId === selector.ref).map((b) => b.nodeId);
553
+ case 'nodeId':
554
+ return snapshot.blocks.filter((b) => b.nodeId === selector.nodeId).map((b) => b.nodeId);
555
+ case 'tableCell': {
556
+ const table = snapshot.tables[selector.tableOrdinal - 1];
557
+ if (!table)
558
+ return [];
559
+ const cell = table.cells.find((entry) => entry.rowIndex === selector.rowIndex && entry.columnIndex === selector.columnIndex);
560
+ return cell?.nodeId ? [cell.nodeId] : [];
561
+ }
562
+ case 'textSearch': {
563
+ const matchMode = selector.match ?? 'all';
564
+ const occurrence = selector.occurrence ?? 1;
565
+ const caseSensitive = selector.caseSensitive === true;
566
+ const allowedNodeTypes = new Set(selector.nodeTypes ?? ['paragraph', 'heading', 'listItem']);
567
+ const terms = selector.terms.filter((term) => term.trim().length > 0);
568
+ if (terms.length === 0)
569
+ return [];
570
+ const normalizedTerms = caseSensitive ? terms : terms.map((term) => term.toLocaleLowerCase());
571
+ const matches = snapshot.blocks.filter((block) => {
572
+ if (!allowedNodeTypes.has(block.nodeType))
573
+ return false;
574
+ if (block.text.trim().length === 0)
575
+ return false;
576
+ const haystack = caseSensitive ? block.text : block.text.toLocaleLowerCase();
577
+ const hits = normalizedTerms.filter((term) => haystack.includes(term)).length;
578
+ return matchMode === 'any' ? hits > 0 : hits === normalizedTerms.length;
579
+ });
580
+ const target = matches[occurrence - 1];
581
+ return target ? [target.nodeId] : [];
582
+ }
583
+ case 'ordinal': {
584
+ switch (selector.ordinalKind) {
585
+ case 'blockOrdinal': {
586
+ const target = snapshot.blocks[selector.value - 1];
587
+ return target ? [target.nodeId] : [];
588
+ }
589
+ case 'paragraphOrdinal': {
590
+ const target = nonEmptyParagraphs[selector.value - 1];
591
+ return target ? [target.nodeId] : [];
592
+ }
593
+ case 'bodyParagraphOrdinal': {
594
+ const target = (bodyParagraphs.length > 0 ? bodyParagraphs : nonEmptyParagraphs)[selector.value - 1];
595
+ return target ? [target.nodeId] : [];
596
+ }
597
+ case 'headingOrdinal': {
598
+ const headings = snapshot.blocks.filter((b) => b.nodeType === 'heading');
599
+ const target = headings[selector.value - 1];
600
+ return target ? [target.nodeId] : [];
601
+ }
602
+ case 'tableOrdinal': {
603
+ const target = snapshot.tables[selector.value - 1];
604
+ return target ? [target.nodeId] : [];
605
+ }
606
+ case 'listOrdinal': {
607
+ const target = snapshot.lists[selector.value - 1];
608
+ return target ? target.items.map((item) => item.nodeId) : [];
609
+ }
610
+ case 'sectionOrdinal': {
611
+ const target = snapshot.sections[selector.value - 1];
612
+ return target?.startNodeId ? [target.startNodeId] : [];
613
+ }
614
+ }
615
+ return [];
616
+ }
617
+ case 'entity':
618
+ switch (selector.entityType) {
619
+ case 'comment':
620
+ return snapshot.comments.filter((c) => c.id === selector.entityId).map((c) => c.id);
621
+ case 'trackedChange':
622
+ return snapshot.trackedChanges.filter((c) => c.id === selector.entityId).map((c) => c.id);
623
+ case 'bookmark':
624
+ return snapshot.bookmarks.filter((b) => b.id === selector.entityId).map((b) => b.id);
625
+ case 'image':
626
+ return snapshot.images.filter((i) => i.imageId === selector.entityId).map((i) => i.imageId);
627
+ case 'hyperlink':
628
+ return snapshot.hyperlinks.filter((h) => h.id === selector.entityId).map((h) => h.id);
629
+ case 'field':
630
+ return snapshot.fields.filter((f) => f.id === selector.entityId).map((f) => f.id);
631
+ }
632
+ return [];
633
+ case 'placement':
634
+ if (selector.at === 'document_start') {
635
+ const first = snapshot.blocks[0];
636
+ return first ? [first.nodeId] : [];
637
+ }
638
+ const last = snapshot.blocks[snapshot.blocks.length - 1];
639
+ return last ? [last.nodeId] : [];
640
+ case 'relative': {
641
+ const targetIds = resolveSnapshotSelector(snapshot, selector.target);
642
+ const offset = selector.position === 'before' ? -1 : 1;
643
+ const matches = [];
644
+ for (const targetId of targetIds) {
645
+ const index = snapshot.blocks.findIndex((block) => block.nodeId === targetId);
646
+ if (index === -1)
647
+ continue;
648
+ const sibling = snapshot.blocks[index + offset];
649
+ if (sibling != null)
650
+ matches.push(sibling.nodeId);
651
+ }
652
+ return [...new Set(matches)];
653
+ }
654
+ case 'document':
655
+ return snapshot.blocks.map((b) => b.nodeId);
656
+ }
657
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Clean DOCX agent runtime.
3
+ *
4
+ * This barrel exposes the four product-stable agent tool entry points
5
+ * (inspect, apply, verify, operation) plus the IR types and the
6
+ * contract-derived operation catalog. Consumers should depend on this
7
+ * barrel — never reach into the benchmark `workflow-poc` profile from
8
+ * product code.
9
+ */
10
+ export { AGENT_TOOL_DEFINITIONS, AGENT_TOOL_NAMES, isAgentToolName, listAgentTools, type AgentToolDefinition, type AgentToolName, type AgentProviderTool, } from './catalog.js';
11
+ export { agentInspect, agentApply, agentVerify, agentOperation, type AgentApplyArgs, type AgentInspectArgs, type AgentOperationArgs, type AgentReceipt, type AgentVerifyArgs, type SelectedTarget, type VerificationResult, } from './runtime.js';
12
+ export { validatePlan, isApplyStep, isInspectStep, isSelectStep, isVerifyStep, type AgentApplyStep, type AgentChangeMode, type AgentEntityKind, type AgentInspectStep, type AgentOrdinalKind, type AgentPlan, type AgentPlanStep, type AgentSelectStep, type AgentSelector, type AgentVerificationCheck, type AgentVerifyStep, type IrValidationError, type IrValidationResult, } from './ir.js';
13
+ export { OPERATION_CATALOG, getOperationCatalogEntry, getOperationCatalogSummary, listMutatingOperations, listOperationsByDomain, listOperationsMissingStructuralVerification, type ExposureStatus, type OperationCatalogEntry, type OperationDomain, type OperationMode, type TargetShape, } from './operation-catalog.js';
14
+ export { AmbiguousSelectorError, buildDocumentSnapshot, resolveSnapshotSelector, type DocumentSnapshot, type SnapshotBlock, type SnapshotComment, type SnapshotDiagnostic, type SnapshotDomain, type SnapshotImage, type SnapshotList, type SnapshotSection, type SnapshotTable, type SnapshotTrackedChange, } from './doc-snapshot.js';
15
+ export { superdocPerformAction, isActionName, ACTION_NAMES_LIST, type AcceptTrackedChangesArgs, type AddCommentsArgs, type AddHyperlinkArgs, type AddListItemsArgs, type ApplyLetterSpacingArgs, type ApplyStyleArgs, type AppendListArgs, type AttachNumberingArgs, type ConvertListArgs, type FormatParagraphArgs, type FormatTextArgs, type InsertPageBreakArgs, type MoveTextArgs, type RedoChangesArgs, type ReplyToCommentArgs, type ResolveCommentsArgs, type SetFontFamilyArgs, type SetParagraphSpacingArgs, type SplitListArgs, type UndoChangesArgs, type CommentParagraphsArgs, type CreateTableArgs, type DeleteTableColumnArgs, type DeleteTableRowArgs, type DeleteTextArgs, type FillPlaceholdersArgs, type InsertHeadingArgs, type StyleTableArgs, type MoveTableArgs, type DeleteTableArgs, type InsertListItemsArgs, type InsertParagraphsArgs, type InsertTableColumnArgs, type InsertTableRowArgs, type InsertTocArgs, type MoveRangeArgs, type NormalizeBodyFontSizeArgs, type ActionArgs, type ActionName, type ActionPlacement, type RejectTrackedChangesArgs, type ReplaceTextArgs, type RewriteBlockArgs, type SplitTableArgs, } from './actions.js';
16
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/agent/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EACL,sBAAsB,EACtB,gBAAgB,EAChB,eAAe,EACf,cAAc,EACd,KAAK,mBAAmB,EACxB,KAAK,aAAa,EAClB,KAAK,iBAAiB,GACvB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,YAAY,EACZ,UAAU,EACV,WAAW,EACX,cAAc,EACd,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,EACvB,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,kBAAkB,GACxB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,YAAY,EACZ,WAAW,EACX,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,SAAS,EACd,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,sBAAsB,EAC3B,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,GACxB,MAAM,SAAS,CAAC;AACjB,OAAO,EACL,iBAAiB,EACjB,wBAAwB,EACxB,0BAA0B,EAC1B,sBAAsB,EACtB,sBAAsB,EACtB,2CAA2C,EAC3C,KAAK,cAAc,EACnB,KAAK,qBAAqB,EAC1B,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,WAAW,GACjB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,sBAAsB,EACtB,qBAAqB,EACrB,uBAAuB,EACvB,KAAK,gBAAgB,EACrB,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,qBAAqB,GAC3B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,qBAAqB,EACrB,YAAY,EACZ,iBAAiB,EACjB,KAAK,wBAAwB,EAC7B,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,sBAAsB,EAC3B,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,mBAAmB,EACxB,KAAK,eAAe,EACpB,KAAK,mBAAmB,EACxB,KAAK,cAAc,EACnB,KAAK,mBAAmB,EACxB,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EACtB,KAAK,uBAAuB,EAC5B,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,qBAAqB,EAC1B,KAAK,eAAe,EACpB,KAAK,qBAAqB,EAC1B,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACnB,KAAK,oBAAoB,EACzB,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,EAC1B,KAAK,kBAAkB,EACvB,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,yBAAyB,EAC9B,KAAK,UAAU,EACf,KAAK,UAAU,EACf,KAAK,eAAe,EACpB,KAAK,wBAAwB,EAC7B,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,cAAc,GACpB,MAAM,cAAc,CAAC"}