@eigenpal/docx-editor-agents 1.0.1 → 1.0.3

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 (39) hide show
  1. package/README.md +1 -1
  2. package/dist/ai-sdk/vue.js +1 -1
  3. package/dist/ai-sdk/vue.mjs +27 -30
  4. package/dist/bridge.d.mts +1 -1
  5. package/dist/bridge.d.ts +1 -1
  6. package/dist/bridge.js +1 -1
  7. package/dist/bridge.mjs +1 -1
  8. package/dist/chunk-7C5RGTQY.js +71 -0
  9. package/dist/{chunk-JH5VOTEK.js → chunk-DDW6L3LZ.js} +2 -2
  10. package/dist/{chunk-DZYPK4JQ.mjs → chunk-JQBSMHZA.mjs} +1 -1
  11. package/dist/{chunk-TFIRB2ZB.js → chunk-MOAJJKKG.js} +3 -3
  12. package/dist/{chunk-BJPVVT5W.mjs → chunk-NGMVN6QV.mjs} +1 -1
  13. package/dist/chunk-OHVUJUDE.mjs +71 -0
  14. package/dist/{chunk-DEDOV3KL.mjs → chunk-PSSPSJR4.mjs} +1 -1
  15. package/dist/{chunk-LSPYEWWJ.js → chunk-SCYZRJWI.js} +1 -1
  16. package/dist/docx-editor-agents.css +2 -1
  17. package/dist/{headless-ULW7Q5F4.js → headless-3IX5WQEZ.js} +1 -1
  18. package/dist/{headless-J5TF46GZ.mjs → headless-V7JUUMG6.mjs} +1 -1
  19. package/dist/index.d.mts +2 -2
  20. package/dist/index.d.ts +2 -2
  21. package/dist/index.js +1 -1
  22. package/dist/index.mjs +1 -1
  23. package/dist/mcp.d.mts +1 -1
  24. package/dist/mcp.d.ts +1 -1
  25. package/dist/react.d.mts +2 -2
  26. package/dist/react.d.ts +2 -2
  27. package/dist/react.js +1 -1
  28. package/dist/react.mjs +1 -1
  29. package/dist/{server-B7RHNVSu.d.mts → server-CGxgyhy-.d.mts} +25 -0
  30. package/dist/{server-B7RHNVSu.d.ts → server-CGxgyhy-.d.ts} +25 -0
  31. package/dist/server.d.mts +1 -1
  32. package/dist/server.d.ts +1 -1
  33. package/dist/server.js +1 -1
  34. package/dist/server.mjs +1 -1
  35. package/dist/vue.js +12 -13
  36. package/dist/vue.mjs +1983 -1829
  37. package/package.json +3 -3
  38. package/dist/chunk-DQH7AV5E.js +0 -71
  39. package/dist/chunk-NX2KNBB6.mjs +0 -71
