@zeke-02/docx-editor-agents 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +126 -0
- package/dist/agent-types-C8RvQB7n.d.mts +36 -0
- package/dist/agent-types-C8RvQB7n.d.ts +36 -0
- package/dist/ai-sdk/react.d.mts +57 -0
- package/dist/ai-sdk/react.d.ts +57 -0
- package/dist/ai-sdk/react.js +1 -0
- package/dist/ai-sdk/react.mjs +1 -0
- package/dist/ai-sdk/server.d.mts +80 -0
- package/dist/ai-sdk/server.d.ts +80 -0
- package/dist/ai-sdk/server.js +1 -0
- package/dist/ai-sdk/server.mjs +1 -0
- package/dist/ai-sdk/vue.d.ts +32 -0
- package/dist/ai-sdk/vue.js +1 -0
- package/dist/ai-sdk/vue.mjs +28 -0
- package/dist/bridge.d.mts +19 -0
- package/dist/bridge.d.ts +19 -0
- package/dist/bridge.js +1 -0
- package/dist/bridge.mjs +1 -0
- package/dist/chunk-24MVJKCP.mjs +8 -0
- package/dist/chunk-2RGRAPLW.js +5 -0
- package/dist/chunk-53PAUP4S.js +2 -0
- package/dist/chunk-AU3KR5IN.mjs +5 -0
- package/dist/chunk-KMEZXSKR.mjs +2 -0
- package/dist/chunk-RI5S75JY.js +8 -0
- package/dist/chunk-UNUH3LRU.mjs +1 -0
- package/dist/chunk-VXAJD6QK.js +1 -0
- package/dist/docx-editor-agents.css +2 -0
- package/dist/index.d.mts +178 -0
- package/dist/index.d.ts +178 -0
- package/dist/index.js +1 -0
- package/dist/index.mjs +1 -0
- package/dist/mcp.d.mts +200 -0
- package/dist/mcp.d.ts +200 -0
- package/dist/mcp.js +4 -0
- package/dist/mcp.mjs +4 -0
- package/dist/react.d.mts +251 -0
- package/dist/react.d.ts +251 -0
- package/dist/react.js +9 -0
- package/dist/react.mjs +9 -0
- package/dist/server-uWvnaIh-.d.mts +620 -0
- package/dist/server-uWvnaIh-.d.ts +620 -0
- package/dist/server.d.mts +35 -0
- package/dist/server.d.ts +35 -0
- package/dist/server.js +1 -0
- package/dist/server.mjs +1 -0
- package/dist/vue/components/AIContextMenu.d.ts +33 -0
- package/dist/vue/components/AIResponsePreview.d.ts +40 -0
- package/dist/vue/components/AgentChatLog.d.ts +37 -0
- package/dist/vue/components/AgentComposer.d.ts +30 -0
- package/dist/vue/components/AgentPanel.d.ts +49 -0
- package/dist/vue/components/AgentSuggestionChip.d.ts +10 -0
- package/dist/vue/components/AgentTimeline.d.ts +19 -0
- package/dist/vue/composables/useAgentBridge.d.ts +19 -0
- package/dist/vue/types.d.ts +5 -0
- package/dist/vue.d.ts +72 -0
- package/dist/vue.js +20 -0
- package/dist/vue.mjs +2026 -0
- package/package.json +157 -0
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @zeke-02/docx-editor-agents/ai-sdk/server
|
|
3
|
+
*
|
|
4
|
+
* Vercel AI SDK adapter (server side). Opt-in.
|
|
5
|
+
*
|
|
6
|
+
* The core toolkit is runtime-agnostic. Use this entry only if you're
|
|
7
|
+
* wiring `streamText` / `generateText` from `ai` in your route handler.
|
|
8
|
+
* For LangChain, the Anthropic SDK, or OpenAI direct, import
|
|
9
|
+
* `getToolSchemas` from `@zeke-02/docx-editor-agents/server` and shape it
|
|
10
|
+
* however your runtime expects.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```ts
|
|
14
|
+
* import { getAiSdkTools } from '@zeke-02/docx-editor-agents/ai-sdk/server';
|
|
15
|
+
* import { streamText, stepCountIs, convertToModelMessages } from 'ai';
|
|
16
|
+
*
|
|
17
|
+
* const tools = getAiSdkTools();
|
|
18
|
+
*
|
|
19
|
+
* export async function POST(req: Request) {
|
|
20
|
+
* const { messages } = await req.json();
|
|
21
|
+
* const result = streamText({
|
|
22
|
+
* model: 'openai/gpt-4o',
|
|
23
|
+
* messages: await convertToModelMessages(messages),
|
|
24
|
+
* tools,
|
|
25
|
+
* stopWhen: stepCountIs(12),
|
|
26
|
+
* });
|
|
27
|
+
* return result.toUIMessageStreamResponse();
|
|
28
|
+
* }
|
|
29
|
+
* ```
|
|
30
|
+
*
|
|
31
|
+
* @packageDocumentation
|
|
32
|
+
* @public
|
|
33
|
+
*/
|
|
34
|
+
import { Tool } from 'ai';
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* @zeke-02/docx-editor-agents/ai-sdk/server
|
|
38
|
+
*
|
|
39
|
+
* Vercel AI SDK adapter (server side). Opt-in.
|
|
40
|
+
*
|
|
41
|
+
* The core toolkit is runtime-agnostic. Use this entry only if you're
|
|
42
|
+
* wiring `streamText` / `generateText` from `ai` in your route handler.
|
|
43
|
+
* For LangChain, the Anthropic SDK, or OpenAI direct, import
|
|
44
|
+
* `getToolSchemas` from `@zeke-02/docx-editor-agents/server` and shape it
|
|
45
|
+
* however your runtime expects.
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* ```ts
|
|
49
|
+
* import { getAiSdkTools } from '@zeke-02/docx-editor-agents/ai-sdk/server';
|
|
50
|
+
* import { streamText, stepCountIs, convertToModelMessages } from 'ai';
|
|
51
|
+
*
|
|
52
|
+
* const tools = getAiSdkTools();
|
|
53
|
+
*
|
|
54
|
+
* export async function POST(req: Request) {
|
|
55
|
+
* const { messages } = await req.json();
|
|
56
|
+
* const result = streamText({
|
|
57
|
+
* model: 'openai/gpt-4o',
|
|
58
|
+
* messages: await convertToModelMessages(messages),
|
|
59
|
+
* tools,
|
|
60
|
+
* stopWhen: stepCountIs(12),
|
|
61
|
+
* });
|
|
62
|
+
* return result.toUIMessageStreamResponse();
|
|
63
|
+
* }
|
|
64
|
+
* ```
|
|
65
|
+
*
|
|
66
|
+
* @packageDocumentation
|
|
67
|
+
* @public
|
|
68
|
+
*/
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Get tool schemas in Vercel AI SDK shape (`{ [name]: Tool }`). Pass
|
|
72
|
+
* directly to `streamText({ tools })`. No `execute` is set, so AI SDK
|
|
73
|
+
* forwards each tool call to the client's `useChat({ onToolCall })`
|
|
74
|
+
* handler — wire that to `useDocxAgentTools().executeToolCall` from
|
|
75
|
+
* `@zeke-02/docx-editor-agents/ai-sdk/react` or
|
|
76
|
+
* `@zeke-02/docx-editor-agents/react`.
|
|
77
|
+
*/
|
|
78
|
+
declare function getAiSdkTools(): Record<string, Tool>;
|
|
79
|
+
|
|
80
|
+
export { getAiSdkTools };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
'use strict';var chunkRI5S75JY_js=require('../chunk-RI5S75JY.js'),ai=require('ai');function n(){return Object.fromEntries(chunkRI5S75JY_js.a.map(o=>[o.name,{description:o.description,inputSchema:ai.jsonSchema(o.inputSchema)}]))}exports.getAiSdkTools=n;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import {a}from'../chunk-24MVJKCP.mjs';import {jsonSchema}from'ai';function n(){return Object.fromEntries(a.map(o=>[o.name,{description:o.description,inputSchema:jsonSchema(o.inputSchema)}]))}export{n as getAiSdkTools};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @zeke-02/docx-editor-agents/ai-sdk/vue
|
|
3
|
+
*
|
|
4
|
+
* Vercel AI SDK adapter (Vue side). Opt-in.
|
|
5
|
+
*
|
|
6
|
+
* Use this if you're driving the chat with `useChat` from `@ai-sdk/vue`.
|
|
7
|
+
* The Vue `<AgentChatLog>` consumes a flat `AgentMessage[]` shape;
|
|
8
|
+
* AI SDK's `useChat` produces `UIMessage[]` with structured `parts`.
|
|
9
|
+
* `toAgentMessages()` is the bridge.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```vue
|
|
13
|
+
* <script setup lang="ts">
|
|
14
|
+
* import { computed } from 'vue';
|
|
15
|
+
* import { useChat } from '@ai-sdk/vue';
|
|
16
|
+
* import { toAgentMessages } from '@zeke-02/docx-editor-agents/ai-sdk/vue';
|
|
17
|
+
* import { AgentChatLog } from '@zeke-02/docx-editor-agents/vue';
|
|
18
|
+
*
|
|
19
|
+
* const chat = useChat({ ... });
|
|
20
|
+
* const messages = computed(() => toAgentMessages(chat.messages.value, chat.status.value));
|
|
21
|
+
* </script>
|
|
22
|
+
*
|
|
23
|
+
* <template>
|
|
24
|
+
* <AgentChatLog :messages="messages" />
|
|
25
|
+
* </template>
|
|
26
|
+
* ```
|
|
27
|
+
*
|
|
28
|
+
* @packageDocumentation
|
|
29
|
+
* @public
|
|
30
|
+
*/
|
|
31
|
+
export type { AgentMessage, AgentToolCall } from '../agent-types';
|
|
32
|
+
export { toAgentMessages, type AiSdkUIMessage } from './shared';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});function e(e,t){return e.map((n,r)=>{let i=``,a=[];for(let e of n.parts??[])if(e.type===`text`)i+=e.text??``;else if(e.type.startsWith(`tool-`)){let t=e.state===`output-available`?`done`:e.state===`output-error`?`error`:`running`;a.push({id:e.toolCallId??`${n.id}-tc-${a.length}`,name:e.type.slice(5),input:e.input,result:typeof e.output==`string`?e.output:void 0,error:e.errorText,status:t})}let o=r===e.length-1,s=n.role===`assistant`&&o&&(t===`streaming`||t===`submitted`);return{id:n.id,role:n.role===`user`?`user`:`assistant`,text:i,toolCalls:a.length>0?a:void 0,status:s?`streaming`:`done`}})}exports.toAgentMessages=e;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
//#region src/ai-sdk/shared.ts
|
|
2
|
+
function e(e, t) {
|
|
3
|
+
return e.map((n, r) => {
|
|
4
|
+
let i = "", a = [];
|
|
5
|
+
for (let e of n.parts ?? []) if (e.type === "text") i += e.text ?? "";
|
|
6
|
+
else if (e.type.startsWith("tool-")) {
|
|
7
|
+
let t = e.state === "output-available" ? "done" : e.state === "output-error" ? "error" : "running";
|
|
8
|
+
a.push({
|
|
9
|
+
id: e.toolCallId ?? `${n.id}-tc-${a.length}`,
|
|
10
|
+
name: e.type.slice(5),
|
|
11
|
+
input: e.input,
|
|
12
|
+
result: typeof e.output == "string" ? e.output : void 0,
|
|
13
|
+
error: e.errorText,
|
|
14
|
+
status: t
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
let o = r === e.length - 1, s = n.role === "assistant" && o && (t === "streaming" || t === "submitted");
|
|
18
|
+
return {
|
|
19
|
+
id: n.id,
|
|
20
|
+
role: n.role === "user" ? "user" : "assistant",
|
|
21
|
+
text: i,
|
|
22
|
+
toolCalls: a.length > 0 ? a : void 0,
|
|
23
|
+
status: s ? "streaming" : "done"
|
|
24
|
+
};
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
//#endregion
|
|
28
|
+
export { e as toAgentMessages };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @zeke-02/docx-editor-agents/bridge
|
|
3
|
+
*
|
|
4
|
+
* Editor bridge that connects agent tools to a live `DocxEditor` instance.
|
|
5
|
+
* Framework-agnostic. The React adapter lives in
|
|
6
|
+
* `@zeke-02/docx-editor-agents/react`.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* import { createEditorBridge } from '@zeke-02/docx-editor-agents/bridge';
|
|
11
|
+
* const bridge = createEditorBridge(editorRef, 'Assistant');
|
|
12
|
+
* bridge.addComment({ paragraphIndex: 3, text: 'Fix this.' });
|
|
13
|
+
* ```
|
|
14
|
+
*
|
|
15
|
+
* @packageDocumentation
|
|
16
|
+
* @public
|
|
17
|
+
*/
|
|
18
|
+
export { j as AgentToolDefinition, k as AgentToolResult, h as ContentChangeEvent, E as EditorBridge, r as EditorRefLike, i as SelectionChangeEvent, n as agentTools, u as createEditorBridge, o as createReviewerBridge, p as executeToolCall, q as getToolSchemas } from './server-uWvnaIh-.mjs';
|
|
19
|
+
import '@zeke-02/docx-editor-core/headless';
|
package/dist/bridge.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @zeke-02/docx-editor-agents/bridge
|
|
3
|
+
*
|
|
4
|
+
* Editor bridge that connects agent tools to a live `DocxEditor` instance.
|
|
5
|
+
* Framework-agnostic. The React adapter lives in
|
|
6
|
+
* `@zeke-02/docx-editor-agents/react`.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* import { createEditorBridge } from '@zeke-02/docx-editor-agents/bridge';
|
|
11
|
+
* const bridge = createEditorBridge(editorRef, 'Assistant');
|
|
12
|
+
* bridge.addComment({ paragraphIndex: 3, text: 'Fix this.' });
|
|
13
|
+
* ```
|
|
14
|
+
*
|
|
15
|
+
* @packageDocumentation
|
|
16
|
+
* @public
|
|
17
|
+
*/
|
|
18
|
+
export { j as AgentToolDefinition, k as AgentToolResult, h as ContentChangeEvent, E as EditorBridge, r as EditorRefLike, i as SelectionChangeEvent, n as agentTools, u as createEditorBridge, o as createReviewerBridge, p as executeToolCall, q as getToolSchemas } from './server-uWvnaIh-.js';
|
|
19
|
+
import '@zeke-02/docx-editor-core/headless';
|
package/dist/bridge.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
'use strict';var chunk53PAUP4S_js=require('./chunk-53PAUP4S.js'),chunk2RGRAPLW_js=require('./chunk-2RGRAPLW.js'),chunkRI5S75JY_js=require('./chunk-RI5S75JY.js');Object.defineProperty(exports,"createEditorBridge",{enumerable:true,get:function(){return chunk53PAUP4S_js.a}});Object.defineProperty(exports,"createReviewerBridge",{enumerable:true,get:function(){return chunk2RGRAPLW_js.m}});Object.defineProperty(exports,"agentTools",{enumerable:true,get:function(){return chunkRI5S75JY_js.a}});Object.defineProperty(exports,"executeToolCall",{enumerable:true,get:function(){return chunkRI5S75JY_js.b}});Object.defineProperty(exports,"getToolSchemas",{enumerable:true,get:function(){return chunkRI5S75JY_js.d}});
|
package/dist/bridge.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export{a as createEditorBridge}from'./chunk-KMEZXSKR.mjs';export{m as createReviewerBridge}from'./chunk-AU3KR5IN.mjs';export{a as agentTools,b as executeToolCall,d as getToolSchemas}from'./chunk-24MVJKCP.mjs';
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
var d=["single","words","double","thick","dotted","dottedHeavy","dash","dashedHeavy","dashLong","dashLongHeavy","dotDash","dashDotHeavy","dotDotDash","dashDotDotHeavy","wave","wavyHeavy","wavyDouble","none"],o=["black","blue","cyan","darkBlue","darkCyan","darkGray","darkGreen","darkMagenta","darkRed","darkYellow","green","lightGray","magenta","red","white","yellow","none"],c={name:"apply_formatting",displayName:"Applying formatting",description:'Apply character formatting (bold, italic, underline, strike, color, highlight, font size, font family) to a paragraph or to a unique phrase within it. Pass `search` to scope the change to part of the paragraph; omit it to format the whole paragraph. Direct edit \u2014 does not create a tracked change. Pass `false` to clear a mark; omit a key to leave it untouched. Color uses `{rgb: "FF0000"}` (no hash) or `{themeColor: "accent1"}`. Font size is in points. Font family takes `{ascii, hAnsi}`.',inputSchema:{type:"object",properties:{paraId:{type:"string",description:"Paragraph id from read_document / find_text."},search:{type:"string",description:"Optional: format only this exact phrase within the paragraph (must be unique)."},marks:{type:"object",description:"Marks to set or clear. Omit a key to leave it untouched.",properties:{bold:{type:"boolean"},italic:{type:"boolean"},underline:{description:'true \u2192 single underline; false \u2192 clear; or { style: "single"|"double"|"thick"|"dotted"|"dottedHeavy"|"dash"|"dashedHeavy"|"dashLong"|"dashLongHeavy"|"dotDash"|"dashDotHeavy"|"dotDotDash"|"dashDotDotHeavy"|"wave"|"wavyHeavy"|"wavyDouble"|"words"|"none" }. Other values are rejected.'},strike:{type:"boolean"},color:{type:"object",description:'Either {rgb: "RRGGBB"} (no hash) or {themeColor: "accent1"|"text1"|...}.',properties:{rgb:{type:"string"},themeColor:{type:"string"}}},highlight:{type:"string",enum:[...o],description:"Highlight color \u2014 must be one of the Word-supported names: "+o.join(", ")+'. Pass "none" to clear. Hex values are rejected (Word does not accept hex for <w:highlight>).'},fontSize:{type:"number",description:"Size in points (e.g. 12, 14, 24)."},fontFamily:{type:"object",properties:{ascii:{type:"string"},hAnsi:{type:"string"}}}}}},required:["paraId","marks"]},handler:(e,r)=>{if(!e.marks||Object.keys(e.marks).length===0)return {success:false,error:"No marks provided. Specify at least one of bold/italic/etc."};let t=typeof e.marks.underline=="object"&&e.marks.underline!==null?e.marks.underline.style:void 0;if(t&&!d.includes(t))return {success:false,error:`Invalid underline.style "${t}". Must be one of: ${d.join(", ")}.`};let n=typeof e.marks.highlight=="string"?e.marks.highlight:void 0;if(n&&!o.includes(n))return {success:false,error:`Invalid highlight "${n}". Must be one of: ${o.join(", ")}. Hex values are not supported by Word's highlight attribute.`};let a=n==="none"?{...e.marks,highlight:""}:e.marks;return r.applyFormatting({paraId:e.paraId,search:e.search,marks:a})?{success:true,data:`Formatting applied to ${e.search?`"${e.search}" in ${e.paraId}`:e.paraId}.`}:{success:false,error:"Could not apply formatting. The paraId may not exist, or `search` is missing / ambiguous."}}},p={name:"set_paragraph_style",displayName:"Setting paragraph style",description:`Apply a paragraph style by id (e.g. "Heading1", "Heading2", "Title", "Quote", "Normal"). The styleId must exist in the document's style definitions \u2014 unknown ids are no-ops. Direct edit, not a tracked change.`,inputSchema:{type:"object",properties:{paraId:{type:"string",description:"Paragraph id from read_document / find_text."},styleId:{type:"string",description:'Style id (e.g. "Heading1", "Title", "Quote", "Normal").'}},required:["paraId","styleId"]},handler:(e,r)=>r.setParagraphStyle({paraId:e.paraId,styleId:e.styleId})?{success:true,data:`Style "${e.styleId}" applied to ${e.paraId}.`}:{success:false,error:`Could not set style. paraId "${e.paraId}" not found, or styleId "${e.styleId}" is not defined.`}};var l={name:"read_page",displayName:"Reading page",description:`Read the contents of one rendered page (1-indexed). Returns paragraphs on the page, each tagged with its stable paraId. Use this when the user asks "summarize page 3" or "comment on what's on this page".`,inputSchema:{type:"object",properties:{pageNumber:{type:"number",description:"1-indexed page number."}},required:["pageNumber"]},handler:(e,r)=>{let t=r.getPage(e.pageNumber);if(!t){let n=r.getTotalPages();return n===0?{success:false,error:"No pages rendered (headless mode or empty document)."}:{success:false,error:`Page ${e.pageNumber} does not exist (document has ${n} page${n===1?"":"s"}).`}}return {success:true,data:t.text||"(empty page)"}}},m={name:"read_pages",displayName:"Reading pages",description:"Read a contiguous range of rendered pages (1-indexed, inclusive). Returns paragraphs across the range, each tagged with paraId. Cheaper than calling read_page repeatedly \u2014 single round-trip.",inputSchema:{type:"object",properties:{from:{type:"number",description:"1-indexed start page (inclusive)."},to:{type:"number",description:"1-indexed end page (inclusive)."}},required:["from","to"]},handler:(e,r)=>{let t=r.getPages({from:e.from,to:e.to});if(t.length===0){let a=r.getTotalPages();return a===0?{success:false,error:"No pages rendered (headless mode or empty document)."}:{success:false,error:`No pages in range ${e.from}\u2013${e.to} (document has ${a} page${a===1?"":"s"}).`}}return {success:true,data:t.map(a=>`--- Page ${a.pageNumber} ---
|
|
2
|
+
${a.text||"(empty page)"}`).join(`
|
|
3
|
+
|
|
4
|
+
`)}}};var h={name:"read_document",displayName:"Reading document",description:'Read the document content. Returns lines tagged with a stable paragraph id, e.g. "[2A1F3B] First paragraph". Use the bracketed id as `paraId` when commenting or suggesting changes \u2014 it survives edits, unlike ordinal indices. Returns the vanilla document (the doc as it exists right now, before any tracked suggestions are accepted): pending insertions are HIDDEN, pending deletions are shown as plain text (still part of the document until accepted), and comment markers are stripped. Use read_changes / read_comments to inspect what is pending.',inputSchema:{type:"object",properties:{fromIndex:{type:"number",description:"Start ordinal index (inclusive). Optional."},toIndex:{type:"number",description:"End ordinal index (inclusive). Optional."}}},handler:(e,r)=>({success:true,data:r.getContentAsText({fromIndex:e.fromIndex,toIndex:e.toIndex,includeTrackedChanges:false,includeCommentAnchors:false})})},g={name:"read_selection",displayName:"Reading selection",description:'Read the user\'s current cursor or selection. Returns the selected text, the paragraph it lives in, and that paragraph\'s `paraId`. Use this when the user asks "fix this" or "review what I have selected".',inputSchema:{type:"object",properties:{}},handler:(e,r)=>{let t=r.getSelection();return t?{success:true,data:t}:{success:false,error:"No selection (editor not focused)."}}},u={name:"find_text",displayName:"Finding text",description:"Locate paragraphs containing `query`. Returns up to `limit` handles, each with `paraId`, the matched substring, and surrounding context. Pass any returned `paraId` (and the `match` as `search`) to add_comment / suggest_change.",inputSchema:{type:"object",properties:{query:{type:"string",description:"Text to find (substring match)."},caseSensitive:{type:"boolean",description:"Default: false."},limit:{type:"number",description:"Max paragraphs to return. Default: 20."}},required:["query"]},handler:(e,r)=>{let t=r.findText(e.query,{caseSensitive:e.caseSensitive,limit:e.limit});return t.length===0?{success:true,data:"No matches."}:{success:true,data:t}}},y={name:"read_comments",displayName:"Reading comments",description:"List all comments in the document with their paragraph anchors.",inputSchema:{type:"object",properties:{}},handler:(e,r)=>{let t=r.getComments();return t.length===0?{success:true,data:"No comments."}:{success:true,data:t.map(a=>`[Comment #${a.id}] ${a.author}: "${a.text}"`+(a.anchoredText?` (anchored to: "${a.anchoredText}")`:"")+(a.replies.length>0?`
|
|
5
|
+
`+a.replies.map(s=>` Reply by ${s.author}: "${s.text}"`).join(`
|
|
6
|
+
`):"")).join(`
|
|
7
|
+
`)}}},f={name:"read_changes",displayName:"Reading changes",description:"List tracked changes (insertions / deletions) currently in the document.",inputSchema:{type:"object",properties:{}},handler:(e,r)=>{let t=r.getChanges();return t.length===0?{success:true,data:"No tracked changes."}:{success:true,data:t.map(a=>`[Change #${a.id}] ${a.type} by ${a.author}: "${a.text}"`).join(`
|
|
8
|
+
`)}}},b={name:"add_comment",displayName:"Adding comment",description:"Attach a comment to a paragraph, optionally anchored to a unique phrase within it. The user sees it instantly in the comments sidebar.",inputSchema:{type:"object",properties:{paraId:{type:"string",description:"Paragraph id from read_document / find_text."},text:{type:"string",description:"Comment body."},search:{type:"string",description:"Optional: anchor to this exact phrase within the paragraph. Must be unique."}},required:["paraId","text"]},handler:(e,r)=>{let t=r.addComment({paraId:e.paraId,text:e.text,search:e.search});return t===null?{success:false,error:"Could not add comment. The paraId may not exist, or `search` is missing / ambiguous."}:{success:true,data:`Comment ${t} added on ${e.paraId}.`}}},I={name:"suggest_change",displayName:"Suggesting change",description:"Suggest a tracked change. Three modes: (1) replacement \u2014 `search` non-empty, `replaceWith` non-empty; (2) deletion \u2014 `search` non-empty, `replaceWith` empty; (3) insertion at paragraph end \u2014 `search` empty, `replaceWith` non-empty. The user can accept or reject in the editor UI.",inputSchema:{type:"object",properties:{paraId:{type:"string",description:"Paragraph id from read_document / find_text."},search:{type:"string",description:"Phrase to find (must be unique). Empty string = insert at paragraph end."},replaceWith:{type:"string",description:"Replacement text. Empty string = delete the matched phrase."}},required:["paraId","search","replaceWith"]},handler:(e,r)=>r.proposeChange({paraId:e.paraId,search:e.search,replaceWith:e.replaceWith})?e.search?e.replaceWith?{success:true,data:`Replacement proposed: "${e.search}" \u2192 "${e.replaceWith}" on ${e.paraId}.`}:{success:true,data:`Deletion proposed: "${e.search}" on ${e.paraId}.`}:{success:true,data:`Insertion proposed on ${e.paraId}.`}:{success:false,error:"Could not propose change. Possible causes: paraId not found; search missing or ambiguous; or the target overlaps an existing tracked change."}},x={name:"reply_comment",displayName:"Replying to comment",description:"Reply to an existing comment by id. Threaded under the original.",inputSchema:{type:"object",properties:{commentId:{type:"number",description:"Comment id from read_comments."},text:{type:"string",description:"Reply body."}},required:["commentId","text"]},handler:(e,r)=>{let t=r.replyTo(e.commentId,{text:e.text});return t===null?{success:false,error:`Comment #${e.commentId} not found.`}:{success:true,data:`Reply ${t} added to comment ${e.commentId}.`}}},k={name:"resolve_comment",displayName:"Resolving comment",description:"Mark a comment as resolved (done).",inputSchema:{type:"object",properties:{commentId:{type:"number",description:"Comment id from read_comments."}},required:["commentId"]},handler:(e,r)=>(r.resolveComment(e.commentId),{success:true,data:`Comment ${e.commentId} resolved.`})},v={name:"scroll",displayName:"Scrolling",description:"Scroll the editor to a paragraph by paraId. Does not move the user's cursor.",inputSchema:{type:"object",properties:{paraId:{type:"string",description:"Paragraph id from read_document / find_text."}},required:["paraId"]},handler:(e,r)=>r.scrollTo(e.paraId)?{success:true,data:`Scrolled to ${e.paraId}.`}:{success:false,error:`paraId ${e.paraId} not found.`}},i=[h,g,l,m,u,y,f,b,I,c,p,x,k,v];function _(e,r,t){let n=i.find(a=>a.name===e);if(!n)return {success:false,error:`Unknown tool: ${e}`};try{return n.handler(r,t)}catch(a){return {success:false,error:a instanceof Error?a.message:String(a)}}}function N(e){let r=i.find(n=>n.name===e);if(r?.displayName)return r.displayName;let t=e.replace(/_/g," ");return t.charAt(0).toUpperCase()+t.slice(1)}function w(){return i.map(e=>({type:"function",function:{name:e.name,description:e.description,parameters:e.inputSchema}}))}export{i as a,_ as b,N as c,w as d};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
'use strict';var headless=require('@zeke-02/docx-editor-core/headless');function h(s){return s.type==="insertion"||s.type==="deletion"||s.type==="moveFrom"||s.type==="moveTo"}function x(s){let n=[];for(let o of s)o.type==="run"?n.push(headless.getRunText(o)):o.type==="hyperlink"&&n.push(headless.getHyperlinkText(o));return n.join("")}function K(s,n){let o=0;for(let t of s.content)if(t.type==="paragraph"){if(o===n)return t;o++;}else if(t.type==="table"){for(let r of t.rows)for(let e of r.cells)for(let a of e.content)if(a.type==="paragraph"){if(o===n)return a;o++;}}else o++;throw new Error(`Paragraph index ${n} out of bounds (max: ${o-1})`)}function I(s,n){let o=0;for(let t of s.content)if(t.type==="paragraph"){if(n(t,o)===false)return;o++;}else if(t.type==="table"){for(let r of t.rows)for(let e of r.cells)for(let a of e.content)if(a.type==="paragraph"){if(n(a,o)===false)return;o++;}}else o++;}function V(s,n={}){let{fromIndex:o,toIndex:t,includeTrackedChanges:r=true,includeCommentAnchors:e=true}=n,a=[],i=0;for(let c of s.content)if(c.type==="paragraph")w(i,o,t)&&a.push(L(c,i,r,e)),i++;else if(c.type==="table"){w(i,o,t)&&a.push(H(c,i,r,e));for(let l of c.rows)for(let u of l.cells)for(let p of u.content)p.type==="paragraph"&&i++;}else i++;return a}function w(s,n,o){return (n===void 0||s>=n)&&(o===void 0||s<=o)}function L(s,n,o,t){let r=B(s,o,t),e=s.formatting?.styleId,a=s.paraId;return headless.isHeadingStyle(e)?{type:"heading",index:n,paraId:a,level:headless.parseHeadingLevel(e)??1,text:r}:s.listRendering?{type:"list-item",index:n,paraId:a,text:r,listLevel:s.listRendering.level??0,listType:s.listRendering.isBullet?"bullet":"number"}:{type:"paragraph",index:n,paraId:a,text:r}}function H(s,n,o,t){let r=[],e=[];for(let a of s.rows){let i=[],c=[];for(let l of a.cells){let u=[],p;for(let g of l.content)g.type==="paragraph"&&(p===void 0&&(p=g.paraId),u.push(B(g,o,t)));i.push(u.join(`
|
|
2
|
+
`)),c.push(p);}r.push(i),e.push(c);}return {type:"table",index:n,rows:r,cellParaIds:e}}function Y(s){let n=[],o=t=>t.paraId?t.paraId:String(t.index);for(let t of s)switch(t.type){case "heading":n.push(`[${o(t)}] (h${t.level}) ${t.text}`);break;case "paragraph":n.push(`[${o(t)}] ${t.text}`);break;case "list-item":{let r=" ".repeat(t.listLevel),e=t.listType==="bullet"?"\u2022":"-";n.push(`[${o(t)}] ${r}${e} ${t.text}`);break}case "table":{let r=t.index;for(let e=0;e<t.rows.length;e++)for(let a=0;a<t.rows[e].length;a++){let c=t.rows[e][a].split(`
|
|
3
|
+
`),l=t.cellParaIds?.[e]?.[a];for(let u=0;u<c.length;u++){let p=u===0&&l?l:String(r);n.push(`[${p}] (table, row ${e+1}, col ${a+1}) ${c[u]}`),r++;}}break}}return n.join(`
|
|
4
|
+
`)}function B(s,n,o){let t=[],r=new Set;for(let e of s.content){if(e.type==="commentRangeStart"&&o){r.add(e.id),t.push(`[comment:${e.id}]`);continue}if(e.type==="commentRangeEnd"&&o){r.has(e.id)&&(r.delete(e.id),t.push("[/comment]"));continue}if(e.type==="run")t.push(headless.getRunText(e));else if(e.type==="hyperlink")t.push(headless.getHyperlinkText(e));else if(h(e)){let a=x(e.content);e.type==="insertion"||e.type==="moveTo"?n&&t.push(`[+${a}+]{by:${e.info.author}}`):n?t.push(`[-${a}-]{by:${e.info.author}}`):t.push(a);}}return t.join("")}var y=class extends Error{constructor(n,o){let t=o!==void 0?` in paragraph ${o}`:" in document";super(`Text not found${t}: "${n}"`),this.name="TextNotFoundError";}},M=class extends Error{constructor(n){super(`Tracked change not found: id=${n}`),this.name="ChangeNotFoundError";}},F=class extends Error{constructor(n){super(`Comment not found: id=${n}`),this.name="CommentNotFoundError";}};function E(s){let n=[],o=0;for(let t=0;t<s.content.length;t++){let r=s.content[t];if(r.type==="run"){let e=headless.getRunText(r);n.push({contentIndex:t,run:r,text:e,startPos:o}),o+=e.length;}else if(r.type==="hyperlink")for(let e=0;e<r.children.length;e++){let a=r.children[e];if(a.type==="run"){let i=headless.getRunText(a);n.push({contentIndex:t,run:a,text:i,startPos:o}),o+=i.length;}}else if(h(r)){if(r.type==="insertion"||r.type==="moveTo")continue;for(let e=0;e<r.content.length;e++){let a=r.content[e];if(a.type==="run"){let i=headless.getRunText(a);n.push({contentIndex:t,run:a,text:i,startPos:o}),o+=i.length;}else if(a.type==="hyperlink"){for(let i of a.children)if(i.type==="run"){let c=headless.getRunText(i);n.push({contentIndex:t,run:i,text:c,startPos:o}),o+=c.length;}}}}}return n}function T(s){return E(s).map(n=>n.text).join("")}function z(s,n,o){let t=E(s),r=t.map(u=>u.text).join(""),e=G(r,n);if(!e)throw new y(n,o);let a=-1,i=0;for(let u=0;u<t.length;u++)if(e.start<t[u].startPos+t[u].text.length){a=u,i=e.start-t[u].startPos;break}let c=-1,l=0;for(let u=t.length-1;u>=0;u--)if(e.end>t[u].startPos){c=u,l=e.end-t[u].startPos;break}if(a===-1||c===-1)throw new y(n,o);return {startRunIndex:t[a].contentIndex,startOffset:i,endRunIndex:t[c].contentIndex,endOffset:l}}function te(s,n,o){let t=z(s,n,o),{startRunIndex:r,endRunIndex:e}=t,{startOffset:a,endOffset:i}=t,c=s.content[e];if(c.type==="run"){let u=headless.getRunText(c);if(i<u.length){let p=D(u.slice(i),c);$(c,u.slice(0,i)),s.content.splice(e+1,0,p);}}let l=s.content[r];if(l.type==="run"&&a>0){let u=headless.getRunText(l),p=D(u.slice(0,a),l);$(l,u.slice(a)),s.content.splice(r,0,p),r++,e++;}return {startIndex:r,endIndex:e}}function D(s,n){return {type:"run",content:[{type:"text",text:s}],formatting:n.formatting?{...n.formatting}:void 0}}function $(s,n){let o=s.content.find(t=>t.type==="text");o&&(o.text=n);}function O(s){let n=[],o=[],t=true;for(let r=0;r<s.length;r++){let e=s[r];if(!"\u200B\u200C\u200D\uFEFF\xAD".includes(e)){if("\u201C\u201D\u201E\u201F".includes(e)&&(e='"'),"\u2018\u2019\u201A\u201B".includes(e)&&(e="'"),"\u2013\u2014\u2012\u2015".includes(e)&&(e="-"),e==="\u2026"){n.push(".",".","."),o.push(r,r,r),t=false;continue}if(/\s/.test(e)||e==="\xA0"){t||(n.push(" "),o.push(r),t=true);continue}n.push(e.toLowerCase()),o.push(r),t=false;}}return n.length>0&&n[n.length-1]===" "&&(n.pop(),o.pop()),{text:n.join(""),posMap:o}}function S(s,n,o,t){let r=s.posMap[n],e=s.posMap[n+o-1]+1;for(;e<t.length&&"\u200B\u200C\u200D\uFEFF\xAD".includes(t[e]);)e++;return {start:r,end:e}}function G(s,n){if(!n||!s)return null;let o=s.indexOf(n);if(o!==-1)return {start:o,end:o+n.length};let t=O(s),r=O(n);if(!r.text)return null;let e=t.text.indexOf(r.text);if(e!==-1)return S(t,e,r.text.length,s);let a=r.text.split(" ");if(a.length>=3)for(let i=1;i<=Math.min(2,a.length-2);i++){let c=a.slice(0,-i).join(" "),l=t.text.indexOf(c);if(l!==-1)return S(t,l,c.length,s)}return null}function se(s,n){let o=new Map;return I(s,(r,e)=>{let a=null;for(let i of r.content)if(h(i)){a===null&&(a=T(r));let c=x(i.content),l=i.info.id,u=o.get(l);u&&u.paragraphIndex===e?u.text+=c:o.set(l,{id:l,type:i.type,author:i.info.author,date:i.info.date??null,text:c,context:a,paragraphIndex:e});}}),Array.from(o.values()).filter(r=>!(n?.author&&r.author!==n.author||n?.type&&r.type!==n.type))}function ae(s,n){let o=s.comments??[];if(o.length===0)return [];let t=W(s),r=[],e=new Map;for(let i of o)if(i.parentId!==void 0){let c=e.get(i.parentId)??[];c.push(i),e.set(i.parentId,c);}else r.push(i);return r.map(i=>{let c=t.get(i.id),l=(e.get(i.id)??[]).map(u=>({id:u.id,author:u.author,date:u.date??null,text:A(u)}));return {id:i.id,author:i.author,date:i.date??null,text:A(i),anchoredText:c?.text??"",paragraphIndex:c?.paragraphIndex??-1,replies:l,done:i.done??false}}).filter(i=>!(n?.author&&i.author!==n.author||n?.done!==void 0&&i.done!==n.done))}function A(s){return s.content.map(n=>T(n)).join(`
|
|
5
|
+
`)}function W(s){let n=new Map,o=new Map;return I(s,(t,r)=>{for(let e of t.content)if(e.type==="commentRangeStart")o.set(e.id,{paragraphIndex:r,parts:[]});else if(e.type==="commentRangeEnd"){let a=o.get(e.id);a&&(n.set(e.id,{text:a.parts.join(""),paragraphIndex:a.paragraphIndex}),o.delete(e.id));}else if(e.type==="run"){let a=headless.getRunText(e);for(let i of o.values())i.parts.push(a);}else if(e.type==="hyperlink"){let a=e.children.filter(i=>i.type==="run").map(headless.getRunText).join("");for(let i of o.values())i.parts.push(a);}else if(h(e)){if(e.type==="insertion"||e.type==="moveTo")continue;let a=x(e.content);for(let i of o.values())i.parts.push(a);}}),n}function N(s){let n=s.toDocument().package?.document;if(!n)return new Map;let o=new Map,t=0;for(let r of n.content)if(r.type==="paragraph"){let e=r.paraId;e&&o.set(e,t),t++;}else if(r.type==="table")for(let e of r.rows)for(let a of e.cells)for(let i of a.content)i.type==="paragraph"&&t++;else t++;return o}function X(s){let n=[],o=t=>{for(let r of t.content)r.type==="text"&&n.push(r.text??"");};for(let t of s.content)if(t.type==="run")o(t);else if(t.type==="hyperlink")for(let r of t.children)r.type==="run"&&o(r);else if(t.type==="deletion"||t.type==="moveFrom"){for(let r of t.content)if(r.type==="run")o(r);else if(r.type==="hyperlink")for(let e of r.children)e.type==="run"&&o(e);}return n.join("")}function ce(s){let n=new Set,o=null;function t(){return o===null&&(o=N(s)),o}function r(){if(n.size===0)return;let e=s.getComments(),a=s.getChanges(),i={commentCount:e.length,changeCount:a.length,comments:e,changes:a};for(let c of n)try{c(i);}catch(l){console.error("reviewerBridge content listener threw:",l);}}return {getContentAsText(e){return s.getContentAsText(e)},getContent(e){return s.getContent(e)},getComments(e){return s.getComments(e)},getChanges(e){return s.getChanges(e)},findText(e,a){if(!e)return [];let i=a?.caseSensitive??false,c=a?.limit??20,l=i?e:e.toLowerCase(),u=s.toDocument().package?.document;if(!u)return [];let p=[],g=40;for(let k of u.content){if(p.length>=c)break;if(k.type!=="paragraph")continue;let b=k;if(!b.paraId)continue;let m=X(b),R=i?m:m.toLowerCase(),d=R.indexOf(l);if(d===-1||R.indexOf(l,d+1)!==-1)continue;let j=m.slice(d,d+e.length);p.push({paraId:b.paraId,match:j,before:m.slice(Math.max(0,d-g),d),after:m.slice(d+e.length,d+e.length+g)});}return p},getSelection(){return null},addComment(e){let a=t().get(e.paraId);if(a===void 0)return null;try{let i=s.addComment({paragraphIndex:a,text:e.text,author:e.author,search:e.search});return r(),i}catch{return null}},replyTo(e,a){try{let i=s.replyTo(e,a);return r(),i}catch{return null}},resolveComment(e){let i=s.toDocument().package?.document?.comments?.find(c=>c.id===e);i&&(i.done=true,r());},proposeChange(e){let a=t().get(e.paraId);if(a===void 0)return false;let i=e.search==="",c=e.replaceWith==="";if(i&&c)return false;try{return i?s.proposeInsertion({paragraphIndex:a,insertText:e.replaceWith,author:e.author}):c?s.proposeDeletion({paragraphIndex:a,search:e.search,author:e.author}):s.replace({paragraphIndex:a,search:e.search,replaceWith:e.replaceWith,author:e.author}),r(),true}catch{return false}},scrollTo(e){return t().has(e)},applyFormatting(){return false},setParagraphStyle(){return false},getPage(){return null},getPages(){return []},getTotalPages(){return 0},getCurrentPage(){return 0},onContentChange(e){return n.add(e),()=>{n.delete(e);}},onSelectionChange(){return ()=>{}}}}exports.a=h;exports.b=K;exports.c=I;exports.d=V;exports.e=Y;exports.f=y;exports.g=M;exports.h=F;exports.i=z;exports.j=te;exports.k=se;exports.l=ae;exports.m=ce;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
'use strict';var chunk2RGRAPLW_js=require('./chunk-2RGRAPLW.js');function y(n){return !n||n.length===0?"":n.map(i=>{let s=i;return s?.content?s.content.map(e=>e.content?.map(t=>t.text||"").join("")||"").join(""):""}).join(`
|
|
2
|
+
`)}function u(n){let i=n.getEditorRef();if(i){let e=i.getDocument();if(e?.package?.document)return e.package.document}return n.getDocument()?.package?.document??null}function T(n,i="AI"){function s(e){return e??i}return {getContentAsText(e){let t=u(n);return t?chunk2RGRAPLW_js.e(chunk2RGRAPLW_js.d(t,e)):""},getContent(e){let t=u(n);return t?chunk2RGRAPLW_js.d(t,e):[]},getComments(e){let t=u(n);if(!t)return [];let r=chunk2RGRAPLW_js.l(t,e);if(r.length>0)return r;let l=n.getComments();if(l.length===0)return [];let a=new Map,g=[];for(let o of l)if(o.parentId){let c=a.get(o.parentId);c?c.push(o):a.set(o.parentId,[o]);}else g.push(o);let m=[];for(let o of g){if(e?.author&&o.author!==e.author||e?.done!==void 0&&(o.done??false)!==e.done)continue;let c=a.get(o.id)??[];m.push({id:o.id,author:o.author,date:o.date??null,text:y(o.content),anchoredText:"",paragraphIndex:-1,replies:c.map(p=>({id:p.id,author:p.author,date:p.date??null,text:y(p.content)})),done:o.done??false});}return m},getChanges(e){let t=u(n);return t?chunk2RGRAPLW_js.k(t,e):[]},findText(e,t){return n.findInDocument(e,t)},getSelection(){return n.getSelectionInfo()},addComment(e){return n.addComment({paraId:e.paraId,text:e.text,author:s(e.author),search:e.search})},replyTo(e,t){return n.replyToComment(e,t.text,s(t.author))},resolveComment(e){n.resolveComment(e);},proposeChange(e){return n.proposeChange({paraId:e.paraId,search:e.search,replaceWith:e.replaceWith,author:s(e.author)})},applyFormatting(e){return n.applyFormatting({paraId:e.paraId,search:e.search,marks:e.marks})},setParagraphStyle(e){return n.setParagraphStyle({paraId:e.paraId,styleId:e.styleId})},getPage(e){return n.getPageContent(e)},getPages(e){let t=n.getTotalPages(),r=Math.max(1,Math.min(e.from,t)),l=Math.max(r,Math.min(e.to,t)),a=[];for(let g=r;g<=l;g++){let m=n.getPageContent(g);m&&a.push(m);}return a},getTotalPages(){return n.getTotalPages()},getCurrentPage(){return n.getCurrentPage()},scrollTo(e){return n.scrollToParaId(e)},onContentChange(e){return n.onContentChange(()=>{let t=u(n),r=t?chunk2RGRAPLW_js.l(t):[],l=t?chunk2RGRAPLW_js.k(t):[];try{e({commentCount:r.length,changeCount:l.length,comments:r,changes:l});}catch(a){console.error("onContentChange listener threw:",a);}})},onSelectionChange(e){return n.onSelectionChange(()=>{try{e(n.getSelectionInfo());}catch(t){console.error("onSelectionChange listener threw:",t);}})}}}exports.a=T;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import {isHeadingStyle,parseHeadingLevel,getRunText,getHyperlinkText}from'@zeke-02/docx-editor-core/headless';function h(s){return s.type==="insertion"||s.type==="deletion"||s.type==="moveFrom"||s.type==="moveTo"}function x(s){let n=[];for(let o of s)o.type==="run"?n.push(getRunText(o)):o.type==="hyperlink"&&n.push(getHyperlinkText(o));return n.join("")}function K(s,n){let o=0;for(let t of s.content)if(t.type==="paragraph"){if(o===n)return t;o++;}else if(t.type==="table"){for(let r of t.rows)for(let e of r.cells)for(let a of e.content)if(a.type==="paragraph"){if(o===n)return a;o++;}}else o++;throw new Error(`Paragraph index ${n} out of bounds (max: ${o-1})`)}function I(s,n){let o=0;for(let t of s.content)if(t.type==="paragraph"){if(n(t,o)===false)return;o++;}else if(t.type==="table"){for(let r of t.rows)for(let e of r.cells)for(let a of e.content)if(a.type==="paragraph"){if(n(a,o)===false)return;o++;}}else o++;}function V(s,n={}){let{fromIndex:o,toIndex:t,includeTrackedChanges:r=true,includeCommentAnchors:e=true}=n,a=[],i=0;for(let c of s.content)if(c.type==="paragraph")w(i,o,t)&&a.push(L(c,i,r,e)),i++;else if(c.type==="table"){w(i,o,t)&&a.push(H(c,i,r,e));for(let l of c.rows)for(let u of l.cells)for(let p of u.content)p.type==="paragraph"&&i++;}else i++;return a}function w(s,n,o){return (n===void 0||s>=n)&&(o===void 0||s<=o)}function L(s,n,o,t){let r=B(s,o,t),e=s.formatting?.styleId,a=s.paraId;return isHeadingStyle(e)?{type:"heading",index:n,paraId:a,level:parseHeadingLevel(e)??1,text:r}:s.listRendering?{type:"list-item",index:n,paraId:a,text:r,listLevel:s.listRendering.level??0,listType:s.listRendering.isBullet?"bullet":"number"}:{type:"paragraph",index:n,paraId:a,text:r}}function H(s,n,o,t){let r=[],e=[];for(let a of s.rows){let i=[],c=[];for(let l of a.cells){let u=[],p;for(let g of l.content)g.type==="paragraph"&&(p===void 0&&(p=g.paraId),u.push(B(g,o,t)));i.push(u.join(`
|
|
2
|
+
`)),c.push(p);}r.push(i),e.push(c);}return {type:"table",index:n,rows:r,cellParaIds:e}}function Y(s){let n=[],o=t=>t.paraId?t.paraId:String(t.index);for(let t of s)switch(t.type){case "heading":n.push(`[${o(t)}] (h${t.level}) ${t.text}`);break;case "paragraph":n.push(`[${o(t)}] ${t.text}`);break;case "list-item":{let r=" ".repeat(t.listLevel),e=t.listType==="bullet"?"\u2022":"-";n.push(`[${o(t)}] ${r}${e} ${t.text}`);break}case "table":{let r=t.index;for(let e=0;e<t.rows.length;e++)for(let a=0;a<t.rows[e].length;a++){let c=t.rows[e][a].split(`
|
|
3
|
+
`),l=t.cellParaIds?.[e]?.[a];for(let u=0;u<c.length;u++){let p=u===0&&l?l:String(r);n.push(`[${p}] (table, row ${e+1}, col ${a+1}) ${c[u]}`),r++;}}break}}return n.join(`
|
|
4
|
+
`)}function B(s,n,o){let t=[],r=new Set;for(let e of s.content){if(e.type==="commentRangeStart"&&o){r.add(e.id),t.push(`[comment:${e.id}]`);continue}if(e.type==="commentRangeEnd"&&o){r.has(e.id)&&(r.delete(e.id),t.push("[/comment]"));continue}if(e.type==="run")t.push(getRunText(e));else if(e.type==="hyperlink")t.push(getHyperlinkText(e));else if(h(e)){let a=x(e.content);e.type==="insertion"||e.type==="moveTo"?n&&t.push(`[+${a}+]{by:${e.info.author}}`):n?t.push(`[-${a}-]{by:${e.info.author}}`):t.push(a);}}return t.join("")}var y=class extends Error{constructor(n,o){let t=o!==void 0?` in paragraph ${o}`:" in document";super(`Text not found${t}: "${n}"`),this.name="TextNotFoundError";}},M=class extends Error{constructor(n){super(`Tracked change not found: id=${n}`),this.name="ChangeNotFoundError";}},F=class extends Error{constructor(n){super(`Comment not found: id=${n}`),this.name="CommentNotFoundError";}};function E(s){let n=[],o=0;for(let t=0;t<s.content.length;t++){let r=s.content[t];if(r.type==="run"){let e=getRunText(r);n.push({contentIndex:t,run:r,text:e,startPos:o}),o+=e.length;}else if(r.type==="hyperlink")for(let e=0;e<r.children.length;e++){let a=r.children[e];if(a.type==="run"){let i=getRunText(a);n.push({contentIndex:t,run:a,text:i,startPos:o}),o+=i.length;}}else if(h(r)){if(r.type==="insertion"||r.type==="moveTo")continue;for(let e=0;e<r.content.length;e++){let a=r.content[e];if(a.type==="run"){let i=getRunText(a);n.push({contentIndex:t,run:a,text:i,startPos:o}),o+=i.length;}else if(a.type==="hyperlink"){for(let i of a.children)if(i.type==="run"){let c=getRunText(i);n.push({contentIndex:t,run:i,text:c,startPos:o}),o+=c.length;}}}}}return n}function T(s){return E(s).map(n=>n.text).join("")}function z(s,n,o){let t=E(s),r=t.map(u=>u.text).join(""),e=G(r,n);if(!e)throw new y(n,o);let a=-1,i=0;for(let u=0;u<t.length;u++)if(e.start<t[u].startPos+t[u].text.length){a=u,i=e.start-t[u].startPos;break}let c=-1,l=0;for(let u=t.length-1;u>=0;u--)if(e.end>t[u].startPos){c=u,l=e.end-t[u].startPos;break}if(a===-1||c===-1)throw new y(n,o);return {startRunIndex:t[a].contentIndex,startOffset:i,endRunIndex:t[c].contentIndex,endOffset:l}}function te(s,n,o){let t=z(s,n,o),{startRunIndex:r,endRunIndex:e}=t,{startOffset:a,endOffset:i}=t,c=s.content[e];if(c.type==="run"){let u=getRunText(c);if(i<u.length){let p=D(u.slice(i),c);$(c,u.slice(0,i)),s.content.splice(e+1,0,p);}}let l=s.content[r];if(l.type==="run"&&a>0){let u=getRunText(l),p=D(u.slice(0,a),l);$(l,u.slice(a)),s.content.splice(r,0,p),r++,e++;}return {startIndex:r,endIndex:e}}function D(s,n){return {type:"run",content:[{type:"text",text:s}],formatting:n.formatting?{...n.formatting}:void 0}}function $(s,n){let o=s.content.find(t=>t.type==="text");o&&(o.text=n);}function O(s){let n=[],o=[],t=true;for(let r=0;r<s.length;r++){let e=s[r];if(!"\u200B\u200C\u200D\uFEFF\xAD".includes(e)){if("\u201C\u201D\u201E\u201F".includes(e)&&(e='"'),"\u2018\u2019\u201A\u201B".includes(e)&&(e="'"),"\u2013\u2014\u2012\u2015".includes(e)&&(e="-"),e==="\u2026"){n.push(".",".","."),o.push(r,r,r),t=false;continue}if(/\s/.test(e)||e==="\xA0"){t||(n.push(" "),o.push(r),t=true);continue}n.push(e.toLowerCase()),o.push(r),t=false;}}return n.length>0&&n[n.length-1]===" "&&(n.pop(),o.pop()),{text:n.join(""),posMap:o}}function S(s,n,o,t){let r=s.posMap[n],e=s.posMap[n+o-1]+1;for(;e<t.length&&"\u200B\u200C\u200D\uFEFF\xAD".includes(t[e]);)e++;return {start:r,end:e}}function G(s,n){if(!n||!s)return null;let o=s.indexOf(n);if(o!==-1)return {start:o,end:o+n.length};let t=O(s),r=O(n);if(!r.text)return null;let e=t.text.indexOf(r.text);if(e!==-1)return S(t,e,r.text.length,s);let a=r.text.split(" ");if(a.length>=3)for(let i=1;i<=Math.min(2,a.length-2);i++){let c=a.slice(0,-i).join(" "),l=t.text.indexOf(c);if(l!==-1)return S(t,l,c.length,s)}return null}function se(s,n){let o=new Map;return I(s,(r,e)=>{let a=null;for(let i of r.content)if(h(i)){a===null&&(a=T(r));let c=x(i.content),l=i.info.id,u=o.get(l);u&&u.paragraphIndex===e?u.text+=c:o.set(l,{id:l,type:i.type,author:i.info.author,date:i.info.date??null,text:c,context:a,paragraphIndex:e});}}),Array.from(o.values()).filter(r=>!(n?.author&&r.author!==n.author||n?.type&&r.type!==n.type))}function ae(s,n){let o=s.comments??[];if(o.length===0)return [];let t=W(s),r=[],e=new Map;for(let i of o)if(i.parentId!==void 0){let c=e.get(i.parentId)??[];c.push(i),e.set(i.parentId,c);}else r.push(i);return r.map(i=>{let c=t.get(i.id),l=(e.get(i.id)??[]).map(u=>({id:u.id,author:u.author,date:u.date??null,text:A(u)}));return {id:i.id,author:i.author,date:i.date??null,text:A(i),anchoredText:c?.text??"",paragraphIndex:c?.paragraphIndex??-1,replies:l,done:i.done??false}}).filter(i=>!(n?.author&&i.author!==n.author||n?.done!==void 0&&i.done!==n.done))}function A(s){return s.content.map(n=>T(n)).join(`
|
|
5
|
+
`)}function W(s){let n=new Map,o=new Map;return I(s,(t,r)=>{for(let e of t.content)if(e.type==="commentRangeStart")o.set(e.id,{paragraphIndex:r,parts:[]});else if(e.type==="commentRangeEnd"){let a=o.get(e.id);a&&(n.set(e.id,{text:a.parts.join(""),paragraphIndex:a.paragraphIndex}),o.delete(e.id));}else if(e.type==="run"){let a=getRunText(e);for(let i of o.values())i.parts.push(a);}else if(e.type==="hyperlink"){let a=e.children.filter(i=>i.type==="run").map(getRunText).join("");for(let i of o.values())i.parts.push(a);}else if(h(e)){if(e.type==="insertion"||e.type==="moveTo")continue;let a=x(e.content);for(let i of o.values())i.parts.push(a);}}),n}function N(s){let n=s.toDocument().package?.document;if(!n)return new Map;let o=new Map,t=0;for(let r of n.content)if(r.type==="paragraph"){let e=r.paraId;e&&o.set(e,t),t++;}else if(r.type==="table")for(let e of r.rows)for(let a of e.cells)for(let i of a.content)i.type==="paragraph"&&t++;else t++;return o}function X(s){let n=[],o=t=>{for(let r of t.content)r.type==="text"&&n.push(r.text??"");};for(let t of s.content)if(t.type==="run")o(t);else if(t.type==="hyperlink")for(let r of t.children)r.type==="run"&&o(r);else if(t.type==="deletion"||t.type==="moveFrom"){for(let r of t.content)if(r.type==="run")o(r);else if(r.type==="hyperlink")for(let e of r.children)e.type==="run"&&o(e);}return n.join("")}function ce(s){let n=new Set,o=null;function t(){return o===null&&(o=N(s)),o}function r(){if(n.size===0)return;let e=s.getComments(),a=s.getChanges(),i={commentCount:e.length,changeCount:a.length,comments:e,changes:a};for(let c of n)try{c(i);}catch(l){console.error("reviewerBridge content listener threw:",l);}}return {getContentAsText(e){return s.getContentAsText(e)},getContent(e){return s.getContent(e)},getComments(e){return s.getComments(e)},getChanges(e){return s.getChanges(e)},findText(e,a){if(!e)return [];let i=a?.caseSensitive??false,c=a?.limit??20,l=i?e:e.toLowerCase(),u=s.toDocument().package?.document;if(!u)return [];let p=[],g=40;for(let k of u.content){if(p.length>=c)break;if(k.type!=="paragraph")continue;let b=k;if(!b.paraId)continue;let m=X(b),R=i?m:m.toLowerCase(),d=R.indexOf(l);if(d===-1||R.indexOf(l,d+1)!==-1)continue;let j=m.slice(d,d+e.length);p.push({paraId:b.paraId,match:j,before:m.slice(Math.max(0,d-g),d),after:m.slice(d+e.length,d+e.length+g)});}return p},getSelection(){return null},addComment(e){let a=t().get(e.paraId);if(a===void 0)return null;try{let i=s.addComment({paragraphIndex:a,text:e.text,author:e.author,search:e.search});return r(),i}catch{return null}},replyTo(e,a){try{let i=s.replyTo(e,a);return r(),i}catch{return null}},resolveComment(e){let i=s.toDocument().package?.document?.comments?.find(c=>c.id===e);i&&(i.done=true,r());},proposeChange(e){let a=t().get(e.paraId);if(a===void 0)return false;let i=e.search==="",c=e.replaceWith==="";if(i&&c)return false;try{return i?s.proposeInsertion({paragraphIndex:a,insertText:e.replaceWith,author:e.author}):c?s.proposeDeletion({paragraphIndex:a,search:e.search,author:e.author}):s.replace({paragraphIndex:a,search:e.search,replaceWith:e.replaceWith,author:e.author}),r(),true}catch{return false}},scrollTo(e){return t().has(e)},applyFormatting(){return false},setParagraphStyle(){return false},getPage(){return null},getPages(){return []},getTotalPages(){return 0},getCurrentPage(){return 0},onContentChange(e){return n.add(e),()=>{n.delete(e);}},onSelectionChange(){return ()=>{}}}}export{h as a,K as b,I as c,V as d,Y as e,y as f,M as g,F as h,z as i,te as j,se as k,ae as l,ce as m};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import {l,k,d,e}from'./chunk-AU3KR5IN.mjs';function y(n){return !n||n.length===0?"":n.map(i=>{let s=i;return s?.content?s.content.map(e=>e.content?.map(t=>t.text||"").join("")||"").join(""):""}).join(`
|
|
2
|
+
`)}function u(n){let i=n.getEditorRef();if(i){let e=i.getDocument();if(e?.package?.document)return e.package.document}return n.getDocument()?.package?.document??null}function T(n,i="AI"){function s(e){return e??i}return {getContentAsText(e$1){let t=u(n);return t?e(d(t,e$1)):""},getContent(e){let t=u(n);return t?d(t,e):[]},getComments(e){let t=u(n);if(!t)return [];let r=l(t,e);if(r.length>0)return r;let l$1=n.getComments();if(l$1.length===0)return [];let a=new Map,g=[];for(let o of l$1)if(o.parentId){let c=a.get(o.parentId);c?c.push(o):a.set(o.parentId,[o]);}else g.push(o);let m=[];for(let o of g){if(e?.author&&o.author!==e.author||e?.done!==void 0&&(o.done??false)!==e.done)continue;let c=a.get(o.id)??[];m.push({id:o.id,author:o.author,date:o.date??null,text:y(o.content),anchoredText:"",paragraphIndex:-1,replies:c.map(p=>({id:p.id,author:p.author,date:p.date??null,text:y(p.content)})),done:o.done??false});}return m},getChanges(e){let t=u(n);return t?k(t,e):[]},findText(e,t){return n.findInDocument(e,t)},getSelection(){return n.getSelectionInfo()},addComment(e){return n.addComment({paraId:e.paraId,text:e.text,author:s(e.author),search:e.search})},replyTo(e,t){return n.replyToComment(e,t.text,s(t.author))},resolveComment(e){n.resolveComment(e);},proposeChange(e){return n.proposeChange({paraId:e.paraId,search:e.search,replaceWith:e.replaceWith,author:s(e.author)})},applyFormatting(e){return n.applyFormatting({paraId:e.paraId,search:e.search,marks:e.marks})},setParagraphStyle(e){return n.setParagraphStyle({paraId:e.paraId,styleId:e.styleId})},getPage(e){return n.getPageContent(e)},getPages(e){let t=n.getTotalPages(),r=Math.max(1,Math.min(e.from,t)),l=Math.max(r,Math.min(e.to,t)),a=[];for(let g=r;g<=l;g++){let m=n.getPageContent(g);m&&a.push(m);}return a},getTotalPages(){return n.getTotalPages()},getCurrentPage(){return n.getCurrentPage()},scrollTo(e){return n.scrollToParaId(e)},onContentChange(e){return n.onContentChange(()=>{let t=u(n),r=t?l(t):[],l$1=t?k(t):[];try{e({commentCount:r.length,changeCount:l$1.length,comments:r,changes:l$1});}catch(a){console.error("onContentChange listener threw:",a);}})},onSelectionChange(e){return n.onSelectionChange(()=>{try{e(n.getSelectionInfo());}catch(t){console.error("onSelectionChange listener threw:",t);}})}}}export{T as a};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
'use strict';var d=["single","words","double","thick","dotted","dottedHeavy","dash","dashedHeavy","dashLong","dashLongHeavy","dotDash","dashDotHeavy","dotDotDash","dashDotDotHeavy","wave","wavyHeavy","wavyDouble","none"],o=["black","blue","cyan","darkBlue","darkCyan","darkGray","darkGreen","darkMagenta","darkRed","darkYellow","green","lightGray","magenta","red","white","yellow","none"],c={name:"apply_formatting",displayName:"Applying formatting",description:'Apply character formatting (bold, italic, underline, strike, color, highlight, font size, font family) to a paragraph or to a unique phrase within it. Pass `search` to scope the change to part of the paragraph; omit it to format the whole paragraph. Direct edit \u2014 does not create a tracked change. Pass `false` to clear a mark; omit a key to leave it untouched. Color uses `{rgb: "FF0000"}` (no hash) or `{themeColor: "accent1"}`. Font size is in points. Font family takes `{ascii, hAnsi}`.',inputSchema:{type:"object",properties:{paraId:{type:"string",description:"Paragraph id from read_document / find_text."},search:{type:"string",description:"Optional: format only this exact phrase within the paragraph (must be unique)."},marks:{type:"object",description:"Marks to set or clear. Omit a key to leave it untouched.",properties:{bold:{type:"boolean"},italic:{type:"boolean"},underline:{description:'true \u2192 single underline; false \u2192 clear; or { style: "single"|"double"|"thick"|"dotted"|"dottedHeavy"|"dash"|"dashedHeavy"|"dashLong"|"dashLongHeavy"|"dotDash"|"dashDotHeavy"|"dotDotDash"|"dashDotDotHeavy"|"wave"|"wavyHeavy"|"wavyDouble"|"words"|"none" }. Other values are rejected.'},strike:{type:"boolean"},color:{type:"object",description:'Either {rgb: "RRGGBB"} (no hash) or {themeColor: "accent1"|"text1"|...}.',properties:{rgb:{type:"string"},themeColor:{type:"string"}}},highlight:{type:"string",enum:[...o],description:"Highlight color \u2014 must be one of the Word-supported names: "+o.join(", ")+'. Pass "none" to clear. Hex values are rejected (Word does not accept hex for <w:highlight>).'},fontSize:{type:"number",description:"Size in points (e.g. 12, 14, 24)."},fontFamily:{type:"object",properties:{ascii:{type:"string"},hAnsi:{type:"string"}}}}}},required:["paraId","marks"]},handler:(e,r)=>{if(!e.marks||Object.keys(e.marks).length===0)return {success:false,error:"No marks provided. Specify at least one of bold/italic/etc."};let t=typeof e.marks.underline=="object"&&e.marks.underline!==null?e.marks.underline.style:void 0;if(t&&!d.includes(t))return {success:false,error:`Invalid underline.style "${t}". Must be one of: ${d.join(", ")}.`};let n=typeof e.marks.highlight=="string"?e.marks.highlight:void 0;if(n&&!o.includes(n))return {success:false,error:`Invalid highlight "${n}". Must be one of: ${o.join(", ")}. Hex values are not supported by Word's highlight attribute.`};let a=n==="none"?{...e.marks,highlight:""}:e.marks;return r.applyFormatting({paraId:e.paraId,search:e.search,marks:a})?{success:true,data:`Formatting applied to ${e.search?`"${e.search}" in ${e.paraId}`:e.paraId}.`}:{success:false,error:"Could not apply formatting. The paraId may not exist, or `search` is missing / ambiguous."}}},p={name:"set_paragraph_style",displayName:"Setting paragraph style",description:`Apply a paragraph style by id (e.g. "Heading1", "Heading2", "Title", "Quote", "Normal"). The styleId must exist in the document's style definitions \u2014 unknown ids are no-ops. Direct edit, not a tracked change.`,inputSchema:{type:"object",properties:{paraId:{type:"string",description:"Paragraph id from read_document / find_text."},styleId:{type:"string",description:'Style id (e.g. "Heading1", "Title", "Quote", "Normal").'}},required:["paraId","styleId"]},handler:(e,r)=>r.setParagraphStyle({paraId:e.paraId,styleId:e.styleId})?{success:true,data:`Style "${e.styleId}" applied to ${e.paraId}.`}:{success:false,error:`Could not set style. paraId "${e.paraId}" not found, or styleId "${e.styleId}" is not defined.`}};var l={name:"read_page",displayName:"Reading page",description:`Read the contents of one rendered page (1-indexed). Returns paragraphs on the page, each tagged with its stable paraId. Use this when the user asks "summarize page 3" or "comment on what's on this page".`,inputSchema:{type:"object",properties:{pageNumber:{type:"number",description:"1-indexed page number."}},required:["pageNumber"]},handler:(e,r)=>{let t=r.getPage(e.pageNumber);if(!t){let n=r.getTotalPages();return n===0?{success:false,error:"No pages rendered (headless mode or empty document)."}:{success:false,error:`Page ${e.pageNumber} does not exist (document has ${n} page${n===1?"":"s"}).`}}return {success:true,data:t.text||"(empty page)"}}},m={name:"read_pages",displayName:"Reading pages",description:"Read a contiguous range of rendered pages (1-indexed, inclusive). Returns paragraphs across the range, each tagged with paraId. Cheaper than calling read_page repeatedly \u2014 single round-trip.",inputSchema:{type:"object",properties:{from:{type:"number",description:"1-indexed start page (inclusive)."},to:{type:"number",description:"1-indexed end page (inclusive)."}},required:["from","to"]},handler:(e,r)=>{let t=r.getPages({from:e.from,to:e.to});if(t.length===0){let a=r.getTotalPages();return a===0?{success:false,error:"No pages rendered (headless mode or empty document)."}:{success:false,error:`No pages in range ${e.from}\u2013${e.to} (document has ${a} page${a===1?"":"s"}).`}}return {success:true,data:t.map(a=>`--- Page ${a.pageNumber} ---
|
|
2
|
+
${a.text||"(empty page)"}`).join(`
|
|
3
|
+
|
|
4
|
+
`)}}};var h={name:"read_document",displayName:"Reading document",description:'Read the document content. Returns lines tagged with a stable paragraph id, e.g. "[2A1F3B] First paragraph". Use the bracketed id as `paraId` when commenting or suggesting changes \u2014 it survives edits, unlike ordinal indices. Returns the vanilla document (the doc as it exists right now, before any tracked suggestions are accepted): pending insertions are HIDDEN, pending deletions are shown as plain text (still part of the document until accepted), and comment markers are stripped. Use read_changes / read_comments to inspect what is pending.',inputSchema:{type:"object",properties:{fromIndex:{type:"number",description:"Start ordinal index (inclusive). Optional."},toIndex:{type:"number",description:"End ordinal index (inclusive). Optional."}}},handler:(e,r)=>({success:true,data:r.getContentAsText({fromIndex:e.fromIndex,toIndex:e.toIndex,includeTrackedChanges:false,includeCommentAnchors:false})})},g={name:"read_selection",displayName:"Reading selection",description:'Read the user\'s current cursor or selection. Returns the selected text, the paragraph it lives in, and that paragraph\'s `paraId`. Use this when the user asks "fix this" or "review what I have selected".',inputSchema:{type:"object",properties:{}},handler:(e,r)=>{let t=r.getSelection();return t?{success:true,data:t}:{success:false,error:"No selection (editor not focused)."}}},u={name:"find_text",displayName:"Finding text",description:"Locate paragraphs containing `query`. Returns up to `limit` handles, each with `paraId`, the matched substring, and surrounding context. Pass any returned `paraId` (and the `match` as `search`) to add_comment / suggest_change.",inputSchema:{type:"object",properties:{query:{type:"string",description:"Text to find (substring match)."},caseSensitive:{type:"boolean",description:"Default: false."},limit:{type:"number",description:"Max paragraphs to return. Default: 20."}},required:["query"]},handler:(e,r)=>{let t=r.findText(e.query,{caseSensitive:e.caseSensitive,limit:e.limit});return t.length===0?{success:true,data:"No matches."}:{success:true,data:t}}},y={name:"read_comments",displayName:"Reading comments",description:"List all comments in the document with their paragraph anchors.",inputSchema:{type:"object",properties:{}},handler:(e,r)=>{let t=r.getComments();return t.length===0?{success:true,data:"No comments."}:{success:true,data:t.map(a=>`[Comment #${a.id}] ${a.author}: "${a.text}"`+(a.anchoredText?` (anchored to: "${a.anchoredText}")`:"")+(a.replies.length>0?`
|
|
5
|
+
`+a.replies.map(s=>` Reply by ${s.author}: "${s.text}"`).join(`
|
|
6
|
+
`):"")).join(`
|
|
7
|
+
`)}}},f={name:"read_changes",displayName:"Reading changes",description:"List tracked changes (insertions / deletions) currently in the document.",inputSchema:{type:"object",properties:{}},handler:(e,r)=>{let t=r.getChanges();return t.length===0?{success:true,data:"No tracked changes."}:{success:true,data:t.map(a=>`[Change #${a.id}] ${a.type} by ${a.author}: "${a.text}"`).join(`
|
|
8
|
+
`)}}},b={name:"add_comment",displayName:"Adding comment",description:"Attach a comment to a paragraph, optionally anchored to a unique phrase within it. The user sees it instantly in the comments sidebar.",inputSchema:{type:"object",properties:{paraId:{type:"string",description:"Paragraph id from read_document / find_text."},text:{type:"string",description:"Comment body."},search:{type:"string",description:"Optional: anchor to this exact phrase within the paragraph. Must be unique."}},required:["paraId","text"]},handler:(e,r)=>{let t=r.addComment({paraId:e.paraId,text:e.text,search:e.search});return t===null?{success:false,error:"Could not add comment. The paraId may not exist, or `search` is missing / ambiguous."}:{success:true,data:`Comment ${t} added on ${e.paraId}.`}}},I={name:"suggest_change",displayName:"Suggesting change",description:"Suggest a tracked change. Three modes: (1) replacement \u2014 `search` non-empty, `replaceWith` non-empty; (2) deletion \u2014 `search` non-empty, `replaceWith` empty; (3) insertion at paragraph end \u2014 `search` empty, `replaceWith` non-empty. The user can accept or reject in the editor UI.",inputSchema:{type:"object",properties:{paraId:{type:"string",description:"Paragraph id from read_document / find_text."},search:{type:"string",description:"Phrase to find (must be unique). Empty string = insert at paragraph end."},replaceWith:{type:"string",description:"Replacement text. Empty string = delete the matched phrase."}},required:["paraId","search","replaceWith"]},handler:(e,r)=>r.proposeChange({paraId:e.paraId,search:e.search,replaceWith:e.replaceWith})?e.search?e.replaceWith?{success:true,data:`Replacement proposed: "${e.search}" \u2192 "${e.replaceWith}" on ${e.paraId}.`}:{success:true,data:`Deletion proposed: "${e.search}" on ${e.paraId}.`}:{success:true,data:`Insertion proposed on ${e.paraId}.`}:{success:false,error:"Could not propose change. Possible causes: paraId not found; search missing or ambiguous; or the target overlaps an existing tracked change."}},x={name:"reply_comment",displayName:"Replying to comment",description:"Reply to an existing comment by id. Threaded under the original.",inputSchema:{type:"object",properties:{commentId:{type:"number",description:"Comment id from read_comments."},text:{type:"string",description:"Reply body."}},required:["commentId","text"]},handler:(e,r)=>{let t=r.replyTo(e.commentId,{text:e.text});return t===null?{success:false,error:`Comment #${e.commentId} not found.`}:{success:true,data:`Reply ${t} added to comment ${e.commentId}.`}}},k={name:"resolve_comment",displayName:"Resolving comment",description:"Mark a comment as resolved (done).",inputSchema:{type:"object",properties:{commentId:{type:"number",description:"Comment id from read_comments."}},required:["commentId"]},handler:(e,r)=>(r.resolveComment(e.commentId),{success:true,data:`Comment ${e.commentId} resolved.`})},v={name:"scroll",displayName:"Scrolling",description:"Scroll the editor to a paragraph by paraId. Does not move the user's cursor.",inputSchema:{type:"object",properties:{paraId:{type:"string",description:"Paragraph id from read_document / find_text."}},required:["paraId"]},handler:(e,r)=>r.scrollTo(e.paraId)?{success:true,data:`Scrolled to ${e.paraId}.`}:{success:false,error:`paraId ${e.paraId} not found.`}},i=[h,g,l,m,u,y,f,b,I,c,p,x,k,v];function _(e,r,t){let n=i.find(a=>a.name===e);if(!n)return {success:false,error:`Unknown tool: ${e}`};try{return n.handler(r,t)}catch(a){return {success:false,error:a instanceof Error?a.message:String(a)}}}function N(e){let r=i.find(n=>n.name===e);if(r?.displayName)return r.displayName;let t=e.replace(/_/g," ");return t.charAt(0).toUpperCase()+t.slice(1)}function w(){return i.map(e=>({type:"function",function:{name:e.name,description:e.description,parameters:e.inputSchema}}))}exports.a=i;exports.b=_;exports.c=N;exports.d=w;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import {d,e,k as k$1,l,b,i,h,c,j,g as g$1,a}from'./chunk-AU3KR5IN.mjs';import {parseDocx}from'@zeke-02/docx-editor-core/headless';function g(o,e){let{paragraphIndex:t,author:n="AI",text:s,search:a}=e,r=b(o,t),i$1=(o.comments??[]).map(m=>m.id),p=i$1.length>0?Math.max(...i$1)+1:1,c={id:p,author:n,date:new Date().toISOString(),content:[{type:"paragraph",content:[{type:"run",content:[{type:"text",text:s}]}],formatting:{}}]};if(o.comments||(o.comments=[]),o.comments.push(c),a){let m=i(r,a,t);r.content.splice(m.endRunIndex+1,0,{type:"commentRangeEnd",id:p}),r.content.splice(m.startRunIndex,0,{type:"commentRangeStart",id:p});}else r.content.unshift({type:"commentRangeStart",id:p}),r.content.push({type:"commentRangeEnd",id:p});return p}function y(o,e,t){let n=o.comments??[];if(!n.find(p=>p.id===e))throw new h(e);let a=n.map(p=>p.id),r=Math.max(...a)+1,i={id:r,author:t.author??"AI",date:new Date().toISOString(),parentId:e,content:[{type:"paragraph",content:[{type:"run",content:[{type:"text",text:t.text}]}],formatting:{}}]};return n.push(i),r}function k(o,e){let t=o.comments??[],n=t.find(r=>r.id===e);if(!n)throw new h(e);let s=n.parentId!==void 0,a=new Set([e]);if(!s)for(let r of t)r.parentId===e&&a.add(r.id);o.comments=t.filter(r=>!a.has(r.id)),!s&&c(o,r=>{for(let i=r.content.length-1;i>=0;i--){let p=r.content[i];(p.type==="commentRangeStart"||p.type==="commentRangeEnd")&&p.id===e&&r.content.splice(i,1);}});}function C(o,e){if(!z(o,e,"accept"))throw new g$1(e)}function I(o,e){if(!z(o,e,"reject"))throw new g$1(e)}function E(o){return F(o,"accept")}function S(o){return F(o,"reject")}function F(o,e){let t=0;return c(o,n=>{for(let s=n.content.length-1;s>=0;s--){let a$1=n.content[s];a(a$1)&&(M(n,s,a$1,e),t++);}}),t}function z(o,e,t){let n=false;return c(o,s=>{for(let a$1=s.content.length-1;a$1>=0;a$1--){let r=s.content[a$1];a(r)&&r.info.id===e&&(M(s,a$1,r,t),n=true);}if(n)return false}),n}function M(o,e,t,n){if(t.type==="insertion"&&n==="accept"||t.type==="deletion"&&n==="reject"||t.type==="moveTo"&&n==="accept"||t.type==="moveFrom"&&n==="reject"){let a=t.content;o.content.splice(e,1,...a);}else o.content.splice(e,1);}function x(o,e){let{paragraphIndex:t,search:n,author:s="AI",replaceWith:a}=e,r=b(o,t),{startIndex:i,endIndex:p}=j(r,n,t),c=new Date().toISOString(),m=w(o),h=r.content.slice(i,p+1),R={type:"deletion",info:{id:m,author:s,date:c},content:h},v={type:"insertion",info:{id:m+1,author:s,date:c},content:[{type:"run",content:[{type:"text",text:a}]}]};r.content.splice(i,p-i+1,R,v);}function W(o,e){let{paragraphIndex:t,author:n="AI",insertText:s,position:a="after",search:r}=e,i=b(o,t),p=new Date().toISOString(),m={type:"insertion",info:{id:w(o),author:n,date:p},content:[{type:"run",content:[{type:"text",text:s}]}]};if(r){let{startIndex:h,endIndex:R}=j(i,r,t),v=a==="after"?R+1:h;i.content.splice(v,0,m);}else a==="before"?i.content.unshift(m):i.content.push(m);}function G(o,e){let{paragraphIndex:t,search:n,author:s="AI"}=e,a=b(o,t),{startIndex:r,endIndex:i}=j(a,n,t),p=new Date().toISOString(),c=w(o),m=a.content.slice(r,i+1),h={type:"deletion",info:{id:c,author:s,date:p},content:m};a.content.splice(r,i-r+1,h);}var T=new WeakMap;function w(o){let e=T.get(o);e===void 0&&(e=0,c(o,n=>{for(let s of n.content)a(s)&&(e=Math.max(e,s.info.id));}));let t=e+1;return T.set(o,t+1),t}function H(o,e,t="AI"){let n=[],s=0,a=0,r=0,i=0,p=0;for(let c of e.accept??[])try{C(o,c),s++;}catch(m){n.push({operation:"accept",id:c,error:m.message});}for(let c of e.reject??[])try{I(o,c),a++;}catch(m){n.push({operation:"reject",id:c,error:m.message});}for(let c of e.comments??[])try{g(o,{...c,author:c.author??t}),r++;}catch(m){n.push({operation:"comment",search:c.search,error:m.message});}for(let c of e.replies??[])try{y(o,c.commentId,{author:c.author??t,text:c.text}),i++;}catch(m){n.push({operation:"reply",id:c.commentId,error:m.message});}for(let c of e.proposals??[])try{x(o,{...c,author:c.author??t}),p++;}catch(m){n.push({operation:"proposal",search:c.search,error:m.message});}return {accepted:s,rejected:a,commentsAdded:r,repliesAdded:i,proposalsAdded:p,errors:n}}var L=class o{constructor(e,t="AI",n){let s=n??e.originalBuffer,{originalBuffer:a,...r}=e;this.doc=structuredClone(r),s&&(this.doc.originalBuffer=s),this.author=t;}static async fromBuffer(e,t="AI"){let n=await parseDocx(e,{preloadFonts:false});return new o(n,t,e)}get body(){return this.doc.package.document}resolveAuthor(e){return e??this.author}getContent(e){return d(this.body,e)}getContentAsText(e$1){return e(d(this.body,e$1))}getChanges(e){return k$1(this.body,e)}getComments(e){return l(this.body,e)}addComment(e,t){let n=typeof e=="number"?{paragraphIndex:e,text:t,author:this.author}:{...e,author:this.resolveAuthor(e.author)};return g(this.body,n)}replyTo(e,t){let n=typeof t=="string"?{text:t,author:this.author}:{...t,author:this.resolveAuthor(t.author)};return y(this.body,e,n)}removeComment(e){k(this.body,e);}replace(e,t,n){let s=typeof e=="number"?{paragraphIndex:e,search:t,replaceWith:n,author:this.author}:{...e,author:this.resolveAuthor(e.author)};x(this.body,s);}proposeReplacement(e){this.replace(e);}proposeInsertion(e){W(this.body,{...e,author:this.resolveAuthor(e.author)});}proposeDeletion(e){G(this.body,{...e,author:this.resolveAuthor(e.author)});}acceptChange(e){C(this.body,e);}rejectChange(e){I(this.body,e);}acceptAll(){return E(this.body)}rejectAll(){return S(this.body)}applyReview(e){return H(this.body,e,this.author)}toDocument(){return this.doc}async toBuffer(){if(!this.doc.originalBuffer)throw new Error("Cannot create buffer: no original DOCX buffer was provided. Use DocxReviewer.fromBuffer() or pass originalBuffer to the constructor.");let{repackDocx:e}=await import('@zeke-02/docx-editor-core/headless');return e(this.doc)}};export{L as a};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
'use strict';var chunk2RGRAPLW_js=require('./chunk-2RGRAPLW.js'),headless=require('@zeke-02/docx-editor-core/headless');function g(o,e){let{paragraphIndex:t,author:n="AI",text:s,search:a}=e,r=chunk2RGRAPLW_js.b(o,t),i=(o.comments??[]).map(m=>m.id),p=i.length>0?Math.max(...i)+1:1,c={id:p,author:n,date:new Date().toISOString(),content:[{type:"paragraph",content:[{type:"run",content:[{type:"text",text:s}]}],formatting:{}}]};if(o.comments||(o.comments=[]),o.comments.push(c),a){let m=chunk2RGRAPLW_js.i(r,a,t);r.content.splice(m.endRunIndex+1,0,{type:"commentRangeEnd",id:p}),r.content.splice(m.startRunIndex,0,{type:"commentRangeStart",id:p});}else r.content.unshift({type:"commentRangeStart",id:p}),r.content.push({type:"commentRangeEnd",id:p});return p}function y(o,e,t){let n=o.comments??[];if(!n.find(p=>p.id===e))throw new chunk2RGRAPLW_js.h(e);let a=n.map(p=>p.id),r=Math.max(...a)+1,i={id:r,author:t.author??"AI",date:new Date().toISOString(),parentId:e,content:[{type:"paragraph",content:[{type:"run",content:[{type:"text",text:t.text}]}],formatting:{}}]};return n.push(i),r}function k(o,e){let t=o.comments??[],n=t.find(r=>r.id===e);if(!n)throw new chunk2RGRAPLW_js.h(e);let s=n.parentId!==void 0,a=new Set([e]);if(!s)for(let r of t)r.parentId===e&&a.add(r.id);o.comments=t.filter(r=>!a.has(r.id)),!s&&chunk2RGRAPLW_js.c(o,r=>{for(let i=r.content.length-1;i>=0;i--){let p=r.content[i];(p.type==="commentRangeStart"||p.type==="commentRangeEnd")&&p.id===e&&r.content.splice(i,1);}});}function C(o,e){if(!z(o,e,"accept"))throw new chunk2RGRAPLW_js.g(e)}function I(o,e){if(!z(o,e,"reject"))throw new chunk2RGRAPLW_js.g(e)}function E(o){return F(o,"accept")}function S(o){return F(o,"reject")}function F(o,e){let t=0;return chunk2RGRAPLW_js.c(o,n=>{for(let s=n.content.length-1;s>=0;s--){let a=n.content[s];chunk2RGRAPLW_js.a(a)&&(M(n,s,a,e),t++);}}),t}function z(o,e,t){let n=false;return chunk2RGRAPLW_js.c(o,s=>{for(let a=s.content.length-1;a>=0;a--){let r=s.content[a];chunk2RGRAPLW_js.a(r)&&r.info.id===e&&(M(s,a,r,t),n=true);}if(n)return false}),n}function M(o,e,t,n){if(t.type==="insertion"&&n==="accept"||t.type==="deletion"&&n==="reject"||t.type==="moveTo"&&n==="accept"||t.type==="moveFrom"&&n==="reject"){let a=t.content;o.content.splice(e,1,...a);}else o.content.splice(e,1);}function x(o,e){let{paragraphIndex:t,search:n,author:s="AI",replaceWith:a}=e,r=chunk2RGRAPLW_js.b(o,t),{startIndex:i,endIndex:p}=chunk2RGRAPLW_js.j(r,n,t),c=new Date().toISOString(),m=w(o),h=r.content.slice(i,p+1),R={type:"deletion",info:{id:m,author:s,date:c},content:h},v={type:"insertion",info:{id:m+1,author:s,date:c},content:[{type:"run",content:[{type:"text",text:a}]}]};r.content.splice(i,p-i+1,R,v);}function W(o,e){let{paragraphIndex:t,author:n="AI",insertText:s,position:a="after",search:r}=e,i=chunk2RGRAPLW_js.b(o,t),p=new Date().toISOString(),m={type:"insertion",info:{id:w(o),author:n,date:p},content:[{type:"run",content:[{type:"text",text:s}]}]};if(r){let{startIndex:h,endIndex:R}=chunk2RGRAPLW_js.j(i,r,t),v=a==="after"?R+1:h;i.content.splice(v,0,m);}else a==="before"?i.content.unshift(m):i.content.push(m);}function G(o,e){let{paragraphIndex:t,search:n,author:s="AI"}=e,a=chunk2RGRAPLW_js.b(o,t),{startIndex:r,endIndex:i}=chunk2RGRAPLW_js.j(a,n,t),p=new Date().toISOString(),c=w(o),m=a.content.slice(r,i+1),h={type:"deletion",info:{id:c,author:s,date:p},content:m};a.content.splice(r,i-r+1,h);}var T=new WeakMap;function w(o){let e=T.get(o);e===void 0&&(e=0,chunk2RGRAPLW_js.c(o,n=>{for(let s of n.content)chunk2RGRAPLW_js.a(s)&&(e=Math.max(e,s.info.id));}));let t=e+1;return T.set(o,t+1),t}function H(o,e,t="AI"){let n=[],s=0,a=0,r=0,i=0,p=0;for(let c of e.accept??[])try{C(o,c),s++;}catch(m){n.push({operation:"accept",id:c,error:m.message});}for(let c of e.reject??[])try{I(o,c),a++;}catch(m){n.push({operation:"reject",id:c,error:m.message});}for(let c of e.comments??[])try{g(o,{...c,author:c.author??t}),r++;}catch(m){n.push({operation:"comment",search:c.search,error:m.message});}for(let c of e.replies??[])try{y(o,c.commentId,{author:c.author??t,text:c.text}),i++;}catch(m){n.push({operation:"reply",id:c.commentId,error:m.message});}for(let c of e.proposals??[])try{x(o,{...c,author:c.author??t}),p++;}catch(m){n.push({operation:"proposal",search:c.search,error:m.message});}return {accepted:s,rejected:a,commentsAdded:r,repliesAdded:i,proposalsAdded:p,errors:n}}var L=class o{constructor(e,t="AI",n){let s=n??e.originalBuffer,{originalBuffer:a,...r}=e;this.doc=structuredClone(r),s&&(this.doc.originalBuffer=s),this.author=t;}static async fromBuffer(e,t="AI"){let n=await headless.parseDocx(e,{preloadFonts:false});return new o(n,t,e)}get body(){return this.doc.package.document}resolveAuthor(e){return e??this.author}getContent(e){return chunk2RGRAPLW_js.d(this.body,e)}getContentAsText(e){return chunk2RGRAPLW_js.e(chunk2RGRAPLW_js.d(this.body,e))}getChanges(e){return chunk2RGRAPLW_js.k(this.body,e)}getComments(e){return chunk2RGRAPLW_js.l(this.body,e)}addComment(e,t){let n=typeof e=="number"?{paragraphIndex:e,text:t,author:this.author}:{...e,author:this.resolveAuthor(e.author)};return g(this.body,n)}replyTo(e,t){let n=typeof t=="string"?{text:t,author:this.author}:{...t,author:this.resolveAuthor(t.author)};return y(this.body,e,n)}removeComment(e){k(this.body,e);}replace(e,t,n){let s=typeof e=="number"?{paragraphIndex:e,search:t,replaceWith:n,author:this.author}:{...e,author:this.resolveAuthor(e.author)};x(this.body,s);}proposeReplacement(e){this.replace(e);}proposeInsertion(e){W(this.body,{...e,author:this.resolveAuthor(e.author)});}proposeDeletion(e){G(this.body,{...e,author:this.resolveAuthor(e.author)});}acceptChange(e){C(this.body,e);}rejectChange(e){I(this.body,e);}acceptAll(){return E(this.body)}rejectAll(){return S(this.body)}applyReview(e){return H(this.body,e,this.author)}toDocument(){return this.doc}async toBuffer(){if(!this.doc.originalBuffer)throw new Error("Cannot create buffer: no original DOCX buffer was provided. Use DocxReviewer.fromBuffer() or pass originalBuffer to the constructor.");let{repackDocx:e}=await import('@zeke-02/docx-editor-core/headless');return e(this.doc)}};exports.a=L;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
.ai-ctx-backdrop[data-v-c30da7a7]{z-index:499;position:fixed;inset:0}.ai-ctx-menu[data-v-c30da7a7]{background:#fff;border:1px solid #d1d5db;border-radius:8px;min-width:200px;padding:4px 0;box-shadow:0 4px 16px #00000024}.ai-ctx-menu__header[data-v-c30da7a7]{color:#6b7280;text-transform:uppercase;letter-spacing:.04em;padding:6px 14px;font-size:11px;font-weight:600}.ai-ctx-menu__item[data-v-c30da7a7]{cursor:pointer;color:#1f2937;text-align:left;background:0 0;border:none;align-items:center;gap:10px;width:100%;padding:7px 14px;font-size:13px;display:flex}.ai-ctx-menu__item[data-v-c30da7a7]:hover{background:#f3f4f6}.ai-ctx-menu__icon[data-v-c30da7a7]{text-align:center;width:18px;font-size:14px}.ai-ctx-menu__label[data-v-c30da7a7]{flex:1}.ai-ctx-menu__divider[data-v-c30da7a7]{background:#e5e7eb;height:1px;margin:4px 10px}.ai-ctx-menu__custom[data-v-c30da7a7]{padding:6px 10px}.ai-ctx-menu__input[data-v-c30da7a7]{border:1px solid #d1d5db;border-radius:4px;outline:none;width:100%;padding:6px 8px;font-size:12px}.ai-ctx-menu__input[data-v-c30da7a7]:focus{border-color:#3b82f6}.ai-preview[data-v-1226b741]{background:#fff;border:1px solid #d1d5db;border-radius:8px;width:420px;max-width:90vw;overflow:hidden;box-shadow:0 4px 16px #0000001f}.ai-preview__header[data-v-1226b741]{background:#f0f4ff;border-bottom:1px solid #d0daf0;justify-content:space-between;align-items:center;padding:10px 14px;display:flex}.ai-preview__title[data-v-1226b741]{color:#1557b0;font-size:13px;font-weight:600}.ai-preview__close[data-v-1226b741]{cursor:pointer;color:#6b7280;background:0 0;border:none;font-size:14px}.ai-preview__loading[data-v-1226b741]{color:#6b7280;align-items:center;gap:10px;padding:24px 14px;font-size:13px;display:flex}.ai-preview__spinner[data-v-1226b741]{border:2px solid #e5e7eb;border-top-color:#3b82f6;border-radius:50%;width:16px;height:16px;animation:.8s linear infinite spin-1226b741}@keyframes spin-1226b741{to{transform:rotate(360deg)}}.ai-preview__error[data-v-1226b741]{color:#dc2626;align-items:center;gap:8px;padding:16px 14px;font-size:13px;display:flex}.ai-preview__retry[data-v-1226b741]{cursor:pointer;background:#fff;border:1px solid #d1d5db;border-radius:3px;padding:4px 10px;font-size:12px}.ai-preview__content[data-v-1226b741]{padding:12px 14px}.ai-preview__diff-label[data-v-1226b741]{color:#6b7280;text-transform:uppercase;margin-bottom:4px;font-size:11px;font-weight:600}.ai-preview__diff-text[data-v-1226b741]{border-radius:4px;margin-bottom:10px;padding:8px 10px;font-size:13px;line-height:1.5}.ai-preview__diff-text--old[data-v-1226b741]{color:#991b1b;background:#fef2f2}.ai-preview__diff-text--new[data-v-1226b741]{color:#166534;background:#f0fdf4}.ai-preview__result[data-v-1226b741]{color:#1f2937;font-size:13px;line-height:1.5}.ai-preview__textarea[data-v-1226b741]{resize:vertical;border:1px solid #d1d5db;border-radius:4px;outline:none;width:100%;margin-top:8px;padding:8px;font-family:inherit;font-size:13px}.ai-preview__textarea[data-v-1226b741]:focus{border-color:#3b82f6}.ai-preview__footer[data-v-1226b741]{border-top:1px solid #e5e7eb;justify-content:flex-end;gap:6px;padding:10px 14px;display:flex}.ai-preview__btn[data-v-1226b741]{cursor:pointer;background:#fff;border:1px solid #d1d5db;border-radius:4px;padding:5px 14px;font-size:12px;font-weight:500}.ai-preview__btn[data-v-1226b741]:hover{background:#f3f4f6}.ai-preview__btn--primary[data-v-1226b741]{color:#fff;background:#1a73e8;border-color:#1a73e8}.ai-preview__btn--primary[data-v-1226b741]:hover{background:#1557b0}
|
|
2
|
+
/*$vite$:1*/
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @zeke-02/docx-editor-agents
|
|
3
|
+
*
|
|
4
|
+
* Word-like API for AI document review.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```ts
|
|
8
|
+
* const reviewer = await DocxReviewer.fromBuffer(buffer, 'AI Reviewer');
|
|
9
|
+
*
|
|
10
|
+
* // Read
|
|
11
|
+
* const text = reviewer.getContentAsText();
|
|
12
|
+
*
|
|
13
|
+
* // Comment on a paragraph
|
|
14
|
+
* reviewer.addComment(5, 'Liability cap seems too low.');
|
|
15
|
+
*
|
|
16
|
+
* // Replace text (creates tracked change)
|
|
17
|
+
* reviewer.replace(5, '$50k', '$500k');
|
|
18
|
+
*
|
|
19
|
+
* // Or batch from LLM JSON response
|
|
20
|
+
* reviewer.applyReview({
|
|
21
|
+
* comments: [{ paragraphIndex: 5, text: 'Too low.' }],
|
|
22
|
+
* proposals: [{ paragraphIndex: 5, search: '$50k', replaceWith: '$500k' }],
|
|
23
|
+
* });
|
|
24
|
+
*
|
|
25
|
+
* const output = await reviewer.toBuffer();
|
|
26
|
+
* ```
|
|
27
|
+
*
|
|
28
|
+
* @packageDocumentation
|
|
29
|
+
* @public
|
|
30
|
+
*/
|
|
31
|
+
import { G as GetContentOptions, C as ContentBlock, a as CommentFilter, R as ReviewComment, b as ChangeFilter, c as ReviewChange, F as FoundMatch, S as SelectionInfo, A as AddCommentByParaIdOptions, d as ReplyOptions, P as ProposeChangeOptions, e as ApplyFormattingOptions, f as SetParagraphStyleOptions, g as PageContent, h as ContentChangeEvent, i as SelectionChangeEvent } from './server-uWvnaIh-.mjs';
|
|
32
|
+
export { j as AgentToolDefinition, k as AgentToolResult, B as BatchError, l as BatchResult, m as BatchReviewOptions, D as DocxReviewer, n as agentTools, o as createReviewerBridge, p as executeToolCall, q as getToolSchemas } from './server-uWvnaIh-.mjs';
|
|
33
|
+
import '@zeke-02/docx-editor-core/headless';
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Error classes for @zeke-02/docx-editor-agents
|
|
37
|
+
*/
|
|
38
|
+
declare class TextNotFoundError extends Error {
|
|
39
|
+
constructor(search: string, paragraphIndex?: number);
|
|
40
|
+
}
|
|
41
|
+
declare class ChangeNotFoundError extends Error {
|
|
42
|
+
constructor(id: number);
|
|
43
|
+
}
|
|
44
|
+
declare class CommentNotFoundError extends Error {
|
|
45
|
+
constructor(id: number);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Formal Word JS API parity contract.
|
|
50
|
+
*
|
|
51
|
+
* This file declares what subset of Microsoft Word's Office.js JavaScript API
|
|
52
|
+
* (https://learn.microsoft.com/en-us/javascript/api/word) we mirror, **at the
|
|
53
|
+
* type level**. It is checked at compile time: `EditorBridge` must satisfy
|
|
54
|
+
* `WordCompatBridge` (verified via the static assertion at the bottom).
|
|
55
|
+
*
|
|
56
|
+
* The assertion is the source of truth. If you change the bridge surface and
|
|
57
|
+
* forget to update parity, typecheck breaks.
|
|
58
|
+
*
|
|
59
|
+
* ## What we mirror (✓)
|
|
60
|
+
*
|
|
61
|
+
* | Word JS API | Our equivalent |
|
|
62
|
+
* | ----------------------------------- | ------------------------------------- |
|
|
63
|
+
* | `Range` (stable handle) | `paraId: string` |
|
|
64
|
+
* | `body.search(text)` → Ranges | `findText(query, opts) → FoundMatch[]`|
|
|
65
|
+
* | `range.insertComment(text)` | `addComment({paraId, text, search?})` |
|
|
66
|
+
* | `comment.reply(text)` | `replyTo(commentId, {text})` |
|
|
67
|
+
* | `comment.resolved = true` | `resolveComment(commentId)` |
|
|
68
|
+
* | `range.insertText(text, location)` | `proposeChange({paraId, search, replaceWith})` (3 modes via empty-string semantics) |
|
|
69
|
+
* | `document.getSelection()` | `getSelection() → SelectionInfo|null` |
|
|
70
|
+
* | `range.scrollIntoView()` | `scrollTo(paraId)` |
|
|
71
|
+
* | `commentCollection.getItems()` | `getComments(filter?)` |
|
|
72
|
+
* | `body.paragraphs.getItems()` | `getContent(opts?)` |
|
|
73
|
+
* | `document.body.text` | `getContentAsText(opts?)` |
|
|
74
|
+
* | `revisionCollection.getItems()` | `getChanges(filter?)` |
|
|
75
|
+
* | `Document.onContentChanged.add(...)`| `onContentChange(listener)` |
|
|
76
|
+
* | `Document.onSelectionChanged.add()` | `onSelectionChange(listener)` |
|
|
77
|
+
* | `Range.font.bold` / `italic` / `color` / `size` / `name` | `applyFormatting({paraId, search?, marks})` |
|
|
78
|
+
* | `ParagraphFormat.style` / `applyStyle(...)` | `setParagraphStyle({paraId, styleId})` |
|
|
79
|
+
*
|
|
80
|
+
* ## Beyond Word's surface (paged-document affordances)
|
|
81
|
+
*
|
|
82
|
+
* - `getPage(n)` / `getPages({from, to})` / `getTotalPages()` — Word's JS API
|
|
83
|
+
* doesn't model pages as first-class addressable units. We do, because the
|
|
84
|
+
* editor is paged. Backed by the layout-painter's page boundary state.
|
|
85
|
+
*
|
|
86
|
+
* ## Differences (intentional, documented)
|
|
87
|
+
*
|
|
88
|
+
* - All "insertText" overloads collapse into `proposeChange` with empty-string
|
|
89
|
+
* semantics: replaceWith="" deletes; search="" inserts at paragraph end;
|
|
90
|
+
* both non-empty replaces. Word has separate `insertText(...,'Replace')`,
|
|
91
|
+
* `insertText(...,'Before')`, etc.; we found three modes were enough and
|
|
92
|
+
* serialize cleaner for LLM tool calls.
|
|
93
|
+
* - Tracked changes are always *suggestions* in our world. Word lets the
|
|
94
|
+
* range mutate directly; we always go through the tracked-change path so
|
|
95
|
+
* the human keeps the final say. (This matches the agent UX.)
|
|
96
|
+
* - Word's `Range.context.sync()` is unnecessary — every call is one PM
|
|
97
|
+
* transaction.
|
|
98
|
+
* - Word's `Range` is a stateful object. Ours is a plain `{paraId, search?}`
|
|
99
|
+
* JSON value, so it survives JSON.stringify and works for tool calls / MCP.
|
|
100
|
+
*
|
|
101
|
+
* ## Out of scope (gaps we deliberately don't implement)
|
|
102
|
+
*
|
|
103
|
+
* - Paragraph creation (`body.insertParagraph`). Out of scope for v1.
|
|
104
|
+
* - Table mutation (insert row/col, delete cell). Read-only.
|
|
105
|
+
* - Headers / footers / sections.
|
|
106
|
+
* - `Range.getOoxml()` / `getHtml()`. Plain text only.
|
|
107
|
+
* - `customXmlParts` / `contentControls`.
|
|
108
|
+
* - Accept / reject tracked changes. Human-only by design.
|
|
109
|
+
*
|
|
110
|
+
* Future versions can grow these by extending this interface — typecheck
|
|
111
|
+
* will then enforce the new contract.
|
|
112
|
+
*/
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* The formal Word-JS-API parity surface. Each method maps to one or more
|
|
116
|
+
* Word API methods (named in the JSDoc above each member).
|
|
117
|
+
*
|
|
118
|
+
* If you change the EditorBridge surface, this interface must change too —
|
|
119
|
+
* the static assertion at the bottom of the file enforces it.
|
|
120
|
+
*/
|
|
121
|
+
interface WordCompatBridge {
|
|
122
|
+
/** Word: `document.body.text` (stringified, indexed lines). */
|
|
123
|
+
getContentAsText(options?: GetContentOptions): string;
|
|
124
|
+
/** Word: `body.paragraphs.getItems()`. */
|
|
125
|
+
getContent(options?: GetContentOptions): ContentBlock[];
|
|
126
|
+
/** Word: `commentCollection.getItems()`. */
|
|
127
|
+
getComments(filter?: CommentFilter): ReviewComment[];
|
|
128
|
+
/** Word: `revisionCollection.getItems()`. */
|
|
129
|
+
getChanges(filter?: ChangeFilter): ReviewChange[];
|
|
130
|
+
/** Word: `body.search(text)` returning Range[]. */
|
|
131
|
+
findText(query: string, options?: {
|
|
132
|
+
caseSensitive?: boolean;
|
|
133
|
+
limit?: number;
|
|
134
|
+
}): FoundMatch[];
|
|
135
|
+
/** Word: `document.getSelection()`. */
|
|
136
|
+
getSelection(): SelectionInfo | null;
|
|
137
|
+
/** Word: `range.insertComment(text)`. Anchored by paraId (Range handle). */
|
|
138
|
+
addComment(options: AddCommentByParaIdOptions): number | null;
|
|
139
|
+
/** Word: `comment.reply(text)`. */
|
|
140
|
+
replyTo(commentId: number, options: ReplyOptions): number | null;
|
|
141
|
+
/** Word: `comment.resolved = true`. */
|
|
142
|
+
resolveComment(commentId: number): void;
|
|
143
|
+
/**
|
|
144
|
+
* Word: `range.insertText(text, location)` collapsed into one verb.
|
|
145
|
+
* - replacement: search non-empty, replaceWith non-empty
|
|
146
|
+
* - deletion: search non-empty, replaceWith ""
|
|
147
|
+
* - insertion: search "", replaceWith non-empty (paragraph end)
|
|
148
|
+
*/
|
|
149
|
+
proposeChange(options: ProposeChangeOptions): boolean;
|
|
150
|
+
/**
|
|
151
|
+
* Word: `range.font.bold = true` / `range.font.italic = true` / etc.
|
|
152
|
+
* Applied to a paragraph or to a unique phrase within it. Direct edit,
|
|
153
|
+
* not a tracked change.
|
|
154
|
+
*/
|
|
155
|
+
applyFormatting(options: ApplyFormattingOptions): boolean;
|
|
156
|
+
/** Word: `paragraph.styleBuiltIn = ...` / `paragraph.style = 'Heading 1'`. */
|
|
157
|
+
setParagraphStyle(options: SetParagraphStyleOptions): boolean;
|
|
158
|
+
/**
|
|
159
|
+
* Read one rendered page (1-indexed). Word's JS API does not expose pages
|
|
160
|
+
* as first-class objects; we do because the editor is paged.
|
|
161
|
+
*/
|
|
162
|
+
getPage(pageNumber: number): PageContent | null;
|
|
163
|
+
/** Read a range of rendered pages (1-indexed, inclusive). */
|
|
164
|
+
getPages(options: {
|
|
165
|
+
from: number;
|
|
166
|
+
to: number;
|
|
167
|
+
}): PageContent[];
|
|
168
|
+
/** Total number of pages currently rendered. */
|
|
169
|
+
getTotalPages(): number;
|
|
170
|
+
/** Word: `range.scrollIntoView()`. */
|
|
171
|
+
scrollTo(paraId: string): boolean;
|
|
172
|
+
/** Word: `Document.onContentChanged.add(handler)`. Returns unsubscribe. */
|
|
173
|
+
onContentChange(listener: (event: ContentChangeEvent) => void): () => void;
|
|
174
|
+
/** Word: `Document.onSelectionChanged.add(handler)`. Returns unsubscribe. */
|
|
175
|
+
onSelectionChange(listener: (event: SelectionChangeEvent) => void): () => void;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
export { ChangeNotFoundError, CommentNotFoundError, ContentBlock, GetContentOptions, ReviewChange, ReviewComment, TextNotFoundError, type WordCompatBridge };
|