@vite-plugin-opencode-assistant/components 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/es/env.d.ts +10 -0
  2. package/es/index.d.ts +6 -0
  3. package/es/index.js +21 -0
  4. package/es/open-code-widget/composables/use-inspector.d.ts +52 -0
  5. package/es/open-code-widget/composables/use-inspector.js +188 -0
  6. package/es/open-code-widget/composables/use-selection.d.ts +19 -0
  7. package/es/open-code-widget/composables/use-selection.js +142 -0
  8. package/es/open-code-widget/composables/use-session.d.ts +16 -0
  9. package/es/open-code-widget/composables/use-session.js +68 -0
  10. package/es/open-code-widget/composables/use-widget.d.ts +24 -0
  11. package/es/open-code-widget/composables/use-widget.js +44 -0
  12. package/es/open-code-widget/index.d.ts +3 -0
  13. package/es/open-code-widget/index.js +6 -0
  14. package/es/open-code-widget/src/components/Frame-sfc.css +1 -0
  15. package/es/open-code-widget/src/components/Frame.vue.d.ts +16 -0
  16. package/es/open-code-widget/src/components/Frame.vue.js +120 -0
  17. package/es/open-code-widget/src/components/Header-sfc.css +1 -0
  18. package/es/open-code-widget/src/components/Header.vue.d.ts +16 -0
  19. package/es/open-code-widget/src/components/Header.vue.js +140 -0
  20. package/es/open-code-widget/src/components/SelectHint-sfc.css +1 -0
  21. package/es/open-code-widget/src/components/SelectHint.vue.d.ts +2 -0
  22. package/es/open-code-widget/src/components/SelectHint.vue.js +46 -0
  23. package/es/open-code-widget/src/components/SelectedBubbles-sfc.css +1 -0
  24. package/es/open-code-widget/src/components/SelectedBubbles.vue.d.ts +2 -0
  25. package/es/open-code-widget/src/components/SelectedBubbles.vue.js +84 -0
  26. package/es/open-code-widget/src/components/SelectedNodes-sfc.css +1 -0
  27. package/es/open-code-widget/src/components/SelectedNodes.vue.d.ts +2 -0
  28. package/es/open-code-widget/src/components/SelectedNodes.vue.js +103 -0
  29. package/es/open-code-widget/src/components/SessionList-sfc.css +1 -0
  30. package/es/open-code-widget/src/components/SessionList.vue.d.ts +12 -0
  31. package/es/open-code-widget/src/components/SessionList.vue.js +209 -0
  32. package/es/open-code-widget/src/components/Trigger-sfc.css +1 -0
  33. package/es/open-code-widget/src/components/Trigger.vue.d.ts +12 -0
  34. package/es/open-code-widget/src/components/Trigger.vue.js +66 -0
  35. package/es/open-code-widget/src/context.d.ts +42 -0
  36. package/es/open-code-widget/src/context.js +16 -0
  37. package/es/open-code-widget/src/index-sfc.css +1 -0
  38. package/es/open-code-widget/src/index.vue.d.ts +83 -0
  39. package/es/open-code-widget/src/index.vue.js +464 -0
  40. package/es/open-code-widget/src/types.d.ts +74 -0
  41. package/es/open-code-widget/src/types.js +0 -0
  42. package/es/open-code-widget/style/index-pure.d.ts +0 -0
  43. package/es/open-code-widget/style/index-pure.js +0 -0
  44. package/es/open-code-widget/style/index.d.ts +0 -0
  45. package/es/open-code-widget/style/index.js +0 -0
  46. package/es/open-code-widget/style/less-pure.d.ts +0 -0
  47. package/es/open-code-widget/style/less-pure.js +0 -0
  48. package/es/open-code-widget/style/less.d.ts +0 -0
  49. package/es/open-code-widget/style/less.js +0 -0
  50. package/lib/@vite-plugin-opencode-assistant/components.cjs.js +1322 -0
  51. package/lib/@vite-plugin-opencode-assistant/components.es.js +1315 -0
  52. package/lib/components.css +9 -0
  53. package/lib/env.d.ts +10 -0
  54. package/lib/index.css +0 -0
  55. package/lib/index.d.ts +6 -0
  56. package/lib/index.js +50 -0
  57. package/lib/index.less +0 -0
  58. package/lib/open-code-widget/composables/use-inspector.d.ts +52 -0
  59. package/lib/open-code-widget/composables/use-inspector.js +207 -0
  60. package/lib/open-code-widget/composables/use-selection.d.ts +19 -0
  61. package/lib/open-code-widget/composables/use-selection.js +161 -0
  62. package/lib/open-code-widget/composables/use-session.d.ts +16 -0
  63. package/lib/open-code-widget/composables/use-session.js +87 -0
  64. package/lib/open-code-widget/composables/use-widget.d.ts +24 -0
  65. package/lib/open-code-widget/composables/use-widget.js +63 -0
  66. package/lib/open-code-widget/index.d.ts +3 -0
  67. package/lib/open-code-widget/index.js +36 -0
  68. package/lib/open-code-widget/src/components/Frame-sfc.css +1 -0
  69. package/lib/open-code-widget/src/components/Frame.vue.d.ts +16 -0
  70. package/lib/open-code-widget/src/components/Frame.vue.js +139 -0
  71. package/lib/open-code-widget/src/components/Header-sfc.css +1 -0
  72. package/lib/open-code-widget/src/components/Header.vue.d.ts +16 -0
  73. package/lib/open-code-widget/src/components/Header.vue.js +159 -0
  74. package/lib/open-code-widget/src/components/SelectHint-sfc.css +1 -0
  75. package/lib/open-code-widget/src/components/SelectHint.vue.d.ts +2 -0
  76. package/lib/open-code-widget/src/components/SelectHint.vue.js +65 -0
  77. package/lib/open-code-widget/src/components/SelectedBubbles-sfc.css +1 -0
  78. package/lib/open-code-widget/src/components/SelectedBubbles.vue.d.ts +2 -0
  79. package/lib/open-code-widget/src/components/SelectedBubbles.vue.js +103 -0
  80. package/lib/open-code-widget/src/components/SelectedNodes-sfc.css +1 -0
  81. package/lib/open-code-widget/src/components/SelectedNodes.vue.d.ts +2 -0
  82. package/lib/open-code-widget/src/components/SelectedNodes.vue.js +122 -0
  83. package/lib/open-code-widget/src/components/SessionList-sfc.css +1 -0
  84. package/lib/open-code-widget/src/components/SessionList.vue.d.ts +12 -0
  85. package/lib/open-code-widget/src/components/SessionList.vue.js +228 -0
  86. package/lib/open-code-widget/src/components/Trigger-sfc.css +1 -0
  87. package/lib/open-code-widget/src/components/Trigger.vue.d.ts +12 -0
  88. package/lib/open-code-widget/src/components/Trigger.vue.js +85 -0
  89. package/lib/open-code-widget/src/context.d.ts +42 -0
  90. package/lib/open-code-widget/src/context.js +35 -0
  91. package/lib/open-code-widget/src/index-sfc.css +1 -0
  92. package/lib/open-code-widget/src/index.vue.d.ts +83 -0
  93. package/lib/open-code-widget/src/index.vue.js +491 -0
  94. package/lib/open-code-widget/src/types.d.ts +74 -0
  95. package/lib/open-code-widget/src/types.js +15 -0
  96. package/lib/open-code-widget/style/index-pure.d.ts +0 -0
  97. package/lib/open-code-widget/style/index-pure.js +0 -0
  98. package/lib/open-code-widget/style/index.d.ts +0 -0
  99. package/lib/open-code-widget/style/index.js +0 -0
  100. package/lib/open-code-widget/style/less-pure.d.ts +0 -0
  101. package/lib/open-code-widget/style/less-pure.js +0 -0
  102. package/lib/open-code-widget/style/less.d.ts +0 -0
  103. package/lib/open-code-widget/style/less.js +0 -0
  104. package/lib/web-types.json +1 -0
  105. package/package.json +46 -0