package/dist/vue.mjs CHANGED
@@ -1,1857 +1,2011 @@
1
- import { defineComponent as _, computed as S, ref as T, watch as N, onBeforeUnmount as ye, openBlock as h, createElementBlock as f, withKeys as D, normalizeStyle as y, normalizeClass as j, createElementVNode as p, renderSlot as E, toDisplayString as v, createCommentVNode as I, createTextVNode as xe, Fragment as H, renderList as z, onMounted as be, nextTick as te, createBlock as ne, withModifiers as $, Teleport as ve, withDirectives as ae, vModelText as oe, unref as we } from "vue";
2
- import { getRunText as P, getHyperlinkText as re, isHeadingStyle as ke, parseHeadingLevel as Ie } from "@eigenpal/docx-editor-core/headless";
3
- const Se = { defaultTitle: "Assistant", close: "Close panel", resizeHandle: "Resize agent panel", thinking: "Assistant is thinking", composerPlaceholder: "Ask the assistant…", send: "Send", timeline: { working: "Working… {count, plural, one {# step} other {# steps}}", summary: "{count, plural, one {# step} other {# steps}}", earlier: "+ {count, plural, one {# earlier step} other {# earlier steps}}" } }, Ce = { header: "AI Actions", askAi: "Ask AI", rewrite: "Rewrite", expand: "Expand", summarize: "Summarize", translate: "Translate", explain: "Explain", fixGrammar: "Fix grammar", makeFormal: "Make formal", makeCasual: "Make casual", custom: "Custom", customPlaceholder: "Custom prompt…" }, $e = { defaultTitle: "AI Response", labels: { rewrite: "Rewrite", expand: "Expand", summarize: "Summary", translate: "Translation", explain: "Explanation", fixGrammar: "Grammar Fix", makeFormal: "Formal Version", makeCasual: "Casual Version", custom: "AI Response", askAi: "AI Response" }, loading: "Processing…", original: "Original:", suggested: "Suggested:", edit: "Edit", discard: "Discard", accept: "Accept", retry: "Retry", close: "Close" }, w = {
4
- agentPanel: Se,
5
- aiActions: Ce,
6
- aiPreview: $e
7
- }, Te = ["aria-hidden", "aria-label", "data-state"], Pe = ["aria-label", "aria-valuenow", "aria-valuemin", "aria-valuemax", "aria-valuetext"], _e = ["aria-label", "title"], R = "eigenpal:docx-editor:agentPanelWidth", Ae = 360, Le = 280, Me = 600, Bt = /* @__PURE__ */ _({
8
- __name: "AgentPanel",
9
- props: {
10
- title: { default: () => w.agentPanel.defaultTitle },
11
- closeLabel: { default: () => w.agentPanel.close },
12
- resizeHandleLabel: { default: () => w.agentPanel.resizeHandle },
13
- width: { default: void 0 },
14
- defaultWidth: { default: Ae },
15
- minWidth: { default: Le },
16
- maxWidth: { default: Me },
17
- closed: { type: Boolean, default: !1 },
18
- closable: { type: Boolean, default: !0 },
19
- className: { default: "" }
20
- },
21
- emits: ["close", "update:width"],
22
- setup(e, { emit: a }) {
23
- const n = e, t = a, o = S(() => n.width !== void 0);
24
- function r() {
25
- if (typeof window > "u") return n.defaultWidth;
26
- try {
27
- const k = window.localStorage.getItem(R);
28
- if (k) {
29
- const b = Number(k);
30
- if (Number.isFinite(b) && b >= n.minWidth && b <= n.maxWidth) return b;
31
- }
32
- } catch {
33
- }
34
- return n.defaultWidth;
35
- }
36
- const i = T(o.value ? n.width : r()), s = S(() => o.value ? n.width : i.value), d = T(!1);
37
- let c = null;
38
- N(
39
- () => n.closed,
40
- () => {
41
- c !== null && window.clearTimeout(c), d.value = !0, c = window.setTimeout(() => {
42
- d.value = !1, c = null;
43
- }, 260);
44
- },
45
- { flush: "post" }
46
- );
47
- let l = null;
48
- function u(k) {
49
- if (!l) return;
50
- const b = l.startX - k.clientX, C = Math.min(n.maxWidth, Math.max(n.minWidth, l.startWidth + b));
51
- l.lastWidth = C, o.value || (i.value = C), t("update:width", C);
52
- }
53
- function g() {
54
- if (!l) return;
55
- const k = l.lastWidth;
56
- if (l = null, document.removeEventListener("pointermove", u), document.removeEventListener("pointerup", g), !o.value)
57
- try {
58
- window.localStorage.setItem(R, String(k));
59
- } catch {
60
- }
61
- }
62
- function m(k) {
63
- k.preventDefault(), l = {
64
- startX: k.clientX,
65
- startWidth: s.value,
66
- lastWidth: s.value
67
- }, document.addEventListener("pointermove", u), document.addEventListener("pointerup", g);
68
- }
69
- function x(k) {
70
- n.closable && (k.stopPropagation(), t("close"));
71
- }
72
- function A(k) {
73
- let b = 0, C = null;
74
- const O = k.shiftKey ? 64 : 16;
75
- switch (k.key) {
76
- case "ArrowLeft":
77
- b = O;
78
- break;
79
- case "ArrowRight":
80
- b = -O;
81
- break;
82
- case "Home":
83
- C = n.maxWidth;
84
- break;
85
- case "End":
86
- C = n.minWidth;
87
- break;
88
- default:
89
- return;
90
- }
91
- k.preventDefault();
92
- const B = C !== null ? C : Math.min(n.maxWidth, Math.max(n.minWidth, s.value + b));
93
- if (o.value || (i.value = B), t("update:width", B), !o.value)
94
- try {
95
- window.localStorage.setItem(R, String(B));
96
- } catch {
97
- }
98
- }
99
- ye(() => {
100
- document.removeEventListener("pointermove", u), document.removeEventListener("pointerup", g), c !== null && window.clearTimeout(c);
101
- });
102
- const ce = S(() => ({
103
- width: n.closed ? "0px" : `${s.value}px`,
104
- flex: n.closed ? "0 0 0px" : `0 0 ${s.value}px`,
105
- height: "calc(100% - 16px)",
106
- margin: n.closed ? "8px 0 8px 0" : "8px 8px 8px 12px",
107
- display: "flex",
108
- flexDirection: "column",
109
- background: "#ffffff",
110
- border: n.closed ? "1px solid transparent" : "1px solid #e3e3e3",
111
- borderRadius: "16px",
112
- boxShadow: n.closed ? "none" : "0 1px 2px rgba(60,64,67,0.05), 0 4px 12px rgba(60,64,67,0.08)",
113
- opacity: n.closed ? 0 : 1,
114
- pointerEvents: n.closed ? "none" : "auto",
115
- position: "relative",
116
- boxSizing: "border-box",
117
- minWidth: n.closed ? 0 : `${n.minWidth}px`,
118
- overflow: "hidden",
119
- fontFamily: "'Google Sans', 'Google Sans Text', system-ui, -apple-system, sans-serif",
120
- transition: d.value ? "flex-basis 220ms cubic-bezier(0.4, 0, 0.2, 1), width 220ms cubic-bezier(0.4, 0, 0.2, 1), margin 220ms cubic-bezier(0.4, 0, 0.2, 1), opacity 180ms ease, box-shadow 220ms ease, border-color 220ms ease" : "opacity 180ms ease, box-shadow 220ms ease, border-color 220ms ease"
121
- })), ue = {
122
- position: "absolute",
123
- left: "-3px",
124
- top: 0,
125
- bottom: 0,
126
- width: "6px",
127
- cursor: "col-resize",
128
- touchAction: "none",
129
- zIndex: 1
130
- }, pe = {
131
- display: "flex",
132
- alignItems: "center",
133
- gap: "10px",
134
- padding: "14px 16px 10px",
135
- flex: "0 0 auto",
136
- background: "#ffffff"
137
- }, me = {
138
- display: "inline-flex",
139
- alignItems: "center",
140
- color: "#0b57d0"
141
- }, he = {
142
- flex: 1,
143
- fontSize: "15px",
144
- fontWeight: 500,
145
- color: "#1f1f1f",
146
- letterSpacing: "0.1px",
147
- overflow: "hidden",
148
- textOverflow: "ellipsis",
149
- whiteSpace: "nowrap"
150
- }, ge = {
151
- border: "none",
152
- background: "transparent",
153
- padding: "6px",
154
- cursor: "pointer",
155
- display: "inline-flex",
156
- alignItems: "center",
157
- justifyContent: "center",
158
- color: "#444746",
159
- borderRadius: "999px",
160
- transition: "background 0.15s"
161
- }, fe = {
162
- flex: 1,
163
- minHeight: 0,
164
- overflow: "hidden",
165
- display: "flex",
166
- flexDirection: "column"
167
- };
168
- function q(k, b) {
169
- const C = b.currentTarget;
170
- C && (C.style.background = k ? "#f1f3f4" : "transparent");
171
- }
172
- return (k, b) => (h(), f("div", {
173
- class: j(["ep-agent-panel", e.className]),
174
- style: y(ce.value),
175
- "aria-hidden": e.closed,
176
- "aria-label": e.title,
177
- role: "complementary",
178
- "data-testid": "agent-panel",
179
- "data-state": e.closed ? "closed" : "open",
180
- onKeydown: D(x, ["esc"])
181
- }, [
182
- p("div", {
183
- role: "separator",
184
- "aria-orientation": "vertical",
185
- "aria-label": e.resizeHandleLabel,
186
- "aria-valuenow": s.value,
187
- "aria-valuemin": e.minWidth,
188
- "aria-valuemax": e.maxWidth,
189
- "aria-valuetext": `${s.value} pixels wide`,
190
- tabindex: "0",
191
- style: ue,
192
- "data-testid": "agent-panel-resize-handle",
193
- onPointerdown: m,
194
- onKeydown: A
195
- }, null, 40, Pe),
196
- p("div", { style: pe }, [
197
- p("span", { style: me }, [
198
- E(k.$slots, "icon", {}, () => [
199
- b[3] || (b[3] = p("svg", {
200
- viewBox: "0 -960 960 960",
201
- width: "22",
202
- height: "22",
203
- fill: "currentColor",
204
- "aria-hidden": "true"
205
- }, [
206
- p("path", { d: "m760-600-50-110-110-50 110-50 50-110 50 110 110 50-110 50-50 110Zm0 560-50-110-110-50 110-50 50-110 50 110 110 50-110 50-50 110ZM360-160 260-380 40-480l220-100 100-220 100 220 220 100-220 100-100 220Zm0-194 40-86 86-40-86-40-40-86-40 86-86 40 86 40 40 86Zm0-126Z" })
207
- ], -1))
208
- ])
209
- ]),
210
- p("span", { style: he }, v(e.title), 1),
211
- e.closable ? (h(), f("button", {
212
- key: 0,
213
- type: "button",
214
- "aria-label": e.closeLabel,
215
- title: e.closeLabel,
216
- "data-testid": "agent-panel-close",
217
- style: ge,
218
- onClick: b[0] || (b[0] = (C) => t("close")),
219
- onMouseenter: b[1] || (b[1] = (C) => q(!0, C)),
220
- onMouseleave: b[2] || (b[2] = (C) => q(!1, C))
221
- }, [...b[4] || (b[4] = [
222
- p("svg", {
223
- viewBox: "0 -960 960 960",
224
- width: "18",
225
- height: "18",
226
- fill: "currentColor",
227
- "aria-hidden": "true"
228
- }, [
229
- p("path", { d: "m256-200-56-56 224-224-224-224 56-56 224 224 224-224 56 56-224 224 224 224-56 56-224-224-224 224Z" })
230
- ], -1)
231
- ])], 40, _e)) : I("", !0)
232
- ]),
233
- p("div", { style: fe }, [
234
- E(k.$slots, "default")
235
- ])
236
- ], 46, Te));
237
- }
1
+ import { Fragment as e, Teleport as t, computed as n, createBlock as r, createCommentVNode as i, createElementBlock as a, createElementVNode as o, createTextVNode as s, defineComponent as c, nextTick as l, normalizeClass as u, normalizeStyle as d, onBeforeUnmount as f, onMounted as p, openBlock as m, ref as h, renderList as g, renderSlot as _, toDisplayString as v, unref as y, vModelText as b, watch as x, withDirectives as S, withKeys as C, withModifiers as w } from "vue";
2
+ import { getHyperlinkText as T, getRunText as E, isHeadingStyle as D, parseHeadingLevel as O } from "@eigenpal/docx-editor-core/headless";
3
+ var k = {
4
+ _lang: "en",
5
+ agentPanel: {
6
+ defaultTitle: "Assistant",
7
+ close: "Close panel",
8
+ resizeHandle: "Resize agent panel",
9
+ thinking: "Assistant is thinking",
10
+ composerPlaceholder: "Ask the assistant…",
11
+ send: "Send",
12
+ timeline: {
13
+ working: "Working… {count, plural, one {# step} other {# steps}}",
14
+ summary: "{count, plural, one {# step} other {# steps}}",
15
+ earlier: "+ {count, plural, one {# earlier step} other {# earlier steps}}"
16
+ }
17
+ },
18
+ aiActions: {
19
+ header: "AI Actions",
20
+ askAi: "Ask AI",
21
+ rewrite: "Rewrite",
22
+ expand: "Expand",
23
+ summarize: "Summarize",
24
+ translate: "Translate",
25
+ explain: "Explain",
26
+ fixGrammar: "Fix grammar",
27
+ makeFormal: "Make formal",
28
+ makeCasual: "Make casual",
29
+ custom: "Custom",
30
+ customPlaceholder: "Custom prompt…"
31
+ },
32
+ aiPreview: {
33
+ defaultTitle: "AI Response",
34
+ labels: {
35
+ rewrite: "Rewrite",
36
+ expand: "Expand",
37
+ summarize: "Summary",
38
+ translate: "Translation",
39
+ explain: "Explanation",
40
+ fixGrammar: "Grammar Fix",
41
+ makeFormal: "Formal Version",
42
+ makeCasual: "Casual Version",
43
+ custom: "AI Response",
44
+ askAi: "AI Response"
45
+ },
46
+ loading: "Processing…",
47
+ original: "Original:",
48
+ suggested: "Suggested:",
49
+ edit: "Edit",
50
+ discard: "Discard",
51
+ accept: "Accept",
52
+ retry: "Retry",
53
+ close: "Close"
54
+ }
55
+ }, A = [
56
+ "aria-hidden",
57
+ "aria-label",
58
+ "data-state"
59
+ ], ee = [
60
+ "aria-label",
61
+ "aria-valuenow",
62
+ "aria-valuemin",
63
+ "aria-valuemax",
64
+ "aria-valuetext"
65
+ ], te = ["aria-label", "title"], j = "eigenpal:docx-editor:agentPanelWidth", M = /* @__PURE__ */ c({
66
+ __name: "AgentPanel",
67
+ props: {
68
+ title: { default: () => k.agentPanel.defaultTitle },
69
+ closeLabel: { default: () => k.agentPanel.close },
70
+ resizeHandleLabel: { default: () => k.agentPanel.resizeHandle },
71
+ width: { default: void 0 },
72
+ defaultWidth: { default: 360 },
73
+ minWidth: { default: 280 },
74
+ maxWidth: { default: 600 },
75
+ closed: {
76
+ type: Boolean,
77
+ default: !1
78
+ },
79
+ closable: {
80
+ type: Boolean,
81
+ default: !0
82
+ },
83
+ className: { default: "" }
84
+ },
85
+ emits: ["close", "update:width"],
86
+ setup(e, { emit: t }) {
87
+ let r = e, s = t, c = n(() => r.width !== void 0);
88
+ function l() {
89
+ if (typeof window > "u") return r.defaultWidth;
90
+ try {
91
+ let e = window.localStorage.getItem(j);
92
+ if (e) {
93
+ let t = Number(e);
94
+ if (Number.isFinite(t) && t >= r.minWidth && t <= r.maxWidth) return t;
95
+ }
96
+ } catch {}
97
+ return r.defaultWidth;
98
+ }
99
+ let p = h(c.value ? r.width : l()), g = n(() => c.value ? r.width : p.value), y = h(!1), b = null;
100
+ x(() => r.closed, () => {
101
+ b !== null && window.clearTimeout(b), y.value = !0, b = window.setTimeout(() => {
102
+ y.value = !1, b = null;
103
+ }, 260);
104
+ }, { flush: "post" });
105
+ let S = null;
106
+ function w(e) {
107
+ if (!S) return;
108
+ let t = S.startX - e.clientX, n = Math.min(r.maxWidth, Math.max(r.minWidth, S.startWidth + t));
109
+ S.lastWidth = n, c.value || (p.value = n), s("update:width", n);
110
+ }
111
+ function T() {
112
+ if (!S) return;
113
+ let e = S.lastWidth;
114
+ if (S = null, document.removeEventListener("pointermove", w), document.removeEventListener("pointerup", T), !c.value) try {
115
+ window.localStorage.setItem(j, String(e));
116
+ } catch {}
117
+ }
118
+ function E(e) {
119
+ e.preventDefault(), S = {
120
+ startX: e.clientX,
121
+ startWidth: g.value,
122
+ lastWidth: g.value
123
+ }, document.addEventListener("pointermove", w), document.addEventListener("pointerup", T);
124
+ }
125
+ function D(e) {
126
+ r.closable && (e.stopPropagation(), s("close"));
127
+ }
128
+ function O(e) {
129
+ let t = 0, n = null, i = e.shiftKey ? 64 : 16;
130
+ switch (e.key) {
131
+ case "ArrowLeft":
132
+ t = i;
133
+ break;
134
+ case "ArrowRight":
135
+ t = -i;
136
+ break;
137
+ case "Home":
138
+ n = r.maxWidth;
139
+ break;
140
+ case "End":
141
+ n = r.minWidth;
142
+ break;
143
+ default: return;
144
+ }
145
+ e.preventDefault();
146
+ let a = n === null ? Math.min(r.maxWidth, Math.max(r.minWidth, g.value + t)) : n;
147
+ if (c.value || (p.value = a), s("update:width", a), !c.value) try {
148
+ window.localStorage.setItem(j, String(a));
149
+ } catch {}
150
+ }
151
+ f(() => {
152
+ document.removeEventListener("pointermove", w), document.removeEventListener("pointerup", T), b !== null && window.clearTimeout(b);
153
+ });
154
+ let k = n(() => ({
155
+ width: r.closed ? "0px" : `${g.value}px`,
156
+ flex: r.closed ? "0 0 0px" : `0 0 ${g.value}px`,
157
+ height: "calc(100% - 16px)",
158
+ margin: r.closed ? "8px 0 8px 0" : "8px 8px 8px 12px",
159
+ display: "flex",
160
+ flexDirection: "column",
161
+ background: "#ffffff",
162
+ border: r.closed ? "1px solid transparent" : "1px solid #e3e3e3",
163
+ borderRadius: "16px",
164
+ boxShadow: r.closed ? "none" : "0 1px 2px rgba(60,64,67,0.05), 0 4px 12px rgba(60,64,67,0.08)",
165
+ opacity: +!r.closed,
166
+ pointerEvents: r.closed ? "none" : "auto",
167
+ position: "relative",
168
+ boxSizing: "border-box",
169
+ minWidth: r.closed ? 0 : `${r.minWidth}px`,
170
+ overflow: "hidden",
171
+ fontFamily: "'Google Sans', 'Google Sans Text', system-ui, -apple-system, sans-serif",
172
+ transition: y.value ? "flex-basis 220ms cubic-bezier(0.4, 0, 0.2, 1), width 220ms cubic-bezier(0.4, 0, 0.2, 1), margin 220ms cubic-bezier(0.4, 0, 0.2, 1), opacity 180ms ease, box-shadow 220ms ease, border-color 220ms ease" : "opacity 180ms ease, box-shadow 220ms ease, border-color 220ms ease"
173
+ })), M = {
174
+ position: "absolute",
175
+ left: "-3px",
176
+ top: 0,
177
+ bottom: 0,
178
+ width: "6px",
179
+ cursor: "col-resize",
180
+ touchAction: "none",
181
+ zIndex: 1
182
+ }, N = {
183
+ display: "flex",
184
+ alignItems: "center",
185
+ gap: "10px",
186
+ padding: "14px 16px 10px",
187
+ flex: "0 0 auto",
188
+ background: "#ffffff"
189
+ }, P = {
190
+ display: "inline-flex",
191
+ alignItems: "center",
192
+ color: "#0b57d0"
193
+ }, F = {
194
+ flex: 1,
195
+ fontSize: "15px",
196
+ fontWeight: 500,
197
+ color: "#1f1f1f",
198
+ letterSpacing: "0.1px",
199
+ overflow: "hidden",
200
+ textOverflow: "ellipsis",
201
+ whiteSpace: "nowrap"
202
+ }, I = {
203
+ border: "none",
204
+ background: "transparent",
205
+ padding: "6px",
206
+ cursor: "pointer",
207
+ display: "inline-flex",
208
+ alignItems: "center",
209
+ justifyContent: "center",
210
+ color: "#444746",
211
+ borderRadius: "999px",
212
+ transition: "background 0.15s"
213
+ }, L = {
214
+ flex: 1,
215
+ minHeight: 0,
216
+ overflow: "hidden",
217
+ display: "flex",
218
+ flexDirection: "column"
219
+ };
220
+ function R(e, t) {
221
+ let n = t.currentTarget;
222
+ n && (n.style.background = e ? "#f1f3f4" : "transparent");
223
+ }
224
+ return (t, n) => (m(), a("div", {
225
+ class: u(["ep-agent-panel", e.className]),
226
+ style: d(k.value),
227
+ "aria-hidden": e.closed,
228
+ "aria-label": e.title,
229
+ role: "complementary",
230
+ "data-testid": "agent-panel",
231
+ "data-state": e.closed ? "closed" : "open",
232
+ onKeydown: C(D, ["esc"])
233
+ }, [
234
+ o("div", {
235
+ role: "separator",
236
+ "aria-orientation": "vertical",
237
+ "aria-label": e.resizeHandleLabel,
238
+ "aria-valuenow": g.value,
239
+ "aria-valuemin": e.minWidth,
240
+ "aria-valuemax": e.maxWidth,
241
+ "aria-valuetext": `${g.value} pixels wide`,
242
+ tabindex: "0",
243
+ style: M,
244
+ "data-testid": "agent-panel-resize-handle",
245
+ onPointerdown: E,
246
+ onKeydown: O
247
+ }, null, 40, ee),
248
+ o("div", { style: N }, [
249
+ o("span", { style: P }, [_(t.$slots, "icon", {}, () => [n[3] ||= o("svg", {
250
+ viewBox: "0 -960 960 960",
251
+ width: "22",
252
+ height: "22",
253
+ fill: "currentColor",
254
+ "aria-hidden": "true"
255
+ }, [o("path", { d: "m760-600-50-110-110-50 110-50 50-110 50 110 110 50-110 50-50 110Zm0 560-50-110-110-50 110-50 50-110 50 110 110 50-110 50-50 110ZM360-160 260-380 40-480l220-100 100-220 100 220 220 100-220 100-100 220Zm0-194 40-86 86-40-86-40-40-86-40 86-86 40 86 40 40 86Zm0-126Z" })], -1)])]),
256
+ o("span", { style: F }, v(e.title), 1),
257
+ e.closable ? (m(), a("button", {
258
+ key: 0,
259
+ type: "button",
260
+ "aria-label": e.closeLabel,
261
+ title: e.closeLabel,
262
+ "data-testid": "agent-panel-close",
263
+ style: I,
264
+ onClick: n[0] ||= (e) => s("close"),
265
+ onMouseenter: n[1] ||= (e) => R(!0, e),
266
+ onMouseleave: n[2] ||= (e) => R(!1, e)
267
+ }, [...n[4] ||= [o("svg", {
268
+ viewBox: "0 -960 960 960",
269
+ width: "18",
270
+ height: "18",
271
+ fill: "currentColor",
272
+ "aria-hidden": "true"
273
+ }, [o("path", { d: "m256-200-56-56 224-224-224-224 56-56 224 224 224-224 56 56-224 224 224 224-56 56-224-224-224 224Z" })], -1)]], 40, te)) : i("", !0)
274
+ ]),
275
+ o("div", { style: L }, [_(t.$slots, "default")])
276
+ ], 46, A));
277
+ }
238
278
  });
239
- function De(e) {
240
- const a = {}, n = /(=\d+|\w+)\s*\{([^}]*)\}/g;
241
- let t;
242
- for (; (t = n.exec(e)) !== null; )
243
- a[t[1]] = t[2];
244
- return a;
279
+ //#endregion
280
+ //#region src/i18n/format-message.ts
281
+ function N(e) {
282
+ let t = {}, n = /(=\d+|\w+)\s*\{([^}]*)\}/g, r;
283
+ for (; (r = n.exec(e)) !== null;) t[r[1]] = r[2];
284
+ return t;
245
285
  }
246
- function F(e, a, n = "en") {
247
- return a ? e.replace(
248
- /\{(\w+),\s*plural,\s*((?:[^{}]|\{[^{}]*\})*)\}/g,
249
- (o, r, i) => {
250
- const s = Number(a[r]);
251
- if (isNaN(s)) return o;
252
- const d = De(i), c = d[`=${s}`];
253
- if (c !== void 0) return c.replace(/#/g, String(s));
254
- let l;
255
- try {
256
- l = new Intl.PluralRules(n).select(s);
257
- } catch {
258
- l = s === 1 ? "one" : "other";
259
- }
260
- return (d[l] ?? d.other ?? "").replace(/#/g, String(s));
261
- }
262
- ).replace(/\{(\w+)\}/g, (o, r) => {
263
- const i = a[r];
264
- return i !== void 0 ? String(i) : `{${r}}`;
265
- }) : e;
286
+ function P(e, t, n = "en") {
287
+ return t ? e.replace(/\{(\w+),\s*plural,\s*((?:[^{}]|\{[^{}]*\})*)\}/g, (e, r, i) => {
288
+ let a = Number(t[r]);
289
+ if (isNaN(a)) return e;
290
+ let o = N(i), s = o[`=${a}`];
291
+ if (s !== void 0) return s.replace(/#/g, String(a));
292
+ let c;
293
+ try {
294
+ c = new Intl.PluralRules(n).select(a);
295
+ } catch {
296
+ c = a === 1 ? "one" : "other";
297
+ }
298
+ return (o[c] ?? o.other ?? "").replace(/#/g, String(a));
299
+ }).replace(/\{(\w+)\}/g, (e, n) => {
300
+ let r = t[n];
301
+ return r === void 0 ? `{${n}}` : String(r);
302
+ }) : e;
266
303
  }
267
- function Ee(e) {
268
- const a = e.replace(/_/g, " ");
269
- return a.charAt(0).toUpperCase() + a.slice(1);
304
+ //#endregion
305
+ //#region src/agent-types.ts
306
+ function F(e) {
307
+ let t = e.replace(/_/g, " ");
308
+ return t.charAt(0).toUpperCase() + t.slice(1);
270
309
  }
271
- const Ne = ["aria-expanded"], We = {
272
- key: 1,
273
- style: { marginRight: "6px", display: "inline-flex" },
274
- "aria-hidden": "true"
275
- }, Be = /* @__PURE__ */ _({
276
- __name: "AgentTimeline",
277
- props: {
278
- toolCalls: {},
279
- streaming: { type: Boolean, default: !1 },
280
- maxVisibleCalls: { default: 3 },
281
- humanizeName: { type: Function, default: void 0 },
282
- workingLabel: { type: Function, default: void 0 },
283
- summaryLabel: { type: Function, default: void 0 },
284
- earlierLabel: { type: Function, default: void 0 }
285
- },
286
- setup(e) {
287
- const a = e, n = T(null), t = S(() => n.value !== null ? n.value : !!a.streaming), o = (g) => (a.humanizeName ?? Ee)(g), r = (g) => (a.earlierLabel ?? ((m) => F(w.agentPanel.timeline.earlier, { count: m })))(
288
- g
289
- ), i = S(() => {
290
- const g = a.toolCalls.length;
291
- return a.streaming ? (a.workingLabel ?? ((m) => F(w.agentPanel.timeline.working, { count: m })))(g) : (a.summaryLabel ?? ((m) => F(w.agentPanel.timeline.summary, { count: m })))(g);
292
- }), s = S(() => a.toolCalls.slice(-a.maxVisibleCalls)), d = S(() => Math.max(0, a.toolCalls.length - s.value.length)), c = S(() => ({
293
- fontSize: "12px",
294
- color: "#5f6368",
295
- transition: "transform 0.15s ease",
296
- marginLeft: "8px",
297
- display: "inline-block",
298
- transform: t.value ? "rotate(180deg)" : "rotate(0deg)"
299
- }));
300
- function l(g = !1) {
301
- return {
302
- marginRight: g ? 0 : "6px",
303
- display: "inline-flex",
304
- animation: "epAgentSpin 0.8s linear infinite",
305
- flexShrink: 0
306
- };
307
- }
308
- const u = {
309
- timelineWrap: {
310
- alignSelf: "flex-start",
311
- maxWidth: "92%",
312
- background: "#fff",
313
- border: "1px solid #e1e3e6",
314
- borderRadius: "12px",
315
- overflow: "hidden",
316
- fontFamily: "'Google Sans Text', system-ui, sans-serif"
317
- },
318
- timelineHeader: {
319
- display: "flex",
320
- alignItems: "center",
321
- justifyContent: "space-between",
322
- width: "100%",
323
- padding: "8px 12px",
324
- background: "transparent",
325
- border: "none",
326
- cursor: "pointer",
327
- fontSize: "12.5px",
328
- color: "#1f1f1f",
329
- fontFamily: "inherit"
330
- },
331
- timelineSummary: {
332
- display: "inline-flex",
333
- alignItems: "center",
334
- fontWeight: 500
335
- },
336
- timelineList: {
337
- listStyle: "none",
338
- margin: 0,
339
- padding: "4px 12px 10px 12px",
340
- display: "flex",
341
- flexDirection: "column",
342
- gap: "6px",
343
- borderTop: "1px solid #ececf0"
344
- },
345
- timelineItem: {
346
- display: "flex",
347
- alignItems: "center",
348
- gap: "8px",
349
- fontSize: "12px",
350
- color: "#444746"
351
- },
352
- timelineDot: {
353
- width: "6px",
354
- height: "6px",
355
- borderRadius: "50%",
356
- flexShrink: 0
357
- },
358
- timelineCall: {
359
- display: "inline-flex",
360
- flexDirection: "column",
361
- minWidth: 0
362
- },
363
- timelineCallName: {
364
- color: "#1f1f1f"
365
- },
366
- timelineError: {
367
- color: "#d93025",
368
- fontSize: "11px"
369
- },
370
- timelineMore: {
371
- fontSize: "11px",
372
- color: "#5f6368",
373
- fontStyle: "italic",
374
- paddingLeft: "14px"
375
- }
376
- };
377
- return (g, m) => e.toolCalls.length > 0 ? (h(), f("div", {
378
- key: 0,
379
- style: y(u.timelineWrap),
380
- "data-testid": "agent-timeline"
381
- }, [
382
- p("button", {
383
- type: "button",
384
- "aria-expanded": t.value,
385
- style: y(u.timelineHeader),
386
- "data-testid": "agent-timeline-toggle",
387
- onClick: m[0] || (m[0] = (x) => n.value = !t.value)
388
- }, [
389
- p("span", {
390
- style: y(u.timelineSummary)
391
- }, [
392
- e.streaming ? (h(), f("span", {
393
- key: 0,
394
- style: y(l()),
395
- "aria-hidden": "true"
396
- }, [...m[1] || (m[1] = [
397
- p("svg", {
398
- width: "12",
399
- height: "12",
400
- viewBox: "0 0 24 24",
401
- fill: "none"
402
- }, [
403
- p("circle", {
404
- cx: "12",
405
- cy: "12",
406
- r: "9",
407
- stroke: "#dadce0",
408
- "stroke-width": "3",
409
- fill: "none"
410
- }),
411
- p("path", {
412
- d: "M21 12a9 9 0 0 0-9-9",
413
- stroke: "#0b57d0",
414
- "stroke-width": "3",
415
- "stroke-linecap": "round"
416
- })
417
- ], -1)
418
- ])], 4)) : (h(), f("span", We, [...m[2] || (m[2] = [
419
- p("svg", {
420
- width: "12",
421
- height: "12",
422
- viewBox: "0 0 24 24",
423
- fill: "none"
424
- }, [
425
- p("path", {
426
- d: "M5 13l4 4L19 7",
427
- stroke: "#1e8e3e",
428
- "stroke-width": "2.5",
429
- "stroke-linecap": "round",
430
- "stroke-linejoin": "round"
431
- })
432
- ], -1)
433
- ])])),
434
- xe(" " + v(i.value), 1)
435
- ], 4),
436
- p("span", {
437
- style: y(c.value),
438
- "aria-hidden": "true"
439
- }, "▾", 4)
440
- ], 12, Ne),
441
- t.value ? (h(), f("ol", {
442
- key: 0,
443
- style: y(u.timelineList)
444
- }, [
445
- d.value > 0 ? (h(), f("li", {
446
- key: 0,
447
- style: y(u.timelineMore),
448
- "data-testid": "agent-timeline-earlier"
449
- }, v(r(d.value)), 5)) : I("", !0),
450
- (h(!0), f(H, null, z(s.value, (x) => (h(), f("li", {
451
- key: x.id,
452
- style: y(u.timelineItem)
453
- }, [
454
- x.status === "running" ? (h(), f("span", {
455
- key: 0,
456
- style: y(l(!0)),
457
- "aria-hidden": "true"
458
- }, [...m[3] || (m[3] = [
459
- p("svg", {
460
- width: "10",
461
- height: "10",
462
- viewBox: "0 0 24 24",
463
- fill: "none"
464
- }, [
465
- p("circle", {
466
- cx: "12",
467
- cy: "12",
468
- r: "9",
469
- stroke: "#dadce0",
470
- "stroke-width": "3",
471
- fill: "none"
472
- }),
473
- p("path", {
474
- d: "M21 12a9 9 0 0 0-9-9",
475
- stroke: "#0b57d0",
476
- "stroke-width": "3",
477
- "stroke-linecap": "round"
478
- })
479
- ], -1)
480
- ])], 4)) : (h(), f("span", {
481
- key: 1,
482
- style: y({
483
- ...u.timelineDot,
484
- background: x.status === "error" ? "#d93025" : "#1e8e3e"
485
- }),
486
- "aria-hidden": "true"
487
- }, null, 4)),
488
- p("span", {
489
- style: y(u.timelineCall)
490
- }, [
491
- p("span", {
492
- style: y(u.timelineCallName)
493
- }, v(o(x.name)), 5),
494
- x.error ? (h(), f("span", {
495
- key: 0,
496
- style: y(u.timelineError)
497
- }, v(x.error), 5)) : I("", !0)
498
- ], 4)
499
- ], 4))), 128))
500
- ], 4)) : I("", !0)
501
- ], 4)) : I("", !0);
502
- }
503
- }), Re = ["data-role"], Fe = ["aria-label"], U = "ep-agent-chat-keyframes", Rt = /* @__PURE__ */ _({
504
- __name: "AgentChatLog",
505
- props: {
506
- messages: {},
507
- loading: { type: Boolean, default: !1 },
508
- error: { default: null },
509
- thinkingLabel: { default: () => w.agentPanel.thinking },
510
- workingLabel: { type: Function, default: void 0 },
511
- summaryLabel: { type: Function, default: void 0 },
512
- earlierLabel: { type: Function, default: void 0 },
513
- autoScroll: { type: Boolean, default: !0 },
514
- humanizeToolName: { type: Function, default: void 0 },
515
- maxVisibleCalls: { default: 3 },
516
- className: { default: "" }
517
- },
518
- setup(e) {
519
- const a = e, n = T(null), t = T(null), o = S(
520
- () => a.messages.length === 0 && !a.loading && !a.error
521
- );
522
- function r() {
523
- if (!a.autoScroll) return;
524
- const l = a.messages[a.messages.length - 1]?.status === "streaming";
525
- t.value?.scrollIntoView({
526
- behavior: l || a.loading ? "auto" : "smooth",
527
- block: "end"
528
- });
529
- }
530
- be(() => {
531
- te(r), i();
532
- }), N(
533
- [
534
- () => a.messages.length,
535
- () => a.messages[a.messages.length - 1]?.toolCalls?.length ?? 0,
536
- () => a.loading,
537
- () => a.messages[a.messages.length - 1]?.status === "streaming"
538
- ],
539
- r,
540
- { flush: "post" }
541
- );
542
- function i() {
543
- if (typeof document > "u" || document.getElementById(U)) return;
544
- const c = document.createElement("style");
545
- c.id = U, c.textContent = `
546
- @keyframes epAgentDot {
547
- 0%, 80%, 100% { transform: scale(0.6); opacity: 0.4; }
548
- 40% { transform: scale(1); opacity: 1; }
549
- }
550
- @keyframes epAgentSpin {
551
- to { transform: rotate(360deg); }
552
- }
553
- `, document.head.appendChild(c);
554
- }
555
- const s = {
556
- flex: 1,
557
- overflow: "auto",
558
- padding: "16px 14px 8px",
559
- display: "flex",
560
- flexDirection: "column",
561
- gap: "10px"
562
- }, d = {
563
- messageGroup: {
564
- display: "flex",
565
- flexDirection: "column",
566
- gap: "6px",
567
- width: "100%"
568
- },
569
- userBubble: {
570
- background: "#0b57d0",
571
- color: "#fff",
572
- padding: "10px 14px",
573
- borderRadius: "20px 20px 4px 20px",
574
- fontSize: "13.5px",
575
- lineHeight: 1.5,
576
- alignSelf: "flex-end",
577
- maxWidth: "88%",
578
- whiteSpace: "pre-wrap",
579
- wordBreak: "break-word",
580
- fontFamily: "'Google Sans', 'Google Sans Text', system-ui, -apple-system, sans-serif"
581
- },
582
- assistantBubble: {
583
- background: "#f0f4f9",
584
- color: "#1f1f1f",
585
- padding: "12px 16px",
586
- borderRadius: "20px 20px 20px 4px",
587
- fontSize: "13.5px",
588
- lineHeight: 1.55,
589
- alignSelf: "flex-start",
590
- maxWidth: "92%",
591
- whiteSpace: "pre-wrap",
592
- wordBreak: "break-word",
593
- fontFamily: "'Google Sans', 'Google Sans Text', system-ui, -apple-system, sans-serif"
594
- },
595
- thinkingBubble: {
596
- background: "#f0f4f9",
597
- padding: "12px 16px",
598
- borderRadius: "20px 20px 20px 4px",
599
- alignSelf: "flex-start",
600
- display: "flex",
601
- gap: "4px",
602
- alignItems: "center"
603
- },
604
- dot: {
605
- width: "6px",
606
- height: "6px",
607
- borderRadius: "50%",
608
- background: "#5f6368",
609
- display: "inline-block",
610
- animation: "epAgentDot 1.4s infinite ease-in-out"
611
- },
612
- errorBubble: {
613
- background: "#fce8e6",
614
- color: "#b3261e",
615
- padding: "10px 14px",
616
- borderRadius: "16px",
617
- fontSize: "12.5px",
618
- alignSelf: "flex-start",
619
- maxWidth: "92%",
620
- whiteSpace: "pre-wrap",
621
- fontFamily: "'Google Sans Text', system-ui, sans-serif"
622
- }
623
- };
624
- return (c, l) => (h(), f("div", {
625
- class: j(["ep-agent-chat-log", e.className]),
626
- style: s,
627
- ref_key: "rootEl",
628
- ref: n,
629
- role: "log",
630
- "aria-live": "polite",
631
- "aria-atomic": "false"
632
- }, [
633
- o.value ? E(c.$slots, "empty", { key: 0 }) : I("", !0),
634
- (h(!0), f(H, null, z(e.messages, (u) => (h(), f("div", {
635
- key: u.id,
636
- style: y(d.messageGroup),
637
- "data-role": u.role
638
- }, [
639
- u.role === "assistant" && u.toolCalls && u.toolCalls.length > 0 ? (h(), ne(Be, {
640
- key: 0,
641
- "tool-calls": u.toolCalls,
642
- streaming: u.status === "streaming",
643
- "humanize-name": e.humanizeToolName,
644
- "max-visible-calls": e.maxVisibleCalls,
645
- "working-label": e.workingLabel,
646
- "summary-label": e.summaryLabel,
647
- "earlier-label": e.earlierLabel
648
- }, null, 8, ["tool-calls", "streaming", "humanize-name", "max-visible-calls", "working-label", "summary-label", "earlier-label"])) : I("", !0),
649
- u.text.length > 0 ? (h(), f("div", {
650
- key: 1,
651
- style: y(u.role === "user" ? d.userBubble : d.assistantBubble)
652
- }, v(u.text), 5)) : I("", !0)
653
- ], 12, Re))), 128)),
654
- e.loading ? (h(), f("div", {
655
- key: 1,
656
- style: y(d.thinkingBubble),
657
- "aria-label": e.thinkingLabel
658
- }, [
659
- p("span", {
660
- style: y({ ...d.dot, animationDelay: "0s" })
661
- }, null, 4),
662
- p("span", {
663
- style: y({ ...d.dot, animationDelay: "0.15s" })
664
- }, null, 4),
665
- p("span", {
666
- style: y({ ...d.dot, animationDelay: "0.3s" })
667
- }, null, 4)
668
- ], 12, Fe)) : I("", !0),
669
- e.error ? (h(), f("div", {
670
- key: 2,
671
- style: y(d.errorBubble),
672
- role: "alert"
673
- }, v(e.error), 5)) : I("", !0),
674
- p("div", {
675
- ref_key: "endEl",
676
- ref: t
677
- }, null, 512)
678
- ], 2));
679
- }
680
- }), je = ["value", "placeholder", "disabled"], He = ["aria-label", "disabled"], Ft = /* @__PURE__ */ _({
681
- __name: "AgentComposer",
682
- props: {
683
- modelValue: {},
684
- disabled: { type: Boolean, default: !1 },
685
- placeholder: { default: () => w.agentPanel.composerPlaceholder },
686
- sendLabel: { default: () => w.agentPanel.send },
687
- className: { default: "" }
688
- },
689
- emits: ["update:modelValue", "submit"],
690
- setup(e, { emit: a }) {
691
- const n = e, t = a, o = S(() => n.modelValue.trim().length > 0 && !n.disabled);
692
- function r() {
693
- o.value && t("submit");
694
- }
695
- const i = S(() => ({
696
- width: "36px",
697
- height: "36px",
698
- borderRadius: "50%",
699
- border: "none",
700
- background: "#0b57d0",
701
- color: "#fff",
702
- flexShrink: 0,
703
- display: "inline-flex",
704
- alignItems: "center",
705
- justifyContent: "center",
706
- transition: "background 0.15s, opacity 0.15s, transform 0.15s",
707
- opacity: o.value ? 1 : 0.35,
708
- cursor: o.value ? "pointer" : "not-allowed"
709
- })), s = {
710
- composerWrap: {
711
- padding: "8px 12px 14px",
712
- background: "#fff",
713
- flex: "0 0 auto"
714
- },
715
- composerShell: {
716
- display: "flex",
717
- alignItems: "center",
718
- gap: "4px",
719
- padding: "6px 6px 6px 18px",
720
- background: "#fff",
721
- border: "1px solid #c4c7c5",
722
- borderRadius: "28px",
723
- boxShadow: "0 1px 2px rgba(60,64,67,0.04)",
724
- transition: "border-color 0.15s, box-shadow 0.15s",
725
- fontFamily: "'Google Sans Text', system-ui, sans-serif"
726
- },
727
- composerInput: {
728
- flex: 1,
729
- padding: "8px 0",
730
- fontSize: "14px",
731
- border: "none",
732
- outline: "none",
733
- background: "transparent",
734
- fontFamily: "inherit",
735
- color: "#1f1f1f"
736
- },
737
- footnote: {
738
- fontSize: "11px",
739
- color: "#5f6368",
740
- textAlign: "center",
741
- marginTop: "10px",
742
- fontFamily: "'Google Sans Text', system-ui, sans-serif"
743
- }
744
- };
745
- return (d, c) => (h(), f("form", {
746
- class: j(["ep-agent-composer", e.className]),
747
- style: y(s.composerWrap),
748
- onSubmit: $(r, ["prevent"])
749
- }, [
750
- p("div", {
751
- style: y(s.composerShell)
752
- }, [
753
- p("input", {
754
- style: y(s.composerInput),
755
- value: e.modelValue,
756
- placeholder: e.placeholder,
757
- disabled: e.disabled,
758
- onInput: c[0] || (c[0] = (l) => t("update:modelValue", l.target.value))
759
- }, null, 44, je),
760
- p("button", {
761
- type: "submit",
762
- "aria-label": e.sendLabel,
763
- disabled: !o.value,
764
- style: y(i.value)
765
- }, [...c[1] || (c[1] = [
766
- p("svg", {
767
- width: "16",
768
- height: "16",
769
- viewBox: "0 0 24 24",
770
- fill: "none",
771
- "aria-hidden": "true"
772
- }, [
773
- p("path", {
774
- d: "M12 19V5M5 12l7-7 7 7",
775
- stroke: "currentColor",
776
- "stroke-width": "2",
777
- "stroke-linecap": "round",
778
- "stroke-linejoin": "round"
779
- })
780
- ], -1)
781
- ])], 12, He)
782
- ], 4),
783
- d.$slots.footnote ? (h(), f("div", {
784
- key: 0,
785
- style: y(s.footnote)
786
- }, [
787
- E(d.$slots, "footnote")
788
- ], 4)) : I("", !0)
789
- ], 38));
790
- }
791
- }), ze = ["disabled"], jt = /* @__PURE__ */ _({
792
- __name: "AgentSuggestionChip",
793
- props: {
794
- label: {},
795
- disabled: { type: Boolean }
796
- },
797
- emits: ["click"],
798
- setup(e, { emit: a }) {
799
- const n = a, t = {
800
- textAlign: "left",
801
- background: "#fff",
802
- border: "1px solid #dadce0",
803
- borderRadius: "18px",
804
- padding: "10px 14px",
805
- fontSize: "13px",
806
- color: "#1f1f1f",
807
- cursor: "pointer",
808
- fontFamily: "'Google Sans Text', system-ui, sans-serif",
809
- lineHeight: 1.4,
810
- transition: "background 0.15s, border-color 0.15s, box-shadow 0.15s",
811
- width: "100%"
812
- };
813
- return (o, r) => (h(), f("button", {
814
- type: "button",
815
- style: t,
816
- disabled: e.disabled,
817
- onClick: r[0] || (r[0] = (i) => n("click"))
818
- }, v(e.label), 9, ze));
819
- }
820
- }), Ge = ["aria-label"], Ve = {
821
- class: "ai-ctx-menu__header",
822
- "aria-hidden": "true"
823
- }, qe = ["onMousedown"], Oe = ["innerHTML"], Ue = { class: "ai-ctx-menu__label" }, Ke = {
824
- key: 0,
825
- class: "ai-ctx-menu__custom"
826
- }, Ze = ["placeholder"], Xe = /* @__PURE__ */ _({
827
- __name: "AIContextMenu",
828
- props: {
829
- isOpen: { type: Boolean },
830
- position: {},
831
- selectedText: {},
832
- showCustomPrompt: { type: Boolean, default: !0 },
833
- labels: { default: () => ({}) }
834
- },
835
- emits: ["close", "action"],
836
- setup(e, { emit: a }) {
837
- const n = e, t = a, o = T(""), r = T([]);
838
- N(
839
- () => n.isOpen,
840
- (g) => {
841
- g && te(() => r.value[0]?.focus());
842
- },
843
- { immediate: !0 }
844
- );
845
- const i = [
846
- { id: "rewrite", icon: "&#x270D;" },
847
- { id: "expand", icon: "&#x2194;" },
848
- { id: "summarize", icon: "&#x1F4DD;" },
849
- { id: "fixGrammar", icon: "&#x2714;" },
850
- { id: "makeFormal", icon: "&#x1F454;" },
851
- { id: "makeCasual", icon: "&#x1F60A;" },
852
- { id: "translate", icon: "&#x1F310;" },
853
- { id: "explain", icon: "&#x1F4A1;" }
854
- ], s = S(() => n.labels?.header ?? w.aiActions.header), d = S(
855
- () => n.labels?.customPlaceholder ?? w.aiActions.customPlaceholder
856
- );
857
- function c(g) {
858
- const m = n.labels?.[g];
859
- return m || (w.aiActions[g] ?? g);
860
- }
861
- const l = S(() => {
862
- let g = n.position.x, m = n.position.y;
863
- const x = 220, A = 360;
864
- return typeof window < "u" && (g + x + 10 > window.innerWidth && (g = window.innerWidth - x - 10), m + A + 10 > window.innerHeight && (m = window.innerHeight - A - 10)), { position: "fixed", left: `${g}px`, top: `${m}px`, zIndex: 500 };
865
- });
866
- function u(g) {
867
- t("action", g, g === "custom" ? o.value : void 0), o.value = "", t("close");
868
- }
869
- return (g, m) => (h(), ne(ve, { to: "body" }, [
870
- e.isOpen ? (h(), f("div", {
871
- key: 0,
872
- class: "ai-ctx-backdrop",
873
- onMousedown: m[0] || (m[0] = (x) => t("close")),
874
- onContextmenu: m[1] || (m[1] = $((x) => t("close"), ["prevent"]))
875
- }, null, 32)) : I("", !0),
876
- e.isOpen ? (h(), f("div", {
877
- key: 1,
878
- class: "ai-ctx-menu",
879
- "aria-label": s.value,
880
- style: y(l.value),
881
- tabindex: "-1",
882
- onContextmenu: m[4] || (m[4] = $(() => {
883
- }, ["prevent"])),
884
- onKeydown: m[5] || (m[5] = D($((x) => t("close"), ["stop"]), ["esc"]))
885
- }, [
886
- p("div", Ve, v(s.value), 1),
887
- (h(), f(H, null, z(i, (x) => p("button", {
888
- key: x.id,
889
- ref_for: !0,
890
- ref_key: "itemRefs",
891
- ref: r,
892
- class: "ai-ctx-menu__item",
893
- onMousedown: $((A) => u(x.id), ["prevent"])
894
- }, [
895
- p("span", {
896
- class: "ai-ctx-menu__icon",
897
- innerHTML: x.icon
898
- }, null, 8, Oe),
899
- p("span", Ue, v(c(x.id)), 1)
900
- ], 40, qe)), 64)),
901
- m[6] || (m[6] = p("div", { class: "ai-ctx-menu__divider" }, null, -1)),
902
- e.showCustomPrompt ? (h(), f("div", Ke, [
903
- ae(p("input", {
904
- "onUpdate:modelValue": m[2] || (m[2] = (x) => o.value = x),
905
- class: "ai-ctx-menu__input",
906
- placeholder: d.value,
907
- onKeydown: m[3] || (m[3] = D($((x) => u("custom"), ["prevent"]), ["enter"]))
908
- }, null, 40, Ze), [
909
- [oe, o.value]
910
- ])
911
- ])) : I("", !0)
912
- ], 44, Ge)) : I("", !0)
913
- ]));
914
- }
915
- }), se = (e, a) => {
916
- const n = e.__vccOpts || e;
917
- for (const [t, o] of a)
918
- n[t] = o;
919
- return n;
920
- }, Ht = /* @__PURE__ */ se(Xe, [["__scopeId", "data-v-c30da7a7"]]), Ye = ["aria-label"], Qe = { class: "ai-preview__header" }, Je = { class: "ai-preview__title" }, et = ["aria-label"], tt = {
921
- key: 0,
922
- class: "ai-preview__loading"
923
- }, nt = {
924
- key: 1,
925
- class: "ai-preview__error"
926
- }, at = {
927
- key: 2,
928
- class: "ai-preview__content"
929
- }, ot = {
930
- key: 0,
931
- class: "ai-preview__diff"
932
- }, rt = { class: "ai-preview__diff-label" }, st = { class: "ai-preview__diff-text ai-preview__diff-text--old" }, it = { class: "ai-preview__diff-label" }, lt = { class: "ai-preview__diff-text ai-preview__diff-text--new" }, dt = {
933
- key: 1,
934
- class: "ai-preview__result"
935
- }, ct = {
936
- key: 3,
937
- class: "ai-preview__footer"
938
- }, ut = /* @__PURE__ */ _({
939
- __name: "AIResponsePreview",
940
- props: {
941
- isVisible: { type: Boolean },
942
- originalText: {},
943
- responseText: {},
944
- action: {},
945
- isLoading: { type: Boolean },
946
- error: { default: void 0 },
947
- allowEdit: { type: Boolean, default: !0 },
948
- showDiff: { type: Boolean, default: !0 },
949
- showRetry: { type: Boolean, default: !0 },
950
- labels: { default: () => ({}) }
951
- },
952
- emits: ["accept", "reject", "retry"],
953
- setup(e, { emit: a }) {
954
- const n = e, t = a, o = T(!1), r = T(""), i = S(() => ({
955
- loading: n.labels?.loading ?? w.aiPreview.loading,
956
- original: n.labels?.original ?? w.aiPreview.original,
957
- suggested: n.labels?.suggested ?? w.aiPreview.suggested,
958
- edit: n.labels?.edit ?? w.aiPreview.edit,
959
- discard: n.labels?.discard ?? w.aiPreview.discard,
960
- accept: n.labels?.accept ?? w.aiPreview.accept,
961
- retry: n.labels?.retry ?? w.aiPreview.retry,
962
- close: n.labels?.close ?? w.aiPreview.close
963
- })), s = S(() => {
964
- const c = n.labels?.actionTitles?.[n.action];
965
- return c || (w.aiPreview.labels[n.action] ?? w.aiPreview.defaultTitle);
966
- });
967
- N(
968
- () => n.responseText,
969
- (c) => {
970
- r.value = c, o.value = !1;
971
- }
972
- );
973
- function d() {
974
- t("accept", o.value ? r.value : n.responseText);
975
- }
976
- return (c, l) => e.isVisible ? (h(), f("div", {
977
- key: 0,
978
- class: "ai-preview",
979
- role: "region",
980
- "aria-label": s.value,
981
- tabindex: "-1",
982
- onKeydown: l[5] || (l[5] = D($((u) => t("reject"), ["stop"]), ["esc"]))
983
- }, [
984
- p("div", Qe, [
985
- p("span", Je, v(s.value), 1),
986
- p("button", {
987
- class: "ai-preview__close",
988
- "aria-label": i.value.close,
989
- onClick: l[0] || (l[0] = (u) => t("reject"))
990
- }, " ✕ ", 8, et)
991
- ]),
992
- e.isLoading ? (h(), f("div", tt, [
993
- l[6] || (l[6] = p("span", { class: "ai-preview__spinner" }, null, -1)),
994
- p("span", null, v(i.value.loading), 1)
995
- ])) : e.error ? (h(), f("div", nt, [
996
- p("span", null, v(e.error), 1),
997
- e.showRetry ? (h(), f("button", {
998
- key: 0,
999
- class: "ai-preview__retry",
1000
- onMousedown: l[1] || (l[1] = $((u) => t("retry"), ["prevent"]))
1001
- }, v(i.value.retry), 33)) : I("", !0)
1002
- ])) : (h(), f("div", at, [
1003
- e.showDiff ? (h(), f("div", ot, [
1004
- p("div", rt, v(i.value.original), 1),
1005
- p("div", st, v(e.originalText), 1),
1006
- p("div", it, v(i.value.suggested), 1),
1007
- p("div", lt, v(e.responseText), 1)
1008
- ])) : (h(), f("div", dt, v(e.responseText), 1)),
1009
- e.allowEdit && o.value ? ae((h(), f("textarea", {
1010
- key: 2,
1011
- "onUpdate:modelValue": l[2] || (l[2] = (u) => r.value = u),
1012
- class: "ai-preview__textarea",
1013
- rows: "4"
1014
- }, null, 512)), [
1015
- [oe, r.value]
1016
- ]) : I("", !0)
1017
- ])),
1018
- !e.isLoading && !e.error ? (h(), f("div", ct, [
1019
- e.allowEdit && !o.value ? (h(), f("button", {
1020
- key: 0,
1021
- class: "ai-preview__btn",
1022
- onMousedown: l[3] || (l[3] = $((u) => o.value = !0, ["prevent"]))
1023
- }, v(i.value.edit), 33)) : I("", !0),
1024
- p("button", {
1025
- class: "ai-preview__btn",
1026
- onMousedown: l[4] || (l[4] = $((u) => t("reject"), ["prevent"]))
1027
- }, v(i.value.discard), 33),
1028
- p("button", {
1029
- class: "ai-preview__btn ai-preview__btn--primary",
1030
- onMousedown: $(d, ["prevent"])
1031
- }, v(i.value.accept), 33)
1032
- ])) : I("", !0)
1033
- ], 40, Ye)) : I("", !0);
1034
- }
1035
- }), zt = /* @__PURE__ */ se(ut, [["__scopeId", "data-v-1226b741"]]), K = [
1036
- "single",
1037
- "words",
1038
- "double",
1039
- "thick",
1040
- "dotted",
1041
- "dottedHeavy",
1042
- "dash",
1043
- "dashedHeavy",
1044
- "dashLong",
1045
- "dashLongHeavy",
1046
- "dotDash",
1047
- "dashDotHeavy",
1048
- "dotDotDash",
1049
- "dashDotDotHeavy",
1050
- "wave",
1051
- "wavyHeavy",
1052
- "wavyDouble",
1053
- "none"
1054
- ], M = [
1055
- "black",
1056
- "blue",
1057
- "cyan",
1058
- "darkBlue",
1059
- "darkCyan",
1060
- "darkGray",
1061
- "darkGreen",
1062
- "darkMagenta",
1063
- "darkRed",
1064
- "darkYellow",
1065
- "green",
1066
- "lightGray",
1067
- "magenta",
1068
- "red",
1069
- "white",
1070
- "yellow",
1071
- "none"
1072
- ], pt = {
1073
- name: "apply_formatting",
1074
- displayName: "Applying formatting",
1075
- 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 — 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}`.',
1076
- inputSchema: {
1077
- type: "object",
1078
- properties: {
1079
- paraId: { type: "string", description: "Paragraph id from read_document / find_text." },
1080
- search: {
1081
- type: "string",
1082
- description: "Optional: format only this exact phrase within the paragraph (must be unique)."
1083
- },
1084
- marks: {
1085
- type: "object",
1086
- description: "Marks to set or clear. Omit a key to leave it untouched.",
1087
- properties: {
1088
- bold: { type: "boolean" },
1089
- italic: { type: "boolean" },
1090
- underline: {
1091
- description: 'true single underline; false 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.'
1092
- },
1093
- strike: { type: "boolean" },
1094
- color: {
1095
- type: "object",
1096
- description: 'Either {rgb: "RRGGBB"} (no hash) or {themeColor: "accent1"|"text1"|...}.',
1097
- properties: {
1098
- rgb: { type: "string" },
1099
- themeColor: { type: "string" }
1100
- }
1101
- },
1102
- highlight: {
1103
- type: "string",
1104
- enum: [...M],
1105
- description: "Highlight color — must be one of the Word-supported names: " + M.join(", ") + '. Pass "none" to clear. Hex values are rejected (Word does not accept hex for <w:highlight>).'
1106
- },
1107
- fontSize: { type: "number", description: "Size in points (e.g. 12, 14, 24)." },
1108
- fontFamily: {
1109
- type: "object",
1110
- properties: {
1111
- ascii: { type: "string" },
1112
- hAnsi: { type: "string" }
1113
- }
1114
- }
1115
- }
1116
- }
1117
- },
1118
- required: ["paraId", "marks"]
1119
- },
1120
- handler: (e, a) => {
1121
- if (!e.marks || Object.keys(e.marks).length === 0)
1122
- return {
1123
- success: !1,
1124
- error: "No marks provided. Specify at least one of bold/italic/etc."
1125
- };
1126
- const n = typeof e.marks.underline == "object" && e.marks.underline !== null ? e.marks.underline.style : void 0;
1127
- if (n && !K.includes(n))
1128
- return {
1129
- success: !1,
1130
- error: `Invalid underline.style "${n}". Must be one of: ${K.join(", ")}.`
1131
- };
1132
- const t = typeof e.marks.highlight == "string" ? e.marks.highlight : void 0;
1133
- if (t && !M.includes(t))
1134
- return {
1135
- success: !1,
1136
- error: `Invalid highlight "${t}". Must be one of: ${M.join(", ")}. Hex values are not supported by Word's highlight attribute.`
1137
- };
1138
- const o = t === "none" ? { ...e.marks, highlight: "" } : e.marks;
1139
- return a.applyFormatting({
1140
- paraId: e.paraId,
1141
- search: e.search,
1142
- marks: o
1143
- }) ? { success: !0, data: `Formatting applied to ${e.search ? `"${e.search}" in ${e.paraId}` : e.paraId}.` } : {
1144
- success: !1,
1145
- error: "Could not apply formatting. The paraId may not exist, or `search` is missing / ambiguous."
1146
- };
1147
- }
1148
- }, mt = {
1149
- name: "set_paragraph_style",
1150
- displayName: "Setting paragraph style",
1151
- description: `Apply a paragraph style by id (e.g. "Heading1", "Heading2", "Title", "Quote", "Normal"). The styleId must exist in the document's style definitions — unknown ids are no-ops. Direct edit, not a tracked change.`,
1152
- inputSchema: {
1153
- type: "object",
1154
- properties: {
1155
- paraId: { type: "string", description: "Paragraph id from read_document / find_text." },
1156
- styleId: {
1157
- type: "string",
1158
- description: 'Style id (e.g. "Heading1", "Title", "Quote", "Normal").'
1159
- }
1160
- },
1161
- required: ["paraId", "styleId"]
1162
- },
1163
- handler: (e, a) => a.setParagraphStyle({ paraId: e.paraId, styleId: e.styleId }) ? { success: !0, data: `Style "${e.styleId}" applied to ${e.paraId}.` } : {
1164
- success: !1,
1165
- error: `Could not set style. paraId "${e.paraId}" not found, or styleId "${e.styleId}" is not defined.`
1166
- }
1167
- }, ht = {
1168
- name: "read_page",
1169
- displayName: "Reading page",
1170
- 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".`,
1171
- inputSchema: {
1172
- type: "object",
1173
- properties: {
1174
- pageNumber: { type: "number", description: "1-indexed page number." }
1175
- },
1176
- required: ["pageNumber"]
1177
- },
1178
- handler: (e, a) => {
1179
- const n = a.getPage(e.pageNumber);
1180
- if (!n) {
1181
- const t = a.getTotalPages();
1182
- return t === 0 ? { success: !1, error: "No pages rendered (headless mode or empty document)." } : {
1183
- success: !1,
1184
- error: `Page ${e.pageNumber} does not exist (document has ${t} page${t === 1 ? "" : "s"}).`
1185
- };
1186
- }
1187
- return { success: !0, data: n.text || "(empty page)" };
1188
- }
1189
- }, gt = {
1190
- name: "read_pages",
1191
- displayName: "Reading pages",
1192
- 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 — single round-trip.",
1193
- inputSchema: {
1194
- type: "object",
1195
- properties: {
1196
- from: { type: "number", description: "1-indexed start page (inclusive)." },
1197
- to: { type: "number", description: "1-indexed end page (inclusive)." }
1198
- },
1199
- required: ["from", "to"]
1200
- },
1201
- handler: (e, a) => {
1202
- const n = a.getPages({ from: e.from, to: e.to });
1203
- if (n.length === 0) {
1204
- const o = a.getTotalPages();
1205
- return o === 0 ? { success: !1, error: "No pages rendered (headless mode or empty document)." } : {
1206
- success: !1,
1207
- error: `No pages in range ${e.from}–${e.to} (document has ${o} page${o === 1 ? "" : "s"}).`
1208
- };
1209
- }
1210
- return { success: !0, data: n.map((o) => `--- Page ${o.pageNumber} ---
1211
- ${o.text || "(empty page)"}`).join(`
1212
-
1213
- `) };
1214
- }
1215
- }, ft = {
1216
- name: "read_document",
1217
- displayName: "Reading document",
1218
- 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 — 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.',
1219
- inputSchema: {
1220
- type: "object",
1221
- properties: {
1222
- fromIndex: { type: "number", description: "Start ordinal index (inclusive). Optional." },
1223
- toIndex: { type: "number", description: "End ordinal index (inclusive). Optional." }
1224
- }
1225
- },
1226
- handler: (e, a) => ({ success: !0, data: a.getContentAsText({
1227
- fromIndex: e.fromIndex,
1228
- toIndex: e.toIndex,
1229
- includeTrackedChanges: !1,
1230
- includeCommentAnchors: !1
1231
- }) })
1232
- }, yt = {
1233
- name: "read_selection",
1234
- displayName: "Reading selection",
1235
- 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".',
1236
- inputSchema: { type: "object", properties: {} },
1237
- handler: (e, a) => {
1238
- const n = a.getSelection();
1239
- return n ? { success: !0, data: n } : { success: !1, error: "No selection (editor not focused)." };
1240
- }
1241
- }, xt = {
1242
- name: "find_text",
1243
- displayName: "Finding text",
1244
- 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.",
1245
- inputSchema: {
1246
- type: "object",
1247
- properties: {
1248
- query: { type: "string", description: "Text to find (substring match)." },
1249
- caseSensitive: { type: "boolean", description: "Default: false." },
1250
- limit: { type: "number", description: "Max paragraphs to return. Default: 20." }
1251
- },
1252
- required: ["query"]
1253
- },
1254
- handler: (e, a) => {
1255
- const n = a.findText(e.query, {
1256
- caseSensitive: e.caseSensitive,
1257
- limit: e.limit
1258
- });
1259
- return n.length === 0 ? { success: !0, data: "No matches." } : { success: !0, data: n };
1260
- }
1261
- }, bt = {
1262
- name: "read_comments",
1263
- displayName: "Reading comments",
1264
- description: "List all comments in the document with their paragraph anchors.",
1265
- inputSchema: { type: "object", properties: {} },
1266
- handler: (e, a) => {
1267
- const n = a.getComments();
1268
- return n.length === 0 ? { success: !0, data: "No comments." } : { success: !0, data: n.map(
1269
- (o) => `[Comment #${o.id}] ${o.author}: "${o.text}"` + (o.anchoredText ? ` (anchored to: "${o.anchoredText}")` : "") + (o.replies.length > 0 ? `
1270
- ` + o.replies.map((r) => ` Reply by ${r.author}: "${r.text}"`).join(`
1271
- `) : "")
1272
- ).join(`
1273
- `) };
1274
- }
1275
- }, vt = {
1276
- name: "read_changes",
1277
- displayName: "Reading changes",
1278
- description: "List tracked changes (insertions / deletions) currently in the document.",
1279
- inputSchema: { type: "object", properties: {} },
1280
- handler: (e, a) => {
1281
- const n = a.getChanges();
1282
- return n.length === 0 ? { success: !0, data: "No tracked changes." } : { success: !0, data: n.map((o) => `[Change #${o.id}] ${o.type} by ${o.author}: "${o.text}"`).join(`
1283
- `) };
1284
- }
1285
- }, wt = {
1286
- name: "add_comment",
1287
- displayName: "Adding comment",
1288
- description: "Attach a comment to a paragraph, optionally anchored to a unique phrase within it. The user sees it instantly in the comments sidebar.",
1289
- inputSchema: {
1290
- type: "object",
1291
- properties: {
1292
- paraId: { type: "string", description: "Paragraph id from read_document / find_text." },
1293
- text: { type: "string", description: "Comment body." },
1294
- search: {
1295
- type: "string",
1296
- description: "Optional: anchor to this exact phrase within the paragraph. Must be unique."
1297
- }
1298
- },
1299
- required: ["paraId", "text"]
1300
- },
1301
- handler: (e, a) => {
1302
- const n = a.addComment({
1303
- paraId: e.paraId,
1304
- text: e.text,
1305
- search: e.search
1306
- });
1307
- return n === null ? {
1308
- success: !1,
1309
- error: "Could not add comment. The paraId may not exist, or `search` is missing / ambiguous."
1310
- } : { success: !0, data: `Comment ${n} added on ${e.paraId}.` };
1311
- }
1312
- }, kt = {
1313
- name: "suggest_change",
1314
- displayName: "Suggesting change",
1315
- description: "Suggest a tracked change. Three modes: (1) replacement — `search` non-empty, `replaceWith` non-empty; (2) deletion — `search` non-empty, `replaceWith` empty; (3) insertion at paragraph end — `search` empty, `replaceWith` non-empty. The user can accept or reject in the editor UI.",
1316
- inputSchema: {
1317
- type: "object",
1318
- properties: {
1319
- paraId: { type: "string", description: "Paragraph id from read_document / find_text." },
1320
- search: {
1321
- type: "string",
1322
- description: "Phrase to find (must be unique). Empty string = insert at paragraph end."
1323
- },
1324
- replaceWith: {
1325
- type: "string",
1326
- description: "Replacement text. Empty string = delete the matched phrase."
1327
- }
1328
- },
1329
- required: ["paraId", "search", "replaceWith"]
1330
- },
1331
- handler: (e, a) => a.proposeChange({
1332
- paraId: e.paraId,
1333
- search: e.search,
1334
- replaceWith: e.replaceWith
1335
- }) ? e.search ? e.replaceWith ? {
1336
- success: !0,
1337
- data: `Replacement proposed: "${e.search}" → "${e.replaceWith}" on ${e.paraId}.`
1338
- } : { success: !0, data: `Deletion proposed: "${e.search}" on ${e.paraId}.` } : { success: !0, data: `Insertion proposed on ${e.paraId}.` } : {
1339
- success: !1,
1340
- error: "Could not propose change. Possible causes: paraId not found; search missing or ambiguous; or the target overlaps an existing tracked change."
1341
- }
1342
- }, It = {
1343
- name: "reply_comment",
1344
- displayName: "Replying to comment",
1345
- description: "Reply to an existing comment by id. Threaded under the original.",
1346
- inputSchema: {
1347
- type: "object",
1348
- properties: {
1349
- commentId: { type: "number", description: "Comment id from read_comments." },
1350
- text: { type: "string", description: "Reply body." }
1351
- },
1352
- required: ["commentId", "text"]
1353
- },
1354
- handler: (e, a) => {
1355
- const n = a.replyTo(e.commentId, { text: e.text });
1356
- return n === null ? { success: !1, error: `Comment #${e.commentId} not found.` } : { success: !0, data: `Reply ${n} added to comment ${e.commentId}.` };
1357
- }
1358
- }, St = {
1359
- name: "resolve_comment",
1360
- displayName: "Resolving comment",
1361
- description: "Mark a comment as resolved (done).",
1362
- inputSchema: {
1363
- type: "object",
1364
- properties: {
1365
- commentId: { type: "number", description: "Comment id from read_comments." }
1366
- },
1367
- required: ["commentId"]
1368
- },
1369
- handler: (e, a) => (a.resolveComment(e.commentId), { success: !0, data: `Comment ${e.commentId} resolved.` })
1370
- }, Ct = {
1371
- name: "scroll",
1372
- displayName: "Scrolling",
1373
- description: "Scroll the editor to a paragraph by paraId. Does not move the user's cursor.",
1374
- inputSchema: {
1375
- type: "object",
1376
- properties: {
1377
- paraId: { type: "string", description: "Paragraph id from read_document / find_text." }
1378
- },
1379
- required: ["paraId"]
1380
- },
1381
- handler: (e, a) => a.scrollTo(e.paraId) ? { success: !0, data: `Scrolled to ${e.paraId}.` } : { success: !1, error: `paraId ${e.paraId} not found.` }
1382
- }, G = [
1383
- ft,
1384
- yt,
1385
- ht,
1386
- gt,
1387
- xt,
1388
- bt,
1389
- vt,
1390
- wt,
1391
- kt,
1392
- pt,
1393
- mt,
1394
- It,
1395
- St,
1396
- Ct
310
+ //#endregion
311
+ //#region src/vue/components/AgentTimeline.vue?vue&type=script&setup=true&lang.ts
312
+ var I = ["aria-expanded"], L = {
313
+ key: 1,
314
+ style: {
315
+ marginRight: "6px",
316
+ display: "inline-flex"
317
+ },
318
+ "aria-hidden": "true"
319
+ }, R = /* @__PURE__ */ c({
320
+ __name: "AgentTimeline",
321
+ props: {
322
+ toolCalls: {},
323
+ streaming: {
324
+ type: Boolean,
325
+ default: !1
326
+ },
327
+ maxVisibleCalls: { default: 3 },
328
+ humanizeName: {
329
+ type: Function,
330
+ default: void 0
331
+ },
332
+ workingLabel: {
333
+ type: Function,
334
+ default: void 0
335
+ },
336
+ summaryLabel: {
337
+ type: Function,
338
+ default: void 0
339
+ },
340
+ earlierLabel: {
341
+ type: Function,
342
+ default: void 0
343
+ }
344
+ },
345
+ setup(t) {
346
+ let r = t, c = h(null), l = n(() => c.value === null ? !!r.streaming : c.value), u = (e) => (r.humanizeName ?? F)(e), f = (e) => (r.earlierLabel ?? ((e) => P(k.agentPanel.timeline.earlier, { count: e })))(e), p = n(() => {
347
+ let e = r.toolCalls.length;
348
+ return r.streaming ? (r.workingLabel ?? ((e) => P(k.agentPanel.timeline.working, { count: e })))(e) : (r.summaryLabel ?? ((e) => P(k.agentPanel.timeline.summary, { count: e })))(e);
349
+ }), _ = n(() => r.toolCalls.slice(-r.maxVisibleCalls)), y = n(() => Math.max(0, r.toolCalls.length - _.value.length)), b = n(() => ({
350
+ fontSize: "12px",
351
+ color: "#5f6368",
352
+ transition: "transform 0.15s ease",
353
+ marginLeft: "8px",
354
+ display: "inline-block",
355
+ transform: l.value ? "rotate(180deg)" : "rotate(0deg)"
356
+ }));
357
+ function x(e = !1) {
358
+ return {
359
+ marginRight: e ? 0 : "6px",
360
+ display: "inline-flex",
361
+ animation: "epAgentSpin 0.8s linear infinite",
362
+ flexShrink: 0
363
+ };
364
+ }
365
+ let S = {
366
+ timelineWrap: {
367
+ alignSelf: "flex-start",
368
+ maxWidth: "92%",
369
+ background: "#fff",
370
+ border: "1px solid #e1e3e6",
371
+ borderRadius: "12px",
372
+ overflow: "hidden",
373
+ fontFamily: "'Google Sans Text', system-ui, sans-serif"
374
+ },
375
+ timelineHeader: {
376
+ display: "flex",
377
+ alignItems: "center",
378
+ justifyContent: "space-between",
379
+ width: "100%",
380
+ padding: "8px 12px",
381
+ background: "transparent",
382
+ border: "none",
383
+ cursor: "pointer",
384
+ fontSize: "12.5px",
385
+ color: "#1f1f1f",
386
+ fontFamily: "inherit"
387
+ },
388
+ timelineSummary: {
389
+ display: "inline-flex",
390
+ alignItems: "center",
391
+ fontWeight: 500
392
+ },
393
+ timelineList: {
394
+ listStyle: "none",
395
+ margin: 0,
396
+ padding: "4px 12px 10px 12px",
397
+ display: "flex",
398
+ flexDirection: "column",
399
+ gap: "6px",
400
+ borderTop: "1px solid #ececf0"
401
+ },
402
+ timelineItem: {
403
+ display: "flex",
404
+ alignItems: "center",
405
+ gap: "8px",
406
+ fontSize: "12px",
407
+ color: "#444746"
408
+ },
409
+ timelineDot: {
410
+ width: "6px",
411
+ height: "6px",
412
+ borderRadius: "50%",
413
+ flexShrink: 0
414
+ },
415
+ timelineCall: {
416
+ display: "inline-flex",
417
+ flexDirection: "column",
418
+ minWidth: 0
419
+ },
420
+ timelineCallName: { color: "#1f1f1f" },
421
+ timelineError: {
422
+ color: "#d93025",
423
+ fontSize: "11px"
424
+ },
425
+ timelineMore: {
426
+ fontSize: "11px",
427
+ color: "#5f6368",
428
+ fontStyle: "italic",
429
+ paddingLeft: "14px"
430
+ }
431
+ };
432
+ return (n, r) => t.toolCalls.length > 0 ? (m(), a("div", {
433
+ key: 0,
434
+ style: d(S.timelineWrap),
435
+ "data-testid": "agent-timeline"
436
+ }, [o("button", {
437
+ type: "button",
438
+ "aria-expanded": l.value,
439
+ style: d(S.timelineHeader),
440
+ "data-testid": "agent-timeline-toggle",
441
+ onClick: r[0] ||= (e) => c.value = !l.value
442
+ }, [o("span", { style: d(S.timelineSummary) }, [t.streaming ? (m(), a("span", {
443
+ key: 0,
444
+ style: d(x()),
445
+ "aria-hidden": "true"
446
+ }, [...r[1] ||= [o("svg", {
447
+ width: "12",
448
+ height: "12",
449
+ viewBox: "0 0 24 24",
450
+ fill: "none"
451
+ }, [o("circle", {
452
+ cx: "12",
453
+ cy: "12",
454
+ r: "9",
455
+ stroke: "#dadce0",
456
+ "stroke-width": "3",
457
+ fill: "none"
458
+ }), o("path", {
459
+ d: "M21 12a9 9 0 0 0-9-9",
460
+ stroke: "#0b57d0",
461
+ "stroke-width": "3",
462
+ "stroke-linecap": "round"
463
+ })], -1)]], 4)) : (m(), a("span", L, [...r[2] ||= [o("svg", {
464
+ width: "12",
465
+ height: "12",
466
+ viewBox: "0 0 24 24",
467
+ fill: "none"
468
+ }, [o("path", {
469
+ d: "M5 13l4 4L19 7",
470
+ stroke: "#1e8e3e",
471
+ "stroke-width": "2.5",
472
+ "stroke-linecap": "round",
473
+ "stroke-linejoin": "round"
474
+ })], -1)]])), s(" " + v(p.value), 1)], 4), o("span", {
475
+ style: d(b.value),
476
+ "aria-hidden": "true"
477
+ }, "", 4)], 12, I), l.value ? (m(), a("ol", {
478
+ key: 0,
479
+ style: d(S.timelineList)
480
+ }, [y.value > 0 ? (m(), a("li", {
481
+ key: 0,
482
+ style: d(S.timelineMore),
483
+ "data-testid": "agent-timeline-earlier"
484
+ }, v(f(y.value)), 5)) : i("", !0), (m(!0), a(e, null, g(_.value, (e) => (m(), a("li", {
485
+ key: e.id,
486
+ style: d(S.timelineItem)
487
+ }, [e.status === "running" ? (m(), a("span", {
488
+ key: 0,
489
+ style: d(x(!0)),
490
+ "aria-hidden": "true"
491
+ }, [...r[3] ||= [o("svg", {
492
+ width: "10",
493
+ height: "10",
494
+ viewBox: "0 0 24 24",
495
+ fill: "none"
496
+ }, [o("circle", {
497
+ cx: "12",
498
+ cy: "12",
499
+ r: "9",
500
+ stroke: "#dadce0",
501
+ "stroke-width": "3",
502
+ fill: "none"
503
+ }), o("path", {
504
+ d: "M21 12a9 9 0 0 0-9-9",
505
+ stroke: "#0b57d0",
506
+ "stroke-width": "3",
507
+ "stroke-linecap": "round"
508
+ })], -1)]], 4)) : (m(), a("span", {
509
+ key: 1,
510
+ style: d({
511
+ ...S.timelineDot,
512
+ background: e.status === "error" ? "#d93025" : "#1e8e3e"
513
+ }),
514
+ "aria-hidden": "true"
515
+ }, null, 4)), o("span", { style: d(S.timelineCall) }, [o("span", { style: d(S.timelineCallName) }, v(u(e.name)), 5), e.error ? (m(), a("span", {
516
+ key: 0,
517
+ style: d(S.timelineError)
518
+ }, v(e.error), 5)) : i("", !0)], 4)], 4))), 128))], 4)) : i("", !0)], 4)) : i("", !0);
519
+ }
520
+ }), ne = ["data-role"], re = ["aria-label"], z = "ep-agent-chat-keyframes", ie = /* @__PURE__ */ c({
521
+ __name: "AgentChatLog",
522
+ props: {
523
+ messages: {},
524
+ loading: {
525
+ type: Boolean,
526
+ default: !1
527
+ },
528
+ error: { default: null },
529
+ thinkingLabel: { default: () => k.agentPanel.thinking },
530
+ workingLabel: {
531
+ type: Function,
532
+ default: void 0
533
+ },
534
+ summaryLabel: {
535
+ type: Function,
536
+ default: void 0
537
+ },
538
+ earlierLabel: {
539
+ type: Function,
540
+ default: void 0
541
+ },
542
+ autoScroll: {
543
+ type: Boolean,
544
+ default: !0
545
+ },
546
+ humanizeToolName: {
547
+ type: Function,
548
+ default: void 0
549
+ },
550
+ maxVisibleCalls: { default: 3 },
551
+ className: { default: "" }
552
+ },
553
+ setup(t) {
554
+ let s = t, c = h(null), f = h(null), y = n(() => s.messages.length === 0 && !s.loading && !s.error);
555
+ function b() {
556
+ if (!s.autoScroll) return;
557
+ let e = s.messages[s.messages.length - 1]?.status === "streaming";
558
+ f.value?.scrollIntoView({
559
+ behavior: e || s.loading ? "auto" : "smooth",
560
+ block: "end"
561
+ });
562
+ }
563
+ p(() => {
564
+ l(b), S();
565
+ }), x([
566
+ () => s.messages.length,
567
+ () => s.messages[s.messages.length - 1]?.toolCalls?.length ?? 0,
568
+ () => s.loading,
569
+ () => s.messages[s.messages.length - 1]?.status === "streaming"
570
+ ], b, { flush: "post" });
571
+ function S() {
572
+ if (typeof document > "u" || document.getElementById(z)) return;
573
+ let e = document.createElement("style");
574
+ e.id = z, e.textContent = "\n@keyframes epAgentDot {\n 0%, 80%, 100% { transform: scale(0.6); opacity: 0.4; }\n 40% { transform: scale(1); opacity: 1; }\n}\n@keyframes epAgentSpin {\n to { transform: rotate(360deg); }\n}\n", document.head.appendChild(e);
575
+ }
576
+ let C = {
577
+ flex: 1,
578
+ overflow: "auto",
579
+ padding: "16px 14px 8px",
580
+ display: "flex",
581
+ flexDirection: "column",
582
+ gap: "10px"
583
+ }, w = {
584
+ messageGroup: {
585
+ display: "flex",
586
+ flexDirection: "column",
587
+ gap: "6px",
588
+ width: "100%"
589
+ },
590
+ userBubble: {
591
+ background: "#0b57d0",
592
+ color: "#fff",
593
+ padding: "10px 14px",
594
+ borderRadius: "20px 20px 4px 20px",
595
+ fontSize: "13.5px",
596
+ lineHeight: 1.5,
597
+ alignSelf: "flex-end",
598
+ maxWidth: "88%",
599
+ whiteSpace: "pre-wrap",
600
+ wordBreak: "break-word",
601
+ fontFamily: "'Google Sans', 'Google Sans Text', system-ui, -apple-system, sans-serif"
602
+ },
603
+ assistantBubble: {
604
+ background: "#f0f4f9",
605
+ color: "#1f1f1f",
606
+ padding: "12px 16px",
607
+ borderRadius: "20px 20px 20px 4px",
608
+ fontSize: "13.5px",
609
+ lineHeight: 1.55,
610
+ alignSelf: "flex-start",
611
+ maxWidth: "92%",
612
+ whiteSpace: "pre-wrap",
613
+ wordBreak: "break-word",
614
+ fontFamily: "'Google Sans', 'Google Sans Text', system-ui, -apple-system, sans-serif"
615
+ },
616
+ thinkingBubble: {
617
+ background: "#f0f4f9",
618
+ padding: "12px 16px",
619
+ borderRadius: "20px 20px 20px 4px",
620
+ alignSelf: "flex-start",
621
+ display: "flex",
622
+ gap: "4px",
623
+ alignItems: "center"
624
+ },
625
+ dot: {
626
+ width: "6px",
627
+ height: "6px",
628
+ borderRadius: "50%",
629
+ background: "#5f6368",
630
+ display: "inline-block",
631
+ animation: "epAgentDot 1.4s infinite ease-in-out"
632
+ },
633
+ errorBubble: {
634
+ background: "#fce8e6",
635
+ color: "#b3261e",
636
+ padding: "10px 14px",
637
+ borderRadius: "16px",
638
+ fontSize: "12.5px",
639
+ alignSelf: "flex-start",
640
+ maxWidth: "92%",
641
+ whiteSpace: "pre-wrap",
642
+ fontFamily: "'Google Sans Text', system-ui, sans-serif"
643
+ }
644
+ };
645
+ return (n, s) => (m(), a("div", {
646
+ class: u(["ep-agent-chat-log", t.className]),
647
+ style: C,
648
+ ref_key: "rootEl",
649
+ ref: c,
650
+ role: "log",
651
+ "aria-live": "polite",
652
+ "aria-atomic": "false"
653
+ }, [
654
+ y.value ? _(n.$slots, "empty", { key: 0 }) : i("", !0),
655
+ (m(!0), a(e, null, g(t.messages, (e) => (m(), a("div", {
656
+ key: e.id,
657
+ style: d(w.messageGroup),
658
+ "data-role": e.role
659
+ }, [e.role === "assistant" && e.toolCalls && e.toolCalls.length > 0 ? (m(), r(R, {
660
+ key: 0,
661
+ "tool-calls": e.toolCalls,
662
+ streaming: e.status === "streaming",
663
+ "humanize-name": t.humanizeToolName,
664
+ "max-visible-calls": t.maxVisibleCalls,
665
+ "working-label": t.workingLabel,
666
+ "summary-label": t.summaryLabel,
667
+ "earlier-label": t.earlierLabel
668
+ }, null, 8, [
669
+ "tool-calls",
670
+ "streaming",
671
+ "humanize-name",
672
+ "max-visible-calls",
673
+ "working-label",
674
+ "summary-label",
675
+ "earlier-label"
676
+ ])) : i("", !0), e.text.length > 0 ? (m(), a("div", {
677
+ key: 1,
678
+ style: d(e.role === "user" ? w.userBubble : w.assistantBubble)
679
+ }, v(e.text), 5)) : i("", !0)], 12, ne))), 128)),
680
+ t.loading ? (m(), a("div", {
681
+ key: 1,
682
+ style: d(w.thinkingBubble),
683
+ "aria-label": t.thinkingLabel
684
+ }, [
685
+ o("span", { style: d({
686
+ ...w.dot,
687
+ animationDelay: "0s"
688
+ }) }, null, 4),
689
+ o("span", { style: d({
690
+ ...w.dot,
691
+ animationDelay: "0.15s"
692
+ }) }, null, 4),
693
+ o("span", { style: d({
694
+ ...w.dot,
695
+ animationDelay: "0.3s"
696
+ }) }, null, 4)
697
+ ], 12, re)) : i("", !0),
698
+ t.error ? (m(), a("div", {
699
+ key: 2,
700
+ style: d(w.errorBubble),
701
+ role: "alert"
702
+ }, v(t.error), 5)) : i("", !0),
703
+ o("div", {
704
+ ref_key: "endEl",
705
+ ref: f
706
+ }, null, 512)
707
+ ], 2));
708
+ }
709
+ }), ae = [
710
+ "value",
711
+ "placeholder",
712
+ "disabled"
713
+ ], oe = ["aria-label", "disabled"], se = /* @__PURE__ */ c({
714
+ __name: "AgentComposer",
715
+ props: {
716
+ modelValue: {},
717
+ disabled: {
718
+ type: Boolean,
719
+ default: !1
720
+ },
721
+ placeholder: { default: () => k.agentPanel.composerPlaceholder },
722
+ sendLabel: { default: () => k.agentPanel.send },
723
+ className: { default: "" }
724
+ },
725
+ emits: ["update:modelValue", "submit"],
726
+ setup(e, { emit: t }) {
727
+ let r = e, s = t, c = n(() => r.modelValue.trim().length > 0 && !r.disabled);
728
+ function l() {
729
+ c.value && s("submit");
730
+ }
731
+ let f = n(() => ({
732
+ width: "36px",
733
+ height: "36px",
734
+ borderRadius: "50%",
735
+ border: "none",
736
+ background: "#0b57d0",
737
+ color: "#fff",
738
+ flexShrink: 0,
739
+ display: "inline-flex",
740
+ alignItems: "center",
741
+ justifyContent: "center",
742
+ transition: "background 0.15s, opacity 0.15s, transform 0.15s",
743
+ opacity: c.value ? 1 : .35,
744
+ cursor: c.value ? "pointer" : "not-allowed"
745
+ })), p = {
746
+ composerWrap: {
747
+ padding: "8px 12px 14px",
748
+ background: "#fff",
749
+ flex: "0 0 auto"
750
+ },
751
+ composerShell: {
752
+ display: "flex",
753
+ alignItems: "center",
754
+ gap: "4px",
755
+ padding: "6px 6px 6px 18px",
756
+ background: "#fff",
757
+ border: "1px solid #c4c7c5",
758
+ borderRadius: "28px",
759
+ boxShadow: "0 1px 2px rgba(60,64,67,0.04)",
760
+ transition: "border-color 0.15s, box-shadow 0.15s",
761
+ fontFamily: "'Google Sans Text', system-ui, sans-serif"
762
+ },
763
+ composerInput: {
764
+ flex: 1,
765
+ padding: "8px 0",
766
+ fontSize: "14px",
767
+ border: "none",
768
+ outline: "none",
769
+ background: "transparent",
770
+ fontFamily: "inherit",
771
+ color: "#1f1f1f"
772
+ },
773
+ footnote: {
774
+ fontSize: "11px",
775
+ color: "#5f6368",
776
+ textAlign: "center",
777
+ marginTop: "10px",
778
+ fontFamily: "'Google Sans Text', system-ui, sans-serif"
779
+ }
780
+ };
781
+ return (t, n) => (m(), a("form", {
782
+ class: u(["ep-agent-composer", e.className]),
783
+ style: d(p.composerWrap),
784
+ onSubmit: w(l, ["prevent"])
785
+ }, [o("div", { style: d(p.composerShell) }, [o("input", {
786
+ style: d(p.composerInput),
787
+ value: e.modelValue,
788
+ placeholder: e.placeholder,
789
+ disabled: e.disabled,
790
+ onInput: n[0] ||= (e) => s("update:modelValue", e.target.value)
791
+ }, null, 44, ae), o("button", {
792
+ type: "submit",
793
+ "aria-label": e.sendLabel,
794
+ disabled: !c.value,
795
+ style: d(f.value)
796
+ }, [...n[1] ||= [o("svg", {
797
+ width: "16",
798
+ height: "16",
799
+ viewBox: "0 0 24 24",
800
+ fill: "none",
801
+ "aria-hidden": "true"
802
+ }, [o("path", {
803
+ d: "M12 19V5M5 12l7-7 7 7",
804
+ stroke: "currentColor",
805
+ "stroke-width": "2",
806
+ "stroke-linecap": "round",
807
+ "stroke-linejoin": "round"
808
+ })], -1)]], 12, oe)], 4), t.$slots.footnote ? (m(), a("div", {
809
+ key: 0,
810
+ style: d(p.footnote)
811
+ }, [_(t.$slots, "footnote")], 4)) : i("", !0)], 38));
812
+ }
813
+ }), ce = ["disabled"], le = /* @__PURE__ */ c({
814
+ __name: "AgentSuggestionChip",
815
+ props: {
816
+ label: {},
817
+ disabled: { type: Boolean }
818
+ },
819
+ emits: ["click"],
820
+ setup(e, { emit: t }) {
821
+ let n = t, r = {
822
+ textAlign: "left",
823
+ background: "#fff",
824
+ border: "1px solid #dadce0",
825
+ borderRadius: "18px",
826
+ padding: "10px 14px",
827
+ fontSize: "13px",
828
+ color: "#1f1f1f",
829
+ cursor: "pointer",
830
+ fontFamily: "'Google Sans Text', system-ui, sans-serif",
831
+ lineHeight: 1.4,
832
+ transition: "background 0.15s, border-color 0.15s, box-shadow 0.15s",
833
+ width: "100%"
834
+ };
835
+ return (t, i) => (m(), a("button", {
836
+ type: "button",
837
+ style: r,
838
+ disabled: e.disabled,
839
+ onClick: i[0] ||= (e) => n("click")
840
+ }, v(e.label), 9, ce));
841
+ }
842
+ }), ue = ["aria-label"], de = {
843
+ class: "ai-ctx-menu__header",
844
+ "aria-hidden": "true"
845
+ }, fe = ["onMousedown"], pe = ["innerHTML"], me = { class: "ai-ctx-menu__label" }, he = {
846
+ key: 0,
847
+ class: "ai-ctx-menu__custom"
848
+ }, ge = ["placeholder"], _e = /* @__PURE__ */ c({
849
+ __name: "AIContextMenu",
850
+ props: {
851
+ isOpen: { type: Boolean },
852
+ position: {},
853
+ selectedText: {},
854
+ showCustomPrompt: {
855
+ type: Boolean,
856
+ default: !0
857
+ },
858
+ labels: { default: () => ({}) }
859
+ },
860
+ emits: ["close", "action"],
861
+ setup(s, { emit: c }) {
862
+ let u = s, f = c, p = h(""), _ = h([]);
863
+ x(() => u.isOpen, (e) => {
864
+ e && l(() => _.value[0]?.focus());
865
+ }, { immediate: !0 });
866
+ let y = [
867
+ {
868
+ id: "rewrite",
869
+ icon: "&#x270D;"
870
+ },
871
+ {
872
+ id: "expand",
873
+ icon: "&#x2194;"
874
+ },
875
+ {
876
+ id: "summarize",
877
+ icon: "&#x1F4DD;"
878
+ },
879
+ {
880
+ id: "fixGrammar",
881
+ icon: "&#x2714;"
882
+ },
883
+ {
884
+ id: "makeFormal",
885
+ icon: "&#x1F454;"
886
+ },
887
+ {
888
+ id: "makeCasual",
889
+ icon: "&#x1F60A;"
890
+ },
891
+ {
892
+ id: "translate",
893
+ icon: "&#x1F310;"
894
+ },
895
+ {
896
+ id: "explain",
897
+ icon: "&#x1F4A1;"
898
+ }
899
+ ], T = n(() => u.labels?.header ?? k.aiActions.header), E = n(() => u.labels?.customPlaceholder ?? k.aiActions.customPlaceholder);
900
+ function D(e) {
901
+ return u.labels?.[e] || (k.aiActions[e] ?? e);
902
+ }
903
+ let O = n(() => {
904
+ let e = u.position.x, t = u.position.y;
905
+ return typeof window < "u" && (e + 220 + 10 > window.innerWidth && (e = window.innerWidth - 220 - 10), t + 360 + 10 > window.innerHeight && (t = window.innerHeight - 360 - 10)), {
906
+ position: "fixed",
907
+ left: `${e}px`,
908
+ top: `${t}px`,
909
+ zIndex: 500
910
+ };
911
+ });
912
+ function A(e) {
913
+ f("action", e, e === "custom" ? p.value : void 0), p.value = "", f("close");
914
+ }
915
+ return (n, c) => (m(), r(t, { to: "body" }, [s.isOpen ? (m(), a("div", {
916
+ key: 0,
917
+ class: "ai-ctx-backdrop",
918
+ onMousedown: c[0] ||= (e) => f("close"),
919
+ onContextmenu: c[1] ||= w((e) => f("close"), ["prevent"])
920
+ }, null, 32)) : i("", !0), s.isOpen ? (m(), a("div", {
921
+ key: 1,
922
+ class: "ai-ctx-menu",
923
+ "aria-label": T.value,
924
+ style: d(O.value),
925
+ tabindex: "-1",
926
+ onContextmenu: c[4] ||= w(() => {}, ["prevent"]),
927
+ onKeydown: c[5] ||= C(w((e) => f("close"), ["stop"]), ["esc"])
928
+ }, [
929
+ o("div", de, v(T.value), 1),
930
+ (m(), a(e, null, g(y, (e) => o("button", {
931
+ key: e.id,
932
+ ref_for: !0,
933
+ ref_key: "itemRefs",
934
+ ref: _,
935
+ class: "ai-ctx-menu__item",
936
+ onMousedown: w((t) => A(e.id), ["prevent"])
937
+ }, [o("span", {
938
+ class: "ai-ctx-menu__icon",
939
+ innerHTML: e.icon
940
+ }, null, 8, pe), o("span", me, v(D(e.id)), 1)], 40, fe)), 64)),
941
+ c[6] ||= o("div", { class: "ai-ctx-menu__divider" }, null, -1),
942
+ s.showCustomPrompt ? (m(), a("div", he, [S(o("input", {
943
+ "onUpdate:modelValue": c[2] ||= (e) => p.value = e,
944
+ class: "ai-ctx-menu__input",
945
+ placeholder: E.value,
946
+ onKeydown: c[3] ||= C(w((e) => A("custom"), ["prevent"]), ["enter"])
947
+ }, null, 40, ge), [[b, p.value]])])) : i("", !0)
948
+ ], 44, ue)) : i("", !0)]));
949
+ }
950
+ }), B = (e, t) => {
951
+ let n = e.__vccOpts || e;
952
+ for (let [e, r] of t) n[e] = r;
953
+ return n;
954
+ }, ve = /* @__PURE__ */ B(_e, [["__scopeId", "data-v-c30da7a7"]]), ye = ["aria-label"], be = { class: "ai-preview__header" }, xe = { class: "ai-preview__title" }, Se = ["aria-label"], Ce = {
955
+ key: 0,
956
+ class: "ai-preview__loading"
957
+ }, we = {
958
+ key: 1,
959
+ class: "ai-preview__error"
960
+ }, Te = {
961
+ key: 2,
962
+ class: "ai-preview__content"
963
+ }, Ee = {
964
+ key: 0,
965
+ class: "ai-preview__diff"
966
+ }, De = { class: "ai-preview__diff-label" }, Oe = { class: "ai-preview__diff-text ai-preview__diff-text--old" }, ke = { class: "ai-preview__diff-label" }, Ae = { class: "ai-preview__diff-text ai-preview__diff-text--new" }, je = {
967
+ key: 1,
968
+ class: "ai-preview__result"
969
+ }, Me = {
970
+ key: 3,
971
+ class: "ai-preview__footer"
972
+ }, Ne = /* @__PURE__ */ B(/* @__PURE__ */ c({
973
+ __name: "AIResponsePreview",
974
+ props: {
975
+ isVisible: { type: Boolean },
976
+ originalText: {},
977
+ responseText: {},
978
+ action: {},
979
+ isLoading: { type: Boolean },
980
+ error: { default: void 0 },
981
+ allowEdit: {
982
+ type: Boolean,
983
+ default: !0
984
+ },
985
+ showDiff: {
986
+ type: Boolean,
987
+ default: !0
988
+ },
989
+ showRetry: {
990
+ type: Boolean,
991
+ default: !0
992
+ },
993
+ labels: { default: () => ({}) }
994
+ },
995
+ emits: [
996
+ "accept",
997
+ "reject",
998
+ "retry"
999
+ ],
1000
+ setup(e, { emit: t }) {
1001
+ let r = e, s = t, c = h(!1), l = h(""), u = n(() => ({
1002
+ loading: r.labels?.loading ?? k.aiPreview.loading,
1003
+ original: r.labels?.original ?? k.aiPreview.original,
1004
+ suggested: r.labels?.suggested ?? k.aiPreview.suggested,
1005
+ edit: r.labels?.edit ?? k.aiPreview.edit,
1006
+ discard: r.labels?.discard ?? k.aiPreview.discard,
1007
+ accept: r.labels?.accept ?? k.aiPreview.accept,
1008
+ retry: r.labels?.retry ?? k.aiPreview.retry,
1009
+ close: r.labels?.close ?? k.aiPreview.close
1010
+ })), d = n(() => r.labels?.actionTitles?.[r.action] || (k.aiPreview.labels[r.action] ?? k.aiPreview.defaultTitle));
1011
+ x(() => r.responseText, (e) => {
1012
+ l.value = e, c.value = !1;
1013
+ });
1014
+ function f() {
1015
+ s("accept", c.value ? l.value : r.responseText);
1016
+ }
1017
+ return (t, n) => e.isVisible ? (m(), a("div", {
1018
+ key: 0,
1019
+ class: "ai-preview",
1020
+ role: "region",
1021
+ "aria-label": d.value,
1022
+ tabindex: "-1",
1023
+ onKeydown: n[5] ||= C(w((e) => s("reject"), ["stop"]), ["esc"])
1024
+ }, [
1025
+ o("div", be, [o("span", xe, v(d.value), 1), o("button", {
1026
+ class: "ai-preview__close",
1027
+ "aria-label": u.value.close,
1028
+ onClick: n[0] ||= (e) => s("reject")
1029
+ }, " ✕ ", 8, Se)]),
1030
+ e.isLoading ? (m(), a("div", Ce, [n[6] ||= o("span", { class: "ai-preview__spinner" }, null, -1), o("span", null, v(u.value.loading), 1)])) : e.error ? (m(), a("div", we, [o("span", null, v(e.error), 1), e.showRetry ? (m(), a("button", {
1031
+ key: 0,
1032
+ class: "ai-preview__retry",
1033
+ onMousedown: n[1] ||= w((e) => s("retry"), ["prevent"])
1034
+ }, v(u.value.retry), 33)) : i("", !0)])) : (m(), a("div", Te, [e.showDiff ? (m(), a("div", Ee, [
1035
+ o("div", De, v(u.value.original), 1),
1036
+ o("div", Oe, v(e.originalText), 1),
1037
+ o("div", ke, v(u.value.suggested), 1),
1038
+ o("div", Ae, v(e.responseText), 1)
1039
+ ])) : (m(), a("div", je, v(e.responseText), 1)), e.allowEdit && c.value ? S((m(), a("textarea", {
1040
+ key: 2,
1041
+ "onUpdate:modelValue": n[2] ||= (e) => l.value = e,
1042
+ class: "ai-preview__textarea",
1043
+ rows: "4"
1044
+ }, null, 512)), [[b, l.value]]) : i("", !0)])),
1045
+ !e.isLoading && !e.error ? (m(), a("div", Me, [
1046
+ e.allowEdit && !c.value ? (m(), a("button", {
1047
+ key: 0,
1048
+ class: "ai-preview__btn",
1049
+ onMousedown: n[3] ||= w((e) => c.value = !0, ["prevent"])
1050
+ }, v(u.value.edit), 33)) : i("", !0),
1051
+ o("button", {
1052
+ class: "ai-preview__btn",
1053
+ onMousedown: n[4] ||= w((e) => s("reject"), ["prevent"])
1054
+ }, v(u.value.discard), 33),
1055
+ o("button", {
1056
+ class: "ai-preview__btn ai-preview__btn--primary",
1057
+ onMousedown: w(f, ["prevent"])
1058
+ }, v(u.value.accept), 33)
1059
+ ])) : i("", !0)
1060
+ ], 40, ye)) : i("", !0);
1061
+ }
1062
+ }), [["__scopeId", "data-v-1226b741"]]), V = [
1063
+ "single",
1064
+ "words",
1065
+ "double",
1066
+ "thick",
1067
+ "dotted",
1068
+ "dottedHeavy",
1069
+ "dash",
1070
+ "dashedHeavy",
1071
+ "dashLong",
1072
+ "dashLongHeavy",
1073
+ "dotDash",
1074
+ "dashDotHeavy",
1075
+ "dotDotDash",
1076
+ "dashDotDotHeavy",
1077
+ "wave",
1078
+ "wavyHeavy",
1079
+ "wavyDouble",
1080
+ "none"
1081
+ ], H = [
1082
+ "black",
1083
+ "blue",
1084
+ "cyan",
1085
+ "darkBlue",
1086
+ "darkCyan",
1087
+ "darkGray",
1088
+ "darkGreen",
1089
+ "darkMagenta",
1090
+ "darkRed",
1091
+ "darkYellow",
1092
+ "green",
1093
+ "lightGray",
1094
+ "magenta",
1095
+ "red",
1096
+ "white",
1097
+ "yellow",
1098
+ "none"
1099
+ ], U = [
1100
+ {
1101
+ name: "read_document",
1102
+ displayName: "Reading document",
1103
+ 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 — 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.",
1104
+ inputSchema: {
1105
+ type: "object",
1106
+ properties: {
1107
+ fromIndex: {
1108
+ type: "number",
1109
+ description: "Start ordinal index (inclusive). Optional."
1110
+ },
1111
+ toIndex: {
1112
+ type: "number",
1113
+ description: "End ordinal index (inclusive). Optional."
1114
+ }
1115
+ }
1116
+ },
1117
+ handler: (e, t) => ({
1118
+ success: !0,
1119
+ data: t.getContentAsText({
1120
+ fromIndex: e.fromIndex,
1121
+ toIndex: e.toIndex,
1122
+ includeTrackedChanges: !1,
1123
+ includeCommentAnchors: !1
1124
+ })
1125
+ })
1126
+ },
1127
+ {
1128
+ name: "read_selection",
1129
+ displayName: "Reading selection",
1130
+ 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\".",
1131
+ inputSchema: {
1132
+ type: "object",
1133
+ properties: {}
1134
+ },
1135
+ handler: (e, t) => {
1136
+ let n = t.getSelection();
1137
+ return n ? {
1138
+ success: !0,
1139
+ data: n
1140
+ } : {
1141
+ success: !1,
1142
+ error: "No selection (editor not focused)."
1143
+ };
1144
+ }
1145
+ },
1146
+ {
1147
+ name: "read_page",
1148
+ displayName: "Reading page",
1149
+ 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\".",
1150
+ inputSchema: {
1151
+ type: "object",
1152
+ properties: { pageNumber: {
1153
+ type: "number",
1154
+ description: "1-indexed page number."
1155
+ } },
1156
+ required: ["pageNumber"]
1157
+ },
1158
+ handler: (e, t) => {
1159
+ let n = t.getPage(e.pageNumber);
1160
+ if (!n) {
1161
+ let n = t.getTotalPages();
1162
+ return n === 0 ? {
1163
+ success: !1,
1164
+ error: "No pages rendered (headless mode or empty document)."
1165
+ } : {
1166
+ success: !1,
1167
+ error: `Page ${e.pageNumber} does not exist (document has ${n} page${n === 1 ? "" : "s"}).`
1168
+ };
1169
+ }
1170
+ return {
1171
+ success: !0,
1172
+ data: n.text || "(empty page)"
1173
+ };
1174
+ }
1175
+ },
1176
+ {
1177
+ name: "read_pages",
1178
+ displayName: "Reading pages",
1179
+ 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 — single round-trip.",
1180
+ inputSchema: {
1181
+ type: "object",
1182
+ properties: {
1183
+ from: {
1184
+ type: "number",
1185
+ description: "1-indexed start page (inclusive)."
1186
+ },
1187
+ to: {
1188
+ type: "number",
1189
+ description: "1-indexed end page (inclusive)."
1190
+ }
1191
+ },
1192
+ required: ["from", "to"]
1193
+ },
1194
+ handler: (e, t) => {
1195
+ let n = t.getPages({
1196
+ from: e.from,
1197
+ to: e.to
1198
+ });
1199
+ if (n.length === 0) {
1200
+ let n = t.getTotalPages();
1201
+ return n === 0 ? {
1202
+ success: !1,
1203
+ error: "No pages rendered (headless mode or empty document)."
1204
+ } : {
1205
+ success: !1,
1206
+ error: `No pages in range ${e.from}–${e.to} (document has ${n} page${n === 1 ? "" : "s"}).`
1207
+ };
1208
+ }
1209
+ return {
1210
+ success: !0,
1211
+ data: n.map((e) => `--- Page ${e.pageNumber} ---\n${e.text || "(empty page)"}`).join("\n\n")
1212
+ };
1213
+ }
1214
+ },
1215
+ {
1216
+ name: "find_text",
1217
+ displayName: "Finding text",
1218
+ 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.",
1219
+ inputSchema: {
1220
+ type: "object",
1221
+ properties: {
1222
+ query: {
1223
+ type: "string",
1224
+ description: "Text to find (substring match)."
1225
+ },
1226
+ caseSensitive: {
1227
+ type: "boolean",
1228
+ description: "Default: false."
1229
+ },
1230
+ limit: {
1231
+ type: "number",
1232
+ description: "Max paragraphs to return. Default: 20."
1233
+ }
1234
+ },
1235
+ required: ["query"]
1236
+ },
1237
+ handler: (e, t) => {
1238
+ let n = t.findText(e.query, {
1239
+ caseSensitive: e.caseSensitive,
1240
+ limit: e.limit
1241
+ });
1242
+ return n.length === 0 ? {
1243
+ success: !0,
1244
+ data: "No matches."
1245
+ } : {
1246
+ success: !0,
1247
+ data: n
1248
+ };
1249
+ }
1250
+ },
1251
+ {
1252
+ name: "read_comments",
1253
+ displayName: "Reading comments",
1254
+ description: "List all comments in the document with their paragraph anchors.",
1255
+ inputSchema: {
1256
+ type: "object",
1257
+ properties: {}
1258
+ },
1259
+ handler: (e, t) => {
1260
+ let n = t.getComments();
1261
+ return n.length === 0 ? {
1262
+ success: !0,
1263
+ data: "No comments."
1264
+ } : {
1265
+ success: !0,
1266
+ data: n.map((e) => `[Comment #${e.id}] ${e.author}: "${e.text}"` + (e.anchoredText ? ` (anchored to: "${e.anchoredText}")` : "") + (e.replies.length > 0 ? "\n" + e.replies.map((e) => ` Reply by ${e.author}: "${e.text}"`).join("\n") : "")).join("\n")
1267
+ };
1268
+ }
1269
+ },
1270
+ {
1271
+ name: "read_changes",
1272
+ displayName: "Reading changes",
1273
+ description: "List tracked changes (insertions / deletions) currently in the document.",
1274
+ inputSchema: {
1275
+ type: "object",
1276
+ properties: {}
1277
+ },
1278
+ handler: (e, t) => {
1279
+ let n = t.getChanges();
1280
+ return n.length === 0 ? {
1281
+ success: !0,
1282
+ data: "No tracked changes."
1283
+ } : {
1284
+ success: !0,
1285
+ data: n.map((e) => `[Change #${e.id}] ${e.type} by ${e.author}: "${e.text}"`).join("\n")
1286
+ };
1287
+ }
1288
+ },
1289
+ {
1290
+ name: "add_comment",
1291
+ displayName: "Adding comment",
1292
+ description: "Attach a comment to a paragraph, optionally anchored to a unique phrase within it. The user sees it instantly in the comments sidebar.",
1293
+ inputSchema: {
1294
+ type: "object",
1295
+ properties: {
1296
+ paraId: {
1297
+ type: "string",
1298
+ description: "Paragraph id from read_document / find_text."
1299
+ },
1300
+ text: {
1301
+ type: "string",
1302
+ description: "Comment body."
1303
+ },
1304
+ search: {
1305
+ type: "string",
1306
+ description: "Optional: anchor to this exact phrase within the paragraph. Must be unique."
1307
+ }
1308
+ },
1309
+ required: ["paraId", "text"]
1310
+ },
1311
+ handler: (e, t) => {
1312
+ let n = t.addComment({
1313
+ paraId: e.paraId,
1314
+ text: e.text,
1315
+ search: e.search
1316
+ });
1317
+ return n === null ? {
1318
+ success: !1,
1319
+ error: "Could not add comment. The paraId may not exist, or `search` is missing / ambiguous."
1320
+ } : {
1321
+ success: !0,
1322
+ data: `Comment ${n} added on ${e.paraId}.`
1323
+ };
1324
+ }
1325
+ },
1326
+ {
1327
+ name: "suggest_change",
1328
+ displayName: "Suggesting change",
1329
+ description: "Suggest a tracked change. Three modes: (1) replacement — `search` non-empty, `replaceWith` non-empty; (2) deletion — `search` non-empty, `replaceWith` empty; (3) insertion at paragraph end — `search` empty, `replaceWith` non-empty. The user can accept or reject in the editor UI.",
1330
+ inputSchema: {
1331
+ type: "object",
1332
+ properties: {
1333
+ paraId: {
1334
+ type: "string",
1335
+ description: "Paragraph id from read_document / find_text."
1336
+ },
1337
+ search: {
1338
+ type: "string",
1339
+ description: "Phrase to find (must be unique). Empty string = insert at paragraph end."
1340
+ },
1341
+ replaceWith: {
1342
+ type: "string",
1343
+ description: "Replacement text. Empty string = delete the matched phrase."
1344
+ }
1345
+ },
1346
+ required: [
1347
+ "paraId",
1348
+ "search",
1349
+ "replaceWith"
1350
+ ]
1351
+ },
1352
+ handler: (e, t) => t.proposeChange({
1353
+ paraId: e.paraId,
1354
+ search: e.search,
1355
+ replaceWith: e.replaceWith
1356
+ }) ? e.search ? e.replaceWith ? {
1357
+ success: !0,
1358
+ data: `Replacement proposed: "${e.search}" "${e.replaceWith}" on ${e.paraId}.`
1359
+ } : {
1360
+ success: !0,
1361
+ data: `Deletion proposed: "${e.search}" on ${e.paraId}.`
1362
+ } : {
1363
+ success: !0,
1364
+ data: `Insertion proposed on ${e.paraId}.`
1365
+ } : {
1366
+ success: !1,
1367
+ error: "Could not propose change. Possible causes: paraId not found; search missing or ambiguous; or the target overlaps an existing tracked change."
1368
+ }
1369
+ },
1370
+ {
1371
+ name: "apply_formatting",
1372
+ displayName: "Applying formatting",
1373
+ 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 — 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}`.",
1374
+ inputSchema: {
1375
+ type: "object",
1376
+ properties: {
1377
+ paraId: {
1378
+ type: "string",
1379
+ description: "Paragraph id from read_document / find_text."
1380
+ },
1381
+ search: {
1382
+ type: "string",
1383
+ description: "Optional: format only this exact phrase within the paragraph (must be unique)."
1384
+ },
1385
+ marks: {
1386
+ type: "object",
1387
+ description: "Marks to set or clear. Omit a key to leave it untouched.",
1388
+ properties: {
1389
+ bold: { type: "boolean" },
1390
+ italic: { type: "boolean" },
1391
+ underline: { description: "true → single underline; false → 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." },
1392
+ strike: { type: "boolean" },
1393
+ color: {
1394
+ type: "object",
1395
+ description: "Either {rgb: \"RRGGBB\"} (no hash) or {themeColor: \"accent1\"|\"text1\"|...}.",
1396
+ properties: {
1397
+ rgb: { type: "string" },
1398
+ themeColor: { type: "string" }
1399
+ }
1400
+ },
1401
+ highlight: {
1402
+ type: "string",
1403
+ enum: [...H],
1404
+ description: "Highlight color — must be one of the Word-supported names: " + H.join(", ") + ". Pass \"none\" to clear. Hex values are rejected (Word does not accept hex for <w:highlight>)."
1405
+ },
1406
+ fontSize: {
1407
+ type: "number",
1408
+ description: "Size in points (e.g. 12, 14, 24)."
1409
+ },
1410
+ fontFamily: {
1411
+ type: "object",
1412
+ properties: {
1413
+ ascii: { type: "string" },
1414
+ hAnsi: { type: "string" }
1415
+ }
1416
+ }
1417
+ }
1418
+ }
1419
+ },
1420
+ required: ["paraId", "marks"]
1421
+ },
1422
+ handler: (e, t) => {
1423
+ if (!e.marks || Object.keys(e.marks).length === 0) return {
1424
+ success: !1,
1425
+ error: "No marks provided. Specify at least one of bold/italic/etc."
1426
+ };
1427
+ let n = typeof e.marks.underline == "object" && e.marks.underline !== null ? e.marks.underline.style : void 0;
1428
+ if (n && !V.includes(n)) return {
1429
+ success: !1,
1430
+ error: `Invalid underline.style "${n}". Must be one of: ${V.join(", ")}.`
1431
+ };
1432
+ let r = typeof e.marks.highlight == "string" ? e.marks.highlight : void 0;
1433
+ if (r && !H.includes(r)) return {
1434
+ success: !1,
1435
+ error: `Invalid highlight "${r}". Must be one of: ${H.join(", ")}. Hex values are not supported by Word's highlight attribute.`
1436
+ };
1437
+ let i = r === "none" ? {
1438
+ ...e.marks,
1439
+ highlight: ""
1440
+ } : e.marks;
1441
+ return t.applyFormatting({
1442
+ paraId: e.paraId,
1443
+ search: e.search,
1444
+ marks: i
1445
+ }) ? {
1446
+ success: !0,
1447
+ data: `Formatting applied to ${e.search ? `"${e.search}" in ${e.paraId}` : e.paraId}.`
1448
+ } : {
1449
+ success: !1,
1450
+ error: "Could not apply formatting. The paraId may not exist, or `search` is missing / ambiguous."
1451
+ };
1452
+ }
1453
+ },
1454
+ {
1455
+ name: "set_paragraph_style",
1456
+ displayName: "Setting paragraph style",
1457
+ description: "Apply a paragraph style by id (e.g. \"Heading1\", \"Heading2\", \"Title\", \"Quote\", \"Normal\"). The styleId must exist in the document's style definitions — unknown ids are no-ops. Direct edit, not a tracked change.",
1458
+ inputSchema: {
1459
+ type: "object",
1460
+ properties: {
1461
+ paraId: {
1462
+ type: "string",
1463
+ description: "Paragraph id from read_document / find_text."
1464
+ },
1465
+ styleId: {
1466
+ type: "string",
1467
+ description: "Style id (e.g. \"Heading1\", \"Title\", \"Quote\", \"Normal\")."
1468
+ }
1469
+ },
1470
+ required: ["paraId", "styleId"]
1471
+ },
1472
+ handler: (e, t) => t.setParagraphStyle({
1473
+ paraId: e.paraId,
1474
+ styleId: e.styleId
1475
+ }) ? {
1476
+ success: !0,
1477
+ data: `Style "${e.styleId}" applied to ${e.paraId}.`
1478
+ } : {
1479
+ success: !1,
1480
+ error: `Could not set style. paraId "${e.paraId}" not found, or styleId "${e.styleId}" is not defined.`
1481
+ }
1482
+ },
1483
+ {
1484
+ name: "reply_comment",
1485
+ displayName: "Replying to comment",
1486
+ description: "Reply to an existing comment by id. Threaded under the original.",
1487
+ inputSchema: {
1488
+ type: "object",
1489
+ properties: {
1490
+ commentId: {
1491
+ type: "number",
1492
+ description: "Comment id from read_comments."
1493
+ },
1494
+ text: {
1495
+ type: "string",
1496
+ description: "Reply body."
1497
+ }
1498
+ },
1499
+ required: ["commentId", "text"]
1500
+ },
1501
+ handler: (e, t) => {
1502
+ let n = t.replyTo(e.commentId, { text: e.text });
1503
+ return n === null ? {
1504
+ success: !1,
1505
+ error: `Comment #${e.commentId} not found.`
1506
+ } : {
1507
+ success: !0,
1508
+ data: `Reply ${n} added to comment ${e.commentId}.`
1509
+ };
1510
+ }
1511
+ },
1512
+ {
1513
+ name: "resolve_comment",
1514
+ displayName: "Resolving comment",
1515
+ description: "Mark a comment as resolved (done).",
1516
+ inputSchema: {
1517
+ type: "object",
1518
+ properties: { commentId: {
1519
+ type: "number",
1520
+ description: "Comment id from read_comments."
1521
+ } },
1522
+ required: ["commentId"]
1523
+ },
1524
+ handler: (e, t) => (t.resolveComment(e.commentId), {
1525
+ success: !0,
1526
+ data: `Comment ${e.commentId} resolved.`
1527
+ })
1528
+ },
1529
+ {
1530
+ name: "scroll",
1531
+ displayName: "Scrolling",
1532
+ description: "Scroll the editor to a paragraph by paraId. Does not move the user's cursor.",
1533
+ inputSchema: {
1534
+ type: "object",
1535
+ properties: { paraId: {
1536
+ type: "string",
1537
+ description: "Paragraph id from read_document / find_text."
1538
+ } },
1539
+ required: ["paraId"]
1540
+ },
1541
+ handler: (e, t) => t.scrollTo(e.paraId) ? {
1542
+ success: !0,
1543
+ data: `Scrolled to ${e.paraId}.`
1544
+ } : {
1545
+ success: !1,
1546
+ error: `paraId ${e.paraId} not found.`
1547
+ }
1548
+ }
1397
1549
  ];
1398
- function $t(e, a, n) {
1399
- const t = G.find((o) => o.name === e);
1400
- if (!t) return { success: !1, error: `Unknown tool: ${e}` };
1401
- try {
1402
- return t.handler(a, n);
1403
- } catch (o) {
1404
- return { success: !1, error: o instanceof Error ? o.message : String(o) };
1405
- }
1550
+ function Pe(e, t, n) {
1551
+ let r = U.find((t) => t.name === e);
1552
+ if (!r) return {
1553
+ success: !1,
1554
+ error: `Unknown tool: ${e}`
1555
+ };
1556
+ try {
1557
+ return r.handler(t, n);
1558
+ } catch (e) {
1559
+ return {
1560
+ success: !1,
1561
+ error: e instanceof Error ? e.message : String(e)
1562
+ };
1563
+ }
1406
1564
  }
1407
- function Gt(e) {
1408
- const a = G.find((t) => t.name === e);
1409
- if (a?.displayName) return a.displayName;
1410
- const n = e.replace(/_/g, " ");
1411
- return n.charAt(0).toUpperCase() + n.slice(1);
1565
+ function Fe(e) {
1566
+ let t = U.find((t) => t.name === e);
1567
+ if (t?.displayName) return t.displayName;
1568
+ let n = e.replace(/_/g, " ");
1569
+ return n.charAt(0).toUpperCase() + n.slice(1);
1412
1570
  }
1413
- function Tt() {
1414
- return G.map((e) => ({
1415
- type: "function",
1416
- function: {
1417
- name: e.name,
1418
- description: e.description,
1419
- parameters: e.inputSchema
1420
- }
1421
- }));
1571
+ function Ie() {
1572
+ return U.map((e) => ({
1573
+ type: "function",
1574
+ function: {
1575
+ name: e.name,
1576
+ description: e.description,
1577
+ parameters: e.inputSchema
1578
+ }
1579
+ }));
1422
1580
  }
1581
+ //#endregion
1582
+ //#region src/utils.ts
1423
1583
  function W(e) {
1424
- return e.type === "insertion" || e.type === "deletion" || e.type === "moveFrom" || e.type === "moveTo";
1584
+ return e.type === "insertion" || e.type === "deletion" || e.type === "moveFrom" || e.type === "moveTo";
1425
1585
  }
1426
- function V(e) {
1427
- const a = [];
1428
- for (const n of e)
1429
- n.type === "run" ? a.push(P(n)) : n.type === "hyperlink" && a.push(re(n));
1430
- return a.join("");
1586
+ function G(e) {
1587
+ let t = [];
1588
+ for (let n of e) n.type === "run" ? t.push(E(n)) : n.type === "hyperlink" && t.push(T(n));
1589
+ return t.join("");
1431
1590
  }
1432
- function ie(e, a) {
1433
- let n = 0;
1434
- for (const t of e.content)
1435
- if (t.type === "paragraph") {
1436
- if (a(t, n) === !1) return;
1437
- n++;
1438
- } else if (t.type === "table") {
1439
- for (const o of t.rows)
1440
- for (const r of o.cells)
1441
- for (const i of r.content)
1442
- if (i.type === "paragraph") {
1443
- if (a(i, n) === !1) return;
1444
- n++;
1445
- }
1446
- } else
1447
- n++;
1591
+ function K(e, t) {
1592
+ let n = 0;
1593
+ for (let r of e.content) if (r.type === "paragraph") {
1594
+ if (t(r, n) === !1) return;
1595
+ n++;
1596
+ } else if (r.type === "table") {
1597
+ for (let e of r.rows) for (let r of e.cells) for (let e of r.content) if (e.type === "paragraph") {
1598
+ if (t(e, n) === !1) return;
1599
+ n++;
1600
+ }
1601
+ } else n++;
1448
1602
  }
1449
- function Z(e, a = {}) {
1450
- const {
1451
- fromIndex: n,
1452
- toIndex: t,
1453
- includeTrackedChanges: o = !0,
1454
- includeCommentAnchors: r = !0
1455
- } = a, i = [];
1456
- let s = 0;
1457
- for (const d of e.content)
1458
- if (d.type === "paragraph")
1459
- X(s, n, t) && i.push(
1460
- Pt(d, s, o, r)
1461
- ), s++;
1462
- else if (d.type === "table") {
1463
- X(s, n, t) && i.push(_t(d, s, o, r));
1464
- for (const c of d.rows)
1465
- for (const l of c.cells)
1466
- for (const u of l.content)
1467
- u.type === "paragraph" && s++;
1468
- } else
1469
- s++;
1470
- return i;
1603
+ //#endregion
1604
+ //#region src/content.ts
1605
+ function q(e, t = {}) {
1606
+ let { fromIndex: n, toIndex: r, includeTrackedChanges: i = !0, includeCommentAnchors: a = !0 } = t, o = [], s = 0;
1607
+ for (let t of e.content) if (t.type === "paragraph") J(s, n, r) && o.push(Le(t, s, i, a)), s++;
1608
+ else if (t.type === "table") {
1609
+ J(s, n, r) && o.push(Re(t, s, i, a));
1610
+ for (let e of t.rows) for (let t of e.cells) for (let e of t.content) e.type === "paragraph" && s++;
1611
+ } else s++;
1612
+ return o;
1471
1613
  }
1472
- function X(e, a, n) {
1473
- return (a === void 0 || e >= a) && (n === void 0 || e <= n);
1614
+ function J(e, t, n) {
1615
+ return (t === void 0 || e >= t) && (n === void 0 || e <= n);
1474
1616
  }
1475
- function Pt(e, a, n, t) {
1476
- const o = le(e, n, t), r = e.formatting?.styleId, i = e.paraId;
1477
- return ke(r) ? {
1478
- type: "heading",
1479
- index: a,
1480
- paraId: i,
1481
- level: Ie(r) ?? 1,
1482
- text: o
1483
- } : e.listRendering ? {
1484
- type: "list-item",
1485
- index: a,
1486
- paraId: i,
1487
- text: o,
1488
- listLevel: e.listRendering.level ?? 0,
1489
- listType: e.listRendering.isBullet ? "bullet" : "number"
1490
- } : { type: "paragraph", index: a, paraId: i, text: o };
1617
+ function Le(e, t, n, r) {
1618
+ let i = Y(e, n, r), a = e.formatting?.styleId, o = e.paraId;
1619
+ return D(a) ? {
1620
+ type: "heading",
1621
+ index: t,
1622
+ paraId: o,
1623
+ level: O(a) ?? 1,
1624
+ text: i
1625
+ } : e.listRendering ? {
1626
+ type: "list-item",
1627
+ index: t,
1628
+ paraId: o,
1629
+ text: i,
1630
+ listLevel: e.listRendering.level ?? 0,
1631
+ listType: e.listRendering.isBullet ? "bullet" : "number"
1632
+ } : {
1633
+ type: "paragraph",
1634
+ index: t,
1635
+ paraId: o,
1636
+ text: i
1637
+ };
1491
1638
  }
1492
- function _t(e, a, n, t) {
1493
- const o = [], r = [];
1494
- for (const i of e.rows) {
1495
- const s = [], d = [];
1496
- for (const c of i.cells) {
1497
- const l = [];
1498
- let u;
1499
- for (const g of c.content)
1500
- g.type === "paragraph" && (u === void 0 && (u = g.paraId), l.push(le(g, n, t)));
1501
- s.push(l.join(`
1502
- `)), d.push(u);
1503
- }
1504
- o.push(s), r.push(d);
1505
- }
1506
- return { type: "table", index: a, rows: o, cellParaIds: r };
1639
+ function Re(e, t, n, r) {
1640
+ let i = [], a = [];
1641
+ for (let t of e.rows) {
1642
+ let e = [], o = [];
1643
+ for (let i of t.cells) {
1644
+ let t = [], a;
1645
+ for (let e of i.content) e.type === "paragraph" && (a === void 0 && (a = e.paraId), t.push(Y(e, n, r)));
1646
+ e.push(t.join("\n")), o.push(a);
1647
+ }
1648
+ i.push(e), a.push(o);
1649
+ }
1650
+ return {
1651
+ type: "table",
1652
+ index: t,
1653
+ rows: i,
1654
+ cellParaIds: a
1655
+ };
1507
1656
  }
1508
- function At(e) {
1509
- const a = [], n = (t) => t.paraId ? t.paraId : String(t.index);
1510
- for (const t of e)
1511
- switch (t.type) {
1512
- case "heading":
1513
- a.push(`[${n(t)}] (h${t.level}) ${t.text}`);
1514
- break;
1515
- case "paragraph":
1516
- a.push(`[${n(t)}] ${t.text}`);
1517
- break;
1518
- case "list-item": {
1519
- const o = " ".repeat(t.listLevel), r = t.listType === "bullet" ? "•" : "-";
1520
- a.push(`[${n(t)}] ${o}${r} ${t.text}`);
1521
- break;
1522
- }
1523
- case "table": {
1524
- let o = t.index;
1525
- for (let r = 0; r < t.rows.length; r++)
1526
- for (let i = 0; i < t.rows[r].length; i++) {
1527
- const d = t.rows[r][i].split(`
1528
- `), c = t.cellParaIds?.[r]?.[i];
1529
- for (let l = 0; l < d.length; l++) {
1530
- const u = l === 0 && c ? c : String(o);
1531
- a.push(`[${u}] (table, row ${r + 1}, col ${i + 1}) ${d[l]}`), o++;
1532
- }
1533
- }
1534
- break;
1535
- }
1536
- }
1537
- return a.join(`
1538
- `);
1657
+ function ze(e) {
1658
+ let t = [], n = (e) => e.paraId ? e.paraId : String(e.index);
1659
+ for (let r of e) switch (r.type) {
1660
+ case "heading":
1661
+ t.push(`[${n(r)}] (h${r.level}) ${r.text}`);
1662
+ break;
1663
+ case "paragraph":
1664
+ t.push(`[${n(r)}] ${r.text}`);
1665
+ break;
1666
+ case "list-item": {
1667
+ let e = " ".repeat(r.listLevel), i = r.listType === "bullet" ? "•" : "-";
1668
+ t.push(`[${n(r)}] ${e}${i} ${r.text}`);
1669
+ break;
1670
+ }
1671
+ case "table": {
1672
+ let e = r.index;
1673
+ for (let n = 0; n < r.rows.length; n++) for (let i = 0; i < r.rows[n].length; i++) {
1674
+ let a = r.rows[n][i].split("\n"), o = r.cellParaIds?.[n]?.[i];
1675
+ for (let r = 0; r < a.length; r++) {
1676
+ let s = r === 0 && o ? o : String(e);
1677
+ t.push(`[${s}] (table, row ${n + 1}, col ${i + 1}) ${a[r]}`), e++;
1678
+ }
1679
+ }
1680
+ break;
1681
+ }
1682
+ }
1683
+ return t.join("\n");
1539
1684
  }
1540
- function le(e, a, n) {
1541
- const t = [], o = /* @__PURE__ */ new Set();
1542
- for (const r of e.content) {
1543
- if (r.type === "commentRangeStart" && n) {
1544
- o.add(r.id), t.push(`[comment:${r.id}]`);
1545
- continue;
1546
- }
1547
- if (r.type === "commentRangeEnd" && n) {
1548
- o.has(r.id) && (o.delete(r.id), t.push("[/comment]"));
1549
- continue;
1550
- }
1551
- if (r.type === "run")
1552
- t.push(P(r));
1553
- else if (r.type === "hyperlink")
1554
- t.push(re(r));
1555
- else if (W(r)) {
1556
- const i = V(r.content);
1557
- r.type === "insertion" || r.type === "moveTo" ? a && t.push(`[+${i}+]{by:${r.info.author}}`) : a ? t.push(`[-${i}-]{by:${r.info.author}}`) : t.push(i);
1558
- }
1559
- }
1560
- return t.join("");
1685
+ function Y(e, t, n) {
1686
+ let r = [], i = /* @__PURE__ */ new Set();
1687
+ for (let a of e.content) {
1688
+ if (a.type === "commentRangeStart" && n) {
1689
+ i.add(a.id), r.push(`[comment:${a.id}]`);
1690
+ continue;
1691
+ }
1692
+ if (a.type === "commentRangeEnd" && n) {
1693
+ i.has(a.id) && (i.delete(a.id), r.push("[/comment]"));
1694
+ continue;
1695
+ }
1696
+ if (a.type === "run") r.push(E(a));
1697
+ else if (a.type === "hyperlink") r.push(T(a));
1698
+ else if (W(a)) {
1699
+ let e = G(a.content);
1700
+ a.type === "insertion" || a.type === "moveTo" ? t && r.push(`[+${e}+]{by:${a.info.author}}`) : t ? r.push(`[-${e}-]{by:${a.info.author}}`) : r.push(e);
1701
+ }
1702
+ }
1703
+ return r.join("");
1561
1704
  }
1562
- function Lt(e) {
1563
- const a = [];
1564
- let n = 0;
1565
- for (let t = 0; t < e.content.length; t++) {
1566
- const o = e.content[t];
1567
- if (o.type === "run") {
1568
- const r = P(o);
1569
- a.push({ contentIndex: t, run: o, text: r, startPos: n }), n += r.length;
1570
- } else if (o.type === "hyperlink")
1571
- for (let r = 0; r < o.children.length; r++) {
1572
- const i = o.children[r];
1573
- if (i.type === "run") {
1574
- const s = P(i);
1575
- a.push({ contentIndex: t, run: i, text: s, startPos: n }), n += s.length;
1576
- }
1577
- }
1578
- else if (W(o)) {
1579
- if (o.type === "insertion" || o.type === "moveTo") continue;
1580
- for (let r = 0; r < o.content.length; r++) {
1581
- const i = o.content[r];
1582
- if (i.type === "run") {
1583
- const s = P(i);
1584
- a.push({ contentIndex: t, run: i, text: s, startPos: n }), n += s.length;
1585
- } else if (i.type === "hyperlink") {
1586
- for (const s of i.children)
1587
- if (s.type === "run") {
1588
- const d = P(s);
1589
- a.push({ contentIndex: t, run: s, text: d, startPos: n }), n += d.length;
1590
- }
1591
- }
1592
- }
1593
- }
1594
- }
1595
- return a;
1705
+ //#endregion
1706
+ //#region src/textSearch.ts
1707
+ function Be(e) {
1708
+ let t = [], n = 0;
1709
+ for (let r = 0; r < e.content.length; r++) {
1710
+ let i = e.content[r];
1711
+ if (i.type === "run") {
1712
+ let e = E(i);
1713
+ t.push({
1714
+ contentIndex: r,
1715
+ run: i,
1716
+ text: e,
1717
+ startPos: n
1718
+ }), n += e.length;
1719
+ } else if (i.type === "hyperlink") for (let e = 0; e < i.children.length; e++) {
1720
+ let a = i.children[e];
1721
+ if (a.type === "run") {
1722
+ let e = E(a);
1723
+ t.push({
1724
+ contentIndex: r,
1725
+ run: a,
1726
+ text: e,
1727
+ startPos: n
1728
+ }), n += e.length;
1729
+ }
1730
+ }
1731
+ else if (W(i)) {
1732
+ if (i.type === "insertion" || i.type === "moveTo") continue;
1733
+ for (let e = 0; e < i.content.length; e++) {
1734
+ let a = i.content[e];
1735
+ if (a.type === "run") {
1736
+ let e = E(a);
1737
+ t.push({
1738
+ contentIndex: r,
1739
+ run: a,
1740
+ text: e,
1741
+ startPos: n
1742
+ }), n += e.length;
1743
+ } else if (a.type === "hyperlink") {
1744
+ for (let e of a.children) if (e.type === "run") {
1745
+ let i = E(e);
1746
+ t.push({
1747
+ contentIndex: r,
1748
+ run: e,
1749
+ text: i,
1750
+ startPos: n
1751
+ }), n += i.length;
1752
+ }
1753
+ }
1754
+ }
1755
+ }
1756
+ }
1757
+ return t;
1596
1758
  }
1597
- function de(e) {
1598
- return Lt(e).map((a) => a.text).join("");
1759
+ function X(e) {
1760
+ return Be(e).map((e) => e.text).join("");
1599
1761
  }
1600
- function Y(e, a) {
1601
- const n = /* @__PURE__ */ new Map();
1602
- return ie(e, (o, r) => {
1603
- let i = null;
1604
- for (const s of o.content)
1605
- if (W(s)) {
1606
- i === null && (i = de(o));
1607
- const d = V(s.content), c = s.info.id, l = n.get(c);
1608
- l && l.paragraphIndex === r ? l.text += d : n.set(c, {
1609
- id: c,
1610
- type: s.type,
1611
- author: s.info.author,
1612
- date: s.info.date ?? null,
1613
- text: d,
1614
- context: i,
1615
- paragraphIndex: r
1616
- });
1617
- }
1618
- }), Array.from(n.values()).filter((o) => !(a?.author && o.author !== a.author || a?.type && o.type !== a.type));
1762
+ //#endregion
1763
+ //#region src/discovery.ts
1764
+ function Z(e, t) {
1765
+ let n = /* @__PURE__ */ new Map();
1766
+ return K(e, (e, t) => {
1767
+ let r = null;
1768
+ for (let i of e.content) if (W(i)) {
1769
+ r === null && (r = X(e));
1770
+ let a = G(i.content), o = i.info.id, s = n.get(o);
1771
+ s && s.paragraphIndex === t ? s.text += a : n.set(o, {
1772
+ id: o,
1773
+ type: i.type,
1774
+ author: i.info.author,
1775
+ date: i.info.date ?? null,
1776
+ text: a,
1777
+ context: r,
1778
+ paragraphIndex: t
1779
+ });
1780
+ }
1781
+ }), Array.from(n.values()).filter((e) => !(t?.author && e.author !== t.author || t?.type && e.type !== t.type));
1619
1782
  }
1620
- function Q(e, a) {
1621
- const n = e.comments ?? [];
1622
- if (n.length === 0) return [];
1623
- const t = Mt(e), o = [], r = /* @__PURE__ */ new Map();
1624
- for (const s of n)
1625
- if (s.parentId !== void 0) {
1626
- const d = r.get(s.parentId) ?? [];
1627
- d.push(s), r.set(s.parentId, d);
1628
- } else
1629
- o.push(s);
1630
- return o.map((s) => {
1631
- const d = t.get(s.id), c = (r.get(s.id) ?? []).map((l) => ({
1632
- id: l.id,
1633
- author: l.author,
1634
- date: l.date ?? null,
1635
- text: J(l)
1636
- }));
1637
- return {
1638
- id: s.id,
1639
- author: s.author,
1640
- date: s.date ?? null,
1641
- text: J(s),
1642
- anchoredText: d?.text ?? "",
1643
- paragraphIndex: d?.paragraphIndex ?? -1,
1644
- replies: c,
1645
- done: s.done ?? !1
1646
- };
1647
- }).filter((s) => !(a?.author && s.author !== a.author || a?.done !== void 0 && s.done !== a.done));
1783
+ function Q(e, t) {
1784
+ let n = e.comments ?? [];
1785
+ if (n.length === 0) return [];
1786
+ let r = He(e), i = [], a = /* @__PURE__ */ new Map();
1787
+ for (let e of n) if (e.parentId !== void 0) {
1788
+ let t = a.get(e.parentId) ?? [];
1789
+ t.push(e), a.set(e.parentId, t);
1790
+ } else i.push(e);
1791
+ return i.map((e) => {
1792
+ let t = r.get(e.id), n = (a.get(e.id) ?? []).map((e) => ({
1793
+ id: e.id,
1794
+ author: e.author,
1795
+ date: e.date ?? null,
1796
+ text: Ve(e)
1797
+ }));
1798
+ return {
1799
+ id: e.id,
1800
+ author: e.author,
1801
+ date: e.date ?? null,
1802
+ text: Ve(e),
1803
+ anchoredText: t?.text ?? "",
1804
+ paragraphIndex: t?.paragraphIndex ?? -1,
1805
+ replies: n,
1806
+ done: e.done ?? !1
1807
+ };
1808
+ }).filter((e) => !(t?.author && e.author !== t.author || t?.done !== void 0 && e.done !== t.done));
1648
1809
  }
1649
- function J(e) {
1650
- return e.content.map((a) => de(a)).join(`
1651
- `);
1810
+ function Ve(e) {
1811
+ return e.content.map((e) => X(e)).join("\n");
1652
1812
  }
1653
- function Mt(e) {
1654
- const a = /* @__PURE__ */ new Map(), n = /* @__PURE__ */ new Map();
1655
- return ie(e, (t, o) => {
1656
- for (const r of t.content)
1657
- if (r.type === "commentRangeStart")
1658
- n.set(r.id, { paragraphIndex: o, parts: [] });
1659
- else if (r.type === "commentRangeEnd") {
1660
- const i = n.get(r.id);
1661
- i && (a.set(r.id, { text: i.parts.join(""), paragraphIndex: i.paragraphIndex }), n.delete(r.id));
1662
- } else if (r.type === "run") {
1663
- const i = P(r);
1664
- for (const s of n.values())
1665
- s.parts.push(i);
1666
- } else if (r.type === "hyperlink") {
1667
- const i = r.children.filter((s) => s.type === "run").map(P).join("");
1668
- for (const s of n.values())
1669
- s.parts.push(i);
1670
- } else if (W(r)) {
1671
- if (r.type === "insertion" || r.type === "moveTo") continue;
1672
- const i = V(r.content);
1673
- for (const s of n.values())
1674
- s.parts.push(i);
1675
- }
1676
- }), a;
1813
+ function He(e) {
1814
+ let t = /* @__PURE__ */ new Map(), n = /* @__PURE__ */ new Map();
1815
+ return K(e, (e, r) => {
1816
+ for (let i of e.content) if (i.type === "commentRangeStart") n.set(i.id, {
1817
+ paragraphIndex: r,
1818
+ parts: []
1819
+ });
1820
+ else if (i.type === "commentRangeEnd") {
1821
+ let e = n.get(i.id);
1822
+ e && (t.set(i.id, {
1823
+ text: e.parts.join(""),
1824
+ paragraphIndex: e.paragraphIndex
1825
+ }), n.delete(i.id));
1826
+ } else if (i.type === "run") {
1827
+ let e = E(i);
1828
+ for (let t of n.values()) t.parts.push(e);
1829
+ } else if (i.type === "hyperlink") {
1830
+ let e = i.children.filter((e) => e.type === "run").map(E).join("");
1831
+ for (let t of n.values()) t.parts.push(e);
1832
+ } else if (W(i)) {
1833
+ if (i.type === "insertion" || i.type === "moveTo") continue;
1834
+ let e = G(i.content);
1835
+ for (let t of n.values()) t.parts.push(e);
1836
+ }
1837
+ }), t;
1677
1838
  }
1678
- function ee(e) {
1679
- return !e || e.length === 0 ? "" : e.map((a) => {
1680
- const n = a;
1681
- return n?.content ? n.content.map((t) => t.content?.map((o) => o.text || "").join("") || "").join("") : "";
1682
- }).join(`
1683
- `);
1839
+ //#endregion
1840
+ //#region src/bridge.ts
1841
+ function Ue(e) {
1842
+ return !e || e.length === 0 ? "" : e.map((e) => {
1843
+ let t = e;
1844
+ return t?.content ? t.content.map((e) => e.content?.map((e) => e.text || "").join("") || "").join("") : "";
1845
+ }).join("\n");
1684
1846
  }
1685
- function L(e) {
1686
- const a = e.getEditorRef();
1687
- if (a) {
1688
- const t = a.getDocument();
1689
- if (t?.package?.document) return t.package.document;
1690
- }
1691
- return e.getDocument()?.package?.document ?? null;
1847
+ function $(e) {
1848
+ let t = e.getEditorRef();
1849
+ if (t) {
1850
+ let e = t.getDocument();
1851
+ if (e?.package?.document) return e.package.document;
1852
+ }
1853
+ return e.getDocument()?.package?.document ?? null;
1692
1854
  }
1693
- function Dt(e, a = "AI") {
1694
- function n(t) {
1695
- return t ?? a;
1696
- }
1697
- return {
1698
- getContentAsText(t) {
1699
- const o = L(e);
1700
- return o ? At(Z(o, t)) : "";
1701
- },
1702
- getContent(t) {
1703
- const o = L(e);
1704
- return o ? Z(o, t) : [];
1705
- },
1706
- getComments(t) {
1707
- const o = L(e);
1708
- if (!o) return [];
1709
- const r = Q(o, t);
1710
- if (r.length > 0) return r;
1711
- const i = e.getComments();
1712
- if (i.length === 0) return [];
1713
- const s = /* @__PURE__ */ new Map(), d = [];
1714
- for (const l of i)
1715
- if (l.parentId) {
1716
- const u = s.get(l.parentId);
1717
- u ? u.push(l) : s.set(l.parentId, [l]);
1718
- } else
1719
- d.push(l);
1720
- const c = [];
1721
- for (const l of d) {
1722
- if (t?.author && l.author !== t.author || t?.done !== void 0 && (l.done ?? !1) !== t.done) continue;
1723
- const u = s.get(l.id) ?? [];
1724
- c.push({
1725
- id: l.id,
1726
- author: l.author,
1727
- date: l.date ?? null,
1728
- text: ee(l.content),
1729
- anchoredText: "",
1730
- paragraphIndex: -1,
1731
- replies: u.map((g) => ({
1732
- id: g.id,
1733
- author: g.author,
1734
- date: g.date ?? null,
1735
- text: ee(g.content)
1736
- })),
1737
- done: l.done ?? !1
1738
- });
1739
- }
1740
- return c;
1741
- },
1742
- getChanges(t) {
1743
- const o = L(e);
1744
- return o ? Y(o, t) : [];
1745
- },
1746
- findText(t, o) {
1747
- return e.findInDocument(t, o);
1748
- },
1749
- getSelection() {
1750
- return e.getSelectionInfo();
1751
- },
1752
- addComment(t) {
1753
- return e.addComment({
1754
- paraId: t.paraId,
1755
- text: t.text,
1756
- author: n(t.author),
1757
- search: t.search
1758
- });
1759
- },
1760
- replyTo(t, o) {
1761
- return e.replyToComment(t, o.text, n(o.author));
1762
- },
1763
- resolveComment(t) {
1764
- e.resolveComment(t);
1765
- },
1766
- proposeChange(t) {
1767
- return e.proposeChange({
1768
- paraId: t.paraId,
1769
- search: t.search,
1770
- replaceWith: t.replaceWith,
1771
- author: n(t.author)
1772
- });
1773
- },
1774
- applyFormatting(t) {
1775
- return e.applyFormatting({
1776
- paraId: t.paraId,
1777
- search: t.search,
1778
- marks: t.marks
1779
- });
1780
- },
1781
- setParagraphStyle(t) {
1782
- return e.setParagraphStyle({
1783
- paraId: t.paraId,
1784
- styleId: t.styleId
1785
- });
1786
- },
1787
- getPage(t) {
1788
- return e.getPageContent(t);
1789
- },
1790
- getPages(t) {
1791
- const o = e.getTotalPages(), r = Math.max(1, Math.min(t.from, o)), i = Math.max(r, Math.min(t.to, o)), s = [];
1792
- for (let d = r; d <= i; d++) {
1793
- const c = e.getPageContent(d);
1794
- c && s.push(c);
1795
- }
1796
- return s;
1797
- },
1798
- getTotalPages() {
1799
- return e.getTotalPages();
1800
- },
1801
- getCurrentPage() {
1802
- return e.getCurrentPage();
1803
- },
1804
- scrollTo(t) {
1805
- return e.scrollToParaId(t);
1806
- },
1807
- onContentChange(t) {
1808
- return e.onContentChange(() => {
1809
- const o = L(e), r = o ? Q(o) : [], i = o ? Y(o) : [];
1810
- try {
1811
- t({
1812
- commentCount: r.length,
1813
- changeCount: i.length,
1814
- comments: r,
1815
- changes: i
1816
- });
1817
- } catch (s) {
1818
- console.error("onContentChange listener threw:", s);
1819
- }
1820
- });
1821
- },
1822
- onSelectionChange(t) {
1823
- return e.onSelectionChange(() => {
1824
- try {
1825
- t(e.getSelectionInfo());
1826
- } catch (o) {
1827
- console.error("onSelectionChange listener threw:", o);
1828
- }
1829
- });
1830
- }
1831
- };
1855
+ function We(e, t = "AI") {
1856
+ function n(e) {
1857
+ return e ?? t;
1858
+ }
1859
+ return {
1860
+ getContentAsText(t) {
1861
+ let n = $(e);
1862
+ return n ? ze(q(n, t)) : "";
1863
+ },
1864
+ getContent(t) {
1865
+ let n = $(e);
1866
+ return n ? q(n, t) : [];
1867
+ },
1868
+ getComments(t) {
1869
+ let n = $(e);
1870
+ if (!n) return [];
1871
+ let r = Q(n, t);
1872
+ if (r.length > 0) return r;
1873
+ let i = e.getComments();
1874
+ if (i.length === 0) return [];
1875
+ let a = /* @__PURE__ */ new Map(), o = [];
1876
+ for (let e of i) if (e.parentId) {
1877
+ let t = a.get(e.parentId);
1878
+ t ? t.push(e) : a.set(e.parentId, [e]);
1879
+ } else o.push(e);
1880
+ let s = [];
1881
+ for (let e of o) {
1882
+ if (t?.author && e.author !== t.author || t?.done !== void 0 && (e.done ?? !1) !== t.done) continue;
1883
+ let n = a.get(e.id) ?? [];
1884
+ s.push({
1885
+ id: e.id,
1886
+ author: e.author,
1887
+ date: e.date ?? null,
1888
+ text: Ue(e.content),
1889
+ anchoredText: "",
1890
+ paragraphIndex: -1,
1891
+ replies: n.map((e) => ({
1892
+ id: e.id,
1893
+ author: e.author,
1894
+ date: e.date ?? null,
1895
+ text: Ue(e.content)
1896
+ })),
1897
+ done: e.done ?? !1
1898
+ });
1899
+ }
1900
+ return s;
1901
+ },
1902
+ getChanges(t) {
1903
+ let n = $(e);
1904
+ return n ? Z(n, t) : [];
1905
+ },
1906
+ findText(t, n) {
1907
+ return e.findInDocument(t, n);
1908
+ },
1909
+ getSelection() {
1910
+ return e.getSelectionInfo();
1911
+ },
1912
+ addComment(t) {
1913
+ return e.addComment({
1914
+ paraId: t.paraId,
1915
+ text: t.text,
1916
+ author: n(t.author),
1917
+ search: t.search
1918
+ });
1919
+ },
1920
+ replyTo(t, r) {
1921
+ return e.replyToComment(t, r.text, n(r.author));
1922
+ },
1923
+ resolveComment(t) {
1924
+ e.resolveComment(t);
1925
+ },
1926
+ proposeChange(t) {
1927
+ return e.proposeChange({
1928
+ paraId: t.paraId,
1929
+ search: t.search,
1930
+ replaceWith: t.replaceWith,
1931
+ author: n(t.author)
1932
+ });
1933
+ },
1934
+ applyFormatting(t) {
1935
+ return e.applyFormatting({
1936
+ paraId: t.paraId,
1937
+ search: t.search,
1938
+ marks: t.marks
1939
+ });
1940
+ },
1941
+ setParagraphStyle(t) {
1942
+ return e.setParagraphStyle({
1943
+ paraId: t.paraId,
1944
+ styleId: t.styleId
1945
+ });
1946
+ },
1947
+ getPage(t) {
1948
+ return e.getPageContent(t);
1949
+ },
1950
+ getPages(t) {
1951
+ let n = e.getTotalPages(), r = Math.max(1, Math.min(t.from, n)), i = Math.max(r, Math.min(t.to, n)), a = [];
1952
+ for (let t = r; t <= i; t++) {
1953
+ let n = e.getPageContent(t);
1954
+ n && a.push(n);
1955
+ }
1956
+ return a;
1957
+ },
1958
+ getTotalPages() {
1959
+ return e.getTotalPages();
1960
+ },
1961
+ getCurrentPage() {
1962
+ return e.getCurrentPage();
1963
+ },
1964
+ scrollTo(t) {
1965
+ return e.scrollToParaId(t);
1966
+ },
1967
+ onContentChange(t) {
1968
+ return e.onContentChange(() => {
1969
+ let n = $(e), r = n ? Q(n) : [], i = n ? Z(n) : [];
1970
+ try {
1971
+ t({
1972
+ commentCount: r.length,
1973
+ changeCount: i.length,
1974
+ comments: r,
1975
+ changes: i
1976
+ });
1977
+ } catch (e) {
1978
+ console.error("onContentChange listener threw:", e);
1979
+ }
1980
+ });
1981
+ },
1982
+ onSelectionChange(t) {
1983
+ return e.onSelectionChange(() => {
1984
+ try {
1985
+ t(e.getSelectionInfo());
1986
+ } catch (e) {
1987
+ console.error("onSelectionChange listener threw:", e);
1988
+ }
1989
+ });
1990
+ }
1991
+ };
1832
1992
  }
1833
- const Et = Tt();
1834
- function Vt(e) {
1835
- const { editorRef: a, author: n = "AI" } = e, t = S(
1836
- () => a.value ? Dt(a.value, we(n)) : null
1837
- );
1838
- function o(r, i) {
1839
- const s = t.value;
1840
- return s ? $t(r, i, s) : { success: !1, error: "Editor not ready" };
1841
- }
1842
- return {
1843
- executeToolCall: o,
1844
- toolSchemas: Et
1845
- };
1993
+ //#endregion
1994
+ //#region src/vue/composables/useAgentBridge.ts
1995
+ var Ge = Ie();
1996
+ function Ke(e) {
1997
+ let { editorRef: t, author: r = "AI" } = e, i = n(() => t.value ? We(t.value, y(r)) : null);
1998
+ function a(e, t) {
1999
+ let n = i.value;
2000
+ return n ? Pe(e, t, n) : {
2001
+ success: !1,
2002
+ error: "Editor not ready"
2003
+ };
2004
+ }
2005
+ return {
2006
+ executeToolCall: a,
2007
+ toolSchemas: Ge
2008
+ };
1846
2009
  }
1847
- export {
1848
- Ht as AIContextMenu,
1849
- zt as AIResponsePreview,
1850
- Rt as AgentChatLog,
1851
- Ft as AgentComposer,
1852
- Bt as AgentPanel,
1853
- jt as AgentSuggestionChip,
1854
- Be as AgentTimeline,
1855
- Gt as getToolDisplayName,
1856
- Vt as useAgentBridge
1857
- };
2010
+ //#endregion
2011
+ export { ve as AIContextMenu, Ne as AIResponsePreview, ie as AgentChatLog, se as AgentComposer, M as AgentPanel, le as AgentSuggestionChip, R as AgentTimeline, Fe as getToolDisplayName, Ke as useAgentBridge };