@vite-plugin-opencode-assistant/components 1.1.3 → 1.1.4

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.
@@ -1,3355 +0,0 @@
1
- Object.defineProperties(exports, {
2
- __esModule: { value: true },
3
- [Symbol.toStringTag]: { value: "Module" }
4
- });
5
- //#region \0rolldown/runtime.js
6
- var __create = Object.create;
7
- var __defProp$5 = Object.defineProperty;
8
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
9
- var __getOwnPropNames = Object.getOwnPropertyNames;
10
- var __getProtoOf = Object.getPrototypeOf;
11
- var __hasOwnProp$5 = Object.prototype.hasOwnProperty;
12
- var __copyProps = (to, from, except, desc) => {
13
- if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
14
- key = keys[i];
15
- if (!__hasOwnProp$5.call(to, key) && key !== except) __defProp$5(to, key, {
16
- get: ((k) => from[k]).bind(null, key),
17
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
18
- });
19
- }
20
- return to;
21
- };
22
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp$5(target, "default", {
23
- value: mod,
24
- enumerable: true
25
- }) : target, mod));
26
- //#endregion
27
- let vue = require("vue");
28
- let _vite_plugin_opencode_assistant_shared = require("@vite-plugin-opencode-assistant/shared");
29
- let css_selector_generator = require("css-selector-generator");
30
- css_selector_generator = __toESM(css_selector_generator, 1);
31
- //#region es/open-code-widget/src/context.mjs
32
- var CONTEXT_KEY = /* @__PURE__ */ Symbol("OpenCodeWidgetContext");
33
- function provideOpenCodeWidgetContext(context) {
34
- (0, vue.provide)(CONTEXT_KEY, context);
35
- }
36
- function useOpenCodeWidgetContext() {
37
- const context = (0, vue.inject)(CONTEXT_KEY);
38
- if (!context) throw new Error("useOpenCodeWidgetContext must be used within OpenCodeWidget");
39
- return context;
40
- }
41
- //#endregion
42
- //#region es/open-code-widget/src/components/Frame.vue.mjs
43
- var __defProp$4 = Object.defineProperty;
44
- var __getOwnPropSymbols$4 = Object.getOwnPropertySymbols;
45
- var __hasOwnProp$4 = Object.prototype.hasOwnProperty;
46
- var __propIsEnum$4 = Object.prototype.propertyIsEnumerable;
47
- var __defNormalProp$4 = (obj, key, value) => key in obj ? __defProp$4(obj, key, {
48
- enumerable: true,
49
- configurable: true,
50
- writable: true,
51
- value
52
- }) : obj[key] = value;
53
- var __spreadValues$4 = (a, b) => {
54
- for (var prop in b || (b = {})) if (__hasOwnProp$4.call(b, prop)) __defNormalProp$4(a, prop, b[prop]);
55
- if (__getOwnPropSymbols$4) {
56
- for (var prop of __getOwnPropSymbols$4(b)) if (__propIsEnum$4.call(b, prop)) __defNormalProp$4(a, prop, b[prop]);
57
- }
58
- return a;
59
- };
60
- var __vue_sfc__$9 = /* @__PURE__ */ (0, vue.defineComponent)({
61
- __name: "Frame",
62
- setup(__props, { expose: __expose }) {
63
- const iframeRef = (0, vue.ref)(null);
64
- const { frameLoading, showEmptyState, showError, iframeSource: iframeSrc, emptyStateText, emptyStateActionText, handleEmptyAction, handleFrameLoaded } = useOpenCodeWidgetContext();
65
- function sendMessageToIframe(type, data) {
66
- var _a;
67
- if (!((_a = iframeRef.value) == null ? void 0 : _a.contentWindow)) return;
68
- iframeRef.value.contentWindow.postMessage(__spreadValues$4({ type }, data), "*");
69
- }
70
- __expose({ sendMessageToIframe });
71
- const __returned__ = {
72
- iframeRef,
73
- frameLoading,
74
- showEmptyState,
75
- showError,
76
- iframeSrc,
77
- emptyStateText,
78
- emptyStateActionText,
79
- handleEmptyAction,
80
- handleFrameLoaded,
81
- sendMessageToIframe
82
- };
83
- Object.defineProperty(__returned__, "__isScriptSetup", {
84
- enumerable: false,
85
- value: true
86
- });
87
- return __returned__;
88
- }
89
- });
90
- var _hoisted_1$7 = { class: "opencode-iframe-container" };
91
- var _hoisted_2$5 = { class: "opencode-empty-state-text" };
92
- var _hoisted_3$5 = ["src"];
93
- function __vue_render__$9(_ctx, _cache, $props, $setup, $data, $options) {
94
- return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_1$7, [
95
- (0, vue.createElementVNode)("div", { class: (0, vue.normalizeClass)(["opencode-empty-state-overlay", { visible: $setup.showEmptyState }]) }, [(0, vue.renderSlot)(_ctx.$slots, "empty-state", {}, () => [
96
- _cache[2] || (_cache[2] = (0, vue.createElementVNode)("div", { class: "opencode-empty-state-icon" }, [(0, vue.createElementVNode)("svg", {
97
- viewBox: "0 0 24 24",
98
- width: "48",
99
- height: "48",
100
- fill: "none",
101
- stroke: "currentColor",
102
- "stroke-width": "1.5",
103
- "aria-hidden": "true"
104
- }, [(0, vue.createElementVNode)("path", {
105
- "stroke-linecap": "round",
106
- "stroke-linejoin": "round",
107
- d: "M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 0 1-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z"
108
- })])], -1)),
109
- (0, vue.createElementVNode)("div", _hoisted_2$5, (0, vue.toDisplayString)($setup.emptyStateText), 1),
110
- (0, vue.createElementVNode)("button", {
111
- class: "opencode-empty-state-btn",
112
- type: "button",
113
- onClick: _cache[0] || (_cache[0] = (...args) => $setup.handleEmptyAction && $setup.handleEmptyAction(...args))
114
- }, (0, vue.toDisplayString)($setup.emptyStateActionText), 1)
115
- ])], 2),
116
- (0, vue.createElementVNode)("div", { class: (0, vue.normalizeClass)(["opencode-loading-overlay", { visible: $setup.frameLoading }]) }, [(0, vue.renderSlot)(_ctx.$slots, "loading", {}, () => [_cache[3] || (_cache[3] = (0, vue.createElementVNode)("div", { class: "opencode-loading-spinner" }, null, -1)), _cache[4] || (_cache[4] = (0, vue.createElementVNode)("div", { class: "opencode-loading-text" }, "加载中...", -1))])], 2),
117
- (0, vue.createElementVNode)("div", { class: (0, vue.normalizeClass)(["opencode-error-overlay", { visible: $setup.showError }]) }, [(0, vue.renderSlot)(_ctx.$slots, "error")], 2),
118
- (0, vue.renderSlot)(_ctx.$slots, "content", {}, () => [(0, vue.createElementVNode)("iframe", {
119
- ref: "iframeRef",
120
- class: "opencode-iframe",
121
- src: $setup.iframeSrc,
122
- allow: "clipboard-write; clipboard-read",
123
- referrerpolicy: "origin",
124
- onLoad: _cache[1] || (_cache[1] = (...args) => $setup.handleFrameLoaded && $setup.handleFrameLoaded(...args))
125
- }, null, 40, _hoisted_3$5)])
126
- ]);
127
- }
128
- __vue_sfc__$9.render = __vue_render__$9;
129
- var Frame_vue_default = __vue_sfc__$9;
130
- //#endregion
131
- //#region es/open-code-widget/src/components/Header.vue.mjs
132
- var __vue_sfc__$8 = /* @__PURE__ */ (0, vue.defineComponent)({
133
- __name: "Header",
134
- setup(__props, { expose: __expose }) {
135
- __expose();
136
- const { title, sessionListTitle, sessionListCollapsed, selectMode, selectEnabled, theme, resolvedTheme, minimized, promptDockVisible, reviewPanelVisible, mode, displayMode, splitPosition, handleToggleSessionList, handleToggleSelectMode, handleToggleTheme, handleToggleDisplayMode, handleToggleSplitPosition, handleClose, handleToggleMinimize, handleTogglePromptDock, handleToggleReviewPanel, handleRefresh } = useOpenCodeWidgetContext();
137
- const __returned__ = {
138
- title,
139
- sessionListTitle,
140
- sessionListCollapsed,
141
- selectMode,
142
- selectEnabled,
143
- theme,
144
- resolvedTheme,
145
- minimized,
146
- promptDockVisible,
147
- reviewPanelVisible,
148
- mode,
149
- displayMode,
150
- splitPosition,
151
- handleToggleSessionList,
152
- handleToggleSelectMode,
153
- handleToggleTheme,
154
- handleToggleDisplayMode,
155
- handleToggleSplitPosition,
156
- handleClose,
157
- handleToggleMinimize,
158
- handleTogglePromptDock,
159
- handleToggleReviewPanel,
160
- handleRefresh,
161
- isSplitMode: (0, vue.computed)(() => mode.value === "split"),
162
- themeIconTitle: (0, vue.computed)(() => {
163
- return `\u4E3B\u9898: ${{
164
- auto: "自动",
165
- light: "亮色",
166
- dark: "暗色"
167
- }[theme.value]} (${resolvedTheme.value})`;
168
- }),
169
- themeIconLabel: (0, vue.computed)(() => {
170
- return `\u5207\u6362\u4E3B\u9898 - \u5F53\u524D: ${{
171
- auto: "自动跟随系统",
172
- light: "亮色主题",
173
- dark: "暗色主题"
174
- }[theme.value]}`;
175
- }),
176
- displayModeIconTitle: (0, vue.computed)(() => {
177
- return `\u5C55\u793A\u6A21\u5F0F: ${{
178
- bubble: "气泡模式",
179
- split: "分屏模式",
180
- auto: "自动模式",
181
- extension: "扩展模式",
182
- "extension-selector": "扩展选择器模式"
183
- }[displayMode.value]}`;
184
- }),
185
- displayModeIconLabel: (0, vue.computed)(() => {
186
- const displayModeLabels = {
187
- bubble: "气泡模式",
188
- split: "分屏模式",
189
- auto: "自动模式",
190
- extension: "扩展模式",
191
- "extension-selector": "扩展选择器模式"
192
- };
193
- const modes = [
194
- "bubble",
195
- "split",
196
- "auto"
197
- ];
198
- return `\u5207\u6362\u5C55\u793A\u6A21\u5F0F - \u4E0B\u4E00\u4E2A: ${displayModeLabels[modes[(modes.indexOf(displayMode.value) + 1) % modes.length]]}`;
199
- }),
200
- splitPositionIconTitle: (0, vue.computed)(() => {
201
- return `\u5206\u680F\u4F4D\u7F6E: ${{
202
- left: "左侧",
203
- right: "右侧"
204
- }[splitPosition.value]}`;
205
- }),
206
- splitPositionIconLabel: (0, vue.computed)(() => {
207
- return `\u5207\u6362\u5206\u680F\u4F4D\u7F6E - \u4E0B\u4E00\u4E2A: ${splitPosition.value === "right" ? "左侧" : "右侧"}`;
208
- })
209
- };
210
- Object.defineProperty(__returned__, "__isScriptSetup", {
211
- enumerable: false,
212
- value: true
213
- });
214
- return __returned__;
215
- }
216
- });
217
- var _hoisted_1$6 = { class: "opencode-chat-header" };
218
- var _hoisted_2$4 = { class: "opencode-chat-header-left" };
219
- var _hoisted_3$4 = [
220
- "title",
221
- "aria-label",
222
- "aria-expanded"
223
- ];
224
- var _hoisted_4$4 = ["aria-pressed", "disabled"];
225
- var _hoisted_5$4 = ["title", "aria-label"];
226
- var _hoisted_6$4 = {
227
- key: 0,
228
- viewBox: "0 0 24 24",
229
- width: "16",
230
- height: "16",
231
- fill: "none",
232
- stroke: "currentColor",
233
- "stroke-width": "2",
234
- "aria-hidden": "true"
235
- };
236
- var _hoisted_7$2 = {
237
- key: 1,
238
- viewBox: "0 0 24 24",
239
- width: "16",
240
- height: "16",
241
- fill: "none",
242
- stroke: "currentColor",
243
- "stroke-width": "2",
244
- "aria-hidden": "true"
245
- };
246
- var _hoisted_8$1 = {
247
- key: 2,
248
- viewBox: "0 0 24 24",
249
- width: "16",
250
- height: "16",
251
- fill: "none",
252
- stroke: "currentColor",
253
- "stroke-width": "2",
254
- "aria-hidden": "true"
255
- };
256
- var _hoisted_9$1 = ["title", "aria-label"];
257
- var _hoisted_10$1 = {
258
- key: 0,
259
- viewBox: "0 0 24 24",
260
- width: "16",
261
- height: "16",
262
- fill: "none",
263
- stroke: "currentColor",
264
- "stroke-width": "2",
265
- "aria-hidden": "true"
266
- };
267
- var _hoisted_11 = {
268
- key: 1,
269
- viewBox: "0 0 24 24",
270
- width: "16",
271
- height: "16",
272
- fill: "none",
273
- stroke: "currentColor",
274
- "stroke-width": "2",
275
- "aria-hidden": "true"
276
- };
277
- var _hoisted_12 = {
278
- key: 2,
279
- viewBox: "0 0 24 24",
280
- width: "16",
281
- height: "16",
282
- fill: "none",
283
- stroke: "currentColor",
284
- "stroke-width": "2",
285
- "aria-hidden": "true"
286
- };
287
- var _hoisted_13 = { class: "opencode-chat-header-title" };
288
- var _hoisted_14 = { class: "opencode-chat-header-actions" };
289
- var _hoisted_15 = ["title", "aria-label"];
290
- var _hoisted_16 = {
291
- key: 0,
292
- viewBox: "0 0 24 24",
293
- width: "16",
294
- height: "16",
295
- fill: "none",
296
- stroke: "currentColor",
297
- "stroke-width": "2",
298
- "aria-hidden": "true"
299
- };
300
- var _hoisted_17 = {
301
- key: 1,
302
- viewBox: "0 0 24 24",
303
- width: "16",
304
- height: "16",
305
- fill: "none",
306
- stroke: "currentColor",
307
- "stroke-width": "2",
308
- "aria-hidden": "true"
309
- };
310
- var _hoisted_18 = [
311
- "title",
312
- "aria-label",
313
- "aria-pressed"
314
- ];
315
- var _hoisted_19 = [
316
- "title",
317
- "aria-label",
318
- "aria-pressed"
319
- ];
320
- var _hoisted_20 = [
321
- "title",
322
- "aria-label",
323
- "aria-pressed"
324
- ];
325
- var _hoisted_21 = {
326
- key: 0,
327
- viewBox: "0 0 24 24",
328
- width: "14",
329
- height: "14",
330
- fill: "none",
331
- stroke: "currentColor",
332
- "stroke-width": "2",
333
- "aria-hidden": "true"
334
- };
335
- var _hoisted_22 = {
336
- key: 1,
337
- viewBox: "0 0 24 24",
338
- width: "14",
339
- height: "14",
340
- fill: "none",
341
- stroke: "currentColor",
342
- "stroke-width": "2",
343
- "aria-hidden": "true"
344
- };
345
- function __vue_render__$8(_ctx, _cache, $props, $setup, $data, $options) {
346
- return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_1$6, [
347
- (0, vue.createElementVNode)("div", _hoisted_2$4, [
348
- (0, vue.createElementVNode)("button", {
349
- class: (0, vue.normalizeClass)(["opencode-header-btn session-toggle", { active: !$setup.sessionListCollapsed }]),
350
- type: "button",
351
- title: $setup.sessionListTitle,
352
- "aria-label": $setup.sessionListTitle,
353
- "aria-expanded": !$setup.sessionListCollapsed,
354
- onClick: _cache[0] || (_cache[0] = (...args) => $setup.handleToggleSessionList && $setup.handleToggleSessionList(...args))
355
- }, [(0, vue.renderSlot)(_ctx.$slots, "session-toggle-icon", {}, () => [_cache[10] || (_cache[10] = (0, vue.createElementVNode)("svg", {
356
- viewBox: "0 0 24 24",
357
- width: "16",
358
- height: "16",
359
- fill: "none",
360
- stroke: "currentColor",
361
- "stroke-width": "2",
362
- "aria-hidden": "true"
363
- }, [(0, vue.createElementVNode)("path", {
364
- d: "M4 6h16M4 12h16M4 18h16",
365
- "stroke-linecap": "round"
366
- })], -1))])], 10, _hoisted_3$4),
367
- (0, vue.createElementVNode)("button", {
368
- class: (0, vue.normalizeClass)(["opencode-header-btn select-btn", { active: $setup.selectMode }]),
369
- type: "button",
370
- title: "选择页面元素 (Ctrl+P)",
371
- "aria-label": "选择页面元素",
372
- "aria-pressed": $setup.selectMode,
373
- disabled: !$setup.selectEnabled,
374
- onClick: _cache[1] || (_cache[1] = (...args) => $setup.handleToggleSelectMode && $setup.handleToggleSelectMode(...args))
375
- }, [(0, vue.renderSlot)(_ctx.$slots, "select-icon", {}, () => [_cache[11] || (_cache[11] = (0, vue.createElementVNode)("svg", {
376
- viewBox: "0 0 1024 1024",
377
- width: "16",
378
- height: "16",
379
- "aria-hidden": "true"
380
- }, [(0, vue.createElementVNode)("path", {
381
- fill: "currentColor",
382
- d: "M512 896a384 384 0 1 0 0-768 384 384 0 0 0 0 768m0 64a448 448 0 1 1 0-896 448 448 0 0 1 0 896"
383
- }), (0, vue.createElementVNode)("path", {
384
- fill: "currentColor",
385
- d: "M512 96a32 32 0 0 1 32 32v192a32 32 0 0 1-64 0V128a32 32 0 0 1 32-32m0 576a32 32 0 0 1 32 32v192a32 32 0 1 1-64 0V704a32 32 0 0 1 32-32M96 512a32 32 0 0 1 32-32h192a32 32 0 0 1 0 64H128a32 32 0 0 1-32-32m576 0a32 32 0 0 1 32-32h192a32 32 0 1 1 0 64H704a32 32 0 0 1-32-32"
386
- })], -1))])], 10, _hoisted_4$4),
387
- (0, vue.createElementVNode)("button", {
388
- class: "opencode-header-btn theme-btn",
389
- type: "button",
390
- title: $setup.themeIconTitle,
391
- "aria-label": $setup.themeIconLabel,
392
- onClick: _cache[2] || (_cache[2] = (...args) => $setup.handleToggleTheme && $setup.handleToggleTheme(...args))
393
- }, [(0, vue.renderSlot)(_ctx.$slots, "theme-icon", {}, () => [$setup.theme === "light" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("svg", _hoisted_6$4, [..._cache[12] || (_cache[12] = [(0, vue.createStaticVNode)("<circle cx=\"12\" cy=\"12\" r=\"5\"></circle><line x1=\"12\" y1=\"1\" x2=\"12\" y2=\"3\"></line><line x1=\"12\" y1=\"21\" x2=\"12\" y2=\"23\"></line><line x1=\"4.22\" y1=\"4.22\" x2=\"5.64\" y2=\"5.64\"></line><line x1=\"18.36\" y1=\"18.36\" x2=\"19.78\" y2=\"19.78\"></line><line x1=\"1\" y1=\"12\" x2=\"3\" y2=\"12\"></line><line x1=\"21\" y1=\"12\" x2=\"23\" y2=\"12\"></line><line x1=\"4.22\" y1=\"19.78\" x2=\"5.64\" y2=\"18.36\"></line><line x1=\"18.36\" y1=\"5.64\" x2=\"19.78\" y2=\"4.22\"></line>", 9)])])) : $setup.theme === "dark" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("svg", _hoisted_7$2, [..._cache[13] || (_cache[13] = [(0, vue.createElementVNode)("path", { d: "M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" }, null, -1)])])) : ((0, vue.openBlock)(), (0, vue.createElementBlock)("svg", _hoisted_8$1, [..._cache[14] || (_cache[14] = [(0, vue.createStaticVNode)("<rect x=\"2\" y=\"3\" width=\"20\" height=\"14\" rx=\"2\" ry=\"2\"></rect><line x1=\"8\" y1=\"21\" x2=\"16\" y2=\"21\"></line><line x1=\"12\" y1=\"17\" x2=\"12\" y2=\"21\"></line><circle cx=\"12\" cy=\"10\" r=\"3\"></circle><path d=\"M7 7l2 2M17 7l-2 2M7 13l2-2M17 13l-2-2\"></path>", 5)])]))])], 8, _hoisted_5$4),
394
- $setup.displayMode !== "extension" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("button", {
395
- key: 0,
396
- class: "opencode-header-btn display-mode-btn",
397
- type: "button",
398
- title: $setup.displayModeIconTitle,
399
- "aria-label": $setup.displayModeIconLabel,
400
- onClick: _cache[3] || (_cache[3] = (...args) => $setup.handleToggleDisplayMode && $setup.handleToggleDisplayMode(...args))
401
- }, [(0, vue.renderSlot)(_ctx.$slots, "display-mode-icon", {}, () => [$setup.displayMode === "bubble" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("svg", _hoisted_10$1, [..._cache[15] || (_cache[15] = [
402
- (0, vue.createElementVNode)("circle", {
403
- cx: "12",
404
- cy: "12",
405
- r: "10"
406
- }, null, -1),
407
- (0, vue.createElementVNode)("path", {
408
- d: "M8 14s1.5 2 4 2 4-2 4-2",
409
- "stroke-linecap": "round"
410
- }, null, -1),
411
- (0, vue.createElementVNode)("line", {
412
- x1: "9",
413
- y1: "9",
414
- x2: "9.01",
415
- y2: "9",
416
- "stroke-linecap": "round"
417
- }, null, -1),
418
- (0, vue.createElementVNode)("line", {
419
- x1: "15",
420
- y1: "9",
421
- x2: "15.01",
422
- y2: "9",
423
- "stroke-linecap": "round"
424
- }, null, -1)
425
- ])])) : $setup.displayMode === "split" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("svg", _hoisted_11, [..._cache[16] || (_cache[16] = [(0, vue.createElementVNode)("rect", {
426
- x: "3",
427
- y: "3",
428
- width: "18",
429
- height: "18",
430
- rx: "2"
431
- }, null, -1), (0, vue.createElementVNode)("line", {
432
- x1: "12",
433
- y1: "3",
434
- x2: "12",
435
- y2: "21"
436
- }, null, -1)])])) : ((0, vue.openBlock)(), (0, vue.createElementBlock)("svg", _hoisted_12, [..._cache[17] || (_cache[17] = [
437
- (0, vue.createElementVNode)("rect", {
438
- x: "3",
439
- y: "3",
440
- width: "8",
441
- height: "8",
442
- rx: "1"
443
- }, null, -1),
444
- (0, vue.createElementVNode)("rect", {
445
- x: "15",
446
- y: "3",
447
- width: "6",
448
- height: "8",
449
- rx: "1"
450
- }, null, -1),
451
- (0, vue.createElementVNode)("rect", {
452
- x: "3",
453
- y: "15",
454
- width: "8",
455
- height: "6",
456
- rx: "1"
457
- }, null, -1),
458
- (0, vue.createElementVNode)("circle", {
459
- cx: "18",
460
- cy: "18",
461
- r: "3"
462
- }, null, -1)
463
- ])]))])], 8, _hoisted_9$1)) : (0, vue.createCommentVNode)("v-if", true)
464
- ]),
465
- (0, vue.createElementVNode)("span", _hoisted_13, (0, vue.toDisplayString)($setup.title), 1),
466
- (0, vue.createElementVNode)("div", _hoisted_14, [
467
- $setup.displayMode === "extension" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("button", {
468
- key: 0,
469
- class: "opencode-header-btn refresh-btn",
470
- type: "button",
471
- title: "刷新面板",
472
- "aria-label": "刷新面板",
473
- onClick: _cache[4] || (_cache[4] = (...args) => $setup.handleRefresh && $setup.handleRefresh(...args))
474
- }, [..._cache[18] || (_cache[18] = [(0, vue.createElementVNode)("svg", {
475
- viewBox: "0 0 24 24",
476
- width: "16",
477
- height: "16",
478
- fill: "none",
479
- stroke: "currentColor",
480
- "stroke-width": "2",
481
- "aria-hidden": "true"
482
- }, [(0, vue.createElementVNode)("polyline", { points: "23,4 23,10 17,10" }), (0, vue.createElementVNode)("path", { d: "M20.49 15a9 9 0 1 1-2.12-9.36L23 10" })], -1)])])) : (0, vue.createCommentVNode)("v-if", true),
483
- $setup.isSplitMode && $setup.displayMode !== "extension" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("button", {
484
- key: 1,
485
- class: "opencode-header-btn split-position-btn",
486
- type: "button",
487
- title: $setup.splitPositionIconTitle,
488
- "aria-label": $setup.splitPositionIconLabel,
489
- onClick: _cache[5] || (_cache[5] = (...args) => $setup.handleToggleSplitPosition && $setup.handleToggleSplitPosition(...args))
490
- }, [(0, vue.renderSlot)(_ctx.$slots, "split-position-icon", {}, () => [$setup.splitPosition === "right" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("svg", _hoisted_16, [..._cache[19] || (_cache[19] = [(0, vue.createElementVNode)("rect", {
491
- x: "3",
492
- y: "3",
493
- width: "18",
494
- height: "18",
495
- rx: "2"
496
- }, null, -1), (0, vue.createElementVNode)("line", {
497
- x1: "15",
498
- y1: "3",
499
- x2: "15",
500
- y2: "21"
501
- }, null, -1)])])) : ((0, vue.openBlock)(), (0, vue.createElementBlock)("svg", _hoisted_17, [..._cache[20] || (_cache[20] = [(0, vue.createElementVNode)("rect", {
502
- x: "3",
503
- y: "3",
504
- width: "18",
505
- height: "18",
506
- rx: "2"
507
- }, null, -1), (0, vue.createElementVNode)("line", {
508
- x1: "9",
509
- y1: "3",
510
- x2: "9",
511
- y2: "21"
512
- }, null, -1)])]))])], 8, _hoisted_15)) : (0, vue.createCommentVNode)("v-if", true),
513
- (0, vue.createElementVNode)("button", {
514
- class: (0, vue.normalizeClass)(["opencode-header-btn review-panel", { active: $setup.reviewPanelVisible }]),
515
- type: "button",
516
- title: $setup.reviewPanelVisible ? "收起审查面板" : "展开审查面板",
517
- "aria-label": $setup.reviewPanelVisible ? "收起审查面板" : "展开审查面板",
518
- "aria-pressed": $setup.reviewPanelVisible,
519
- onClick: _cache[6] || (_cache[6] = (...args) => $setup.handleToggleReviewPanel && $setup.handleToggleReviewPanel(...args))
520
- }, [..._cache[21] || (_cache[21] = [(0, vue.createElementVNode)("svg", {
521
- viewBox: "0 0 24 24",
522
- width: "15",
523
- height: "15",
524
- fill: "none",
525
- stroke: "currentColor",
526
- "stroke-width": "2",
527
- "stroke-linecap": "round",
528
- "stroke-linejoin": "round",
529
- "aria-hidden": "true"
530
- }, [(0, vue.createElementVNode)("polyline", { points: "16 18 22 12 16 6" }), (0, vue.createElementVNode)("polyline", { points: "8 6 2 12 8 18" })], -1)])], 10, _hoisted_18),
531
- !$setup.isSplitMode ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("button", {
532
- key: 2,
533
- class: "opencode-header-btn prompt-dock",
534
- type: "button",
535
- title: $setup.promptDockVisible ? "隐藏对话框" : "显示对话框",
536
- "aria-label": $setup.promptDockVisible ? "隐藏对话框" : "显示对话框",
537
- "aria-pressed": $setup.promptDockVisible,
538
- onClick: _cache[7] || (_cache[7] = (...args) => $setup.handleTogglePromptDock && $setup.handleTogglePromptDock(...args))
539
- }, [(0, vue.renderSlot)(_ctx.$slots, "prompt-dock-icon", {}, () => [_cache[22] || (_cache[22] = (0, vue.createElementVNode)("svg", {
540
- viewBox: "0 0 24 24",
541
- width: "14",
542
- height: "14",
543
- fill: "none",
544
- stroke: "currentColor",
545
- "stroke-width": "2",
546
- "aria-hidden": "true"
547
- }, [(0, vue.createElementVNode)("path", { d: "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" })], -1))])], 8, _hoisted_19)) : (0, vue.createCommentVNode)("v-if", true),
548
- !$setup.isSplitMode ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("button", {
549
- key: 3,
550
- class: "opencode-header-btn minimize",
551
- type: "button",
552
- title: $setup.minimized ? "展开" : "最小化",
553
- "aria-label": $setup.minimized ? "展开面板" : "最小化面板",
554
- "aria-pressed": $setup.minimized,
555
- onClick: _cache[8] || (_cache[8] = (...args) => $setup.handleToggleMinimize && $setup.handleToggleMinimize(...args))
556
- }, [(0, vue.renderSlot)(_ctx.$slots, "minimize-icon", {}, () => [$setup.minimized ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("svg", _hoisted_21, [..._cache[23] || (_cache[23] = [(0, vue.createElementVNode)("path", { d: "M8 3v3a2 2 0 0 1-2 2H3m18 0h-3a2 2 0 0 1-2-2V3m0 18v-3a2 2 0 0 1 2-2h3M3 16h3a2 2 0 0 1 2 2v3" }, null, -1)])])) : ((0, vue.openBlock)(), (0, vue.createElementBlock)("svg", _hoisted_22, [..._cache[24] || (_cache[24] = [(0, vue.createElementVNode)("path", { d: "M8 3v3a2 2 0 0 1-2 2H3m18 0h-3a2 2 0 0 1-2-2V3m0 18v-3a2 2 0 0 1 2-2h3M3 16h3a2 2 0 0 1 2 2v3" }, null, -1)])]))])], 8, _hoisted_20)) : (0, vue.createCommentVNode)("v-if", true),
557
- !$setup.isSplitMode ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("button", {
558
- key: 4,
559
- class: "opencode-header-btn close",
560
- type: "button",
561
- title: "关闭",
562
- "aria-label": "关闭面板",
563
- onClick: _cache[9] || (_cache[9] = (...args) => $setup.handleClose && $setup.handleClose(...args))
564
- }, [(0, vue.renderSlot)(_ctx.$slots, "close-icon", {}, () => [_cache[25] || (_cache[25] = (0, vue.createElementVNode)("svg", {
565
- viewBox: "0 0 24 24",
566
- width: "14",
567
- height: "14",
568
- fill: "none",
569
- stroke: "currentColor",
570
- "stroke-width": "2",
571
- "aria-hidden": "true"
572
- }, [(0, vue.createElementVNode)("path", { d: "M18 6L6 18M6 6l12 12" })], -1))])])) : (0, vue.createCommentVNode)("v-if", true)
573
- ])
574
- ]);
575
- }
576
- __vue_sfc__$8.render = __vue_render__$8;
577
- var Header_vue_default = __vue_sfc__$8;
578
- //#endregion
579
- //#region es/open-code-widget/src/components/SessionList.vue.mjs
580
- var __vue_sfc__$7 = /* @__PURE__ */ (0, vue.defineComponent)({
581
- __name: "SessionList",
582
- setup(__props, { expose: __expose }) {
583
- __expose();
584
- const { sessionListCollapsed: collapsed, sessionItems: sessions, loadingSessionList, showSessionListSkeleton, handleCreateSession, handleSelectSession, handleDeleteSession, sessionKey, sessionStates } = useOpenCodeWidgetContext();
585
- const isAnimating = (0, vue.ref)(false);
586
- let animTimer = null;
587
- (0, vue.watch)(collapsed, () => {
588
- isAnimating.value = true;
589
- if (animTimer) clearTimeout(animTimer);
590
- animTimer = setTimeout(() => {
591
- isAnimating.value = false;
592
- }, 200);
593
- });
594
- const showSkeleton = (0, vue.computed)(() => {
595
- if (isAnimating.value) return true;
596
- if (showSessionListSkeleton.value) return true;
597
- return false;
598
- });
599
- function isSessionThinking(sessionId) {
600
- var _a, _b;
601
- if (!(sessionStates == null ? void 0 : sessionStates.value) || !sessionId) return false;
602
- return (_b = (_a = sessionStates.value[sessionId]) == null ? void 0 : _a.thinking) != null ? _b : false;
603
- }
604
- const __returned__ = {
605
- collapsed,
606
- sessions,
607
- loadingSessionList,
608
- showSessionListSkeleton,
609
- handleCreateSession,
610
- handleSelectSession,
611
- handleDeleteSession,
612
- sessionKey,
613
- sessionStates,
614
- isAnimating,
615
- get animTimer() {
616
- return animTimer;
617
- },
618
- set animTimer(v) {
619
- animTimer = v;
620
- },
621
- showSkeleton,
622
- isSessionThinking
623
- };
624
- Object.defineProperty(__returned__, "__isScriptSetup", {
625
- enumerable: false,
626
- value: true
627
- });
628
- return __returned__;
629
- }
630
- });
631
- var _hoisted_1$5 = {
632
- key: 0,
633
- class: "opencode-session-list-header"
634
- };
635
- var _hoisted_2$3 = {
636
- key: 2,
637
- class: "opencode-session-skeleton visible"
638
- };
639
- var _hoisted_3$3 = {
640
- class: "opencode-session-list-content",
641
- role: "listbox",
642
- "aria-labelledby": "opencode-session-list-title"
643
- };
644
- var _hoisted_4$3 = {
645
- key: 0,
646
- class: "opencode-session-list-loading-overlay"
647
- };
648
- var _hoisted_5$3 = ["aria-selected", "onClick"];
649
- var _hoisted_6$3 = { class: "opencode-session-header" };
650
- var _hoisted_7$1 = { class: "opencode-session-title" };
651
- var _hoisted_8 = {
652
- key: 0,
653
- class: "opencode-thinking-loading"
654
- };
655
- var _hoisted_9 = ["aria-label", "onClick"];
656
- var _hoisted_10 = { class: "opencode-session-meta" };
657
- function __vue_render__$7(_ctx, _cache, $props, $setup, $data, $options) {
658
- return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", { class: (0, vue.normalizeClass)(["opencode-session-list", { collapsed: $setup.collapsed }]) }, [
659
- (0, vue.createCommentVNode)(" Header "),
660
- !$setup.showSkeleton ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_1$5, [_cache[1] || (_cache[1] = (0, vue.createElementVNode)("span", { id: "opencode-session-list-title" }, "会话列表", -1)), (0, vue.createElementVNode)("button", {
661
- class: "opencode-new-session-btn",
662
- type: "button",
663
- title: "新建会话",
664
- "aria-label": "新建会话",
665
- onClick: _cache[0] || (_cache[0] = (...args) => $setup.handleCreateSession && $setup.handleCreateSession(...args))
666
- }, " + ")])) : ((0, vue.openBlock)(), (0, vue.createElementBlock)(vue.Fragment, { key: 1 }, [(0, vue.createCommentVNode)(" Header Skeleton "), _cache[2] || (_cache[2] = (0, vue.createElementVNode)("div", { class: "opencode-session-header-skeleton visible" }, [(0, vue.createElementVNode)("div", { class: "opencode-skeleton-header-title" }), (0, vue.createElementVNode)("div", { class: "opencode-skeleton-header-btn" })], -1))], 2112)),
667
- (0, vue.createCommentVNode)(" Content Skeleton "),
668
- $setup.showSkeleton ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_2$3, [((0, vue.openBlock)(), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)(5, (i) => {
669
- return (0, vue.createElementVNode)("div", {
670
- key: `skeleton-${i}`,
671
- class: "opencode-skeleton-item"
672
- }, [..._cache[3] || (_cache[3] = [(0, vue.createElementVNode)("div", { class: "opencode-skeleton-title" }, null, -1), (0, vue.createElementVNode)("div", { class: "opencode-skeleton-meta" }, null, -1)])]);
673
- }), 64))])) : ((0, vue.openBlock)(), (0, vue.createElementBlock)(vue.Fragment, { key: 3 }, [(0, vue.createCommentVNode)(" Content "), (0, vue.createElementVNode)("div", _hoisted_3$3, [$setup.loadingSessionList ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_4$3, [..._cache[4] || (_cache[4] = [(0, vue.createElementVNode)("div", { class: "opencode-loading-spinner small" }, null, -1)])])) : (0, vue.createCommentVNode)("v-if", true), $setup.sessions.length > 0 ? ((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, { key: 1 }, (0, vue.renderList)($setup.sessions, (item) => {
674
- return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", {
675
- key: item[$setup.sessionKey],
676
- class: (0, vue.normalizeClass)(["opencode-session-item", {
677
- active: item.active,
678
- thinking: $setup.isSessionThinking(item.id)
679
- }]),
680
- role: "option",
681
- "aria-selected": item.active,
682
- onClick: ($event) => $setup.handleSelectSession(item)
683
- }, [(0, vue.createElementVNode)("div", _hoisted_6$3, [(0, vue.createElementVNode)("div", _hoisted_7$1, [$setup.isSessionThinking(item.id) ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_8)) : (0, vue.createCommentVNode)("v-if", true), (0, vue.createTextVNode)(" " + (0, vue.toDisplayString)(item.title), 1)]), (0, vue.createElementVNode)("button", {
684
- class: "opencode-session-delete-btn",
685
- type: "button",
686
- "aria-label": `\u5220\u9664\u4F1A\u8BDD: ${item.title}`,
687
- onClick: (0, vue.withModifiers)(($event) => $setup.handleDeleteSession(item), ["stop"])
688
- }, " × ", 8, _hoisted_9)]), (0, vue.createElementVNode)("div", _hoisted_10, (0, vue.toDisplayString)(item.meta), 1)], 10, _hoisted_5$3);
689
- }), 128)) : ((0, vue.openBlock)(), (0, vue.createElementBlock)(vue.Fragment, { key: 2 }, [(0, vue.createCommentVNode)(" Empty State "), (0, vue.renderSlot)(_ctx.$slots, "empty")], 64))])], 2112))
690
- ], 2);
691
- }
692
- __vue_sfc__$7.render = __vue_render__$7;
693
- var SessionList_vue_default = __vue_sfc__$7;
694
- //#endregion
695
- //#region es/open-code-widget/src/components/SelectedNodes.vue.mjs
696
- var __vue_sfc__$6 = /* @__PURE__ */ (0, vue.defineComponent)({
697
- __name: "SelectedNodes",
698
- setup(__props, { expose: __expose }) {
699
- __expose();
700
- const { selectedElementItems: items, showClearAll, handleClickSelectedNode, handleRemoveSelectedNode, handleClearSelectedNodes } = useOpenCodeWidgetContext();
701
- const __returned__ = {
702
- items,
703
- showClearAll,
704
- handleClickSelectedNode,
705
- handleRemoveSelectedNode,
706
- handleClearSelectedNodes
707
- };
708
- Object.defineProperty(__returned__, "__isScriptSetup", {
709
- enumerable: false,
710
- value: true
711
- });
712
- return __returned__;
713
- }
714
- });
715
- var _hoisted_1$4 = {
716
- class: "opencode-selected-nodes",
717
- role: "list",
718
- "aria-label": "已选元素列表"
719
- };
720
- var _hoisted_2$2 = ["onClick"];
721
- var _hoisted_3$2 = { class: "opencode-node-content" };
722
- var _hoisted_4$2 = { class: "opencode-node-text" };
723
- var _hoisted_5$2 = { class: "opencode-node-file" };
724
- var _hoisted_6$2 = ["aria-label", "onClick"];
725
- function __vue_render__$6(_ctx, _cache, $props, $setup, $data, $options) {
726
- return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", { class: (0, vue.normalizeClass)(["opencode-right-toolbar", { collapsed: $setup.items.length === 0 }]) }, [
727
- _cache[1] || (_cache[1] = (0, vue.createElementVNode)("div", { class: "opencode-selected-nodes-header" }, [(0, vue.createElementVNode)("div", { class: "opencode-selected-nodes-title" }, "已选节点"), (0, vue.createElementVNode)("div", { class: "opencode-selected-nodes-desc" }, "选中的节点会在对话时一起发送给助手")], -1)),
728
- (0, vue.createElementVNode)("div", _hoisted_1$4, [((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)($setup.items, (item, index) => {
729
- return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", {
730
- key: item.key,
731
- class: "opencode-selected-node",
732
- role: "listitem",
733
- onClick: ($event) => $setup.handleClickSelectedNode(item)
734
- }, [(0, vue.createElementVNode)("div", _hoisted_3$2, [(0, vue.createElementVNode)("span", _hoisted_4$2, (0, vue.toDisplayString)(item.description), 1), (0, vue.createElementVNode)("span", _hoisted_5$2, (0, vue.toDisplayString)(item.panelFileText), 1)]), (0, vue.createElementVNode)("button", {
735
- class: "opencode-node-remove",
736
- type: "button",
737
- "aria-label": `\u79FB\u9664\u5143\u7D20: ${item.description}`,
738
- onClick: (0, vue.withModifiers)(($event) => $setup.handleRemoveSelectedNode({
739
- item,
740
- index,
741
- source: "panel"
742
- }), ["stop"])
743
- }, " × ", 8, _hoisted_6$2)], 8, _hoisted_2$2);
744
- }), 128))]),
745
- $setup.showClearAll && $setup.items.length > 0 ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("button", {
746
- key: 0,
747
- class: "opencode-clear-all-btn",
748
- type: "button",
749
- "aria-label": "清空所有已选节点",
750
- onClick: _cache[0] || (_cache[0] = (...args) => $setup.handleClearSelectedNodes && $setup.handleClearSelectedNodes(...args))
751
- }, " 一键清空 ")) : (0, vue.createCommentVNode)("v-if", true)
752
- ], 2);
753
- }
754
- __vue_sfc__$6.render = __vue_render__$6;
755
- var SelectedNodes_vue_default = __vue_sfc__$6;
756
- //#endregion
757
- //#region es/open-code-widget/src/components/ResizeHandle.vue.mjs
758
- var __defProp$3 = Object.defineProperty;
759
- var __defProps$3 = Object.defineProperties;
760
- var __getOwnPropDescs$3 = Object.getOwnPropertyDescriptors;
761
- var __getOwnPropSymbols$3 = Object.getOwnPropertySymbols;
762
- var __hasOwnProp$3 = Object.prototype.hasOwnProperty;
763
- var __propIsEnum$3 = Object.prototype.propertyIsEnumerable;
764
- var __defNormalProp$3 = (obj, key, value) => key in obj ? __defProp$3(obj, key, {
765
- enumerable: true,
766
- configurable: true,
767
- writable: true,
768
- value
769
- }) : obj[key] = value;
770
- var __spreadValues$3 = (a, b) => {
771
- for (var prop in b || (b = {})) if (__hasOwnProp$3.call(b, prop)) __defNormalProp$3(a, prop, b[prop]);
772
- if (__getOwnPropSymbols$3) {
773
- for (var prop of __getOwnPropSymbols$3(b)) if (__propIsEnum$3.call(b, prop)) __defNormalProp$3(a, prop, b[prop]);
774
- }
775
- return a;
776
- };
777
- var __spreadProps$3 = (a, b) => __defProps$3(a, __getOwnPropDescs$3(b));
778
- var __vue_sfc__$5 = /* @__PURE__ */ (0, vue.defineComponent)(__spreadProps$3(__spreadValues$3({}, { name: "ResizeHandle" }), {
779
- __name: "ResizeHandle",
780
- props: {
781
- width: {
782
- type: Number,
783
- required: false,
784
- default: 500
785
- },
786
- minWidth: {
787
- type: Number,
788
- required: false,
789
- default: 400
790
- },
791
- maxWidth: {
792
- type: Number,
793
- required: false,
794
- default: 800
795
- },
796
- position: {
797
- type: String,
798
- required: false,
799
- default: "right"
800
- }
801
- },
802
- emits: [
803
- "resize",
804
- "resize-start",
805
- "resize-end"
806
- ],
807
- setup(__props, { expose: __expose, emit: __emit }) {
808
- __expose();
809
- const props = __props;
810
- const emit = __emit;
811
- const isResizing = (0, vue.ref)(false);
812
- const startX = (0, vue.ref)(0);
813
- const startWidth = (0, vue.ref)(0);
814
- const handleMouseDown = (e) => {
815
- e.preventDefault();
816
- isResizing.value = true;
817
- startX.value = e.clientX;
818
- startWidth.value = props.width;
819
- emit("resize-start");
820
- document.addEventListener("mousemove", handleMouseMove);
821
- document.addEventListener("mouseup", handleMouseUp);
822
- };
823
- const handleMouseMove = (e) => {
824
- if (!isResizing.value) return;
825
- let deltaX;
826
- if (props.position === "right") deltaX = startX.value - e.clientX;
827
- else deltaX = e.clientX - startX.value;
828
- const newWidth = Math.max(props.minWidth, Math.min(props.maxWidth, startWidth.value + deltaX));
829
- emit("resize", newWidth);
830
- };
831
- const handleMouseUp = () => {
832
- isResizing.value = false;
833
- emit("resize-end");
834
- document.removeEventListener("mousemove", handleMouseMove);
835
- document.removeEventListener("mouseup", handleMouseUp);
836
- };
837
- const handleDoubleClick = () => {
838
- emit("resize", 500);
839
- };
840
- (0, vue.onUnmounted)(() => {
841
- document.removeEventListener("mousemove", handleMouseMove);
842
- document.removeEventListener("mouseup", handleMouseUp);
843
- });
844
- const __returned__ = {
845
- props,
846
- emit,
847
- isResizing,
848
- startX,
849
- startWidth,
850
- handleMouseDown,
851
- handleMouseMove,
852
- handleMouseUp,
853
- handleDoubleClick
854
- };
855
- Object.defineProperty(__returned__, "__isScriptSetup", {
856
- enumerable: false,
857
- value: true
858
- });
859
- return __returned__;
860
- }
861
- }));
862
- function __vue_render__$5(_ctx, _cache, $props, $setup, $data, $options) {
863
- return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", {
864
- class: (0, vue.normalizeClass)(["opencode-resize-handle", {
865
- resizing: $setup.isResizing,
866
- "handle-left": $props.position === "left"
867
- }]),
868
- onMousedown: $setup.handleMouseDown,
869
- onDblclick: $setup.handleDoubleClick
870
- }, null, 34);
871
- }
872
- __vue_sfc__$5.render = __vue_render__$5;
873
- var ResizeHandle_vue_default = __vue_sfc__$5;
874
- //#endregion
875
- //#region es/open-code-widget/src/components/ChatPanel.vue.mjs
876
- var __defProp$2 = Object.defineProperty;
877
- var __defProps$2 = Object.defineProperties;
878
- var __getOwnPropDescs$2 = Object.getOwnPropertyDescriptors;
879
- var __getOwnPropSymbols$2 = Object.getOwnPropertySymbols;
880
- var __hasOwnProp$2 = Object.prototype.hasOwnProperty;
881
- var __propIsEnum$2 = Object.prototype.propertyIsEnumerable;
882
- var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, {
883
- enumerable: true,
884
- configurable: true,
885
- writable: true,
886
- value
887
- }) : obj[key] = value;
888
- var __spreadValues$2 = (a, b) => {
889
- for (var prop in b || (b = {})) if (__hasOwnProp$2.call(b, prop)) __defNormalProp$2(a, prop, b[prop]);
890
- if (__getOwnPropSymbols$2) {
891
- for (var prop of __getOwnPropSymbols$2(b)) if (__propIsEnum$2.call(b, prop)) __defNormalProp$2(a, prop, b[prop]);
892
- }
893
- return a;
894
- };
895
- var __spreadProps$2 = (a, b) => __defProps$2(a, __getOwnPropDescs$2(b));
896
- var __vue_sfc__$4 = /* @__PURE__ */ (0, vue.defineComponent)(__spreadProps$2(__spreadValues$2({}, { name: "ChatPanel" }), {
897
- __name: "ChatPanel",
898
- props: {
899
- mode: {
900
- type: String,
901
- required: false,
902
- default: "bubble"
903
- },
904
- open: {
905
- type: Boolean,
906
- required: false,
907
- default: false
908
- },
909
- minimized: {
910
- type: Boolean,
911
- required: false,
912
- default: false
913
- },
914
- positionStyle: {
915
- type: Object,
916
- required: false,
917
- default: () => ({})
918
- },
919
- animationOrigin: {
920
- type: Object,
921
- required: false,
922
- default: () => ({
923
- x: "20px",
924
- y: "20px"
925
- })
926
- },
927
- panelWidth: {
928
- type: Number,
929
- required: false,
930
- default: 500
931
- },
932
- resizable: {
933
- type: Boolean,
934
- required: false,
935
- default: true
936
- },
937
- minWidth: {
938
- type: Number,
939
- required: false,
940
- default: 400
941
- },
942
- maxWidth: {
943
- type: Number,
944
- required: false,
945
- default: 800
946
- },
947
- noTransition: {
948
- type: Boolean,
949
- required: false,
950
- default: false
951
- },
952
- dragging: {
953
- type: Boolean,
954
- required: false,
955
- default: false
956
- },
957
- thinking: {
958
- type: Boolean,
959
- required: false,
960
- default: false
961
- },
962
- resolvedTheme: {
963
- type: String,
964
- required: false,
965
- default: "light"
966
- },
967
- splitPosition: {
968
- type: String,
969
- required: false,
970
- default: "right"
971
- },
972
- extension: {
973
- type: Boolean,
974
- required: false,
975
- default: false
976
- }
977
- },
978
- emits: [
979
- "resize",
980
- "resize-start",
981
- "resize-end",
982
- "toggle"
983
- ],
984
- setup(__props, { expose: __expose, emit: __emit }) {
985
- (0, vue.useCssVars)((_ctx) => ({
986
- "-animationOrigin.x": _ctx.animationOrigin.x,
987
- "-animationOrigin.y": _ctx.animationOrigin.y
988
- }));
989
- const props = __props;
990
- const emit = __emit;
991
- const slots = (0, vue.useSlots)();
992
- const frameRef = (0, vue.ref)(null);
993
- const sendMessageToIframe = (type, data) => {
994
- var _a;
995
- (_a = frameRef.value) == null || _a.sendMessageToIframe(type, data);
996
- };
997
- __expose({
998
- sendMessageToIframe,
999
- frameRef
1000
- });
1001
- const handleResizeStart = () => {
1002
- emit("resize-start");
1003
- };
1004
- const handleResize = (width) => {
1005
- emit("resize", width);
1006
- };
1007
- const handleResizeEnd = () => {
1008
- emit("resize-end");
1009
- };
1010
- const handleToggle = () => {
1011
- emit("toggle");
1012
- };
1013
- const __returned__ = {
1014
- props,
1015
- emit,
1016
- slots,
1017
- frameRef,
1018
- sendMessageToIframe,
1019
- handleResizeStart,
1020
- handleResize,
1021
- handleResizeEnd,
1022
- handleToggle,
1023
- panelStyle: (0, vue.computed)(() => {
1024
- if (props.extension) return {};
1025
- if (props.mode === "split") return { width: `${props.panelWidth}px` };
1026
- return props.positionStyle;
1027
- }),
1028
- panelClasses: (0, vue.computed)(() => ["opencode-chat", {
1029
- open: props.open,
1030
- minimized: props.minimized,
1031
- dragging: props.dragging,
1032
- "no-transition": props.noTransition,
1033
- "split-mode": props.mode === "split",
1034
- "split-left": props.mode === "split" && props.splitPosition === "left" && !props.extension,
1035
- "split-right": props.mode === "split" && props.splitPosition === "right" && !props.extension,
1036
- "extension-mode": props.extension
1037
- }]),
1038
- Frame: Frame_vue_default,
1039
- Header: Header_vue_default,
1040
- SessionList: SessionList_vue_default,
1041
- SelectedNodes: SelectedNodes_vue_default,
1042
- ResizeHandle: ResizeHandle_vue_default
1043
- };
1044
- Object.defineProperty(__returned__, "__isScriptSetup", {
1045
- enumerable: false,
1046
- value: true
1047
- });
1048
- return __returned__;
1049
- }
1050
- }));
1051
- var _hoisted_1$3 = ["aria-expanded"];
1052
- var _hoisted_2$1 = { class: "opencode-split-toggle-icon" };
1053
- var _hoisted_3$1 = {
1054
- key: 0,
1055
- viewBox: "0 0 24 24",
1056
- width: "16",
1057
- height: "16",
1058
- fill: "none",
1059
- stroke: "currentColor",
1060
- "stroke-width": "2"
1061
- };
1062
- var _hoisted_4$1 = {
1063
- key: 1,
1064
- viewBox: "0 0 24 24",
1065
- width: "16",
1066
- height: "16",
1067
- fill: "none",
1068
- stroke: "currentColor",
1069
- "stroke-width": "2"
1070
- };
1071
- var _hoisted_5$1 = {
1072
- key: 2,
1073
- viewBox: "0 0 24 24",
1074
- width: "16",
1075
- height: "16",
1076
- fill: "none",
1077
- stroke: "currentColor",
1078
- "stroke-width": "2"
1079
- };
1080
- var _hoisted_6$1 = {
1081
- key: 3,
1082
- viewBox: "0 0 24 24",
1083
- width: "16",
1084
- height: "16",
1085
- fill: "none",
1086
- stroke: "currentColor",
1087
- "stroke-width": "2"
1088
- };
1089
- var _hoisted_7 = { class: "opencode-chat-content" };
1090
- function __vue_render__$4(_ctx, _cache, $props, $setup, $data, $options) {
1091
- return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", {
1092
- class: (0, vue.normalizeClass)($setup.panelClasses),
1093
- style: (0, vue.normalizeStyle)($setup.panelStyle)
1094
- }, [
1095
- $props.mode === "split" && $props.resizable && $props.open ? ((0, vue.openBlock)(), (0, vue.createBlock)($setup["ResizeHandle"], {
1096
- key: 0,
1097
- width: $props.panelWidth,
1098
- "min-width": $props.minWidth,
1099
- "max-width": $props.maxWidth,
1100
- position: $props.splitPosition,
1101
- onResize: $setup.handleResize,
1102
- onResizeStart: $setup.handleResizeStart,
1103
- onResizeEnd: $setup.handleResizeEnd
1104
- }, null, 8, [
1105
- "width",
1106
- "min-width",
1107
- "max-width",
1108
- "position"
1109
- ])) : (0, vue.createCommentVNode)("v-if", true),
1110
- $props.mode === "split" && $props.resizable ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("button", {
1111
- key: 1,
1112
- type: "button",
1113
- class: (0, vue.normalizeClass)(["opencode-split-toggle-btn", {
1114
- open: $setup.props.open,
1115
- thinking: $setup.props.thinking,
1116
- "opencode-theme-dark": $props.resolvedTheme === "dark",
1117
- "split-left": $props.splitPosition === "left"
1118
- }]),
1119
- "aria-expanded": $props.open,
1120
- "aria-label": "切换面板",
1121
- onClick: $setup.handleToggle
1122
- }, [(0, vue.createElementVNode)("span", _hoisted_2$1, [
1123
- $props.open && $props.splitPosition === "right" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("svg", _hoisted_3$1, [..._cache[0] || (_cache[0] = [(0, vue.createElementVNode)("path", {
1124
- d: "M9 18l6-6-6-6",
1125
- "stroke-linecap": "round",
1126
- "stroke-linejoin": "round"
1127
- }, null, -1)])])) : (0, vue.createCommentVNode)("v-if", true),
1128
- !$props.open && $props.splitPosition === "right" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("svg", _hoisted_4$1, [..._cache[1] || (_cache[1] = [(0, vue.createElementVNode)("path", {
1129
- d: "M15 18l-6-6 6-6",
1130
- "stroke-linecap": "round",
1131
- "stroke-linejoin": "round"
1132
- }, null, -1)])])) : (0, vue.createCommentVNode)("v-if", true),
1133
- $props.open && $props.splitPosition === "left" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("svg", _hoisted_5$1, [..._cache[2] || (_cache[2] = [(0, vue.createElementVNode)("path", {
1134
- d: "M15 18l-6-6 6-6",
1135
- "stroke-linecap": "round",
1136
- "stroke-linejoin": "round"
1137
- }, null, -1)])])) : (0, vue.createCommentVNode)("v-if", true),
1138
- !$props.open && $props.splitPosition === "left" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("svg", _hoisted_6$1, [..._cache[3] || (_cache[3] = [(0, vue.createElementVNode)("path", {
1139
- d: "M9 18l6-6-6-6",
1140
- "stroke-linecap": "round",
1141
- "stroke-linejoin": "round"
1142
- }, null, -1)])])) : (0, vue.createCommentVNode)("v-if", true)
1143
- ])], 10, _hoisted_1$3)) : (0, vue.createCommentVNode)("v-if", true),
1144
- (0, vue.createVNode)($setup["Header"], null, (0, vue.createSlots)({ _: 2 }, [
1145
- $setup.slots["session-toggle-icon"] ? {
1146
- name: "session-toggle-icon",
1147
- fn: (0, vue.withCtx)(() => [(0, vue.renderSlot)(_ctx.$slots, "session-toggle-icon")]),
1148
- key: "0"
1149
- } : void 0,
1150
- $setup.slots["select-icon"] ? {
1151
- name: "select-icon",
1152
- fn: (0, vue.withCtx)(() => [(0, vue.renderSlot)(_ctx.$slots, "select-icon")]),
1153
- key: "1"
1154
- } : void 0,
1155
- $setup.slots["close-icon"] ? {
1156
- name: "close-icon",
1157
- fn: (0, vue.withCtx)(() => [(0, vue.renderSlot)(_ctx.$slots, "close-icon")]),
1158
- key: "2"
1159
- } : void 0
1160
- ]), 1024),
1161
- (0, vue.createElementVNode)("div", _hoisted_7, [
1162
- (0, vue.createVNode)($setup["SessionList"], null, {
1163
- empty: (0, vue.withCtx)(() => [(0, vue.renderSlot)(_ctx.$slots, "sessions-empty", {}, () => [_cache[4] || (_cache[4] = (0, vue.createElementVNode)("div", { class: "opencode-session-empty" }, "暂无会话", -1))])]),
1164
- _: 3
1165
- }),
1166
- (0, vue.createVNode)($setup["Frame"], { ref: "frameRef" }, (0, vue.createSlots)({ _: 2 }, [
1167
- $setup.slots["empty-state"] ? {
1168
- name: "empty-state",
1169
- fn: (0, vue.withCtx)(() => [(0, vue.renderSlot)(_ctx.$slots, "empty-state")]),
1170
- key: "0"
1171
- } : void 0,
1172
- $setup.slots.loading ? {
1173
- name: "loading",
1174
- fn: (0, vue.withCtx)(() => [(0, vue.renderSlot)(_ctx.$slots, "loading")]),
1175
- key: "1"
1176
- } : void 0,
1177
- $setup.slots.error ? {
1178
- name: "error",
1179
- fn: (0, vue.withCtx)(() => [(0, vue.renderSlot)(_ctx.$slots, "error")]),
1180
- key: "2"
1181
- } : void 0,
1182
- $setup.slots.content ? {
1183
- name: "content",
1184
- fn: (0, vue.withCtx)(() => [(0, vue.renderSlot)(_ctx.$slots, "content")]),
1185
- key: "3"
1186
- } : void 0
1187
- ]), 1536),
1188
- (0, vue.createVNode)($setup["SelectedNodes"])
1189
- ])
1190
- ], 6);
1191
- }
1192
- __vue_sfc__$4.render = __vue_render__$4;
1193
- var ChatPanel_vue_default = __vue_sfc__$4;
1194
- //#endregion
1195
- //#region es/open-code-widget/src/components/SelectHint.vue.mjs
1196
- var __vue_sfc__$3 = /* @__PURE__ */ (0, vue.defineComponent)({
1197
- __name: "SelectHint",
1198
- setup(__props, { expose: __expose }) {
1199
- __expose();
1200
- const { selectMode: visible, selectShortcutLabel: shortcutLabel } = useOpenCodeWidgetContext();
1201
- const __returned__ = {
1202
- visible,
1203
- shortcutLabel
1204
- };
1205
- Object.defineProperty(__returned__, "__isScriptSetup", {
1206
- enumerable: false,
1207
- value: true
1208
- });
1209
- return __returned__;
1210
- }
1211
- });
1212
- var _hoisted_1$2 = { class: "opencode-hint-shortcut" };
1213
- function __vue_render__$3(_ctx, _cache, $props, $setup, $data, $options) {
1214
- return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", { class: (0, vue.normalizeClass)(["opencode-select-mode-hint", { visible: $setup.visible }]) }, [_cache[0] || (_cache[0] = (0, vue.createStaticVNode)("<span class=\"opencode-hint-main\"><span class=\"opencode-hint-icon\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" width=\"18\" height=\"18\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"8\"></circle><circle cx=\"12\" cy=\"12\" r=\"2.5\" fill=\"currentColor\"></circle><line x1=\"12\" y1=\"2\" x2=\"12\" y2=\"5\"></line><line x1=\"12\" y1=\"19\" x2=\"12\" y2=\"22\"></line><line x1=\"2\" y1=\"12\" x2=\"5\" y2=\"12\"></line><line x1=\"19\" y1=\"12\" x2=\"22\" y2=\"12\"></line></svg></span><span class=\"opencode-hint-text\">选择模式已开启 · 点击元素进行选择</span></span>", 1)), (0, vue.createElementVNode)("span", _hoisted_1$2, (0, vue.toDisplayString)($setup.shortcutLabel), 1)], 2);
1215
- }
1216
- __vue_sfc__$3.render = __vue_render__$3;
1217
- var SelectHint_vue_default = __vue_sfc__$3;
1218
- //#endregion
1219
- //#region es/open-code-widget/src/components/FloatingBubble/FloatingBubble.vue.mjs
1220
- var __defProp$1 = Object.defineProperty;
1221
- var __defProps$1 = Object.defineProperties;
1222
- var __getOwnPropDescs$1 = Object.getOwnPropertyDescriptors;
1223
- var __getOwnPropSymbols$1 = Object.getOwnPropertySymbols;
1224
- var __hasOwnProp$1 = Object.prototype.hasOwnProperty;
1225
- var __propIsEnum$1 = Object.prototype.propertyIsEnumerable;
1226
- var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, {
1227
- enumerable: true,
1228
- configurable: true,
1229
- writable: true,
1230
- value
1231
- }) : obj[key] = value;
1232
- var __spreadValues$1 = (a, b) => {
1233
- for (var prop in b || (b = {})) if (__hasOwnProp$1.call(b, prop)) __defNormalProp$1(a, prop, b[prop]);
1234
- if (__getOwnPropSymbols$1) {
1235
- for (var prop of __getOwnPropSymbols$1(b)) if (__propIsEnum$1.call(b, prop)) __defNormalProp$1(a, prop, b[prop]);
1236
- }
1237
- return a;
1238
- };
1239
- var __spreadProps$1 = (a, b) => __defProps$1(a, __getOwnPropDescs$1(b));
1240
- var __vue_sfc__$2 = /* @__PURE__ */ (0, vue.defineComponent)(__spreadProps$1(__spreadValues$1({}, { name: "FloatingBubble" }), {
1241
- __name: "FloatingBubble",
1242
- props: {
1243
- offset: {
1244
- type: Object,
1245
- required: false,
1246
- default: void 0
1247
- },
1248
- axis: {
1249
- type: String,
1250
- required: false,
1251
- default: "xy"
1252
- },
1253
- magnetic: {
1254
- type: String,
1255
- required: false,
1256
- default: void 0
1257
- },
1258
- gap: {
1259
- type: [Number, Object],
1260
- required: false,
1261
- default: 24
1262
- },
1263
- teleport: {
1264
- type: null,
1265
- required: false,
1266
- default: "body"
1267
- }
1268
- },
1269
- emits: [
1270
- "update:offset",
1271
- "click",
1272
- "offset-change",
1273
- "drag-start",
1274
- "drag-end"
1275
- ],
1276
- setup(__props, { expose: __expose, emit: __emit }) {
1277
- const props = __props;
1278
- const emit = __emit;
1279
- const rootRef = (0, vue.ref)(null);
1280
- const state = (0, vue.ref)({
1281
- x: 0,
1282
- y: 0,
1283
- width: 0,
1284
- height: 0
1285
- });
1286
- const isObject = (val) => val !== null && typeof val === "object";
1287
- const gapX = (0, vue.computed)(() => isObject(props.gap) ? props.gap.x : props.gap);
1288
- const gapY = (0, vue.computed)(() => isObject(props.gap) ? props.gap.y : props.gap);
1289
- const windowWidth = (0, vue.ref)(typeof window !== "undefined" ? window.innerWidth : 0);
1290
- const windowHeight = (0, vue.ref)(typeof window !== "undefined" ? window.innerHeight : 0);
1291
- const boundary = (0, vue.computed)(() => ({
1292
- top: gapY.value,
1293
- right: windowWidth.value - state.value.width - gapX.value,
1294
- bottom: windowHeight.value - state.value.height - gapY.value,
1295
- left: gapX.value
1296
- }));
1297
- const closest = (arr, target) => {
1298
- return arr.reduce((pre, cur) => Math.abs(pre - target) < Math.abs(cur - target) ? pre : cur);
1299
- };
1300
- const applyMagnetic = () => {
1301
- if (props.magnetic === "x") if (magneticSide.value === "left") state.value.x = boundary.value.left;
1302
- else if (magneticSide.value === "right") state.value.x = boundary.value.right;
1303
- else {
1304
- const nextX = closest([boundary.value.left, boundary.value.right], state.value.x);
1305
- state.value.x = nextX;
1306
- magneticSide.value = nextX === boundary.value.left ? "left" : "right";
1307
- }
1308
- if (props.magnetic === "y") {
1309
- const nextY = closest([boundary.value.top, boundary.value.bottom], state.value.y);
1310
- state.value.y = nextY;
1311
- }
1312
- };
1313
- const dragging = (0, vue.ref)(false);
1314
- const initialized = (0, vue.ref)(false);
1315
- const magneticSide = (0, vue.ref)(null);
1316
- const rootStyle = (0, vue.computed)(() => {
1317
- const style = {};
1318
- style.transform = `translate3d(${`${state.value.x}px`}, ${`${state.value.y}px`}, 0)`;
1319
- if (dragging.value || !initialized.value) style.transition = "none";
1320
- else style.transition = "transform 0.3s ease";
1321
- return style;
1322
- });
1323
- const updateState = () => {
1324
- if (!rootRef.value || typeof window === "undefined") return;
1325
- const rect = rootRef.value.getBoundingClientRect();
1326
- const { offset } = props;
1327
- let x = offset ? offset.x : windowWidth.value - rect.width - gapX.value;
1328
- let y = offset ? offset.y : windowHeight.value - rect.height - gapY.value;
1329
- const maxX = windowWidth.value - rect.width - gapX.value;
1330
- const maxY = windowHeight.value - rect.height - gapY.value;
1331
- if (x < gapX.value) x = gapX.value;
1332
- if (x > maxX) x = maxX;
1333
- if (y < gapY.value) y = gapY.value;
1334
- if (y > maxY) y = maxY;
1335
- const oldX = state.value.x;
1336
- const oldY = state.value.y;
1337
- state.value = {
1338
- x,
1339
- y,
1340
- width: rect.width,
1341
- height: rect.height
1342
- };
1343
- if (!dragging.value) {
1344
- if (props.magnetic === "x" && magneticSide.value) if (magneticSide.value === "left") state.value.x = boundary.value.left;
1345
- else state.value.x = boundary.value.right;
1346
- else applyMagnetic();
1347
- if (state.value.x !== oldX || state.value.y !== oldY) {
1348
- const offset2 = {
1349
- x: state.value.x,
1350
- y: state.value.y
1351
- };
1352
- emit("update:offset", offset2);
1353
- emit("offset-change", offset2);
1354
- }
1355
- }
1356
- };
1357
- const touch = {
1358
- startX: (0, vue.ref)(0),
1359
- startY: (0, vue.ref)(0),
1360
- deltaX: (0, vue.ref)(0),
1361
- deltaY: (0, vue.ref)(0),
1362
- offsetX: (0, vue.ref)(0),
1363
- offsetY: (0, vue.ref)(0),
1364
- isTap: (0, vue.ref)(true),
1365
- start(e) {
1366
- this.startX.value = "touches" in e ? e.touches[0].clientX : e.clientX;
1367
- this.startY.value = "touches" in e ? e.touches[0].clientY : e.clientY;
1368
- this.deltaX.value = 0;
1369
- this.deltaY.value = 0;
1370
- this.offsetX.value = 0;
1371
- this.offsetY.value = 0;
1372
- this.isTap.value = true;
1373
- },
1374
- move(e) {
1375
- const clientX = "touches" in e ? e.touches[0].clientX : e.clientX;
1376
- const clientY = "touches" in e ? e.touches[0].clientY : e.clientY;
1377
- this.deltaX.value = clientX - this.startX.value;
1378
- this.deltaY.value = clientY - this.startY.value;
1379
- this.offsetX.value = Math.abs(this.deltaX.value);
1380
- this.offsetY.value = Math.abs(this.deltaY.value);
1381
- const TAP_OFFSET = 5;
1382
- if (this.isTap.value && (this.offsetX.value > TAP_OFFSET || this.offsetY.value > TAP_OFFSET)) this.isTap.value = false;
1383
- }
1384
- };
1385
- let prevX = 0;
1386
- let prevY = 0;
1387
- const onTouchStart = (e) => {
1388
- touch.start(e);
1389
- dragging.value = true;
1390
- prevX = state.value.x;
1391
- prevY = state.value.y;
1392
- document.body.classList.add("floating-bubble-dragging");
1393
- if (!("touches" in e)) {
1394
- window.addEventListener("mousemove", onTouchMove, { passive: false });
1395
- window.addEventListener("mouseup", onTouchEnd);
1396
- }
1397
- };
1398
- const onTouchMove = (e) => {
1399
- if (e.cancelable) e.preventDefault();
1400
- const wasTap = touch.isTap.value;
1401
- touch.move(e);
1402
- if (wasTap && !touch.isTap.value) emit("drag-start");
1403
- if (props.axis === "lock") return;
1404
- if (!touch.isTap.value) {
1405
- if (props.axis === "x" || props.axis === "xy") {
1406
- let nextX = prevX + touch.deltaX.value;
1407
- if (nextX < boundary.value.left) nextX = boundary.value.left;
1408
- if (nextX > boundary.value.right) nextX = boundary.value.right;
1409
- state.value.x = nextX;
1410
- }
1411
- if (props.axis === "y" || props.axis === "xy") {
1412
- let nextY = prevY + touch.deltaY.value;
1413
- if (nextY < boundary.value.top) nextY = boundary.value.top;
1414
- if (nextY > boundary.value.bottom) nextY = boundary.value.bottom;
1415
- state.value.y = nextY;
1416
- }
1417
- const offset = {
1418
- x: state.value.x,
1419
- y: state.value.y
1420
- };
1421
- emit("update:offset", offset);
1422
- }
1423
- };
1424
- const onTouchEnd = (e) => {
1425
- dragging.value = false;
1426
- document.body.classList.remove("floating-bubble-dragging");
1427
- if (e && !("touches" in e) && e.type === "mouseup") {
1428
- window.removeEventListener("mousemove", onTouchMove);
1429
- window.removeEventListener("mouseup", onTouchEnd);
1430
- }
1431
- requestAnimationFrame(() => {
1432
- if (props.magnetic === "x" && !touch.isTap.value) {
1433
- const centerX = state.value.x + state.value.width / 2;
1434
- const windowCenterX = windowWidth.value / 2;
1435
- magneticSide.value = centerX < windowCenterX ? "left" : "right";
1436
- }
1437
- applyMagnetic();
1438
- if (!touch.isTap.value) {
1439
- emit("drag-end");
1440
- const offset = {
1441
- x: state.value.x,
1442
- y: state.value.y
1443
- };
1444
- emit("update:offset", offset);
1445
- if (prevX !== offset.x || prevY !== offset.y) emit("offset-change", offset);
1446
- }
1447
- });
1448
- };
1449
- const onClick = (e) => {
1450
- if (touch.isTap.value) emit("click", e);
1451
- else e.stopPropagation();
1452
- };
1453
- const handleResize = () => {
1454
- if (typeof window !== "undefined") {
1455
- windowWidth.value = window.innerWidth;
1456
- windowHeight.value = window.innerHeight;
1457
- }
1458
- };
1459
- (0, vue.onMounted)(() => {
1460
- updateState();
1461
- requestAnimationFrame(() => {
1462
- initialized.value = true;
1463
- });
1464
- if (typeof window !== "undefined") window.addEventListener("resize", handleResize);
1465
- if (rootRef.value) rootRef.value.addEventListener("touchmove", onTouchMove, { passive: false });
1466
- });
1467
- (0, vue.onUnmounted)(() => {
1468
- document.body.classList.remove("floating-bubble-dragging");
1469
- if (typeof window !== "undefined") {
1470
- window.removeEventListener("resize", handleResize);
1471
- window.removeEventListener("mousemove", onTouchMove);
1472
- window.removeEventListener("mouseup", onTouchEnd);
1473
- }
1474
- if (rootRef.value) rootRef.value.removeEventListener("touchmove", onTouchMove);
1475
- });
1476
- (0, vue.watch)([
1477
- windowWidth,
1478
- windowHeight,
1479
- gapX,
1480
- gapY
1481
- ], updateState);
1482
- (0, vue.watch)(() => props.offset, (newOffset) => {
1483
- if (newOffset) magneticSide.value = null;
1484
- updateState();
1485
- }, { deep: true });
1486
- __expose({ offset: (0, vue.computed)(() => ({
1487
- x: state.value.x,
1488
- y: state.value.y
1489
- })) });
1490
- const __returned__ = {
1491
- props,
1492
- emit,
1493
- rootRef,
1494
- state,
1495
- isObject,
1496
- gapX,
1497
- gapY,
1498
- windowWidth,
1499
- windowHeight,
1500
- boundary,
1501
- closest,
1502
- applyMagnetic,
1503
- dragging,
1504
- initialized,
1505
- magneticSide,
1506
- rootStyle,
1507
- updateState,
1508
- touch,
1509
- get prevX() {
1510
- return prevX;
1511
- },
1512
- set prevX(v) {
1513
- prevX = v;
1514
- },
1515
- get prevY() {
1516
- return prevY;
1517
- },
1518
- set prevY(v) {
1519
- prevY = v;
1520
- },
1521
- onTouchStart,
1522
- onTouchMove,
1523
- onTouchEnd,
1524
- onClick,
1525
- handleResize
1526
- };
1527
- Object.defineProperty(__returned__, "__isScriptSetup", {
1528
- enumerable: false,
1529
- value: true
1530
- });
1531
- return __returned__;
1532
- }
1533
- }));
1534
- function __vue_render__$2(_ctx, _cache, $props, $setup, $data, $options) {
1535
- return (0, vue.openBlock)(), (0, vue.createBlock)(vue.Teleport, { to: $props.teleport }, [(0, vue.createElementVNode)("div", {
1536
- ref: "rootRef",
1537
- class: "floating-bubble",
1538
- style: (0, vue.normalizeStyle)($setup.rootStyle),
1539
- onTouchstartPassive: $setup.onTouchStart,
1540
- onTouchend: $setup.onTouchEnd,
1541
- onTouchcancel: $setup.onTouchEnd,
1542
- onMousedown: $setup.onTouchStart,
1543
- onClickCapture: $setup.onClick
1544
- }, [(0, vue.renderSlot)(_ctx.$slots, "default")], 36)], 8, ["to"]);
1545
- }
1546
- __vue_sfc__$2.render = __vue_render__$2;
1547
- var FloatingBubble_vue_default = __vue_sfc__$2;
1548
- //#endregion
1549
- //#region es/open-code-widget/src/components/Trigger.vue.mjs
1550
- var __vue_sfc__$1 = /* @__PURE__ */ (0, vue.defineComponent)({
1551
- __name: "Trigger",
1552
- emits: ["drag-start", "drag-end"],
1553
- setup(__props, { expose: __expose, emit: __emit }) {
1554
- const { buttonActive: active, open, hotkeyLabel, thinking, resolvedTheme, handleToggle, bubbleOffset, handleBubbleOffsetChange } = useOpenCodeWidgetContext();
1555
- const offset = (0, vue.ref)(bubbleOffset.value);
1556
- const emit = __emit;
1557
- const handleOffsetChange = (value) => {
1558
- offset.value = value;
1559
- handleBubbleOffsetChange(value);
1560
- };
1561
- (0, vue.watch)(bubbleOffset, (newOffset) => {
1562
- offset.value = newOffset;
1563
- });
1564
- __expose({ offset });
1565
- const __returned__ = {
1566
- active,
1567
- open,
1568
- hotkeyLabel,
1569
- thinking,
1570
- resolvedTheme,
1571
- handleToggle,
1572
- bubbleOffset,
1573
- handleBubbleOffsetChange,
1574
- offset,
1575
- emit,
1576
- handleOffsetChange,
1577
- FloatingBubble: FloatingBubble_vue_default
1578
- };
1579
- Object.defineProperty(__returned__, "__isScriptSetup", {
1580
- enumerable: false,
1581
- value: true
1582
- });
1583
- return __returned__;
1584
- }
1585
- });
1586
- var _hoisted_1$1 = ["aria-expanded", "title"];
1587
- function __vue_render__$1(_ctx, _cache, $props, $setup, $data, $options) {
1588
- return (0, vue.openBlock)(), (0, vue.createBlock)($setup["FloatingBubble"], {
1589
- ref: "bubbleRef",
1590
- offset: $setup.offset,
1591
- "onUpdate:offset": _cache[0] || (_cache[0] = ($event) => $setup.offset = $event),
1592
- axis: "xy",
1593
- magnetic: "x",
1594
- gap: 24,
1595
- onClick: $setup.handleToggle,
1596
- onOffsetChange: $setup.handleOffsetChange,
1597
- onDragStart: _cache[1] || (_cache[1] = ($event) => $setup.emit("drag-start")),
1598
- onDragEnd: _cache[2] || (_cache[2] = ($event) => $setup.emit("drag-end"))
1599
- }, {
1600
- default: (0, vue.withCtx)(() => [(0, vue.createElementVNode)("button", {
1601
- class: (0, vue.normalizeClass)(["opencode-button", {
1602
- active: $setup.active,
1603
- thinking: $setup.thinking,
1604
- "opencode-theme-dark": $setup.resolvedTheme === "dark"
1605
- }]),
1606
- type: "button",
1607
- "aria-expanded": $setup.open,
1608
- "aria-label": "打开 AI 助手",
1609
- title: `AI \u52A9\u624B (${$setup.hotkeyLabel})`
1610
- }, [(0, vue.renderSlot)(_ctx.$slots, "default", {}, () => [_cache[3] || (_cache[3] = (0, vue.createElementVNode)("svg", {
1611
- t: "1775402599580",
1612
- class: "icon",
1613
- viewBox: "0 0 1024 1024",
1614
- version: "1.1",
1615
- xmlns: "http://www.w3.org/2000/svg",
1616
- "p-id": "5390",
1617
- "xmlns:xlink": "http://www.w3.org/1999/xlink",
1618
- width: "100%",
1619
- height: "100%"
1620
- }, [
1621
- (0, vue.createElementVNode)("defs", null, [(0, vue.createElementVNode)("linearGradient", {
1622
- id: "opencode-logo-gradient",
1623
- x1: "0%",
1624
- y1: "0%",
1625
- x2: "100%",
1626
- y2: "100%"
1627
- }, [(0, vue.createElementVNode)("stop", {
1628
- offset: "0%",
1629
- style: { "stop-color": "#667eea" }
1630
- }), (0, vue.createElementVNode)("stop", {
1631
- offset: "100%",
1632
- style: { "stop-color": "#764ba2" }
1633
- })])]),
1634
- (0, vue.createElementVNode)("path", {
1635
- d: "M512 981.33H85.34c-15.85 0-30.38-8.77-37.77-22.81a42.624 42.624 0 0 1 2.6-44.02L135 791.08C75.25 710.5 42.67 612.6 42.67 512 42.67 253.21 253.21 42.67 512 42.67S981.34 253.21 981.34 512 770.8 981.33 512 981.33zM166.44 896H512c211.73 0 384-172.27 384-384S723.73 128 512 128 128 300.27 128 512c0 91.29 32.83 179.9 92.46 249.46 12.58 14.69 13.73 36 2.77 51.94L166.44 896z",
1636
- fill: "url(#opencode-logo-gradient)",
1637
- "p-id": "5391"
1638
- }),
1639
- (0, vue.createElementVNode)("path", {
1640
- d: "M384 448m-64 0a64 64 0 1 0 128 0 64 64 0 1 0 -128 0Z",
1641
- fill: "url(#opencode-logo-gradient)",
1642
- "p-id": "5392"
1643
- }),
1644
- (0, vue.createElementVNode)("path", {
1645
- d: "M640 448m-64 0a64 64 0 1 0 128 0 64 64 0 1 0 -128 0Z",
1646
- fill: "url(#opencode-logo-gradient)",
1647
- "p-id": "5393"
1648
- })
1649
- ], -1))])], 10, _hoisted_1$1)]),
1650
- _: 3
1651
- }, 8, ["offset", "onClick"]);
1652
- }
1653
- __vue_sfc__$1.render = __vue_render__$1;
1654
- var Trigger_vue_default = __vue_sfc__$1;
1655
- //#endregion
1656
- //#region es/open-code-widget/composables/use-selection.mjs
1657
- var __async$1 = (__this, __arguments, generator) => {
1658
- return new Promise((resolve, reject) => {
1659
- var fulfilled = (value) => {
1660
- try {
1661
- step(generator.next(value));
1662
- } catch (e) {
1663
- reject(e);
1664
- }
1665
- };
1666
- var rejected = (value) => {
1667
- try {
1668
- step(generator.throw(value));
1669
- } catch (e) {
1670
- reject(e);
1671
- }
1672
- };
1673
- var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
1674
- step((generator = generator.apply(__this, __arguments)).next());
1675
- });
1676
- };
1677
- function getElementKey(element, index) {
1678
- var _a;
1679
- if (element.filePath && element.line) return `${element.filePath}:${element.line}:${(_a = element.column) != null ? _a : 0}`;
1680
- return `${element.description}-${index}`;
1681
- }
1682
- function getBubbleFileText(element) {
1683
- var _a;
1684
- return `${((_a = element.filePath) == null ? void 0 : _a.split("/").pop()) || ""}${element.line ? `:${element.line}${element.column ? `:${element.column}` : ""}` : ""}`;
1685
- }
1686
- function getPanelFileText(element) {
1687
- var _a, _b;
1688
- const fileName = ((_a = element.filePath) == null ? void 0 : _a.split("/").pop()) || "未知文件";
1689
- const lineInfo = element.line ? `:${element.line}${element.column ? `:${element.column}` : ""}` : "";
1690
- return `${((_b = element.innerText) == null ? void 0 : _b.trim()) ? `${(0, _vite_plugin_opencode_assistant_shared.truncate)(element.innerText.trim(), 30)} \xB7 ` : ""}${fileName}${lineInfo}`;
1691
- }
1692
- function useSelection(options) {
1693
- const bubbleVisible = (0, vue.computed)(() => options.selectMode.value);
1694
- const selectedElementItems = (0, vue.computed)(() => (options.selectedElements.value || []).map((element, index) => ({
1695
- key: getElementKey(element, index),
1696
- description: element.description || "未知元素",
1697
- bubbleFileText: getBubbleFileText(element),
1698
- panelFileText: getPanelFileText(element),
1699
- element
1700
- })));
1701
- const hasSelectedElements = (0, vue.computed)(() => selectedElementItems.value.length > 0);
1702
- function handleToggleSelectMode() {
1703
- options.onToggleSelectMode(!options.selectMode.value);
1704
- }
1705
- function handleClickSelectedNode(item) {
1706
- const description = item.element.description;
1707
- if (!description) return;
1708
- let targetElement = null;
1709
- if (description.includes("#")) {
1710
- const idMatch = description.match(/#([^.[\s]+)/);
1711
- if (idMatch) targetElement = document.getElementById(idMatch[1]);
1712
- }
1713
- if (!targetElement && description.includes(".")) {
1714
- const classMatch = description.match(/^([a-z]+)\.([^[\s]+)/i);
1715
- if (classMatch) {
1716
- const selector = `${classMatch[1]}.${classMatch[2].split(".").filter(Boolean).join(".")}`;
1717
- targetElement = document.querySelector(selector);
1718
- }
1719
- }
1720
- if (!targetElement) {
1721
- if (description.match(/^([a-z]+)/i)) {
1722
- const simpleSelector = description.split(/[.[\s]/)[0];
1723
- targetElement = document.querySelector(simpleSelector);
1724
- }
1725
- }
1726
- if (targetElement) {
1727
- targetElement.scrollIntoView({
1728
- behavior: "smooth",
1729
- block: "center"
1730
- });
1731
- const highlightOverlay = document.createElement("div");
1732
- highlightOverlay.className = "opencode-element-highlight-temp";
1733
- const widget = document.querySelector(".opencode-widget");
1734
- let primary = "#3b82f6";
1735
- let primaryBg = "rgba(59, 130, 246, 0.1)";
1736
- if (widget) {
1737
- const style = getComputedStyle(widget);
1738
- primary = style.getPropertyValue("--oc-primary").trim() || primary;
1739
- primaryBg = style.getPropertyValue("--oc-primary-bg").trim() || primaryBg;
1740
- }
1741
- highlightOverlay.style.border = `2px solid ${primary}`;
1742
- highlightOverlay.style.background = primaryBg;
1743
- const rect = targetElement.getBoundingClientRect();
1744
- highlightOverlay.style.top = `${rect.top + window.scrollY}px`;
1745
- highlightOverlay.style.left = `${rect.left + window.scrollX}px`;
1746
- highlightOverlay.style.width = `${rect.width}px`;
1747
- highlightOverlay.style.height = `${rect.height}px`;
1748
- document.body.appendChild(highlightOverlay);
1749
- setTimeout(() => {
1750
- highlightOverlay.remove();
1751
- }, 2e3);
1752
- }
1753
- }
1754
- function handleRemoveSelectedNode(item, index, source) {
1755
- options.onRemoveSelectedNode({
1756
- element: item.element,
1757
- index,
1758
- source
1759
- });
1760
- }
1761
- function handleClearSelectedNodes() {
1762
- return __async$1(this, null, function* () {
1763
- if (!options.selectedElements.value || options.selectedElements.value.length === 0) return;
1764
- if (yield options.showConfirmDialog(`\u786E\u5B9A\u8981\u6E05\u7A7A\u6240\u6709 ${options.selectedElements.value.length} \u4E2A\u5DF2\u9009\u8282\u70B9\u5417\uFF1F`)) options.onClearSelectedNodes();
1765
- });
1766
- }
1767
- return {
1768
- bubbleVisible,
1769
- hasSelectedElements,
1770
- selectedElementItems,
1771
- handleClearSelectedNodes,
1772
- handleClickSelectedNode,
1773
- handleRemoveSelectedNode,
1774
- handleToggleSelectMode
1775
- };
1776
- }
1777
- //#endregion
1778
- //#region es/open-code-widget/composables/use-session.mjs
1779
- var __async = (__this, __arguments, generator) => {
1780
- return new Promise((resolve, reject) => {
1781
- var fulfilled = (value) => {
1782
- try {
1783
- step(generator.next(value));
1784
- } catch (e) {
1785
- reject(e);
1786
- }
1787
- };
1788
- var rejected = (value) => {
1789
- try {
1790
- step(generator.throw(value));
1791
- } catch (e) {
1792
- reject(e);
1793
- }
1794
- };
1795
- var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
1796
- step((generator = generator.apply(__this, __arguments)).next());
1797
- });
1798
- };
1799
- function formatSessionMeta(session) {
1800
- if (session.meta) return session.meta;
1801
- if (!session.updatedAt) return "";
1802
- const date = new Date(session.updatedAt);
1803
- if (Number.isNaN(date.getTime())) return "";
1804
- return `${date.toLocaleDateString()} ${date.toLocaleTimeString()}`;
1805
- }
1806
- function useSession(options) {
1807
- const sessionItems = (0, vue.computed)(() => (options.sessions.value || []).map((session) => ({
1808
- key: session.id,
1809
- id: session.id,
1810
- title: session.title || "新会话",
1811
- meta: formatSessionMeta(session),
1812
- active: session.id === options.currentSessionId.value,
1813
- session
1814
- })));
1815
- function handleCreateSession() {
1816
- options.onCreateSession();
1817
- }
1818
- function handleSelectSession(item) {
1819
- options.onSelectSession(item.session);
1820
- }
1821
- function handleDeleteSession(item) {
1822
- return __async(this, null, function* () {
1823
- if (yield options.showConfirmDialog(`\u786E\u5B9A\u8981\u5220\u9664\u4F1A\u8BDD "${item.title}" \u5417\uFF1F`)) options.onDeleteSession(item.session);
1824
- });
1825
- }
1826
- return {
1827
- sessionItems,
1828
- handleCreateSession,
1829
- handleDeleteSession,
1830
- handleSelectSession
1831
- };
1832
- }
1833
- //#endregion
1834
- //#region es/open-code-widget/composables/use-widget.mjs
1835
- var THEME_CYCLE = [
1836
- "auto",
1837
- "light",
1838
- "dark"
1839
- ];
1840
- function useWidget(options) {
1841
- const systemTheme = (0, vue.ref)("light");
1842
- function getSystemTheme() {
1843
- if (typeof window === "undefined") return "light";
1844
- return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
1845
- }
1846
- let mediaQuery = null;
1847
- let handleChange = null;
1848
- (0, vue.onMounted)(() => {
1849
- if (typeof window === "undefined") return;
1850
- systemTheme.value = getSystemTheme();
1851
- mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
1852
- handleChange = (e) => {
1853
- systemTheme.value = e.matches ? "dark" : "light";
1854
- };
1855
- mediaQuery.addEventListener("change", handleChange);
1856
- });
1857
- (0, vue.onUnmounted)(() => {
1858
- if (mediaQuery && handleChange) mediaQuery.removeEventListener("change", handleChange);
1859
- });
1860
- const resolvedTheme = (0, vue.computed)(() => {
1861
- if (options.theme.value === "auto") return systemTheme.value;
1862
- return options.theme.value;
1863
- });
1864
- const containerClasses = (0, vue.computed)(() => ["opencode-widget", `opencode-theme-${resolvedTheme.value}`]);
1865
- const buttonActive = (0, vue.computed)(() => !!(options.open.value || options.selectMode.value));
1866
- const iframeSource = (0, vue.computed)(() => options.iframeSrc.value || "about:blank");
1867
- const sessionListTitle = (0, vue.computed)(() => options.sessionListCollapsed.value ? "展开会话列表" : "折叠会话列表");
1868
- function handleToggle() {
1869
- var _a;
1870
- if (options.selectMode.value) {
1871
- (_a = options.onToggleSelectMode) == null || _a.call(options, false);
1872
- return;
1873
- }
1874
- const nextOpen = !options.open.value;
1875
- options.onToggle(nextOpen);
1876
- }
1877
- function handleClose() {
1878
- options.onClose();
1879
- }
1880
- function handleToggleSessionList() {
1881
- options.onToggleSessionList(!options.sessionListCollapsed.value);
1882
- }
1883
- function handleEmptyAction() {
1884
- options.onEmptyAction();
1885
- }
1886
- function handleToggleTheme() {
1887
- var _a;
1888
- const nextTheme = THEME_CYCLE[(THEME_CYCLE.indexOf(options.theme.value) + 1) % THEME_CYCLE.length];
1889
- (_a = options.onToggleTheme) == null || _a.call(options, nextTheme);
1890
- }
1891
- return {
1892
- buttonActive,
1893
- containerClasses,
1894
- iframeSource,
1895
- sessionListTitle,
1896
- resolvedTheme,
1897
- handleClose,
1898
- handleEmptyAction,
1899
- handleToggle,
1900
- handleToggleSessionList,
1901
- handleToggleTheme
1902
- };
1903
- }
1904
- //#endregion
1905
- //#region es/open-code-widget/composables/use-inspector.mjs
1906
- var IGNORE_SELECTORS = [
1907
- "#vue-inspector-container",
1908
- ".opencode-widget",
1909
- ".opencode-element-highlight",
1910
- ".opencode-element-tooltip",
1911
- ".opencode-select-mode-hint",
1912
- ".floating-bubble"
1913
- ];
1914
- var IGNORE_ATTRIBUTE = "data-v-inspector-ignore";
1915
- var KEY_PROPS_DATA = "__v_inspector";
1916
- var KEY_DATA = "data-v-inspector";
1917
- function getDirectText(element) {
1918
- let text = "";
1919
- for (let i = 0; i < element.childNodes.length; i++) {
1920
- const child = element.childNodes[i];
1921
- if (child.nodeType === Node.TEXT_NODE) text += child.textContent || "";
1922
- }
1923
- return text.trim();
1924
- }
1925
- var DYNAMIC_ID_PATTERN = /^(?:el-|:r[0-9]+:|radix-|uid-|ts-|uuid-|id-[a-f0-9]{4,}|.*[0-9]{4,}.*|.*-[a-f0-9]{6,}$)/i;
1926
- var STATE_CLASS_PATTERN = /^(?:hover|active|focus|focus-visible|focus-within|disabled|enabled|checked|selected|open|closed|loading|error|success|warning|hidden|visible|show|hide|current|expanded|collapsed|pressed|dragging|droppable|sortable|placeholder|transition|enter|leave|appear|move)$/i;
1927
- var STATE_CLASS_PREFIX_PATTERN = /^(?:is-|has-|was-|are-|can-|should-|will-|did-|does-|on-|off-|in-|out-|at-|to-|from-)/i;
1928
- function isDynamicId(id) {
1929
- if (!id) return false;
1930
- if (DYNAMIC_ID_PATTERN.test(id)) return true;
1931
- const digitCount = (id.match(/\d/g) || []).length;
1932
- if (digitCount > (id.match(/[a-zA-Z]/g) || []).length && digitCount >= 3) return true;
1933
- const dashParts = id.split("-");
1934
- if (dashParts.length >= 3) {
1935
- const lastPart = dashParts[dashParts.length - 1];
1936
- if (/^\d+$/.test(lastPart) || /^[a-f0-9]{4,}$/i.test(lastPart)) return true;
1937
- }
1938
- return false;
1939
- }
1940
- function isStateClass(className) {
1941
- if (!className) return false;
1942
- if (STATE_CLASS_PATTERN.test(className)) return true;
1943
- if (STATE_CLASS_PREFIX_PATTERN.test(className)) return true;
1944
- if (className.includes("-active") || className.includes("-hover") || className.includes("-focus")) return true;
1945
- if (/^(?:router-link|nuxt-link)/.test(className)) return true;
1946
- return false;
1947
- }
1948
- function getElementDescription(element) {
1949
- return (0, css_selector_generator.default)(element, {
1950
- selectors: [
1951
- "id",
1952
- "class",
1953
- "tag",
1954
- "nthchild"
1955
- ],
1956
- combineWithinSelector: true,
1957
- combineBetweenSelectors: true,
1958
- maxCombinations: 100,
1959
- maxCandidates: 100,
1960
- blacklist: [(selectorValue) => {
1961
- const idMatch = selectorValue.match(/^#(.+)$/);
1962
- if (idMatch) return isDynamicId(idMatch[1]);
1963
- const classMatch = selectorValue.match(/^\.([a-zA-Z_-][\w-]*)$/);
1964
- if (classMatch) return isStateClass(classMatch[1]);
1965
- return false;
1966
- }]
1967
- });
1968
- }
1969
- function getFileInfoFromVueInstance(element) {
1970
- var _a, _b, _c, _d;
1971
- const vue3Instance = element.__vueParentComponent;
1972
- if (vue3Instance) {
1973
- let current = vue3Instance;
1974
- while (current) {
1975
- const file = ((_a = current.type) == null ? void 0 : _a.__file) || ((_c = (_b = current.vnode) == null ? void 0 : _b.type) == null ? void 0 : _c.__file);
1976
- if (file) return {
1977
- file,
1978
- line: null,
1979
- column: null
1980
- };
1981
- current = current.parent;
1982
- }
1983
- }
1984
- const vue2Instance = element.__vue__;
1985
- if (vue2Instance) {
1986
- let current = vue2Instance;
1987
- while (current) {
1988
- const file = (_d = current.$options) == null ? void 0 : _d.__file;
1989
- if (file) return {
1990
- file,
1991
- line: null,
1992
- column: null
1993
- };
1994
- current = current.$parent;
1995
- }
1996
- }
1997
- return null;
1998
- }
1999
- function shouldIgnoreElement(el) {
2000
- if (el.hasAttribute(IGNORE_ATTRIBUTE)) return true;
2001
- for (const selector of IGNORE_SELECTORS) if (el.closest(selector)) return true;
2002
- return false;
2003
- }
2004
- function getDataFromElement(el) {
2005
- var _a, _b, _c, _d, _e, _f, _g;
2006
- const vnodeData = (_b = (_a = el.__vnode) == null ? void 0 : _a.props) == null ? void 0 : _b[KEY_PROPS_DATA];
2007
- if (vnodeData) return vnodeData;
2008
- const ctxVNode = (_d = (_c = el.__vnode) == null ? void 0 : _c.ctx) == null ? void 0 : _d.vnode;
2009
- if ((ctxVNode == null ? void 0 : ctxVNode.el) === el) {
2010
- const ctxData = (_e = ctxVNode.props) == null ? void 0 : _e[KEY_PROPS_DATA];
2011
- if (ctxData) return ctxData;
2012
- }
2013
- const vueInstance = el.__vueParentComponent;
2014
- let currentParent = vueInstance == null ? void 0 : vueInstance.parent;
2015
- while (currentParent) {
2016
- if (((_f = currentParent.vnode) == null ? void 0 : _f.el) === el) {
2017
- const parentData = (_g = currentParent.vnode.props) == null ? void 0 : _g[KEY_PROPS_DATA];
2018
- if (parentData) return parentData;
2019
- }
2020
- currentParent = currentParent.parent;
2021
- }
2022
- const attr = el.getAttribute(KEY_DATA);
2023
- return attr != null ? attr : void 0;
2024
- }
2025
- function findInspectorFileInfo(element) {
2026
- let current = element;
2027
- while (current) {
2028
- if (shouldIgnoreElement(current)) {
2029
- current = current.parentElement;
2030
- continue;
2031
- }
2032
- const data = getDataFromElement(current);
2033
- if (data) {
2034
- const match = data.match(/(.+):([\d]+):([\d]+)$/);
2035
- if (match) return {
2036
- file: match[1],
2037
- line: parseInt(match[2], 10),
2038
- column: parseInt(match[3], 10)
2039
- };
2040
- }
2041
- current = current.parentElement;
2042
- }
2043
- return null;
2044
- }
2045
- function mergeFileInfo(inspectorFileInfo, vueFileInfo) {
2046
- if (!(inspectorFileInfo == null ? void 0 : inspectorFileInfo.file) && !(vueFileInfo == null ? void 0 : vueFileInfo.file)) return {
2047
- file: null,
2048
- line: null,
2049
- column: null
2050
- };
2051
- const isNodeModules = (path) => path.includes("node_modules");
2052
- if ((inspectorFileInfo == null ? void 0 : inspectorFileInfo.file) && (vueFileInfo == null ? void 0 : vueFileInfo.file)) if (!isNodeModules(inspectorFileInfo.file)) return inspectorFileInfo;
2053
- else if (!isNodeModules(vueFileInfo.file)) return vueFileInfo;
2054
- else return inspectorFileInfo;
2055
- else if (inspectorFileInfo == null ? void 0 : inspectorFileInfo.file) return inspectorFileInfo;
2056
- else return vueFileInfo;
2057
- }
2058
- function getTargetElement(e) {
2059
- if (!e.target || !(e.target instanceof Element)) return null;
2060
- const el = e.target;
2061
- if (shouldIgnoreElement(el)) return null;
2062
- return el;
2063
- }
2064
- function getFileInfo(e, element) {
2065
- let inspectorFileInfo = null;
2066
- if (element) inspectorFileInfo = findInspectorFileInfo(element);
2067
- const vueFileInfo = element ? getFileInfoFromVueInstance(element) : null;
2068
- return mergeFileInfo(inspectorFileInfo, vueFileInfo);
2069
- }
2070
- function useInspector(options) {
2071
- const highlightVisible = (0, vue.ref)(false);
2072
- const highlightStyle = (0, vue.ref)({
2073
- top: "0px",
2074
- left: "0px",
2075
- width: "0px",
2076
- height: "0px"
2077
- });
2078
- const tooltipVisible = (0, vue.ref)(false);
2079
- const tooltipStyle = (0, vue.ref)({
2080
- top: "0px",
2081
- left: "0px"
2082
- });
2083
- const tooltipContent = (0, vue.ref)({
2084
- description: "",
2085
- fileInfo: ""
2086
- });
2087
- const INSPECTOR_CHECK_INTERVAL = 500;
2088
- let inspectorCheckTimer = null;
2089
- let currentPrimary = "#3b82f6";
2090
- let currentPrimaryBg = "rgba(59, 130, 246, 0.1)";
2091
- function setPointerEventsNone(elements) {
2092
- elements.forEach((el) => {
2093
- if (el) el.style.pointerEvents = "none";
2094
- });
2095
- }
2096
- function setPointerEventsAuto(elements) {
2097
- elements.forEach((el) => {
2098
- if (el) el.style.pointerEvents = "";
2099
- });
2100
- }
2101
- function handleMouseMoveCore(e) {
2102
- if (!options.selectMode.value) return;
2103
- const uiElements = [
2104
- document.querySelector(".opencode-element-highlight"),
2105
- document.querySelector(".opencode-element-tooltip"),
2106
- document.querySelector(".opencode-select-mode-hint"),
2107
- document.querySelector(".floating-bubble")
2108
- ];
2109
- setPointerEventsNone(uiElements);
2110
- const elementToHighlight = getTargetElement(e);
2111
- const fileInfo = getFileInfo(e, elementToHighlight);
2112
- setPointerEventsAuto(uiElements);
2113
- if (elementToHighlight) {
2114
- const widget = document.querySelector(".opencode-widget");
2115
- if (widget) {
2116
- const style = getComputedStyle(widget);
2117
- currentPrimary = style.getPropertyValue("--oc-primary").trim() || currentPrimary;
2118
- currentPrimaryBg = style.getPropertyValue("--oc-primary-bg").trim() || currentPrimaryBg;
2119
- }
2120
- const description = getElementDescription(elementToHighlight);
2121
- const fileName = fileInfo.file ? fileInfo.file.split("/").pop() : "";
2122
- let lineInfo = "";
2123
- if (fileInfo.line) {
2124
- lineInfo = `:${fileInfo.line}`;
2125
- if (fileInfo.column) lineInfo += `:${fileInfo.column}`;
2126
- }
2127
- const fileInfoText = fileName ? `${fileName}${lineInfo}` : "";
2128
- tooltipContent.value = {
2129
- description,
2130
- fileInfo: fileInfoText
2131
- };
2132
- const rect = elementToHighlight.getBoundingClientRect();
2133
- const newTop = `${rect.top}px`;
2134
- const newLeft = `${rect.left}px`;
2135
- const newWidth = `${rect.width}px`;
2136
- const newHeight = `${rect.height}px`;
2137
- if (highlightStyle.value.top !== newTop || highlightStyle.value.left !== newLeft || highlightStyle.value.width !== newWidth || highlightStyle.value.height !== newHeight) highlightStyle.value = {
2138
- top: newTop,
2139
- left: newLeft,
2140
- width: newWidth,
2141
- height: newHeight,
2142
- border: `2px solid ${currentPrimary}`,
2143
- background: currentPrimaryBg
2144
- };
2145
- highlightVisible.value = true;
2146
- tooltipVisible.value = true;
2147
- (0, vue.nextTick)(() => {
2148
- const tooltipEl = document.querySelector(".opencode-element-tooltip");
2149
- if (!tooltipEl) return;
2150
- const tooltipWidth = tooltipEl.offsetWidth;
2151
- const tooltipHeight = tooltipEl.offsetHeight;
2152
- if (tooltipWidth === 0 || tooltipHeight === 0) return;
2153
- const margin = 10;
2154
- const gap = 4;
2155
- const viewportWidth = window.innerWidth;
2156
- const viewportHeight = window.innerHeight;
2157
- const clampLeft = (left) => Math.max(margin, Math.min(left, viewportWidth - tooltipWidth - margin));
2158
- const clampTop = (top) => Math.max(margin, Math.min(top, viewportHeight - tooltipHeight - margin));
2159
- const candidateTop = rect.top - tooltipHeight - gap;
2160
- const candidateBottom = rect.bottom + gap;
2161
- const candidateRight = rect.right + gap;
2162
- const candidateLeft = rect.left - tooltipWidth - gap;
2163
- const verticalCenter = rect.top + (rect.height - tooltipHeight) / 2;
2164
- let tooltipTop = 0;
2165
- let tooltipLeft = 0;
2166
- let placed = false;
2167
- if (candidateTop >= margin) {
2168
- tooltipTop = candidateTop;
2169
- tooltipLeft = clampLeft(rect.left);
2170
- placed = true;
2171
- }
2172
- if (!placed && candidateBottom + tooltipHeight <= viewportHeight - margin) {
2173
- tooltipTop = candidateBottom;
2174
- tooltipLeft = clampLeft(rect.left);
2175
- placed = true;
2176
- }
2177
- if (!placed && candidateRight + tooltipWidth <= viewportWidth - margin) {
2178
- tooltipLeft = candidateRight;
2179
- tooltipTop = clampTop(verticalCenter);
2180
- placed = true;
2181
- }
2182
- if (!placed && candidateLeft >= margin) {
2183
- tooltipLeft = candidateLeft;
2184
- tooltipTop = clampTop(verticalCenter);
2185
- placed = true;
2186
- }
2187
- if (!placed) {
2188
- const corners = [
2189
- {
2190
- top: margin,
2191
- left: margin
2192
- },
2193
- {
2194
- top: margin,
2195
- left: viewportWidth - tooltipWidth - margin
2196
- },
2197
- {
2198
- top: viewportHeight - tooltipHeight - margin,
2199
- left: margin
2200
- },
2201
- {
2202
- top: viewportHeight - tooltipHeight - margin,
2203
- left: viewportWidth - tooltipWidth - margin
2204
- }
2205
- ];
2206
- for (const corner of corners) {
2207
- const tooltipRight = corner.left + tooltipWidth;
2208
- const tooltipBottom = corner.top + tooltipHeight;
2209
- if (tooltipRight <= rect.left || rect.right <= corner.left || tooltipBottom <= rect.top || rect.bottom <= corner.top) {
2210
- tooltipTop = corner.top;
2211
- tooltipLeft = corner.left;
2212
- placed = true;
2213
- break;
2214
- }
2215
- }
2216
- if (!placed) {
2217
- tooltipTop = margin;
2218
- tooltipLeft = margin;
2219
- }
2220
- }
2221
- const newTooltipTop = `${tooltipTop}px`;
2222
- const newTooltipLeft = `${tooltipLeft}px`;
2223
- if (tooltipStyle.value.top !== newTooltipTop || tooltipStyle.value.left !== newTooltipLeft) tooltipStyle.value = {
2224
- top: newTooltipTop,
2225
- left: newTooltipLeft
2226
- };
2227
- });
2228
- } else {
2229
- highlightVisible.value = false;
2230
- tooltipVisible.value = false;
2231
- }
2232
- }
2233
- const handleMouseMove = handleMouseMoveCore;
2234
- function setupInspectorHook() {
2235
- const inspector = window.__VUE_INSPECTOR__;
2236
- if (!inspector || inspector.__opencode_hooked) return;
2237
- const originalHandleClick = inspector.handleClick.bind(inspector);
2238
- inspector.handleClick = function(e) {
2239
- if (options.selectMode.value) {
2240
- const targetEl = e.target instanceof Element ? e.target : null;
2241
- if (targetEl && targetEl.closest(".opencode-widget")) return originalHandleClick.call(inspector, e);
2242
- e.preventDefault();
2243
- e.stopPropagation();
2244
- const elementToSelect = getTargetElement(e);
2245
- const fileInfo = getFileInfo(e, elementToSelect);
2246
- if (elementToSelect) {
2247
- const innerText = getDirectText(elementToSelect);
2248
- const description = getElementDescription(elementToSelect);
2249
- const elementInfo = {
2250
- filePath: fileInfo.file,
2251
- line: fileInfo.line,
2252
- column: fileInfo.column,
2253
- innerText: (0, _vite_plugin_opencode_assistant_shared.truncate)(innerText, 200),
2254
- description
2255
- };
2256
- options.onAddSelectedNode(elementInfo);
2257
- }
2258
- return;
2259
- }
2260
- return originalHandleClick.call(inspector, e);
2261
- };
2262
- inspector.__opencode_hooked = true;
2263
- }
2264
- function handleKeydown(e) {
2265
- if (e.key === "Escape" && options.selectMode.value) {
2266
- e.preventDefault();
2267
- e.stopPropagation();
2268
- options.onExitSelectMode();
2269
- }
2270
- }
2271
- (0, vue.watch)(options.selectMode, (newVal) => {
2272
- const inspector = window.__VUE_INSPECTOR__;
2273
- if (newVal) {
2274
- if (inspector) inspector.enable();
2275
- document.addEventListener("mousemove", handleMouseMove);
2276
- document.addEventListener("keydown", handleKeydown, true);
2277
- } else {
2278
- if (inspector) inspector.disable();
2279
- document.removeEventListener("mousemove", handleMouseMove);
2280
- document.removeEventListener("keydown", handleKeydown, true);
2281
- highlightVisible.value = false;
2282
- tooltipVisible.value = false;
2283
- }
2284
- });
2285
- (0, vue.onMounted)(() => {
2286
- if (window.__VUE_INSPECTOR__) setupInspectorHook();
2287
- else inspectorCheckTimer = window.setInterval(() => {
2288
- if (window.__VUE_INSPECTOR__) {
2289
- setupInspectorHook();
2290
- if (inspectorCheckTimer) {
2291
- window.clearInterval(inspectorCheckTimer);
2292
- inspectorCheckTimer = null;
2293
- }
2294
- }
2295
- }, INSPECTOR_CHECK_INTERVAL);
2296
- });
2297
- (0, vue.onUnmounted)(() => {
2298
- if (inspectorCheckTimer) window.clearInterval(inspectorCheckTimer);
2299
- document.removeEventListener("mousemove", handleMouseMove);
2300
- document.removeEventListener("keydown", handleKeydown, true);
2301
- });
2302
- return {
2303
- highlightVisible,
2304
- highlightStyle,
2305
- tooltipVisible,
2306
- tooltipStyle,
2307
- tooltipContent
2308
- };
2309
- }
2310
- //#endregion
2311
- //#region es/open-code-widget/composables/use-persist-state.mjs
2312
- var log = (0, _vite_plugin_opencode_assistant_shared.createLogger)("OpenCodeWidget");
2313
- var STORAGE_KEY = "opencode-widget-state";
2314
- function loadState() {
2315
- if (typeof window === "undefined") return null;
2316
- try {
2317
- const stored = localStorage.getItem(STORAGE_KEY);
2318
- if (stored) return JSON.parse(stored);
2319
- } catch (e) {
2320
- log.error("Failed to load persisted state:", { error: e });
2321
- }
2322
- return null;
2323
- }
2324
- function saveState(state) {
2325
- if (typeof window === "undefined") return;
2326
- try {
2327
- localStorage.setItem(STORAGE_KEY, JSON.stringify(state));
2328
- } catch (e) {
2329
- log.error("Failed to save state:", { error: e });
2330
- }
2331
- }
2332
- function usePersistState(options) {
2333
- const restoreState = () => {
2334
- const saved = loadState();
2335
- if (options.onRestore) options.onRestore(saved || {});
2336
- return saved;
2337
- };
2338
- const getCurrentState = () => {
2339
- var _a, _b, _c;
2340
- return {
2341
- open: options.open.value,
2342
- minimized: options.minimized.value,
2343
- promptDockVisible: options.promptDockVisible.value,
2344
- reviewPanelVisible: options.reviewPanelVisible.value,
2345
- bubbleOffset: options.bubbleOffset.value,
2346
- theme: options.theme.value,
2347
- sessionListCollapsed: options.sessionListCollapsed.value,
2348
- splitPanelWidth: (_a = options.splitPanelWidth) == null ? void 0 : _a.value,
2349
- displayMode: (_b = options.displayMode) == null ? void 0 : _b.value,
2350
- splitPosition: (_c = options.splitPosition) == null ? void 0 : _c.value
2351
- };
2352
- };
2353
- const persistState = () => {
2354
- saveState(getCurrentState());
2355
- };
2356
- const watchers = [
2357
- options.open,
2358
- options.minimized,
2359
- options.promptDockVisible,
2360
- options.reviewPanelVisible,
2361
- options.bubbleOffset,
2362
- options.theme,
2363
- options.sessionListCollapsed
2364
- ];
2365
- if (options.splitPanelWidth) watchers.push(options.splitPanelWidth);
2366
- if (options.displayMode) watchers.push(options.displayMode);
2367
- if (options.splitPosition) watchers.push(options.splitPosition);
2368
- (0, vue.onMounted)(() => {
2369
- restoreState();
2370
- (0, vue.watch)(watchers, () => {
2371
- persistState();
2372
- }, { deep: true });
2373
- });
2374
- return {
2375
- restoreState,
2376
- persistState
2377
- };
2378
- }
2379
- //#endregion
2380
- //#region es/open-code-widget/composables/use-split.mjs
2381
- var AUTO_MODE_THRESHOLD = 1440;
2382
- function useSplitMode(options) {
2383
- var _a, _b;
2384
- const windowWidth = (0, vue.ref)(typeof window !== "undefined" ? window.innerWidth : 0);
2385
- const localSplitPosition = (0, vue.ref)((_b = (_a = options.splitPosition) == null ? void 0 : _a.value) != null ? _b : "right");
2386
- const isExtensionMode = (0, vue.computed)(() => options.displayMode.value === "extension");
2387
- const splitConfig = (0, vue.computed)(() => {
2388
- var _a2, _b2, _c, _d, _e, _f, _g;
2389
- const config = options.splitMode.value || {};
2390
- const isExt = isExtensionMode.value;
2391
- return {
2392
- width: (_a2 = config.width) != null ? _a2 : 500,
2393
- minWidth: (_b2 = config.minWidth) != null ? _b2 : 400,
2394
- maxWidth: (_c = config.maxWidth) != null ? _c : 800,
2395
- resizable: isExt ? false : (_d = config.resizable) != null ? _d : true,
2396
- shrinkPage: isExt ? false : (_e = config.shrinkPage) != null ? _e : true,
2397
- defaultOpen: isExt ? true : (_f = config.defaultOpen) != null ? _f : true,
2398
- position: (_g = config.position) != null ? _g : localSplitPosition.value
2399
- };
2400
- });
2401
- const panelWidth = (0, vue.ref)(splitConfig.value.width);
2402
- const effectiveMode = (0, vue.computed)(() => {
2403
- if (isExtensionMode.value) return "split";
2404
- if (options.displayMode.value === "bubble") return "bubble";
2405
- if (options.displayMode.value === "split") return "split";
2406
- return windowWidth.value >= AUTO_MODE_THRESHOLD ? "split" : "bubble";
2407
- });
2408
- const isSplitMode = (0, vue.computed)(() => effectiveMode.value === "split");
2409
- const splitPosition = (0, vue.computed)(() => splitConfig.value.position);
2410
- const handleResize = (width) => {
2411
- var _a2;
2412
- panelWidth.value = width;
2413
- (_a2 = options.onWidthChange) == null || _a2.call(options, width);
2414
- };
2415
- const handleToggle = () => {
2416
- var _a2;
2417
- const nextOpen = !options.open.value;
2418
- (_a2 = options.onOpenChange) == null || _a2.call(options, nextOpen);
2419
- };
2420
- const handleTogglePosition = () => {
2421
- var _a2;
2422
- const nextPosition = localSplitPosition.value === "right" ? "left" : "right";
2423
- localSplitPosition.value = nextPosition;
2424
- (_a2 = options.onPositionChange) == null || _a2.call(options, nextPosition);
2425
- };
2426
- const handleWindowResize = () => {
2427
- if (typeof window !== "undefined") windowWidth.value = window.innerWidth;
2428
- };
2429
- const updateBodyClass = () => {
2430
- if (typeof document === "undefined") return;
2431
- if (isExtensionMode.value) return;
2432
- if (isSplitMode.value && options.open.value && splitConfig.value.shrinkPage) {
2433
- document.body.classList.add("has-opencode-split");
2434
- document.body.style.setProperty("--opencode-split-width", `${panelWidth.value}px`);
2435
- if (splitPosition.value === "left") {
2436
- document.body.classList.add("has-opencode-split-left");
2437
- document.body.classList.remove("has-opencode-split-right");
2438
- } else {
2439
- document.body.classList.add("has-opencode-split-right");
2440
- document.body.classList.remove("has-opencode-split-left");
2441
- }
2442
- } else {
2443
- document.body.classList.remove("has-opencode-split");
2444
- document.body.classList.remove("has-opencode-split-left");
2445
- document.body.classList.remove("has-opencode-split-right");
2446
- document.body.style.removeProperty("--opencode-split-width");
2447
- }
2448
- };
2449
- (0, vue.watch)([
2450
- isSplitMode,
2451
- options.open,
2452
- panelWidth,
2453
- splitPosition
2454
- ], updateBodyClass, { immediate: true });
2455
- (0, vue.watch)(splitConfig, (config) => {
2456
- if (panelWidth.value < config.minWidth) panelWidth.value = config.minWidth;
2457
- if (panelWidth.value > config.maxWidth) panelWidth.value = config.maxWidth;
2458
- });
2459
- (0, vue.watch)(() => {
2460
- var _a2;
2461
- return (_a2 = options.splitPosition) == null ? void 0 : _a2.value;
2462
- }, (val) => {
2463
- if (val && val !== localSplitPosition.value) localSplitPosition.value = val;
2464
- });
2465
- (0, vue.onMounted)(() => {
2466
- var _a2;
2467
- if (typeof window !== "undefined") {
2468
- window.addEventListener("resize", handleWindowResize);
2469
- if (!isExtensionMode.value && isSplitMode.value && splitConfig.value.defaultOpen && !options.open.value) (_a2 = options.onOpenChange) == null || _a2.call(options, true);
2470
- }
2471
- });
2472
- (0, vue.onUnmounted)(() => {
2473
- if (typeof window !== "undefined") {
2474
- window.removeEventListener("resize", handleWindowResize);
2475
- if (!isExtensionMode.value) {
2476
- document.body.classList.remove("has-opencode-split");
2477
- document.body.classList.remove("has-opencode-split-left");
2478
- document.body.classList.remove("has-opencode-split-right");
2479
- document.body.style.removeProperty("--opencode-split-width");
2480
- }
2481
- }
2482
- });
2483
- return {
2484
- effectiveMode,
2485
- isSplitMode,
2486
- isExtensionMode,
2487
- panelWidth,
2488
- splitConfig,
2489
- splitPosition,
2490
- handleResize,
2491
- handleToggle,
2492
- handleTogglePosition
2493
- };
2494
- }
2495
- //#endregion
2496
- //#region es/open-code-widget/src/index.vue.mjs
2497
- var __defProp = Object.defineProperty;
2498
- var __defProps = Object.defineProperties;
2499
- var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
2500
- var __getOwnPropSymbols = Object.getOwnPropertySymbols;
2501
- var __hasOwnProp = Object.prototype.hasOwnProperty;
2502
- var __propIsEnum = Object.prototype.propertyIsEnumerable;
2503
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, {
2504
- enumerable: true,
2505
- configurable: true,
2506
- writable: true,
2507
- value
2508
- }) : obj[key] = value;
2509
- var __spreadValues = (a, b) => {
2510
- for (var prop in b || (b = {})) if (__hasOwnProp.call(b, prop)) __defNormalProp(a, prop, b[prop]);
2511
- if (__getOwnPropSymbols) {
2512
- for (var prop of __getOwnPropSymbols(b)) if (__propIsEnum.call(b, prop)) __defNormalProp(a, prop, b[prop]);
2513
- }
2514
- return a;
2515
- };
2516
- var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
2517
- var __vue_sfc__ = /* @__PURE__ */ (0, vue.defineComponent)(__spreadProps(__spreadValues({}, { name: "OpencodeWidget" }), {
2518
- __name: "index",
2519
- props: {
2520
- open: {
2521
- type: Boolean,
2522
- required: false,
2523
- default: false
2524
- },
2525
- theme: {
2526
- type: String,
2527
- required: false,
2528
- default: "auto"
2529
- },
2530
- title: {
2531
- type: String,
2532
- required: false,
2533
- default: "AI 助手"
2534
- },
2535
- hotkeyLabel: {
2536
- type: String,
2537
- required: false,
2538
- default: "Ctrl+K"
2539
- },
2540
- selectShortcutLabel: {
2541
- type: String,
2542
- required: false,
2543
- default: "按 ESC 或 Ctrl+P 退出"
2544
- },
2545
- selectMode: {
2546
- type: Boolean,
2547
- required: false,
2548
- default: false
2549
- },
2550
- sessionListCollapsed: {
2551
- type: Boolean,
2552
- required: false,
2553
- default: true
2554
- },
2555
- sessionKey: {
2556
- type: String,
2557
- required: false,
2558
- default: "id"
2559
- },
2560
- frameLoading: {
2561
- type: Boolean,
2562
- required: false,
2563
- default: false
2564
- },
2565
- loadingSessionList: {
2566
- type: Boolean,
2567
- required: false
2568
- },
2569
- showSessionListSkeleton: {
2570
- type: Boolean,
2571
- required: false,
2572
- default: false
2573
- },
2574
- showEmptyState: {
2575
- type: Boolean,
2576
- required: false,
2577
- default: false
2578
- },
2579
- showError: {
2580
- type: Boolean,
2581
- required: false,
2582
- default: false
2583
- },
2584
- emptyStateText: {
2585
- type: String,
2586
- required: false,
2587
- default: "当前项目暂无会话"
2588
- },
2589
- emptyStateActionText: {
2590
- type: String,
2591
- required: false,
2592
- default: "立即创建"
2593
- },
2594
- iframeSrc: {
2595
- type: String,
2596
- required: false,
2597
- default: ""
2598
- },
2599
- sessions: {
2600
- type: Array,
2601
- required: false,
2602
- default: () => []
2603
- },
2604
- currentSessionId: {
2605
- type: [String, null],
2606
- required: false,
2607
- default: null
2608
- },
2609
- selectedElements: {
2610
- type: Array,
2611
- required: false,
2612
- default: () => []
2613
- },
2614
- showClearAll: {
2615
- type: Boolean,
2616
- required: false,
2617
- default: true
2618
- },
2619
- selectEnabled: {
2620
- type: Boolean,
2621
- required: false,
2622
- default: true
2623
- },
2624
- thinking: {
2625
- type: Boolean,
2626
- required: false,
2627
- default: false
2628
- },
2629
- sessionStates: {
2630
- type: Object,
2631
- required: false
2632
- },
2633
- displayMode: {
2634
- type: String,
2635
- required: false,
2636
- default: "bubble"
2637
- },
2638
- splitMode: {
2639
- type: Object,
2640
- required: false,
2641
- default: void 0
2642
- },
2643
- splitPanelWidth: {
2644
- type: Number,
2645
- required: false,
2646
- default: 500
2647
- },
2648
- hideBubble: {
2649
- type: Boolean,
2650
- required: false,
2651
- default: false
2652
- }
2653
- },
2654
- emits: [
2655
- "update:open",
2656
- "update:selectMode",
2657
- "update:sessionListCollapsed",
2658
- "update:currentSessionId",
2659
- "update:selectedElements",
2660
- "update:theme",
2661
- "update:thinking",
2662
- "update:splitPanelWidth",
2663
- "toggle",
2664
- "close",
2665
- "toggle-session-list",
2666
- "toggle-select-mode",
2667
- "toggle-theme",
2668
- "create-session",
2669
- "select-session",
2670
- "delete-session",
2671
- "click-selected-node",
2672
- "remove-selected-node",
2673
- "clear-selected-nodes",
2674
- "empty-action",
2675
- "frame-loaded",
2676
- "thinking-change",
2677
- "split-panel-width-change"
2678
- ],
2679
- setup(__props, { expose: __expose, emit: __emit }) {
2680
- var _a, _b;
2681
- (0, vue.useCssVars)((_ctx) => ({
2682
- "-chatAnimationOrigin.x": chatAnimationOrigin.value.x,
2683
- "-chatAnimationOrigin.y": chatAnimationOrigin.value.y
2684
- }));
2685
- const props = __props;
2686
- const emit = __emit;
2687
- const slots = (0, vue.useSlots)();
2688
- const notificationMessage = (0, vue.ref)("");
2689
- const notificationVisible = (0, vue.ref)(false);
2690
- const notificationMode = (0, vue.ref)("widget");
2691
- let notificationTimer = null;
2692
- const showNotification = (message, options) => {
2693
- const { duration = 3e3, mode = "widget" } = options || {};
2694
- notificationMessage.value = message;
2695
- notificationVisible.value = true;
2696
- notificationMode.value = mode;
2697
- if (notificationTimer) clearTimeout(notificationTimer);
2698
- notificationTimer = setTimeout(() => {
2699
- notificationVisible.value = false;
2700
- }, duration);
2701
- };
2702
- const dialogVisible = (0, vue.ref)(false);
2703
- const dialogMessage = (0, vue.ref)("");
2704
- let dialogResolve = null;
2705
- const showConfirmDialog = (message) => {
2706
- dialogMessage.value = message;
2707
- dialogVisible.value = true;
2708
- return new Promise((resolve) => {
2709
- dialogResolve = resolve;
2710
- });
2711
- };
2712
- const handleDialogConfirm = () => {
2713
- dialogVisible.value = false;
2714
- if (dialogResolve) dialogResolve(true);
2715
- };
2716
- const handleDialogCancel = () => {
2717
- dialogVisible.value = false;
2718
- if (dialogResolve) dialogResolve(false);
2719
- };
2720
- const frameRef = (0, vue.ref)(null);
2721
- const triggerRef = (0, vue.ref)(null);
2722
- const sendMessageToIframe = (type, data) => {
2723
- var _a2;
2724
- (_a2 = frameRef.value) == null || _a2.sendMessageToIframe(type, data);
2725
- };
2726
- const localSessionListCollapsed = (0, vue.ref)(props.sessionListCollapsed);
2727
- const localDisplayMode = (0, vue.ref)(props.displayMode);
2728
- const localSplitPosition = (0, vue.ref)((_b = (_a = props.splitMode) == null ? void 0 : _a.position) != null ? _b : "right");
2729
- const minimized = (0, vue.ref)(false);
2730
- const promptDockVisible = (0, vue.ref)(true);
2731
- const reviewPanelVisible = (0, vue.ref)(false);
2732
- const isRestoring = (0, vue.ref)(true);
2733
- const iframeLoaded = (0, vue.ref)(false);
2734
- const splitPanelWidth = (0, vue.ref)(props.splitPanelWidth);
2735
- const syncStateToIframe = () => {
2736
- if (!iframeLoaded.value) return;
2737
- sendMessageToIframe(_vite_plugin_opencode_assistant_shared.WIDGET_MSG.PROMPT_DOCK_VISIBILITY, { visible: promptDockVisible.value });
2738
- sendMessageToIframe(_vite_plugin_opencode_assistant_shared.WIDGET_MSG.MINIMIZE_STATE, { minimized: minimized.value });
2739
- sendMessageToIframe(_vite_plugin_opencode_assistant_shared.WIDGET_MSG.REVIEW_PANEL_TOGGLE, { visible: reviewPanelVisible.value });
2740
- };
2741
- const handleFrameLoaded = () => {
2742
- emit("frame-loaded");
2743
- iframeLoaded.value = true;
2744
- syncStateToIframe();
2745
- };
2746
- (0, vue.watch)(() => props.sessionListCollapsed, (val) => {
2747
- localSessionListCollapsed.value = val;
2748
- });
2749
- (0, vue.watch)(() => props.splitPanelWidth, (val) => {
2750
- splitPanelWidth.value = val;
2751
- });
2752
- (0, vue.watch)(() => props.displayMode, (val) => {
2753
- localDisplayMode.value = val;
2754
- });
2755
- const handleToggleDisplayMode = () => {
2756
- if (localDisplayMode.value === "extension" || localDisplayMode.value === "extension-selector") return;
2757
- const modes = [
2758
- "bubble",
2759
- "split",
2760
- "auto"
2761
- ];
2762
- const nextIndex = (modes.indexOf(localDisplayMode.value) + 1) % modes.length;
2763
- localDisplayMode.value = modes[nextIndex];
2764
- };
2765
- const { buttonActive, containerClasses, iframeSource, sessionListTitle, resolvedTheme, handleClose, handleEmptyAction, handleToggle, handleToggleSessionList, handleToggleTheme } = useWidget({
2766
- theme: (0, vue.toRef)(props, "theme"),
2767
- open: (0, vue.toRef)(props, "open"),
2768
- selectMode: (0, vue.toRef)(props, "selectMode"),
2769
- iframeSrc: (0, vue.toRef)(props, "iframeSrc"),
2770
- sessionListCollapsed: localSessionListCollapsed,
2771
- onToggle: (nextOpen) => {
2772
- emit("update:open", nextOpen);
2773
- emit("toggle", nextOpen);
2774
- },
2775
- onToggleSelectMode: (mode) => {
2776
- emit("update:selectMode", mode);
2777
- emit("toggle-select-mode", mode);
2778
- },
2779
- onClose: () => {
2780
- emit("update:open", false);
2781
- emit("close");
2782
- },
2783
- onToggleSessionList: (collapsed) => {
2784
- localSessionListCollapsed.value = collapsed;
2785
- emit("update:sessionListCollapsed", collapsed);
2786
- emit("toggle-session-list", collapsed);
2787
- },
2788
- onEmptyAction: () => {
2789
- emit("empty-action");
2790
- },
2791
- onToggleTheme: (newTheme) => {
2792
- emit("update:theme", newTheme);
2793
- emit("toggle-theme", newTheme);
2794
- }
2795
- });
2796
- const { sessionItems, handleCreateSession, handleDeleteSession, handleSelectSession } = useSession({
2797
- sessions: (0, vue.toRef)(props, "sessions"),
2798
- currentSessionId: (0, vue.toRef)(props, "currentSessionId"),
2799
- onCreateSession: () => emit("create-session"),
2800
- onSelectSession: (session) => {
2801
- emit("update:currentSessionId", session.id);
2802
- emit("select-session", session);
2803
- },
2804
- onDeleteSession: (session) => emit("delete-session", session),
2805
- showConfirmDialog
2806
- });
2807
- const { bubbleVisible, hasSelectedElements, selectedElementItems, handleClearSelectedNodes, handleClickSelectedNode, handleRemoveSelectedNode, handleToggleSelectMode } = useSelection({
2808
- selectMode: (0, vue.toRef)(props, "selectMode"),
2809
- selectedElements: (0, vue.toRef)(props, "selectedElements"),
2810
- onToggleSelectMode: (mode) => {
2811
- emit("update:selectMode", mode);
2812
- emit("toggle-select-mode", mode);
2813
- },
2814
- onRemoveSelectedNode: (payload) => {
2815
- emit("remove-selected-node", payload);
2816
- const newElements = [...props.selectedElements];
2817
- newElements.splice(payload.index, 1);
2818
- emit("update:selectedElements", newElements);
2819
- },
2820
- onClearSelectedNodes: () => {
2821
- emit("clear-selected-nodes");
2822
- emit("update:selectedElements", []);
2823
- },
2824
- showConfirmDialog
2825
- });
2826
- const { highlightVisible, highlightStyle, tooltipVisible, tooltipStyle, tooltipContent } = useInspector({
2827
- selectMode: (0, vue.toRef)(props, "selectMode"),
2828
- onAddSelectedNode: (element) => {
2829
- emit("click-selected-node", element);
2830
- },
2831
- onExitSelectMode: () => {
2832
- emit("update:selectMode", false);
2833
- emit("toggle-select-mode", false);
2834
- }
2835
- });
2836
- const bubbleOffset = (0, vue.ref)(void 0);
2837
- const { effectiveMode, isSplitMode, isExtensionMode, panelWidth, splitConfig, splitPosition, handleResize, handleToggle: handleSplitToggle, handleTogglePosition } = useSplitMode({
2838
- displayMode: localDisplayMode,
2839
- splitMode: (0, vue.toRef)(props, "splitMode"),
2840
- open: (0, vue.toRef)(props, "open"),
2841
- splitPosition: localSplitPosition,
2842
- onOpenChange: (nextOpen) => {
2843
- emit("update:open", nextOpen);
2844
- emit("toggle", nextOpen);
2845
- },
2846
- onWidthChange: (width) => {
2847
- splitPanelWidth.value = width;
2848
- emit("update:splitPanelWidth", width);
2849
- emit("split-panel-width-change", width);
2850
- },
2851
- onPositionChange: (position) => {
2852
- localSplitPosition.value = position;
2853
- }
2854
- });
2855
- usePersistState({
2856
- open: (0, vue.toRef)(props, "open"),
2857
- minimized,
2858
- promptDockVisible,
2859
- reviewPanelVisible,
2860
- bubbleOffset,
2861
- theme: (0, vue.toRef)(props, "theme"),
2862
- sessionListCollapsed: localSessionListCollapsed,
2863
- splitPanelWidth,
2864
- displayMode: localDisplayMode,
2865
- splitPosition: localSplitPosition,
2866
- onRestore: (state) => {
2867
- if (state.open !== void 0 && state.open !== props.open) {
2868
- emit("update:open", state.open);
2869
- emit("toggle", state.open);
2870
- }
2871
- if (state.minimized !== void 0) minimized.value = state.minimized;
2872
- if (state.bubbleOffset !== void 0) {
2873
- const bubbleSize = 44;
2874
- const margin = 10;
2875
- const maxX = window.innerWidth - bubbleSize - margin;
2876
- const maxY = window.innerHeight - bubbleSize - margin;
2877
- bubbleOffset.value = {
2878
- x: Math.max(margin, Math.min(state.bubbleOffset.x, maxX)),
2879
- y: Math.max(margin, Math.min(state.bubbleOffset.y, maxY))
2880
- };
2881
- }
2882
- if (state.theme !== void 0 && state.theme !== props.theme) {
2883
- emit("update:theme", state.theme);
2884
- emit("toggle-theme", state.theme);
2885
- }
2886
- if (state.sessionListCollapsed !== void 0 && state.sessionListCollapsed !== props.sessionListCollapsed) {
2887
- localSessionListCollapsed.value = state.sessionListCollapsed;
2888
- emit("update:sessionListCollapsed", state.sessionListCollapsed);
2889
- }
2890
- if (state.promptDockVisible !== void 0) promptDockVisible.value = state.promptDockVisible;
2891
- else if (minimized.value) promptDockVisible.value = false;
2892
- if (state.reviewPanelVisible !== void 0) reviewPanelVisible.value = state.reviewPanelVisible;
2893
- if (state.splitPanelWidth !== void 0 && state.splitPanelWidth !== props.splitPanelWidth) handleResize(state.splitPanelWidth);
2894
- if (state.displayMode !== void 0 && state.displayMode !== props.displayMode) localDisplayMode.value = state.displayMode;
2895
- if (state.splitPosition !== void 0) localSplitPosition.value = state.splitPosition;
2896
- (0, vue.nextTick)(() => {
2897
- syncStateToIframe();
2898
- setTimeout(() => {
2899
- isRestoring.value = false;
2900
- }, 50);
2901
- });
2902
- }
2903
- });
2904
- const handleToggleMinimize = () => {
2905
- minimized.value = !minimized.value;
2906
- promptDockVisible.value = !minimized.value;
2907
- sendMessageToIframe(_vite_plugin_opencode_assistant_shared.WIDGET_MSG.PROMPT_DOCK_VISIBILITY, { visible: promptDockVisible.value });
2908
- sendMessageToIframe(_vite_plugin_opencode_assistant_shared.WIDGET_MSG.MINIMIZE_STATE, { minimized: minimized.value });
2909
- };
2910
- const handleTogglePromptDock = () => {
2911
- promptDockVisible.value = !promptDockVisible.value;
2912
- sendMessageToIframe(_vite_plugin_opencode_assistant_shared.WIDGET_MSG.PROMPT_DOCK_VISIBILITY, { visible: promptDockVisible.value });
2913
- };
2914
- const handleToggleReviewPanel = () => {
2915
- reviewPanelVisible.value = !reviewPanelVisible.value;
2916
- sendMessageToIframe(_vite_plugin_opencode_assistant_shared.WIDGET_MSG.REVIEW_PANEL_TOGGLE, { visible: reviewPanelVisible.value });
2917
- };
2918
- const handleRefresh = () => {
2919
- window.location.reload();
2920
- };
2921
- const windowWidth = (0, vue.ref)(typeof window !== "undefined" ? window.innerWidth : 0);
2922
- const windowHeight = (0, vue.ref)(typeof window !== "undefined" ? window.innerHeight : 0);
2923
- const handleWindowResize = () => {
2924
- if (typeof window !== "undefined") {
2925
- windowWidth.value = window.innerWidth;
2926
- windowHeight.value = window.innerHeight;
2927
- }
2928
- };
2929
- (0, vue.onMounted)(() => {
2930
- if (typeof window !== "undefined") window.addEventListener("resize", handleWindowResize);
2931
- });
2932
- (0, vue.onUnmounted)(() => {
2933
- if (typeof window !== "undefined") window.removeEventListener("resize", handleWindowResize);
2934
- });
2935
- const bubbleQuadrant = (0, vue.computed)(() => {
2936
- var _a2, _b2, _c, _d;
2937
- if (typeof window === "undefined") return "bottom-right";
2938
- const centerX = windowWidth.value / 2;
2939
- const centerY = windowHeight.value / 2;
2940
- const bubbleSize = 44;
2941
- const currentOffset = (_b2 = (_a2 = triggerRef.value) == null ? void 0 : _a2.offset) != null ? _b2 : bubbleOffset.value;
2942
- const effectiveX = ((_c = currentOffset == null ? void 0 : currentOffset.x) != null ? _c : windowWidth.value - bubbleSize - 24) + bubbleSize / 2;
2943
- const effectiveY = ((_d = currentOffset == null ? void 0 : currentOffset.y) != null ? _d : windowHeight.value - bubbleSize - 24) + bubbleSize / 2;
2944
- if (effectiveX >= centerX && effectiveY >= centerY) return "bottom-right";
2945
- else if (effectiveX < centerX && effectiveY >= centerY) return "bottom-left";
2946
- else if (effectiveX >= centerX && effectiveY < centerY) return "top-right";
2947
- else return "top-left";
2948
- });
2949
- const isBubbleOnRightSide = (0, vue.computed)(() => {
2950
- const quadrant = bubbleQuadrant.value;
2951
- return quadrant === "top-right" || quadrant === "bottom-right";
2952
- });
2953
- const chatPositionStyle = (0, vue.computed)(() => {
2954
- var _a2, _b2, _c;
2955
- if (typeof window === "undefined") return {};
2956
- const chatWidth = minimized.value ? 300 : 700;
2957
- const chatHeight = minimized.value ? 300 : Math.min(windowHeight.value * .86, windowHeight.value - 40);
2958
- const gap = 24;
2959
- const bubbleSize = 44;
2960
- const screenMargin = 20;
2961
- const effectiveOffset = (_c = (_b2 = (_a2 = triggerRef.value) == null ? void 0 : _a2.offset) != null ? _b2 : bubbleOffset.value) != null ? _c : {
2962
- x: windowWidth.value - bubbleSize - gap,
2963
- y: windowHeight.value - bubbleSize - gap
2964
- };
2965
- const style = {};
2966
- if (isBubbleOnRightSide.value) {
2967
- let rightPos = windowWidth.value - effectiveOffset.x + gap;
2968
- const minRight = screenMargin;
2969
- const maxRight = windowWidth.value - chatWidth - screenMargin;
2970
- if (rightPos > maxRight) rightPos = maxRight;
2971
- if (rightPos < minRight) rightPos = minRight;
2972
- style.right = `${rightPos}px`;
2973
- style.left = "auto";
2974
- } else {
2975
- let leftPos = effectiveOffset.x + bubbleSize + gap;
2976
- const minLeft = screenMargin;
2977
- const maxLeft = windowWidth.value - chatWidth - screenMargin;
2978
- if (leftPos > maxLeft) leftPos = maxLeft;
2979
- if (leftPos < minLeft) leftPos = minLeft;
2980
- style.left = `${leftPos}px`;
2981
- style.right = "auto";
2982
- }
2983
- let bottomPos = windowHeight.value - effectiveOffset.y - bubbleSize;
2984
- const maxBottom = windowHeight.value - chatHeight - screenMargin;
2985
- if (bottomPos > maxBottom) bottomPos = maxBottom;
2986
- if (bottomPos < screenMargin) bottomPos = screenMargin;
2987
- style.bottom = `${bottomPos}px`;
2988
- return style;
2989
- });
2990
- const handleBubbleOffsetChange = (offset) => {
2991
- bubbleOffset.value = offset;
2992
- };
2993
- const handleResizeStart = () => {
2994
- isDragging.value = true;
2995
- };
2996
- const handleResizeEnd = () => {
2997
- isDragging.value = false;
2998
- };
2999
- const chatAnimationOrigin = (0, vue.computed)(() => {
3000
- switch (bubbleQuadrant.value) {
3001
- case "top-left": return {
3002
- x: "-20px",
3003
- y: "-20px"
3004
- };
3005
- case "top-right": return {
3006
- x: "20px",
3007
- y: "-20px"
3008
- };
3009
- case "bottom-left": return {
3010
- x: "-20px",
3011
- y: "20px"
3012
- };
3013
- default: return {
3014
- x: "20px",
3015
- y: "20px"
3016
- };
3017
- }
3018
- });
3019
- const isDragging = (0, vue.ref)(false);
3020
- let wasOpenBeforeDrag = false;
3021
- const handleDragStart = () => {
3022
- isDragging.value = true;
3023
- wasOpenBeforeDrag = props.open;
3024
- if (props.open) emit("update:open", false);
3025
- };
3026
- const handleDragEnd = () => {
3027
- isDragging.value = false;
3028
- if (wasOpenBeforeDrag) emit("update:open", true);
3029
- };
3030
- provideOpenCodeWidgetContext({
3031
- theme: (0, vue.toRef)(props, "theme"),
3032
- resolvedTheme,
3033
- title: (0, vue.toRef)(props, "title"),
3034
- hotkeyLabel: (0, vue.toRef)(props, "hotkeyLabel"),
3035
- selectShortcutLabel: (0, vue.toRef)(props, "selectShortcutLabel"),
3036
- selectMode: (0, vue.toRef)(props, "selectMode"),
3037
- selectEnabled: (0, vue.toRef)(props, "selectEnabled"),
3038
- sessionListCollapsed: localSessionListCollapsed,
3039
- sessionKey: (0, vue.toRef)(props, "sessionKey"),
3040
- frameLoading: (0, vue.toRef)(props, "frameLoading"),
3041
- loadingSessionList: (0, vue.toRef)(props, "loadingSessionList"),
3042
- showSessionListSkeleton: (0, vue.toRef)(props, "showSessionListSkeleton"),
3043
- showEmptyState: (0, vue.toRef)(props, "showEmptyState"),
3044
- showError: (0, vue.toRef)(props, "showError"),
3045
- emptyStateText: (0, vue.toRef)(props, "emptyStateText"),
3046
- emptyStateActionText: (0, vue.toRef)(props, "emptyStateActionText"),
3047
- showClearAll: (0, vue.toRef)(props, "showClearAll"),
3048
- open: (0, vue.toRef)(props, "open"),
3049
- thinking: (0, vue.toRef)(props, "thinking"),
3050
- minimized,
3051
- promptDockVisible,
3052
- reviewPanelVisible,
3053
- bubbleOffset,
3054
- mode: effectiveMode,
3055
- displayMode: localDisplayMode,
3056
- splitPosition,
3057
- sessionStates: (0, vue.computed)(() => {
3058
- var _a2;
3059
- return (_a2 = props.sessionStates) != null ? _a2 : {};
3060
- }),
3061
- iframeSource,
3062
- buttonActive,
3063
- sessionListTitle,
3064
- bubbleVisible,
3065
- hasSelectedElements,
3066
- sessionItems,
3067
- selectedElementItems,
3068
- handleToggle,
3069
- handleClose,
3070
- handleToggleMinimize,
3071
- handleTogglePromptDock,
3072
- handleToggleReviewPanel,
3073
- handleToggleSessionList,
3074
- handleToggleTheme,
3075
- handleToggleDisplayMode,
3076
- handleToggleSplitPosition: handleTogglePosition,
3077
- handleEmptyAction,
3078
- handleCreateSession,
3079
- handleSelectSession,
3080
- handleDeleteSession,
3081
- handleToggleSelectMode,
3082
- handleClickSelectedNode,
3083
- handleRemoveSelectedNode: (payload) => handleRemoveSelectedNode(payload.item, payload.index, payload.source),
3084
- handleClearSelectedNodes,
3085
- handleFrameLoaded,
3086
- handleBubbleOffsetChange,
3087
- handleRefresh
3088
- });
3089
- __expose({
3090
- showNotification,
3091
- showConfirmDialog,
3092
- sendMessageToIframe,
3093
- isSplitMode
3094
- });
3095
- const __returned__ = {
3096
- props,
3097
- emit,
3098
- slots,
3099
- notificationMessage,
3100
- notificationVisible,
3101
- notificationMode,
3102
- get notificationTimer() {
3103
- return notificationTimer;
3104
- },
3105
- set notificationTimer(v) {
3106
- notificationTimer = v;
3107
- },
3108
- showNotification,
3109
- dialogVisible,
3110
- dialogMessage,
3111
- get dialogResolve() {
3112
- return dialogResolve;
3113
- },
3114
- set dialogResolve(v) {
3115
- dialogResolve = v;
3116
- },
3117
- showConfirmDialog,
3118
- handleDialogConfirm,
3119
- handleDialogCancel,
3120
- frameRef,
3121
- triggerRef,
3122
- sendMessageToIframe,
3123
- localSessionListCollapsed,
3124
- localDisplayMode,
3125
- localSplitPosition,
3126
- minimized,
3127
- promptDockVisible,
3128
- reviewPanelVisible,
3129
- isRestoring,
3130
- iframeLoaded,
3131
- splitPanelWidth,
3132
- syncStateToIframe,
3133
- handleFrameLoaded,
3134
- handleToggleDisplayMode,
3135
- buttonActive,
3136
- containerClasses,
3137
- iframeSource,
3138
- sessionListTitle,
3139
- resolvedTheme,
3140
- handleClose,
3141
- handleEmptyAction,
3142
- handleToggle,
3143
- handleToggleSessionList,
3144
- handleToggleTheme,
3145
- sessionItems,
3146
- handleCreateSession,
3147
- handleDeleteSession,
3148
- handleSelectSession,
3149
- bubbleVisible,
3150
- hasSelectedElements,
3151
- selectedElementItems,
3152
- handleClearSelectedNodes,
3153
- handleClickSelectedNode,
3154
- handleRemoveSelectedNode,
3155
- handleToggleSelectMode,
3156
- highlightVisible,
3157
- highlightStyle,
3158
- tooltipVisible,
3159
- tooltipStyle,
3160
- tooltipContent,
3161
- bubbleOffset,
3162
- effectiveMode,
3163
- isSplitMode,
3164
- isExtensionMode,
3165
- panelWidth,
3166
- splitConfig,
3167
- splitPosition,
3168
- handleResize,
3169
- handleSplitToggle,
3170
- handleTogglePosition,
3171
- handleToggleMinimize,
3172
- handleTogglePromptDock,
3173
- handleToggleReviewPanel,
3174
- handleRefresh,
3175
- windowWidth,
3176
- windowHeight,
3177
- handleWindowResize,
3178
- bubbleQuadrant,
3179
- isBubbleOnRightSide,
3180
- chatPositionStyle,
3181
- handleBubbleOffsetChange,
3182
- handleResizeStart,
3183
- handleResizeEnd,
3184
- chatAnimationOrigin,
3185
- isDragging,
3186
- get wasOpenBeforeDrag() {
3187
- return wasOpenBeforeDrag;
3188
- },
3189
- set wasOpenBeforeDrag(v) {
3190
- wasOpenBeforeDrag = v;
3191
- },
3192
- handleDragStart,
3193
- handleDragEnd,
3194
- ChatPanel: ChatPanel_vue_default,
3195
- SelectHint: SelectHint_vue_default,
3196
- Trigger: Trigger_vue_default
3197
- };
3198
- Object.defineProperty(__returned__, "__isScriptSetup", {
3199
- enumerable: false,
3200
- value: true
3201
- });
3202
- return __returned__;
3203
- }
3204
- }));
3205
- var _hoisted_1 = { class: "opencode-tooltip-tag" };
3206
- var _hoisted_2 = { class: "opencode-tooltip-file" };
3207
- var _hoisted_3 = {
3208
- key: 1,
3209
- class: "opencode-dialog-overlay"
3210
- };
3211
- var _hoisted_4 = {
3212
- class: "opencode-dialog",
3213
- role: "alertdialog",
3214
- "aria-modal": "true"
3215
- };
3216
- var _hoisted_5 = { class: "opencode-dialog-content" };
3217
- var _hoisted_6 = { class: "opencode-dialog-message" };
3218
- function __vue_render__(_ctx, _cache, $props, $setup, $data, $options) {
3219
- return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", { class: (0, vue.normalizeClass)([...$setup.containerClasses, { "extension-mode": $setup.isExtensionMode }]) }, [
3220
- $props.displayMode !== "extension-selector" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)(vue.Fragment, { key: 0 }, [
3221
- !$setup.isSplitMode && !$setup.props.hideBubble ? ((0, vue.openBlock)(), (0, vue.createBlock)($setup["Trigger"], {
3222
- key: 0,
3223
- ref: "triggerRef",
3224
- onDragStart: $setup.handleDragStart,
3225
- onDragEnd: $setup.handleDragEnd
3226
- }, (0, vue.createSlots)({ _: 2 }, [$setup.slots["button-icon"] ? {
3227
- name: "default",
3228
- fn: (0, vue.withCtx)(() => [(0, vue.renderSlot)(_ctx.$slots, "button-icon")]),
3229
- key: "0"
3230
- } : void 0]), 1536)) : (0, vue.createCommentVNode)("v-if", true),
3231
- (0, vue.createVNode)($setup["ChatPanel"], {
3232
- ref: "frameRef",
3233
- mode: $setup.effectiveMode,
3234
- open: $props.open,
3235
- minimized: $setup.minimized,
3236
- "position-style": $setup.chatPositionStyle,
3237
- "animation-origin": $setup.chatAnimationOrigin,
3238
- "panel-width": $setup.panelWidth,
3239
- resizable: $setup.splitConfig.resizable,
3240
- "min-width": $setup.splitConfig.minWidth,
3241
- "max-width": $setup.splitConfig.maxWidth,
3242
- "no-transition": $setup.isRestoring,
3243
- dragging: $setup.isDragging,
3244
- thinking: $props.thinking,
3245
- "resolved-theme": $setup.resolvedTheme,
3246
- "split-position": $setup.splitPosition,
3247
- extension: $setup.isExtensionMode,
3248
- onResize: $setup.handleResize,
3249
- onResizeStart: $setup.handleResizeStart,
3250
- onResizeEnd: $setup.handleResizeEnd,
3251
- onToggle: $setup.handleSplitToggle
3252
- }, (0, vue.createSlots)({
3253
- "sessions-empty": (0, vue.withCtx)(() => [(0, vue.renderSlot)(_ctx.$slots, "sessions-empty", {}, () => [_cache[0] || (_cache[0] = (0, vue.createElementVNode)("div", { class: "opencode-session-empty" }, "暂无会话", -1))])]),
3254
- _: 2
3255
- }, [
3256
- $setup.slots["session-toggle-icon"] ? {
3257
- name: "session-toggle-icon",
3258
- fn: (0, vue.withCtx)(() => [(0, vue.renderSlot)(_ctx.$slots, "session-toggle-icon")]),
3259
- key: "0"
3260
- } : void 0,
3261
- $setup.slots["select-icon"] ? {
3262
- name: "select-icon",
3263
- fn: (0, vue.withCtx)(() => [(0, vue.renderSlot)(_ctx.$slots, "select-icon")]),
3264
- key: "1"
3265
- } : void 0,
3266
- $setup.slots["close-icon"] ? {
3267
- name: "close-icon",
3268
- fn: (0, vue.withCtx)(() => [(0, vue.renderSlot)(_ctx.$slots, "close-icon")]),
3269
- key: "2"
3270
- } : void 0,
3271
- $setup.slots["empty-state"] ? {
3272
- name: "empty-state",
3273
- fn: (0, vue.withCtx)(() => [(0, vue.renderSlot)(_ctx.$slots, "empty-state")]),
3274
- key: "3"
3275
- } : void 0,
3276
- $setup.slots.loading ? {
3277
- name: "loading",
3278
- fn: (0, vue.withCtx)(() => [(0, vue.renderSlot)(_ctx.$slots, "loading")]),
3279
- key: "4"
3280
- } : void 0,
3281
- $setup.slots.error ? {
3282
- name: "error",
3283
- fn: (0, vue.withCtx)(() => [(0, vue.renderSlot)(_ctx.$slots, "error")]),
3284
- key: "5"
3285
- } : void 0,
3286
- $setup.slots.content ? {
3287
- name: "content",
3288
- fn: (0, vue.withCtx)(() => [(0, vue.renderSlot)(_ctx.$slots, "content")]),
3289
- key: "6"
3290
- } : void 0
3291
- ]), 1032, [
3292
- "mode",
3293
- "open",
3294
- "minimized",
3295
- "position-style",
3296
- "animation-origin",
3297
- "panel-width",
3298
- "resizable",
3299
- "min-width",
3300
- "max-width",
3301
- "no-transition",
3302
- "dragging",
3303
- "thinking",
3304
- "resolved-theme",
3305
- "split-position",
3306
- "extension",
3307
- "onResize",
3308
- "onToggle"
3309
- ]),
3310
- (0, vue.createVNode)($setup["SelectHint"])
3311
- ], 64)) : (0, vue.createCommentVNode)("v-if", true),
3312
- (0, vue.withDirectives)((0, vue.createElementVNode)("div", {
3313
- class: "opencode-element-highlight",
3314
- style: (0, vue.normalizeStyle)($setup.highlightStyle)
3315
- }, null, 4), [[vue.vShow, $setup.highlightVisible]]),
3316
- (0, vue.withDirectives)((0, vue.createElementVNode)("div", {
3317
- class: "opencode-element-tooltip",
3318
- style: (0, vue.normalizeStyle)($setup.tooltipStyle)
3319
- }, [(0, vue.createElementVNode)("div", _hoisted_1, (0, vue.toDisplayString)($setup.tooltipContent.description), 1), (0, vue.createElementVNode)("div", _hoisted_2, (0, vue.toDisplayString)($setup.tooltipContent.fileInfo), 1)], 4), [[vue.vShow, $setup.tooltipVisible]]),
3320
- $setup.dialogVisible ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_3, [(0, vue.createElementVNode)("div", _hoisted_4, [(0, vue.createElementVNode)("div", _hoisted_5, [(0, vue.createElementVNode)("div", _hoisted_6, (0, vue.toDisplayString)($setup.dialogMessage), 1)]), (0, vue.createElementVNode)("div", { class: "opencode-dialog-actions" }, [(0, vue.createElementVNode)("button", {
3321
- class: "opencode-dialog-btn cancel",
3322
- onClick: $setup.handleDialogCancel
3323
- }, "取消"), (0, vue.createElementVNode)("button", {
3324
- class: "opencode-dialog-btn confirm",
3325
- onClick: $setup.handleDialogConfirm
3326
- }, "确认")])])])) : (0, vue.createCommentVNode)("v-if", true),
3327
- ((0, vue.openBlock)(), (0, vue.createBlock)(vue.Teleport, {
3328
- to: "body",
3329
- disabled: $setup.notificationMode === "widget"
3330
- }, [$setup.notificationVisible ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", {
3331
- key: 0,
3332
- class: (0, vue.normalizeClass)($setup.notificationMode === "page" ? "opencode-page-notification" : "opencode-notification"),
3333
- role: "alert"
3334
- }, (0, vue.toDisplayString)($setup.notificationMessage), 3)) : (0, vue.createCommentVNode)("v-if", true)], 8, ["disabled"]))
3335
- ], 2);
3336
- }
3337
- __vue_sfc__.render = __vue_render__;
3338
- //#endregion
3339
- //#region es/open-code-widget/index.mjs
3340
- var open_code_widget_default = __vue_sfc__;
3341
- //#endregion
3342
- //#region es/index.mjs
3343
- var version = "1.1.3";
3344
- function install(app, options) {
3345
- [open_code_widget_default].forEach((item) => {
3346
- if (item.install) app.use(item, options);
3347
- else if (item.name) app.component(item.name, item);
3348
- });
3349
- }
3350
- var es_default = install;
3351
- //#endregion
3352
- exports.OpenCodeWidget = open_code_widget_default;
3353
- exports.default = es_default;
3354
- exports.install = install;
3355
- exports.version = version;