@@ -0,0 +1,1315 @@
1
+ import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createSlots, createVNode, defineComponent, inject, normalizeClass, normalizeStyle, onMounted, onUnmounted, openBlock, provide, ref, renderList, renderSlot, toDisplayString, toRef, useSlots, vShow, watch, withCtx, withDirectives, withModifiers } from "vue";
2
+ //#region es/open-code-widget/src/context.js
3
+ var CONTEXT_KEY = /* @__PURE__ */ Symbol("OpenCodeWidgetContext");
4
+ function provideOpenCodeWidgetContext(context) {
5
+ provide(CONTEXT_KEY, context);
6
+ }
7
+ function useOpenCodeWidgetContext() {
8
+ const context = inject(CONTEXT_KEY);
9
+ if (!context) throw new Error("useOpenCodeWidgetContext must be used within OpenCodeWidget");
10
+ return context;
11
+ }
12
+ //#endregion
13
+ //#region es/open-code-widget/src/components/Frame.vue.js
14
+ var __vue_sfc__$7 = /* @__PURE__ */ defineComponent({
15
+ __name: "Frame",
16
+ setup(__props, { expose: __expose }) {
17
+ __expose();
18
+ const { loading, showEmptyState, iframeSource: iframeSrc, emptyStateText, emptyStateActionText, handleEmptyAction } = useOpenCodeWidgetContext();
19
+ const __returned__ = {
20
+ loading,
21
+ showEmptyState,
22
+ iframeSrc,
23
+ emptyStateText,
24
+ emptyStateActionText,
25
+ handleEmptyAction
26
+ };
27
+ Object.defineProperty(__returned__, "__isScriptSetup", {
28
+ enumerable: false,
29
+ value: true
30
+ });
31
+ return __returned__;
32
+ }
33
+ });
34
+ var _hoisted_1$7 = { class: "opencode-iframe-container" };
35
+ var _hoisted_2$5 = { class: "opencode-empty-state-text" };
36
+ var _hoisted_3$5 = ["src"];
37
+ function __vue_render__$7(_ctx, _cache, $props, $setup, $data, $options) {
38
+ return openBlock(), createElementBlock("div", _hoisted_1$7, [
39
+ createElementVNode("div", { class: normalizeClass(["opencode-empty-state-overlay", { visible: $setup.showEmptyState }]) }, [renderSlot(_ctx.$slots, "empty-state", {}, () => [
40
+ _cache[1] || (_cache[1] = createElementVNode("div", { class: "opencode-empty-state-icon" }, [createElementVNode("svg", {
41
+ viewBox: "0 0 24 24",
42
+ width: "48",
43
+ height: "48",
44
+ fill: "none",
45
+ stroke: "currentColor",
46
+ "stroke-width": "1.5",
47
+ "aria-hidden": "true"
48
+ }, [createElementVNode("path", {
49
+ "stroke-linecap": "round",
50
+ "stroke-linejoin": "round",
51
+ 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"
52
+ })])], -1)),
53
+ createElementVNode("div", _hoisted_2$5, toDisplayString($setup.emptyStateText), 1),
54
+ createElementVNode("button", {
55
+ class: "opencode-empty-state-btn",
56
+ type: "button",
57
+ onClick: _cache[0] || (_cache[0] = (...args) => $setup.handleEmptyAction && $setup.handleEmptyAction(...args))
58
+ }, toDisplayString($setup.emptyStateActionText), 1)
59
+ ])], 2),
60
+ createElementVNode("div", { class: normalizeClass(["opencode-loading-overlay", { visible: $setup.loading }]) }, [renderSlot(_ctx.$slots, "loading", {}, () => [_cache[2] || (_cache[2] = createElementVNode("div", { class: "opencode-loading-spinner" }, null, -1)), _cache[3] || (_cache[3] = createElementVNode("div", { class: "opencode-loading-text" }, "加载中...", -1))])], 2),
61
+ renderSlot(_ctx.$slots, "content", {}, () => [createElementVNode("iframe", {
62
+ class: "opencode-iframe",
63
+ src: $setup.iframeSrc,
64
+ allow: "clipboard-write; clipboard-read",
65
+ referrerpolicy: "origin"
66
+ }, null, 8, _hoisted_3$5)])
67
+ ]);
68
+ }
69
+ __vue_sfc__$7.render = __vue_render__$7;
70
+ var Frame_vue_default = __vue_sfc__$7;
71
+ //#endregion
72
+ //#region es/open-code-widget/src/components/Header.vue.js
73
+ var __vue_sfc__$6 = /* @__PURE__ */ defineComponent({
74
+ __name: "Header",
75
+ setup(__props, { expose: __expose }) {
76
+ __expose();
77
+ const { title, sessionListTitle, sessionListCollapsed, selectMode, selectEnabled, handleToggleSessionList, handleToggleSelectMode, handleClose } = useOpenCodeWidgetContext();
78
+ const __returned__ = {
79
+ title,
80
+ sessionListTitle,
81
+ sessionListCollapsed,
82
+ selectMode,
83
+ selectEnabled,
84
+ handleToggleSessionList,
85
+ handleToggleSelectMode,
86
+ handleClose
87
+ };
88
+ Object.defineProperty(__returned__, "__isScriptSetup", {
89
+ enumerable: false,
90
+ value: true
91
+ });
92
+ return __returned__;
93
+ }
94
+ });
95
+ var _hoisted_1$6 = { class: "opencode-chat-header" };
96
+ var _hoisted_2$4 = { class: "opencode-chat-header-left" };
97
+ var _hoisted_3$4 = [
98
+ "title",
99
+ "aria-label",
100
+ "aria-expanded"
101
+ ];
102
+ var _hoisted_4$4 = ["aria-pressed", "disabled"];
103
+ var _hoisted_5$4 = { class: "opencode-chat-header-title" };
104
+ var _hoisted_6$3 = { class: "opencode-chat-header-actions" };
105
+ function __vue_render__$6(_ctx, _cache, $props, $setup, $data, $options) {
106
+ return openBlock(), createElementBlock("div", _hoisted_1$6, [
107
+ createElementVNode("div", _hoisted_2$4, [createElementVNode("button", {
108
+ class: "opencode-header-btn session-toggle",
109
+ type: "button",
110
+ title: $setup.sessionListTitle,
111
+ "aria-label": $setup.sessionListTitle,
112
+ "aria-expanded": !$setup.sessionListCollapsed,
113
+ onClick: _cache[0] || (_cache[0] = (...args) => $setup.handleToggleSessionList && $setup.handleToggleSessionList(...args))
114
+ }, [renderSlot(_ctx.$slots, "session-toggle-icon", {}, () => [_cache[3] || (_cache[3] = createElementVNode("svg", {
115
+ viewBox: "0 0 24 24",
116
+ width: "16",
117
+ height: "16",
118
+ fill: "none",
119
+ stroke: "currentColor",
120
+ "stroke-width": "2",
121
+ "aria-hidden": "true"
122
+ }, [createElementVNode("path", {
123
+ d: "M4 6h16M4 12h16M4 18h16",
124
+ "stroke-linecap": "round"
125
+ })], -1))])], 8, _hoisted_3$4), createElementVNode("button", {
126
+ class: normalizeClass(["opencode-header-btn select-btn", { active: $setup.selectMode }]),
127
+ type: "button",
128
+ title: "选择页面元素 (Ctrl+P)",
129
+ "aria-label": "选择页面元素",
130
+ "aria-pressed": $setup.selectMode,
131
+ disabled: !$setup.selectEnabled,
132
+ onClick: _cache[1] || (_cache[1] = (...args) => $setup.handleToggleSelectMode && $setup.handleToggleSelectMode(...args))
133
+ }, [renderSlot(_ctx.$slots, "select-icon", {}, () => [_cache[4] || (_cache[4] = createElementVNode("svg", {
134
+ viewBox: "0 0 1024 1024",
135
+ width: "16",
136
+ height: "16",
137
+ "aria-hidden": "true"
138
+ }, [createElementVNode("path", {
139
+ fill: "currentColor",
140
+ 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"
141
+ }), createElementVNode("path", {
142
+ fill: "currentColor",
143
+ 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"
144
+ })], -1))])], 10, _hoisted_4$4)]),
145
+ createElementVNode("span", _hoisted_5$4, toDisplayString($setup.title), 1),
146
+ createElementVNode("div", _hoisted_6$3, [createElementVNode("button", {
147
+ class: "opencode-header-btn close",
148
+ type: "button",
149
+ title: "关闭",
150
+ "aria-label": "关闭面板",
151
+ onClick: _cache[2] || (_cache[2] = (...args) => $setup.handleClose && $setup.handleClose(...args))
152
+ }, [renderSlot(_ctx.$slots, "close-icon", {}, () => [_cache[5] || (_cache[5] = createElementVNode("svg", {
153
+ viewBox: "0 0 24 24",
154
+ width: "14",
155
+ height: "14",
156
+ fill: "none",
157
+ stroke: "currentColor",
158
+ "stroke-width": "2",
159
+ "aria-hidden": "true"
160
+ }, [createElementVNode("path", { d: "M18 6L6 18M6 6l12 12" })], -1))])])])
161
+ ]);
162
+ }
163
+ __vue_sfc__$6.render = __vue_render__$6;
164
+ var Header_vue_default = __vue_sfc__$6;
165
+ //#endregion
166
+ //#region es/open-code-widget/src/components/SelectHint.vue.js
167
+ var __vue_sfc__$5 = /* @__PURE__ */ defineComponent({
168
+ __name: "SelectHint",
169
+ setup(__props, { expose: __expose }) {
170
+ __expose();
171
+ const { selectMode: visible, selectShortcutLabel: shortcutLabel } = useOpenCodeWidgetContext();
172
+ const __returned__ = {
173
+ visible,
174
+ shortcutLabel
175
+ };
176
+ Object.defineProperty(__returned__, "__isScriptSetup", {
177
+ enumerable: false,
178
+ value: true
179
+ });
180
+ return __returned__;
181
+ }
182
+ });
183
+ var _hoisted_1$5 = { class: "opencode-hint-shortcut" };
184
+ function __vue_render__$5(_ctx, _cache, $props, $setup, $data, $options) {
185
+ return openBlock(), createElementBlock("div", { class: normalizeClass(["opencode-select-mode-hint", { visible: $setup.visible }]) }, [_cache[0] || (_cache[0] = createElementVNode("span", null, "🎯 选择模式已开启 - 点击元素进行选择", -1)), createElementVNode("span", _hoisted_1$5, toDisplayString($setup.shortcutLabel), 1)], 2);
186
+ }
187
+ __vue_sfc__$5.render = __vue_render__$5;
188
+ var SelectHint_vue_default = __vue_sfc__$5;
189
+ //#endregion
190
+ //#region es/open-code-widget/src/components/SelectedBubbles.vue.js
191
+ var __vue_sfc__$4 = /* @__PURE__ */ defineComponent({
192
+ __name: "SelectedBubbles",
193
+ setup(__props, { expose: __expose }) {
194
+ __expose();
195
+ const { bubbleVisible: visible, selectedElementItems: items, handleClickSelectedNode, handleRemoveSelectedNode } = useOpenCodeWidgetContext();
196
+ const __returned__ = {
197
+ visible,
198
+ items,
199
+ handleClickSelectedNode,
200
+ handleRemoveSelectedNode
201
+ };
202
+ Object.defineProperty(__returned__, "__isScriptSetup", {
203
+ enumerable: false,
204
+ value: true
205
+ });
206
+ return __returned__;
207
+ }
208
+ });
209
+ var _hoisted_1$4 = {
210
+ key: 0,
211
+ class: "opencode-bubble-empty"
212
+ };
213
+ var _hoisted_2$3 = ["onClick"];
214
+ var _hoisted_3$3 = { class: "opencode-bubble-text" };
215
+ var _hoisted_4$3 = {
216
+ key: 0,
217
+ class: "opencode-bubble-file"
218
+ };
219
+ var _hoisted_5$3 = ["aria-label", "onClick"];
220
+ function __vue_render__$4(_ctx, _cache, $props, $setup, $data, $options) {
221
+ return openBlock(), createElementBlock("div", {
222
+ class: normalizeClass(["opencode-selected-bubbles", { visible: $setup.visible }]),
223
+ role: "list",
224
+ "aria-label": "已选元素列表"
225
+ }, [$setup.items.length === 0 ? (openBlock(), createElementBlock("div", _hoisted_1$4, "暂无选中元素")) : (openBlock(true), createElementBlock(Fragment, { key: 1 }, renderList($setup.items, (item, index) => {
226
+ return openBlock(), createElementBlock("div", {
227
+ key: item.key,
228
+ class: "opencode-selected-bubble",
229
+ role: "listitem",
230
+ onClick: ($event) => $setup.handleClickSelectedNode(item)
231
+ }, [
232
+ createElementVNode("span", _hoisted_3$3, toDisplayString(item.description), 1),
233
+ item.bubbleFileText ? (openBlock(), createElementBlock("span", _hoisted_4$3, toDisplayString(item.bubbleFileText), 1)) : createCommentVNode("v-if", true),
234
+ createElementVNode("button", {
235
+ class: "opencode-bubble-remove",
236
+ type: "button",
237
+ "aria-label": `\u79FB\u9664\u5143\u7D20: ${item.description}`,
238
+ onClick: withModifiers(($event) => $setup.handleRemoveSelectedNode({
239
+ item,
240
+ index,
241
+ source: "bubble"
242
+ }), ["stop"])
243
+ }, " × ", 8, _hoisted_5$3)
244
+ ], 8, _hoisted_2$3);
245
+ }), 128))], 2);
246
+ }
247
+ __vue_sfc__$4.render = __vue_render__$4;
248
+ var SelectedBubbles_vue_default = __vue_sfc__$4;
249
+ //#endregion
250
+ //#region es/open-code-widget/src/components/SelectedNodes.vue.js
251
+ var __vue_sfc__$3 = /* @__PURE__ */ defineComponent({
252
+ __name: "SelectedNodes",
253
+ setup(__props, { expose: __expose }) {
254
+ __expose();
255
+ const { selectedElementItems: items, showClearAll, handleClickSelectedNode, handleRemoveSelectedNode, handleClearSelectedNodes } = useOpenCodeWidgetContext();
256
+ const __returned__ = {
257
+ items,
258
+ showClearAll,
259
+ handleClickSelectedNode,
260
+ handleRemoveSelectedNode,
261
+ handleClearSelectedNodes
262
+ };
263
+ Object.defineProperty(__returned__, "__isScriptSetup", {
264
+ enumerable: false,
265
+ value: true
266
+ });
267
+ return __returned__;
268
+ }
269
+ });
270
+ var _hoisted_1$3 = {
271
+ class: "opencode-selected-nodes",
272
+ role: "list",
273
+ "aria-label": "已选元素列表"
274
+ };
275
+ var _hoisted_2$2 = ["onClick"];
276
+ var _hoisted_3$2 = { class: "opencode-node-content" };
277
+ var _hoisted_4$2 = { class: "opencode-node-text" };
278
+ var _hoisted_5$2 = { class: "opencode-node-file" };
279
+ var _hoisted_6$2 = ["aria-label", "onClick"];
280
+ function __vue_render__$3(_ctx, _cache, $props, $setup, $data, $options) {
281
+ return openBlock(), createElementBlock("div", { class: normalizeClass(["opencode-right-toolbar", { collapsed: $setup.items.length === 0 }]) }, [
282
+ _cache[1] || (_cache[1] = createElementVNode("div", { class: "opencode-selected-nodes-header" }, [createElementVNode("div", { class: "opencode-selected-nodes-title" }, "已选节点"), createElementVNode("div", { class: "opencode-selected-nodes-desc" }, "选中的节点会在对话时一起发送给助手")], -1)),
283
+ createElementVNode("div", _hoisted_1$3, [(openBlock(true), createElementBlock(Fragment, null, renderList($setup.items, (item, index) => {
284
+ return openBlock(), createElementBlock("div", {
285
+ key: item.key,
286
+ class: "opencode-selected-node",
287
+ role: "listitem",
288
+ onClick: ($event) => $setup.handleClickSelectedNode(item)
289
+ }, [createElementVNode("div", _hoisted_3$2, [createElementVNode("span", _hoisted_4$2, toDisplayString(item.description), 1), createElementVNode("span", _hoisted_5$2, toDisplayString(item.panelFileText), 1)]), createElementVNode("button", {
290
+ class: "opencode-node-remove",
291
+ type: "button",
292
+ "aria-label": `\u79FB\u9664\u5143\u7D20: ${item.description}`,
293
+ onClick: withModifiers(($event) => $setup.handleRemoveSelectedNode({
294
+ item,
295
+ index,
296
+ source: "panel"
297
+ }), ["stop"])
298
+ }, " × ", 8, _hoisted_6$2)], 8, _hoisted_2$2);
299
+ }), 128))]),
300
+ $setup.showClearAll && $setup.items.length > 0 ? (openBlock(), createElementBlock("button", {
301
+ key: 0,
302
+ class: "opencode-clear-all-btn",
303
+ type: "button",
304
+ "aria-label": "清空所有已选节点",
305
+ onClick: _cache[0] || (_cache[0] = (...args) => $setup.handleClearSelectedNodes && $setup.handleClearSelectedNodes(...args))
306
+ }, " 一键清空 ")) : createCommentVNode("v-if", true)
307
+ ], 2);
308
+ }
309
+ __vue_sfc__$3.render = __vue_render__$3;
310
+ var SelectedNodes_vue_default = __vue_sfc__$3;
311
+ //#endregion
312
+ //#region es/open-code-widget/src/components/SessionList.vue.js
313
+ var __vue_sfc__$2 = /* @__PURE__ */ defineComponent({
314
+ __name: "SessionList",
315
+ setup(__props, { expose: __expose }) {
316
+ __expose();
317
+ const { sessionListCollapsed: collapsed, sessionItems: sessions, loadingSessionList, handleCreateSession, handleSelectSession, handleDeleteSession } = useOpenCodeWidgetContext();
318
+ const isAnimating = ref(false);
319
+ let animTimer = null;
320
+ watch(collapsed, () => {
321
+ isAnimating.value = true;
322
+ if (animTimer) clearTimeout(animTimer);
323
+ animTimer = setTimeout(() => {
324
+ isAnimating.value = false;
325
+ }, 200);
326
+ });
327
+ const __returned__ = {
328
+ collapsed,
329
+ sessions,
330
+ loadingSessionList,
331
+ handleCreateSession,
332
+ handleSelectSession,
333
+ handleDeleteSession,
334
+ isAnimating,
335
+ get animTimer() {
336
+ return animTimer;
337
+ },
338
+ set animTimer(v) {
339
+ animTimer = v;
340
+ },
341
+ showSkeleton: computed(() => {
342
+ if (isAnimating.value) return true;
343
+ return false;
344
+ })
345
+ };
346
+ Object.defineProperty(__returned__, "__isScriptSetup", {
347
+ enumerable: false,
348
+ value: true
349
+ });
350
+ return __returned__;
351
+ }
352
+ });
353
+ var _hoisted_1$2 = {
354
+ key: 0,
355
+ class: "opencode-session-list-header"
356
+ };
357
+ var _hoisted_2$1 = {
358
+ key: 2,
359
+ class: "opencode-session-skeleton visible"
360
+ };
361
+ var _hoisted_3$1 = {
362
+ class: "opencode-session-list-content",
363
+ role: "listbox",
364
+ "aria-labelledby": "opencode-session-list-title"
365
+ };
366
+ var _hoisted_4$1 = {
367
+ key: 0,
368
+ class: "opencode-session-list-loading-overlay"
369
+ };
370
+ var _hoisted_5$1 = ["aria-selected", "onClick"];
371
+ var _hoisted_6$1 = { class: "opencode-session-header" };
372
+ var _hoisted_7$1 = { class: "opencode-session-title" };
373
+ var _hoisted_8$1 = ["aria-label", "onClick"];
374
+ var _hoisted_9 = { class: "opencode-session-meta" };
375
+ function __vue_render__$2(_ctx, _cache, $props, $setup, $data, $options) {
376
+ return openBlock(), createElementBlock("div", { class: normalizeClass(["opencode-session-list", { collapsed: $setup.collapsed }]) }, [
377
+ createCommentVNode(" Header "),
378
+ !$setup.showSkeleton ? (openBlock(), createElementBlock("div", _hoisted_1$2, [_cache[1] || (_cache[1] = createElementVNode("span", { id: "opencode-session-list-title" }, "会话列表", -1)), createElementVNode("button", {
379
+ class: "opencode-new-session-btn",
380
+ type: "button",
381
+ title: "新建会话",
382
+ "aria-label": "新建会话",
383
+ onClick: _cache[0] || (_cache[0] = (...args) => $setup.handleCreateSession && $setup.handleCreateSession(...args))
384
+ }, " + ")])) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [createCommentVNode(" Header Skeleton "), _cache[2] || (_cache[2] = createElementVNode("div", { class: "opencode-session-header-skeleton visible" }, [createElementVNode("div", { class: "opencode-skeleton-header-title" }), createElementVNode("div", { class: "opencode-skeleton-header-btn" })], -1))], 2112)),
385
+ createCommentVNode(" Content Skeleton "),
386
+ $setup.showSkeleton ? (openBlock(), createElementBlock("div", _hoisted_2$1, [(openBlock(), createElementBlock(Fragment, null, renderList(5, (i) => {
387
+ return createElementVNode("div", {
388
+ key: `skeleton-${i}`,
389
+ class: "opencode-skeleton-item"
390
+ }, [..._cache[3] || (_cache[3] = [createElementVNode("div", { class: "opencode-skeleton-title" }, null, -1), createElementVNode("div", { class: "opencode-skeleton-meta" }, null, -1)])]);
391
+ }), 64))])) : (openBlock(), createElementBlock(Fragment, { key: 3 }, [createCommentVNode(" Content "), createElementVNode("div", _hoisted_3$1, [$setup.loadingSessionList ? (openBlock(), createElementBlock("div", _hoisted_4$1, [..._cache[4] || (_cache[4] = [createElementVNode("div", { class: "opencode-loading-spinner small" }, null, -1)])])) : createCommentVNode("v-if", true), $setup.sessions.length > 0 ? (openBlock(true), createElementBlock(Fragment, { key: 1 }, renderList($setup.sessions, (item) => {
392
+ return openBlock(), createElementBlock("div", {
393
+ key: item.key,
394
+ class: normalizeClass(["opencode-session-item", { active: item.active }]),
395
+ role: "option",
396
+ "aria-selected": item.active,
397
+ onClick: ($event) => $setup.handleSelectSession(item)
398
+ }, [createElementVNode("div", _hoisted_6$1, [createElementVNode("div", _hoisted_7$1, toDisplayString(item.title), 1), createElementVNode("button", {
399
+ class: "opencode-session-delete-btn",
400
+ type: "button",
401
+ "aria-label": `\u5220\u9664\u4F1A\u8BDD: ${item.title}`,
402
+ onClick: withModifiers(($event) => $setup.handleDeleteSession(item), ["stop"])
403
+ }, " × ", 8, _hoisted_8$1)]), createElementVNode("div", _hoisted_9, toDisplayString(item.meta), 1)], 10, _hoisted_5$1);
404
+ }), 128)) : (openBlock(), createElementBlock(Fragment, { key: 2 }, [createCommentVNode(" Empty State "), renderSlot(_ctx.$slots, "empty")], 64))])], 2112))
405
+ ], 2);
406
+ }
407
+ __vue_sfc__$2.render = __vue_render__$2;
408
+ var SessionList_vue_default = __vue_sfc__$2;
409
+ //#endregion
410
+ //#region es/open-code-widget/src/components/Trigger.vue.js
411
+ var __vue_sfc__$1 = /* @__PURE__ */ defineComponent({
412
+ __name: "Trigger",
413
+ setup(__props, { expose: __expose }) {
414
+ __expose();
415
+ const { buttonActive: active, open, hotkeyLabel, handleToggle } = useOpenCodeWidgetContext();
416
+ const __returned__ = {
417
+ active,
418
+ open,
419
+ hotkeyLabel,
420
+ handleToggle
421
+ };
422
+ Object.defineProperty(__returned__, "__isScriptSetup", {
423
+ enumerable: false,
424
+ value: true
425
+ });
426
+ return __returned__;
427
+ }
428
+ });
429
+ var _hoisted_1$1 = ["aria-expanded", "title"];
430
+ function __vue_render__$1(_ctx, _cache, $props, $setup, $data, $options) {
431
+ return openBlock(), createElementBlock("button", {
432
+ class: normalizeClass(["opencode-button", { active: $setup.active }]),
433
+ type: "button",
434
+ "aria-expanded": $setup.open,
435
+ "aria-label": "打开 AI 助手",
436
+ title: `AI \u52A9\u624B (${$setup.hotkeyLabel})`,
437
+ onClick: _cache[0] || (_cache[0] = (...args) => $setup.handleToggle && $setup.handleToggle(...args))
438
+ }, [renderSlot(_ctx.$slots, "default", {}, () => [_cache[1] || (_cache[1] = createElementVNode("svg", {
439
+ t: "1775402599580",
440
+ class: "icon",
441
+ viewBox: "0 0 1024 1024",
442
+ version: "1.1",
443
+ xmlns: "http://www.w3.org/2000/svg",
444
+ "p-id": "5390",
445
+ "xmlns:xlink": "http://www.w3.org/1999/xlink",
446
+ width: "100%",
447
+ height: "100%"
448
+ }, [
449
+ createElementVNode("path", {
450
+ 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",
451
+ fill: "white",
452
+ "p-id": "5391"
453
+ }),
454
+ createElementVNode("path", {
455
+ d: "M384 448m-64 0a64 64 0 1 0 128 0 64 64 0 1 0 -128 0Z",
456
+ fill: "white",
457
+ "p-id": "5392"
458
+ }),
459
+ createElementVNode("path", {
460
+ d: "M640 448m-64 0a64 64 0 1 0 128 0 64 64 0 1 0 -128 0Z",
461
+ fill: "white",
462
+ "p-id": "5393"
463
+ })
464
+ ], -1))])], 10, _hoisted_1$1);
465
+ }
466
+ __vue_sfc__$1.render = __vue_render__$1;
467
+ var Trigger_vue_default = __vue_sfc__$1;
468
+ //#endregion
469
+ //#region es/open-code-widget/composables/use-selection.js
470
+ var __async$1 = (__this, __arguments, generator) => {
471
+ return new Promise((resolve, reject) => {
472
+ var fulfilled = (value) => {
473
+ try {
474
+ step(generator.next(value));
475
+ } catch (e) {
476
+ reject(e);
477
+ }
478
+ };
479
+ var rejected = (value) => {
480
+ try {
481
+ step(generator.throw(value));
482
+ } catch (e) {
483
+ reject(e);
484
+ }
485
+ };
486
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
487
+ step((generator = generator.apply(__this, __arguments)).next());
488
+ });
489
+ };
490
+ function truncate$1(value, maxLength) {
491
+ if (value.length <= maxLength) return value;
492
+ return `${value.slice(0, maxLength)}...`;
493
+ }
494
+ function getElementKey(element, index) {
495
+ var _a;
496
+ if (element.filePath && element.line) return `${element.filePath}:${element.line}:${(_a = element.column) != null ? _a : 0}`;
497
+ return `${element.description}-${index}`;
498
+ }
499
+ function getBubbleFileText(element) {
500
+ var _a;
501
+ return `${((_a = element.filePath) == null ? void 0 : _a.split("/").pop()) || ""}${element.line ? `:${element.line}${element.column ? `:${element.column}` : ""}` : ""}`;
502
+ }
503
+ function getPanelFileText(element) {
504
+ var _a, _b;
505
+ const fileName = ((_a = element.filePath) == null ? void 0 : _a.split("/").pop()) || "未知文件";
506
+ const lineInfo = element.line ? `:${element.line}${element.column ? `:${element.column}` : ""}` : "";
507
+ return `${((_b = element.innerText) == null ? void 0 : _b.trim()) ? `${truncate$1(element.innerText.trim(), 30)} \xB7 ` : ""}${fileName}${lineInfo}`;
508
+ }
509
+ function useSelection(options) {
510
+ const bubbleVisible = computed(() => options.selectMode.value);
511
+ const selectedElementItems = computed(() => (options.selectedElements.value || []).map((element, index) => ({
512
+ key: getElementKey(element, index),
513
+ description: element.description || "未知元素",
514
+ bubbleFileText: getBubbleFileText(element),
515
+ panelFileText: getPanelFileText(element),
516
+ element
517
+ })));
518
+ const hasSelectedElements = computed(() => selectedElementItems.value.length > 0);
519
+ function handleToggleSelectMode() {
520
+ options.onToggleSelectMode(!options.selectMode.value);
521
+ }
522
+ function handleClickSelectedNode(item) {
523
+ const description = item.element.description;
524
+ if (!description) return;
525
+ let targetElement = null;
526
+ if (description.includes("#")) {
527
+ const idMatch = description.match(/#([^.[\s]+)/);
528
+ if (idMatch) targetElement = document.getElementById(idMatch[1]);
529
+ }
530
+ if (!targetElement && description.includes(".")) {
531
+ const classMatch = description.match(/^([a-z]+)\.([^[\s]+)/i);
532
+ if (classMatch) {
533
+ const selector = `${classMatch[1]}.${classMatch[2].split(".").filter(Boolean).join(".")}`;
534
+ targetElement = document.querySelector(selector);
535
+ }
536
+ }
537
+ if (!targetElement) {
538
+ if (description.match(/^([a-z]+)/i)) {
539
+ const simpleSelector = description.split(/[.[\s]/)[0];
540
+ targetElement = document.querySelector(simpleSelector);
541
+ }
542
+ }
543
+ if (targetElement) {
544
+ targetElement.scrollIntoView({
545
+ behavior: "smooth",
546
+ block: "center"
547
+ });
548
+ const highlightOverlay = document.createElement("div");
549
+ highlightOverlay.className = "opencode-element-highlight-temp";
550
+ const widget = document.querySelector(".opencode-widget");
551
+ let primary = "#3b82f6";
552
+ let primaryBg = "rgba(59, 130, 246, 0.1)";
553
+ if (widget) {
554
+ const style = getComputedStyle(widget);
555
+ primary = style.getPropertyValue("--oc-primary").trim() || primary;
556
+ primaryBg = style.getPropertyValue("--oc-primary-bg").trim() || primaryBg;
557
+ }
558
+ highlightOverlay.style.border = `2px solid ${primary}`;
559
+ highlightOverlay.style.background = primaryBg;
560
+ const rect = targetElement.getBoundingClientRect();
561
+ highlightOverlay.style.top = `${rect.top + window.scrollY}px`;
562
+ highlightOverlay.style.left = `${rect.left + window.scrollX}px`;
563
+ highlightOverlay.style.width = `${rect.width}px`;
564
+ highlightOverlay.style.height = `${rect.height}px`;
565
+ document.body.appendChild(highlightOverlay);
566
+ setTimeout(() => {
567
+ highlightOverlay.remove();
568
+ }, 2e3);
569
+ }
570
+ }
571
+ function handleRemoveSelectedNode(item, index, source) {
572
+ options.onRemoveSelectedNode({
573
+ element: item.element,
574
+ index,
575
+ source
576
+ });
577
+ }
578
+ function handleClearSelectedNodes() {
579
+ return __async$1(this, null, function* () {
580
+ if (!options.selectedElements.value || options.selectedElements.value.length === 0) return;
581
+ if (yield options.showConfirmDialog(`\u786E\u5B9A\u8981\u6E05\u7A7A\u6240\u6709 ${options.selectedElements.value.length} \u4E2A\u5DF2\u9009\u8282\u70B9\u5417\uFF1F`)) options.onClearSelectedNodes();
582
+ });
583
+ }
584
+ return {
585
+ bubbleVisible,
586
+ hasSelectedElements,
587
+ selectedElementItems,
588
+ handleClearSelectedNodes,
589
+ handleClickSelectedNode,
590
+ handleRemoveSelectedNode,
591
+ handleToggleSelectMode
592
+ };
593
+ }
594
+ //#endregion
595
+ //#region es/open-code-widget/composables/use-session.js
596
+ var __async = (__this, __arguments, generator) => {
597
+ return new Promise((resolve, reject) => {
598
+ var fulfilled = (value) => {
599
+ try {
600
+ step(generator.next(value));
601
+ } catch (e) {
602
+ reject(e);
603
+ }
604
+ };
605
+ var rejected = (value) => {
606
+ try {
607
+ step(generator.throw(value));
608
+ } catch (e) {
609
+ reject(e);
610
+ }
611
+ };
612
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
613
+ step((generator = generator.apply(__this, __arguments)).next());
614
+ });
615
+ };
616
+ function formatSessionMeta(session) {
617
+ if (session.meta) return session.meta;
618
+ if (!session.updatedAt) return "";
619
+ const date = new Date(session.updatedAt);
620
+ if (Number.isNaN(date.getTime())) return "";
621
+ return `${date.toLocaleDateString()} ${date.toLocaleTimeString()}`;
622
+ }
623
+ function useSession(options) {
624
+ const sessionItems = computed(() => (options.sessions.value || []).map((session) => ({
625
+ key: session.id,
626
+ title: session.title || "新会话",
627
+ meta: formatSessionMeta(session),
628
+ active: session.id === options.currentSessionId.value,
629
+ session
630
+ })));
631
+ function handleCreateSession() {
632
+ options.onCreateSession();
633
+ }
634
+ function handleSelectSession(item) {
635
+ options.onSelectSession(item.session);
636
+ }
637
+ function handleDeleteSession(item) {
638
+ return __async(this, null, function* () {
639
+ if (yield options.showConfirmDialog(`\u786E\u5B9A\u8981\u5220\u9664\u4F1A\u8BDD "${item.title}" \u5417\uFF1F`)) options.onDeleteSession(item.session);
640
+ });
641
+ }
642
+ return {
643
+ sessionItems,
644
+ handleCreateSession,
645
+ handleDeleteSession,
646
+ handleSelectSession
647
+ };
648
+ }
649
+ //#endregion
650
+ //#region es/open-code-widget/composables/use-widget.js
651
+ function useWidget(options) {
652
+ const containerClasses = computed(() => [
653
+ "opencode-widget",
654
+ options.position.value,
655
+ `opencode-theme-${options.theme.value}`
656
+ ]);
657
+ const buttonActive = computed(() => !!(options.open.value || options.selectMode.value));
658
+ const iframeSource = computed(() => options.iframeSrc.value || "about:blank");
659
+ const sessionListTitle = computed(() => options.sessionListCollapsed.value ? "展开会话列表" : "折叠会话列表");
660
+ function handleToggle() {
661
+ var _a;
662
+ if (options.selectMode.value) {
663
+ (_a = options.onToggleSelectMode) == null || _a.call(options, false);
664
+ return;
665
+ }
666
+ const nextOpen = !options.open.value;
667
+ options.onToggle(nextOpen);
668
+ }
669
+ function handleClose() {
670
+ options.onClose();
671
+ }
672
+ function handleToggleSessionList() {
673
+ options.onToggleSessionList(!options.sessionListCollapsed.value);
674
+ }
675
+ function handleEmptyAction() {
676
+ options.onEmptyAction();
677
+ }
678
+ return {
679
+ buttonActive,
680
+ containerClasses,
681
+ iframeSource,
682
+ sessionListTitle,
683
+ handleClose,
684
+ handleEmptyAction,
685
+ handleToggle,
686
+ handleToggleSessionList
687
+ };
688
+ }
689
+ //#endregion
690
+ //#region es/open-code-widget/composables/use-inspector.js
691
+ function truncate(str, maxLength) {
692
+ if (!str) return "";
693
+ return str.length > maxLength ? str.substring(0, maxLength) + "..." : str;
694
+ }
695
+ function getDirectText(element) {
696
+ let text = "";
697
+ for (let i = 0; i < element.childNodes.length; i++) {
698
+ const child = element.childNodes[i];
699
+ if (child.nodeType === Node.TEXT_NODE) text += child.textContent || "";
700
+ }
701
+ return text.trim();
702
+ }
703
+ function getElementDescription(element) {
704
+ const parts = [element.tagName.toLowerCase()];
705
+ const id = element.id;
706
+ if (id) parts.push(`#${id}`);
707
+ if (typeof element.className === "string") {
708
+ const className = element.className.trim().split(/\s+/).filter(Boolean).slice(0, 2).join(".");
709
+ if (className) parts.push(`.${className}`);
710
+ }
711
+ const name = element.getAttribute("name");
712
+ if (name) parts.push(`[name="${name}"]`);
713
+ const placeholder = element.getAttribute("placeholder");
714
+ if (placeholder) parts.push(`[placeholder="${placeholder.substring(0, 20)}"]`);
715
+ if (element.getAttribute("src")) parts.push(`[src]`);
716
+ const href = element.getAttribute("href");
717
+ if (href && href !== "#") parts.push(`[href]`);
718
+ return parts.join("");
719
+ }
720
+ function useInspector(options) {
721
+ const highlightVisible = ref(false);
722
+ const highlightStyle = ref({
723
+ top: "0px",
724
+ left: "0px",
725
+ width: "0px",
726
+ height: "0px"
727
+ });
728
+ const tooltipVisible = ref(false);
729
+ const tooltipStyle = ref({
730
+ top: "0px",
731
+ left: "0px"
732
+ });
733
+ const tooltipContent = ref({
734
+ description: "",
735
+ fileInfo: ""
736
+ });
737
+ const INSPECTOR_CHECK_INTERVAL = 500;
738
+ let inspectorCheckTimer = null;
739
+ function handleMouseMove(e) {
740
+ if (!options.selectMode.value) return;
741
+ const inspector = window.__VUE_INSPECTOR__;
742
+ if (!inspector) return;
743
+ const { targetNode, params } = inspector.getTargetNode(e);
744
+ if (targetNode && params) {
745
+ const rect = targetNode.getBoundingClientRect();
746
+ const widget = document.querySelector(".opencode-widget");
747
+ let primary = "#3b82f6";
748
+ let primaryBg = "rgba(59, 130, 246, 0.1)";
749
+ if (widget) {
750
+ const style = getComputedStyle(widget);
751
+ primary = style.getPropertyValue("--oc-primary").trim() || primary;
752
+ primaryBg = style.getPropertyValue("--oc-primary-bg").trim() || primaryBg;
753
+ }
754
+ highlightVisible.value = true;
755
+ highlightStyle.value = {
756
+ top: `${rect.top}px`,
757
+ left: `${rect.left}px`,
758
+ width: `${rect.width}px`,
759
+ height: `${rect.height}px`,
760
+ border: `2px solid ${primary}`,
761
+ background: primaryBg
762
+ };
763
+ const description = getElementDescription(targetNode);
764
+ const fileName = params.file ? params.file.split("/").pop() : "";
765
+ let lineInfo = "";
766
+ if (params.line) {
767
+ lineInfo = `:${params.line}`;
768
+ if (params.column) lineInfo += `:${params.column}`;
769
+ }
770
+ tooltipContent.value = {
771
+ description,
772
+ fileInfo: fileName ? `${fileName}${lineInfo}` : ""
773
+ };
774
+ tooltipVisible.value = true;
775
+ const tooltipHeight = 50;
776
+ const tooltipWidth = 200;
777
+ let tooltipTop = rect.top - tooltipHeight - 8;
778
+ let tooltipLeft = rect.left;
779
+ if (tooltipTop < 10) tooltipTop = rect.bottom + 8;
780
+ if (tooltipLeft + tooltipWidth > window.innerWidth - 10) tooltipLeft = window.innerWidth - tooltipWidth - 10;
781
+ tooltipStyle.value = {
782
+ top: `${tooltipTop}px`,
783
+ left: `${tooltipLeft}px`
784
+ };
785
+ } else {
786
+ highlightVisible.value = false;
787
+ tooltipVisible.value = false;
788
+ }
789
+ }
790
+ function setupInspectorHook() {
791
+ const inspector = window.__VUE_INSPECTOR__;
792
+ if (!inspector || inspector.__opencode_hooked) return;
793
+ const originalHandleClick = inspector.handleClick.bind(inspector);
794
+ inspector.handleClick = function(e) {
795
+ var _a, _b, _c;
796
+ if (options.selectMode.value) {
797
+ const { targetNode, params } = inspector.getTargetNode(e);
798
+ if (targetNode && params) {
799
+ const innerText = getDirectText(targetNode);
800
+ const description = getElementDescription(targetNode);
801
+ const elementInfo = {
802
+ filePath: (_a = params.file) != null ? _a : null,
803
+ line: (_b = params.line) != null ? _b : null,
804
+ column: (_c = params.column) != null ? _c : null,
805
+ innerText: truncate(innerText, 200),
806
+ description
807
+ };
808
+ options.onAddSelectedNode(elementInfo);
809
+ }
810
+ return;
811
+ }
812
+ return originalHandleClick.call(inspector, e);
813
+ };
814
+ inspector.__opencode_hooked = true;
815
+ }
816
+ function handleKeydown(e) {
817
+ if (e.key === "Escape" && options.selectMode.value) {
818
+ e.preventDefault();
819
+ e.stopPropagation();
820
+ options.onExitSelectMode();
821
+ }
822
+ }
823
+ watch(options.selectMode, (newVal) => {
824
+ const inspector = window.__VUE_INSPECTOR__;
825
+ if (newVal) {
826
+ if (inspector) inspector.enable();
827
+ document.addEventListener("mousemove", handleMouseMove);
828
+ document.addEventListener("keydown", handleKeydown, true);
829
+ } else {
830
+ if (inspector) inspector.disable();
831
+ document.removeEventListener("mousemove", handleMouseMove);
832
+ document.removeEventListener("keydown", handleKeydown, true);
833
+ highlightVisible.value = false;
834
+ tooltipVisible.value = false;
835
+ }
836
+ });
837
+ onMounted(() => {
838
+ if (window.__VUE_INSPECTOR__) setupInspectorHook();
839
+ else inspectorCheckTimer = window.setInterval(() => {
840
+ if (window.__VUE_INSPECTOR__) {
841
+ setupInspectorHook();
842
+ if (inspectorCheckTimer) {
843
+ window.clearInterval(inspectorCheckTimer);
844
+ inspectorCheckTimer = null;
845
+ }
846
+ }
847
+ }, INSPECTOR_CHECK_INTERVAL);
848
+ });
849
+ onUnmounted(() => {
850
+ if (inspectorCheckTimer) window.clearInterval(inspectorCheckTimer);
851
+ document.removeEventListener("mousemove", handleMouseMove);
852
+ document.removeEventListener("keydown", handleKeydown, true);
853
+ });
854
+ return {
855
+ highlightVisible,
856
+ highlightStyle,
857
+ tooltipVisible,
858
+ tooltipStyle,
859
+ tooltipContent
860
+ };
861
+ }
862
+ //#endregion
863
+ //#region es/open-code-widget/src/index.vue.js
864
+ var __defProp = Object.defineProperty;
865
+ var __defProps = Object.defineProperties;
866
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
867
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
868
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
869
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
870
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, {
871
+ enumerable: true,
872
+ configurable: true,
873
+ writable: true,
874
+ value
875
+ }) : obj[key] = value;
876
+ var __spreadValues = (a, b) => {
877
+ for (var prop in b || (b = {})) if (__hasOwnProp.call(b, prop)) __defNormalProp(a, prop, b[prop]);
878
+ if (__getOwnPropSymbols) {
879
+ for (var prop of __getOwnPropSymbols(b)) if (__propIsEnum.call(b, prop)) __defNormalProp(a, prop, b[prop]);
880
+ }
881
+ return a;
882
+ };
883
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
884
+ var __vue_sfc__ = /* @__PURE__ */ defineComponent(__spreadProps(__spreadValues({}, { name: "OpencodeWidget" }), {
885
+ __name: "index",
886
+ props: {
887
+ position: {
888
+ type: String,
889
+ required: false,
890
+ default: "bottom-right"
891
+ },
892
+ open: {
893
+ type: Boolean,
894
+ required: false,
895
+ default: false
896
+ },
897
+ theme: {
898
+ type: String,
899
+ required: false,
900
+ default: "light"
901
+ },
902
+ title: {
903
+ type: String,
904
+ required: false,
905
+ default: "AI 助手"
906
+ },
907
+ hotkeyLabel: {
908
+ type: String,
909
+ required: false,
910
+ default: "Ctrl+K"
911
+ },
912
+ selectShortcutLabel: {
913
+ type: String,
914
+ required: false,
915
+ default: "按 ESC 或 Ctrl+P 退出"
916
+ },
917
+ selectMode: {
918
+ type: Boolean,
919
+ required: false,
920
+ default: false
921
+ },
922
+ sessionListCollapsed: {
923
+ type: Boolean,
924
+ required: false,
925
+ default: true
926
+ },
927
+ loading: {
928
+ type: Boolean,
929
+ required: false,
930
+ default: false
931
+ },
932
+ loadingSessionList: {
933
+ type: Boolean,
934
+ required: false
935
+ },
936
+ showEmptyState: {
937
+ type: Boolean,
938
+ required: false,
939
+ default: false
940
+ },
941
+ iframeSrc: {
942
+ type: String,
943
+ required: false,
944
+ default: ""
945
+ },
946
+ sessions: {
947
+ type: Array,
948
+ required: false,
949
+ default: () => []
950
+ },
951
+ currentSessionId: {
952
+ type: [String, null],
953
+ required: false,
954
+ default: null
955
+ },
956
+ selectedElements: {
957
+ type: Array,
958
+ required: false,
959
+ default: () => []
960
+ },
961
+ showClearAll: {
962
+ type: Boolean,
963
+ required: false,
964
+ default: true
965
+ },
966
+ selectEnabled: {
967
+ type: Boolean,
968
+ required: false,
969
+ default: true
970
+ },
971
+ emptyStateText: {
972
+ type: String,
973
+ required: false,
974
+ default: "当前项目暂无会话"
975
+ },
976
+ emptyStateActionText: {
977
+ type: String,
978
+ required: false,
979
+ default: "立即创建"
980
+ }
981
+ },
982
+ emits: [
983
+ "update:open",
984
+ "update:selectMode",
985
+ "update:sessionListCollapsed",
986
+ "update:currentSessionId",
987
+ "update:selectedElements",
988
+ "toggle",
989
+ "close",
990
+ "toggle-session-list",
991
+ "toggle-select-mode",
992
+ "create-session",
993
+ "select-session",
994
+ "delete-session",
995
+ "click-selected-node",
996
+ "remove-selected-node",
997
+ "clear-selected-nodes",
998
+ "empty-action"
999
+ ],
1000
+ setup(__props, { expose: __expose, emit: __emit }) {
1001
+ const props = __props;
1002
+ const emit = __emit;
1003
+ const slots = useSlots();
1004
+ const notificationMessage = ref("");
1005
+ const notificationVisible = ref(false);
1006
+ let notificationTimer = null;
1007
+ const showNotification = (message, duration = 3e3) => {
1008
+ notificationMessage.value = message;
1009
+ notificationVisible.value = true;
1010
+ if (notificationTimer) clearTimeout(notificationTimer);
1011
+ notificationTimer = setTimeout(() => {
1012
+ notificationVisible.value = false;
1013
+ }, duration);
1014
+ };
1015
+ const dialogVisible = ref(false);
1016
+ const dialogMessage = ref("");
1017
+ let dialogResolve = null;
1018
+ const showConfirmDialog = (message) => {
1019
+ dialogMessage.value = message;
1020
+ dialogVisible.value = true;
1021
+ return new Promise((resolve) => {
1022
+ dialogResolve = resolve;
1023
+ });
1024
+ };
1025
+ const handleDialogConfirm = () => {
1026
+ dialogVisible.value = false;
1027
+ if (dialogResolve) dialogResolve(true);
1028
+ };
1029
+ const handleDialogCancel = () => {
1030
+ dialogVisible.value = false;
1031
+ if (dialogResolve) dialogResolve(false);
1032
+ };
1033
+ __expose({
1034
+ showNotification,
1035
+ showConfirmDialog
1036
+ });
1037
+ const localSessionListCollapsed = ref(props.sessionListCollapsed);
1038
+ watch(() => props.sessionListCollapsed, (val) => {
1039
+ localSessionListCollapsed.value = val;
1040
+ });
1041
+ const { buttonActive, containerClasses, iframeSource, sessionListTitle, handleClose, handleEmptyAction, handleToggle, handleToggleSessionList } = useWidget({
1042
+ position: toRef(props, "position"),
1043
+ theme: toRef(props, "theme"),
1044
+ open: toRef(props, "open"),
1045
+ selectMode: toRef(props, "selectMode"),
1046
+ iframeSrc: toRef(props, "iframeSrc"),
1047
+ sessionListCollapsed: localSessionListCollapsed,
1048
+ onToggle: (nextOpen) => {
1049
+ emit("update:open", nextOpen);
1050
+ emit("toggle", nextOpen);
1051
+ },
1052
+ onToggleSelectMode: (mode) => {
1053
+ emit("update:selectMode", mode);
1054
+ emit("toggle-select-mode", mode);
1055
+ },
1056
+ onClose: () => {
1057
+ emit("update:open", false);
1058
+ emit("close");
1059
+ },
1060
+ onToggleSessionList: (collapsed) => {
1061
+ localSessionListCollapsed.value = collapsed;
1062
+ emit("update:sessionListCollapsed", collapsed);
1063
+ emit("toggle-session-list", collapsed);
1064
+ },
1065
+ onEmptyAction: () => {
1066
+ emit("empty-action");
1067
+ }
1068
+ });
1069
+ const { sessionItems, handleCreateSession, handleDeleteSession, handleSelectSession } = useSession({
1070
+ sessions: toRef(props, "sessions"),
1071
+ currentSessionId: toRef(props, "currentSessionId"),
1072
+ onCreateSession: () => emit("create-session"),
1073
+ onSelectSession: (session) => {
1074
+ emit("update:currentSessionId", session.id);
1075
+ emit("select-session", session);
1076
+ },
1077
+ onDeleteSession: (session) => emit("delete-session", session),
1078
+ showConfirmDialog
1079
+ });
1080
+ const { bubbleVisible, hasSelectedElements, selectedElementItems, handleClearSelectedNodes, handleClickSelectedNode, handleRemoveSelectedNode, handleToggleSelectMode } = useSelection({
1081
+ selectMode: toRef(props, "selectMode"),
1082
+ selectedElements: toRef(props, "selectedElements"),
1083
+ onToggleSelectMode: (mode) => {
1084
+ emit("update:selectMode", mode);
1085
+ emit("toggle-select-mode", mode);
1086
+ },
1087
+ onRemoveSelectedNode: (payload) => {
1088
+ emit("remove-selected-node", payload);
1089
+ const newElements = [...props.selectedElements];
1090
+ newElements.splice(payload.index, 1);
1091
+ emit("update:selectedElements", newElements);
1092
+ },
1093
+ onClearSelectedNodes: () => {
1094
+ emit("clear-selected-nodes");
1095
+ emit("update:selectedElements", []);
1096
+ },
1097
+ showConfirmDialog
1098
+ });
1099
+ const { highlightVisible, highlightStyle, tooltipVisible, tooltipStyle, tooltipContent } = useInspector({
1100
+ selectMode: toRef(props, "selectMode"),
1101
+ onAddSelectedNode: (element) => {
1102
+ emit("click-selected-node", element);
1103
+ },
1104
+ onExitSelectMode: () => {
1105
+ emit("update:selectMode", false);
1106
+ emit("toggle-select-mode", false);
1107
+ }
1108
+ });
1109
+ provideOpenCodeWidgetContext({
1110
+ theme: toRef(props, "theme"),
1111
+ title: toRef(props, "title"),
1112
+ hotkeyLabel: toRef(props, "hotkeyLabel"),
1113
+ selectShortcutLabel: toRef(props, "selectShortcutLabel"),
1114
+ selectMode: toRef(props, "selectMode"),
1115
+ selectEnabled: toRef(props, "selectEnabled"),
1116
+ sessionListCollapsed: localSessionListCollapsed,
1117
+ loading: toRef(props, "loading"),
1118
+ loadingSessionList: toRef(props, "loadingSessionList"),
1119
+ showEmptyState: toRef(props, "showEmptyState"),
1120
+ emptyStateText: toRef(props, "emptyStateText"),
1121
+ emptyStateActionText: toRef(props, "emptyStateActionText"),
1122
+ showClearAll: toRef(props, "showClearAll"),
1123
+ open: toRef(props, "open"),
1124
+ iframeSource,
1125
+ buttonActive,
1126
+ sessionListTitle,
1127
+ bubbleVisible,
1128
+ hasSelectedElements,
1129
+ sessionItems,
1130
+ selectedElementItems,
1131
+ handleToggle,
1132
+ handleClose,
1133
+ handleToggleSessionList,
1134
+ handleEmptyAction,
1135
+ handleCreateSession,
1136
+ handleSelectSession,
1137
+ handleDeleteSession,
1138
+ handleToggleSelectMode,
1139
+ handleClickSelectedNode,
1140
+ handleRemoveSelectedNode: (payload) => handleRemoveSelectedNode(payload.item, payload.index, payload.source),
1141
+ handleClearSelectedNodes
1142
+ });
1143
+ const __returned__ = {
1144
+ props,
1145
+ emit,
1146
+ slots,
1147
+ notificationMessage,
1148
+ notificationVisible,
1149
+ get notificationTimer() {
1150
+ return notificationTimer;
1151
+ },
1152
+ set notificationTimer(v) {
1153
+ notificationTimer = v;
1154
+ },
1155
+ showNotification,
1156
+ dialogVisible,
1157
+ dialogMessage,
1158
+ get dialogResolve() {
1159
+ return dialogResolve;
1160
+ },
1161
+ set dialogResolve(v) {
1162
+ dialogResolve = v;
1163
+ },
1164
+ showConfirmDialog,
1165
+ handleDialogConfirm,
1166
+ handleDialogCancel,
1167
+ localSessionListCollapsed,
1168
+ buttonActive,
1169
+ containerClasses,
1170
+ iframeSource,
1171
+ sessionListTitle,
1172
+ handleClose,
1173
+ handleEmptyAction,
1174
+ handleToggle,
1175
+ handleToggleSessionList,
1176
+ sessionItems,
1177
+ handleCreateSession,
1178
+ handleDeleteSession,
1179
+ handleSelectSession,
1180
+ bubbleVisible,
1181
+ hasSelectedElements,
1182
+ selectedElementItems,
1183
+ handleClearSelectedNodes,
1184
+ handleClickSelectedNode,
1185
+ handleRemoveSelectedNode,
1186
+ handleToggleSelectMode,
1187
+ highlightVisible,
1188
+ highlightStyle,
1189
+ tooltipVisible,
1190
+ tooltipStyle,
1191
+ tooltipContent,
1192
+ Frame: Frame_vue_default,
1193
+ Header: Header_vue_default,
1194
+ SelectHint: SelectHint_vue_default,
1195
+ SelectedBubbles: SelectedBubbles_vue_default,
1196
+ SelectedNodes: SelectedNodes_vue_default,
1197
+ SessionList: SessionList_vue_default,
1198
+ Trigger: Trigger_vue_default
1199
+ };
1200
+ Object.defineProperty(__returned__, "__isScriptSetup", {
1201
+ enumerable: false,
1202
+ value: true
1203
+ });
1204
+ return __returned__;
1205
+ }
1206
+ }));
1207
+ var _hoisted_1 = {
1208
+ key: 0,
1209
+ class: "opencode-notification",
1210
+ role: "alert"
1211
+ };
1212
+ var _hoisted_2 = { class: "opencode-chat-content" };
1213
+ var _hoisted_3 = { class: "opencode-tooltip-tag" };
1214
+ var _hoisted_4 = { class: "opencode-tooltip-file" };
1215
+ var _hoisted_5 = {
1216
+ key: 1,
1217
+ class: "opencode-dialog-overlay"
1218
+ };
1219
+ var _hoisted_6 = {
1220
+ class: "opencode-dialog",
1221
+ role: "alertdialog",
1222
+ "aria-modal": "true"
1223
+ };
1224
+ var _hoisted_7 = { class: "opencode-dialog-content" };
1225
+ var _hoisted_8 = { class: "opencode-dialog-message" };
1226
+ function __vue_render__(_ctx, _cache, $props, $setup, $data, $options) {
1227
+ return openBlock(), createElementBlock("div", { class: normalizeClass($setup.containerClasses) }, [
1228
+ createVNode($setup["Trigger"], null, createSlots({ _: 2 }, [$setup.slots["button-icon"] ? {
1229
+ name: "default",
1230
+ fn: withCtx(() => [renderSlot(_ctx.$slots, "button-icon")]),
1231
+ key: "0"
1232
+ } : void 0]), 1024),
1233
+ $setup.bubbleVisible ? (openBlock(), createBlock($setup["SelectedBubbles"], { key: 0 })) : createCommentVNode("v-if", true),
1234
+ withDirectives(createElementVNode("div", { class: normalizeClass(["opencode-chat", { open: $props.open }]) }, [
1235
+ createVNode($setup["Header"], null, createSlots({ _: 2 }, [
1236
+ $setup.slots["session-toggle-icon"] ? {
1237
+ name: "session-toggle-icon",
1238
+ fn: withCtx(() => [renderSlot(_ctx.$slots, "session-toggle-icon")]),
1239
+ key: "0"
1240
+ } : void 0,
1241
+ $setup.slots["select-icon"] ? {
1242
+ name: "select-icon",
1243
+ fn: withCtx(() => [renderSlot(_ctx.$slots, "select-icon")]),
1244
+ key: "1"
1245
+ } : void 0,
1246
+ $setup.slots["close-icon"] ? {
1247
+ name: "close-icon",
1248
+ fn: withCtx(() => [renderSlot(_ctx.$slots, "close-icon")]),
1249
+ key: "2"
1250
+ } : void 0
1251
+ ]), 1024),
1252
+ createCommentVNode(" Notification "),
1253
+ $setup.notificationVisible ? (openBlock(), createElementBlock("div", _hoisted_1, toDisplayString($setup.notificationMessage), 1)) : createCommentVNode("v-if", true),
1254
+ createElementVNode("div", _hoisted_2, [
1255
+ createVNode($setup["SessionList"], null, {
1256
+ empty: withCtx(() => [renderSlot(_ctx.$slots, "sessions-empty", {}, () => [_cache[0] || (_cache[0] = createElementVNode("div", { class: "opencode-session-empty" }, "暂无会话", -1))])]),
1257
+ _: 3
1258
+ }),
1259
+ createVNode($setup["Frame"], null, createSlots({ _: 2 }, [
1260
+ $setup.slots["empty-state"] ? {
1261
+ name: "empty-state",
1262
+ fn: withCtx(() => [renderSlot(_ctx.$slots, "empty-state")]),
1263
+ key: "0"
1264
+ } : void 0,
1265
+ $setup.slots.loading ? {
1266
+ name: "loading",
1267
+ fn: withCtx(() => [renderSlot(_ctx.$slots, "loading")]),
1268
+ key: "1"
1269
+ } : void 0,
1270
+ $setup.slots.content ? {
1271
+ name: "content",
1272
+ fn: withCtx(() => [renderSlot(_ctx.$slots, "content")]),
1273
+ key: "2"
1274
+ } : void 0
1275
+ ]), 1024),
1276
+ createVNode($setup["SelectedNodes"])
1277
+ ])
1278
+ ], 2), [[vShow, !$props.selectMode]]),
1279
+ createVNode($setup["SelectHint"]),
1280
+ createCommentVNode(" Inspector Highlight "),
1281
+ withDirectives(createElementVNode("div", {
1282
+ class: "opencode-element-highlight",
1283
+ style: normalizeStyle(__spreadValues({ display: $setup.highlightVisible ? "block" : "none" }, $setup.highlightStyle))
1284
+ }, null, 4), [[vShow, $setup.highlightVisible]]),
1285
+ createCommentVNode(" Inspector Tooltip "),
1286
+ withDirectives(createElementVNode("div", {
1287
+ class: "opencode-element-tooltip",
1288
+ style: normalizeStyle(__spreadValues({ display: $setup.tooltipVisible ? "block" : "none" }, $setup.tooltipStyle))
1289
+ }, [createElementVNode("div", _hoisted_3, toDisplayString($setup.tooltipContent.description), 1), createElementVNode("div", _hoisted_4, toDisplayString($setup.tooltipContent.fileInfo), 1)], 4), [[vShow, $setup.tooltipVisible]]),
1290
+ createCommentVNode(" Dialog "),
1291
+ $setup.dialogVisible ? (openBlock(), createElementBlock("div", _hoisted_5, [createElementVNode("div", _hoisted_6, [createElementVNode("div", _hoisted_7, [createElementVNode("div", _hoisted_8, toDisplayString($setup.dialogMessage), 1)]), createElementVNode("div", { class: "opencode-dialog-actions" }, [createElementVNode("button", {
1292
+ class: "opencode-dialog-btn cancel",
1293
+ onClick: $setup.handleDialogCancel
1294
+ }, "取消"), createElementVNode("button", {
1295
+ class: "opencode-dialog-btn confirm",
1296
+ onClick: $setup.handleDialogConfirm
1297
+ }, "确认")])])])) : createCommentVNode("v-if", true)
1298
+ ], 2);
1299
+ }
1300
+ __vue_sfc__.render = __vue_render__;
1301
+ //#endregion
1302
+ //#region es/open-code-widget/index.js
1303
+ var open_code_widget_default = __vue_sfc__;
1304
+ //#endregion
1305
+ //#region es/index.js
1306
+ var version = "1.0.5";
1307
+ function install(app, options) {
1308
+ [open_code_widget_default].forEach((item) => {
1309
+ if (item.install) app.use(item, options);
1310
+ else if (item.name) app.component(item.name, item);
1311
+ });
1312
+ }
1313
+ var es_default = install;
1314
+ //#endregion
1315
+ export { open_code_widget_default as OpenCodeWidget, es_default as default, install, version };