@vite-plugin-opencode-assistant/components 1.0.13 → 1.0.15

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 (31) hide show
  1. package/es/index.d.ts +1 -1
  2. package/es/index.js +1 -1
  3. package/es/open-code-widget/composables/use-inspector.js +1 -4
  4. package/es/open-code-widget/composables/use-selection.js +1 -6
  5. package/es/open-code-widget/src/components/Frame-sfc.css +1 -1
  6. package/es/open-code-widget/src/components/Frame.vue.d.ts +4 -2
  7. package/es/open-code-widget/src/components/Frame.vue.js +17 -3
  8. package/es/open-code-widget/src/components/SelectHint-sfc.css +1 -1
  9. package/es/open-code-widget/src/components/SessionList.vue.js +3 -1
  10. package/es/open-code-widget/src/context.d.ts +4 -1
  11. package/es/open-code-widget/src/index.vue.d.ts +34 -28
  12. package/es/open-code-widget/src/index.vue.js +24 -9
  13. package/es/open-code-widget/src/types.d.ts +3 -79
  14. package/lib/@vite-plugin-opencode-assistant/components.cjs.js +52 -30
  15. package/lib/@vite-plugin-opencode-assistant/components.es.js +51 -29
  16. package/lib/components.css +2 -2
  17. package/lib/index.d.ts +1 -1
  18. package/lib/index.js +1 -1
  19. package/lib/open-code-widget/composables/use-inspector.js +2 -5
  20. package/lib/open-code-widget/composables/use-selection.js +2 -7
  21. package/lib/open-code-widget/src/components/Frame-sfc.css +1 -1
  22. package/lib/open-code-widget/src/components/Frame.vue.d.ts +4 -2
  23. package/lib/open-code-widget/src/components/Frame.vue.js +17 -3
  24. package/lib/open-code-widget/src/components/SelectHint-sfc.css +1 -1
  25. package/lib/open-code-widget/src/components/SessionList.vue.js +3 -1
  26. package/lib/open-code-widget/src/context.d.ts +4 -1
  27. package/lib/open-code-widget/src/index.vue.d.ts +34 -28
  28. package/lib/open-code-widget/src/index.vue.js +24 -9
  29. package/lib/open-code-widget/src/types.d.ts +3 -79
  30. package/lib/web-types.json +1 -1
  31. package/package.json +4 -1
@@ -3,6 +3,7 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  let vue = require("vue");
6
+ let _vite_plugin_opencode_assistant_shared = require("@vite-plugin-opencode-assistant/shared");
6
7
  //#region es/open-code-widget/src/context.js
7
8
  var CONTEXT_KEY = /* @__PURE__ */ Symbol("OpenCodeWidgetContext");
8
9
  function provideOpenCodeWidgetContext(context) {
@@ -37,7 +38,7 @@ var __vue_sfc__$7 = /* @__PURE__ */ (0, vue.defineComponent)({
37
38
  setup(__props, { expose: __expose }) {
38
39
  __expose();
39
40
  const iframeRef = (0, vue.ref)(null);
40
- const { loading, showEmptyState, iframeSource: iframeSrc, emptyStateText, emptyStateActionText, handleEmptyAction, theme, resolvedTheme } = useOpenCodeWidgetContext();
41
+ const { frameLoading, showEmptyState, showError, iframeSource: iframeSrc, emptyStateText, emptyStateActionText, handleEmptyAction, handleFrameLoaded, theme, resolvedTheme } = useOpenCodeWidgetContext();
41
42
  const iframeReady = (0, vue.ref)(false);
42
43
  function sendMessageToIframe(type, data) {
43
44
  var _a;
@@ -57,6 +58,7 @@ var __vue_sfc__$7 = /* @__PURE__ */ (0, vue.defineComponent)({
57
58
  (0, vue.onMounted)(() => {
58
59
  if (iframeRef.value) iframeRef.value.addEventListener("load", () => {
59
60
  iframeReady.value = true;
61
+ handleFrameLoaded();
60
62
  });
61
63
  window.addEventListener("message", handleIframeMessage);
62
64
  });
@@ -65,12 +67,14 @@ var __vue_sfc__$7 = /* @__PURE__ */ (0, vue.defineComponent)({
65
67
  });
66
68
  const __returned__ = {
67
69
  iframeRef,
68
- loading,
70
+ frameLoading,
69
71
  showEmptyState,
72
+ showError,
70
73
  iframeSrc,
71
74
  emptyStateText,
72
75
  emptyStateActionText,
73
76
  handleEmptyAction,
77
+ handleFrameLoaded,
74
78
  theme,
75
79
  resolvedTheme,
76
80
  iframeReady,
@@ -111,7 +115,8 @@ function __vue_render__$7(_ctx, _cache, $props, $setup, $data, $options) {
111
115
  onClick: _cache[0] || (_cache[0] = (...args) => $setup.handleEmptyAction && $setup.handleEmptyAction(...args))
112
116
  }, (0, vue.toDisplayString)($setup.emptyStateActionText), 1)
113
117
  ])], 2),
114
- (0, vue.createElementVNode)("div", { class: (0, vue.normalizeClass)(["opencode-loading-overlay", { visible: $setup.loading }]) }, [(0, vue.renderSlot)(_ctx.$slots, "loading", {}, () => [_cache[2] || (_cache[2] = (0, vue.createElementVNode)("div", { class: "opencode-loading-spinner" }, null, -1)), _cache[3] || (_cache[3] = (0, vue.createElementVNode)("div", { class: "opencode-loading-text" }, "加载中...", -1))])], 2),
118
+ (0, vue.createElementVNode)("div", { class: (0, vue.normalizeClass)(["opencode-loading-overlay", { visible: $setup.frameLoading }]) }, [(0, vue.renderSlot)(_ctx.$slots, "loading", {}, () => [_cache[2] || (_cache[2] = (0, vue.createElementVNode)("div", { class: "opencode-loading-spinner" }, null, -1)), _cache[3] || (_cache[3] = (0, vue.createElementVNode)("div", { class: "opencode-loading-text" }, "加载中...", -1))])], 2),
119
+ (0, vue.createElementVNode)("div", { class: (0, vue.normalizeClass)(["opencode-error-overlay", { visible: $setup.showError }]) }, [(0, vue.renderSlot)(_ctx.$slots, "error")], 2),
115
120
  (0, vue.renderSlot)(_ctx.$slots, "content", {}, () => [(0, vue.createElementVNode)("iframe", {
116
121
  ref: "iframeRef",
117
122
  class: "opencode-iframe",
@@ -427,7 +432,7 @@ var __vue_sfc__$2 = /* @__PURE__ */ (0, vue.defineComponent)({
427
432
  __name: "SessionList",
428
433
  setup(__props, { expose: __expose }) {
429
434
  __expose();
430
- const { sessionListCollapsed: collapsed, sessionItems: sessions, loadingSessionList, handleCreateSession, handleSelectSession, handleDeleteSession, sessionKey } = useOpenCodeWidgetContext();
435
+ const { sessionListCollapsed: collapsed, sessionItems: sessions, loadingSessionList, showSessionListSkeleton, handleCreateSession, handleSelectSession, handleDeleteSession, sessionKey } = useOpenCodeWidgetContext();
431
436
  const isAnimating = (0, vue.ref)(false);
432
437
  let animTimer = null;
433
438
  (0, vue.watch)(collapsed, () => {
@@ -441,6 +446,7 @@ var __vue_sfc__$2 = /* @__PURE__ */ (0, vue.defineComponent)({
441
446
  collapsed,
442
447
  sessions,
443
448
  loadingSessionList,
449
+ showSessionListSkeleton,
444
450
  handleCreateSession,
445
451
  handleSelectSession,
446
452
  handleDeleteSession,
@@ -454,6 +460,7 @@ var __vue_sfc__$2 = /* @__PURE__ */ (0, vue.defineComponent)({
454
460
  },
455
461
  showSkeleton: (0, vue.computed)(() => {
456
462
  if (isAnimating.value) return true;
463
+ if (showSessionListSkeleton.value) return true;
457
464
  return false;
458
465
  })
459
466
  };
@@ -601,10 +608,6 @@ var __async$1 = (__this, __arguments, generator) => {
601
608
  step((generator = generator.apply(__this, __arguments)).next());
602
609
  });
603
610
  };
604
- function truncate$1(value, maxLength) {
605
- if (value.length <= maxLength) return value;
606
- return `${value.slice(0, maxLength)}...`;
607
- }
608
611
  function getElementKey(element, index) {
609
612
  var _a;
610
613
  if (element.filePath && element.line) return `${element.filePath}:${element.line}:${(_a = element.column) != null ? _a : 0}`;
@@ -618,7 +621,7 @@ function getPanelFileText(element) {
618
621
  var _a, _b;
619
622
  const fileName = ((_a = element.filePath) == null ? void 0 : _a.split("/").pop()) || "未知文件";
620
623
  const lineInfo = element.line ? `:${element.line}${element.column ? `:${element.column}` : ""}` : "";
621
- return `${((_b = element.innerText) == null ? void 0 : _b.trim()) ? `${truncate$1(element.innerText.trim(), 30)} \xB7 ` : ""}${fileName}${lineInfo}`;
624
+ return `${((_b = element.innerText) == null ? void 0 : _b.trim()) ? `${(0, _vite_plugin_opencode_assistant_shared.truncate)(element.innerText.trim(), 30)} \xB7 ` : ""}${fileName}${lineInfo}`;
622
625
  }
623
626
  function useSelection(options) {
624
627
  const bubbleVisible = (0, vue.computed)(() => options.selectMode.value);
@@ -838,10 +841,6 @@ function useWidget(options) {
838
841
  }
839
842
  //#endregion
840
843
  //#region es/open-code-widget/composables/use-inspector.js
841
- function truncate(str, maxLength) {
842
- if (!str) return "";
843
- return str.length > maxLength ? str.substring(0, maxLength) + "..." : str;
844
- }
845
844
  function getDirectText(element) {
846
845
  let text = "";
847
846
  for (let i = 0; i < element.childNodes.length; i++) {
@@ -980,7 +979,7 @@ function useInspector(options) {
980
979
  filePath: (_a = params.file) != null ? _a : null,
981
980
  line: (_b = params.line) != null ? _b : null,
982
981
  column: (_c = params.column) != null ? _c : null,
983
- innerText: truncate(innerText, 200),
982
+ innerText: (0, _vite_plugin_opencode_assistant_shared.truncate)(innerText, 200),
984
983
  description
985
984
  };
986
985
  options.onAddSelectedNode(elementInfo);
@@ -1107,7 +1106,7 @@ var __vue_sfc__ = /* @__PURE__ */ (0, vue.defineComponent)(__spreadProps(__sprea
1107
1106
  required: false,
1108
1107
  default: "id"
1109
1108
  },
1110
- loading: {
1109
+ frameLoading: {
1111
1110
  type: Boolean,
1112
1111
  required: false,
1113
1112
  default: false
@@ -1116,11 +1115,31 @@ var __vue_sfc__ = /* @__PURE__ */ (0, vue.defineComponent)(__spreadProps(__sprea
1116
1115
  type: Boolean,
1117
1116
  required: false
1118
1117
  },
1118
+ showSessionListSkeleton: {
1119
+ type: Boolean,
1120
+ required: false,
1121
+ default: false
1122
+ },
1119
1123
  showEmptyState: {
1120
1124
  type: Boolean,
1121
1125
  required: false,
1122
1126
  default: false
1123
1127
  },
1128
+ showError: {
1129
+ type: Boolean,
1130
+ required: false,
1131
+ default: false
1132
+ },
1133
+ emptyStateText: {
1134
+ type: String,
1135
+ required: false,
1136
+ default: "当前项目暂无会话"
1137
+ },
1138
+ emptyStateActionText: {
1139
+ type: String,
1140
+ required: false,
1141
+ default: "立即创建"
1142
+ },
1124
1143
  iframeSrc: {
1125
1144
  type: String,
1126
1145
  required: false,
@@ -1150,16 +1169,6 @@ var __vue_sfc__ = /* @__PURE__ */ (0, vue.defineComponent)(__spreadProps(__sprea
1150
1169
  type: Boolean,
1151
1170
  required: false,
1152
1171
  default: true
1153
- },
1154
- emptyStateText: {
1155
- type: String,
1156
- required: false,
1157
- default: "当前项目暂无会话"
1158
- },
1159
- emptyStateActionText: {
1160
- type: String,
1161
- required: false,
1162
- default: "立即创建"
1163
1172
  }
1164
1173
  },
1165
1174
  emits: [
@@ -1180,7 +1189,8 @@ var __vue_sfc__ = /* @__PURE__ */ (0, vue.defineComponent)(__spreadProps(__sprea
1180
1189
  "click-selected-node",
1181
1190
  "remove-selected-node",
1182
1191
  "clear-selected-nodes",
1183
- "empty-action"
1192
+ "empty-action",
1193
+ "frame-loaded"
1184
1194
  ],
1185
1195
  setup(__props, { expose: __expose, emit: __emit }) {
1186
1196
  const props = __props;
@@ -1215,6 +1225,9 @@ var __vue_sfc__ = /* @__PURE__ */ (0, vue.defineComponent)(__spreadProps(__sprea
1215
1225
  dialogVisible.value = false;
1216
1226
  if (dialogResolve) dialogResolve(false);
1217
1227
  };
1228
+ const handleFrameLoaded = () => {
1229
+ emit("frame-loaded");
1230
+ };
1218
1231
  __expose({
1219
1232
  showNotification,
1220
1233
  showConfirmDialog
@@ -1305,9 +1318,11 @@ var __vue_sfc__ = /* @__PURE__ */ (0, vue.defineComponent)(__spreadProps(__sprea
1305
1318
  selectEnabled: (0, vue.toRef)(props, "selectEnabled"),
1306
1319
  sessionListCollapsed: localSessionListCollapsed,
1307
1320
  sessionKey: (0, vue.toRef)(props, "sessionKey"),
1308
- loading: (0, vue.toRef)(props, "loading"),
1321
+ frameLoading: (0, vue.toRef)(props, "frameLoading"),
1309
1322
  loadingSessionList: (0, vue.toRef)(props, "loadingSessionList"),
1323
+ showSessionListSkeleton: (0, vue.toRef)(props, "showSessionListSkeleton"),
1310
1324
  showEmptyState: (0, vue.toRef)(props, "showEmptyState"),
1325
+ showError: (0, vue.toRef)(props, "showError"),
1311
1326
  emptyStateText: (0, vue.toRef)(props, "emptyStateText"),
1312
1327
  emptyStateActionText: (0, vue.toRef)(props, "emptyStateActionText"),
1313
1328
  showClearAll: (0, vue.toRef)(props, "showClearAll"),
@@ -1330,7 +1345,8 @@ var __vue_sfc__ = /* @__PURE__ */ (0, vue.defineComponent)(__spreadProps(__sprea
1330
1345
  handleToggleSelectMode,
1331
1346
  handleClickSelectedNode,
1332
1347
  handleRemoveSelectedNode: (payload) => handleRemoveSelectedNode(payload.item, payload.index, payload.source),
1333
- handleClearSelectedNodes
1348
+ handleClearSelectedNodes,
1349
+ handleFrameLoaded
1334
1350
  });
1335
1351
  const __returned__ = {
1336
1352
  props,
@@ -1356,6 +1372,7 @@ var __vue_sfc__ = /* @__PURE__ */ (0, vue.defineComponent)(__spreadProps(__sprea
1356
1372
  showConfirmDialog,
1357
1373
  handleDialogConfirm,
1358
1374
  handleDialogCancel,
1375
+ handleFrameLoaded,
1359
1376
  localSessionListCollapsed,
1360
1377
  buttonActive,
1361
1378
  containerClasses,
@@ -1461,10 +1478,15 @@ function __vue_render__(_ctx, _cache, $props, $setup, $data, $options) {
1461
1478
  fn: (0, vue.withCtx)(() => [(0, vue.renderSlot)(_ctx.$slots, "loading")]),
1462
1479
  key: "1"
1463
1480
  } : void 0,
1481
+ $setup.slots.error ? {
1482
+ name: "error",
1483
+ fn: (0, vue.withCtx)(() => [(0, vue.renderSlot)(_ctx.$slots, "error")]),
1484
+ key: "2"
1485
+ } : void 0,
1464
1486
  $setup.slots.content ? {
1465
1487
  name: "content",
1466
1488
  fn: (0, vue.withCtx)(() => [(0, vue.renderSlot)(_ctx.$slots, "content")]),
1467
- key: "2"
1489
+ key: "3"
1468
1490
  } : void 0
1469
1491
  ]), 1024),
1470
1492
  (0, vue.createVNode)($setup["SelectedNodes"])
@@ -1497,7 +1519,7 @@ __vue_sfc__.render = __vue_render__;
1497
1519
  var open_code_widget_default = __vue_sfc__;
1498
1520
  //#endregion
1499
1521
  //#region es/index.js
1500
- var version = "1.0.13";
1522
+ var version = "1.0.15";
1501
1523
  function install(app, options) {
1502
1524
  [open_code_widget_default].forEach((item) => {
1503
1525
  if (item.install) app.use(item, options);
@@ -1,4 +1,5 @@
1
1
  import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createSlots, createStaticVNode, createVNode, defineComponent, inject, normalizeClass, normalizeStyle, onMounted, onUnmounted, openBlock, provide, ref, renderList, renderSlot, toDisplayString, toRef, useSlots, vShow, watch, withCtx, withDirectives, withModifiers } from "vue";
2
+ import { truncate } from "@vite-plugin-opencode-assistant/shared";
2
3
  //#region es/open-code-widget/src/context.js
3
4
  var CONTEXT_KEY = /* @__PURE__ */ Symbol("OpenCodeWidgetContext");
4
5
  function provideOpenCodeWidgetContext(context) {
@@ -33,7 +34,7 @@ var __vue_sfc__$7 = /* @__PURE__ */ defineComponent({
33
34
  setup(__props, { expose: __expose }) {
34
35
  __expose();
35
36
  const iframeRef = ref(null);
36
- const { loading, showEmptyState, iframeSource: iframeSrc, emptyStateText, emptyStateActionText, handleEmptyAction, theme, resolvedTheme } = useOpenCodeWidgetContext();
37
+ const { frameLoading, showEmptyState, showError, iframeSource: iframeSrc, emptyStateText, emptyStateActionText, handleEmptyAction, handleFrameLoaded, theme, resolvedTheme } = useOpenCodeWidgetContext();
37
38
  const iframeReady = ref(false);
38
39
  function sendMessageToIframe(type, data) {
39
40
  var _a;
@@ -53,6 +54,7 @@ var __vue_sfc__$7 = /* @__PURE__ */ defineComponent({
53
54
  onMounted(() => {
54
55
  if (iframeRef.value) iframeRef.value.addEventListener("load", () => {
55
56
  iframeReady.value = true;
57
+ handleFrameLoaded();
56
58
  });
57
59
  window.addEventListener("message", handleIframeMessage);
58
60
  });
@@ -61,12 +63,14 @@ var __vue_sfc__$7 = /* @__PURE__ */ defineComponent({
61
63
  });
62
64
  const __returned__ = {
63
65
  iframeRef,
64
- loading,
66
+ frameLoading,
65
67
  showEmptyState,
68
+ showError,
66
69
  iframeSrc,
67
70
  emptyStateText,
68
71
  emptyStateActionText,
69
72
  handleEmptyAction,
73
+ handleFrameLoaded,
70
74
  theme,
71
75
  resolvedTheme,
72
76
  iframeReady,
@@ -107,7 +111,8 @@ function __vue_render__$7(_ctx, _cache, $props, $setup, $data, $options) {
107
111
  onClick: _cache[0] || (_cache[0] = (...args) => $setup.handleEmptyAction && $setup.handleEmptyAction(...args))
108
112
  }, toDisplayString($setup.emptyStateActionText), 1)
109
113
  ])], 2),
110
- 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),
114
+ createElementVNode("div", { class: normalizeClass(["opencode-loading-overlay", { visible: $setup.frameLoading }]) }, [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),
115
+ createElementVNode("div", { class: normalizeClass(["opencode-error-overlay", { visible: $setup.showError }]) }, [renderSlot(_ctx.$slots, "error")], 2),
111
116
  renderSlot(_ctx.$slots, "content", {}, () => [createElementVNode("iframe", {
112
117
  ref: "iframeRef",
113
118
  class: "opencode-iframe",
@@ -423,7 +428,7 @@ var __vue_sfc__$2 = /* @__PURE__ */ defineComponent({
423
428
  __name: "SessionList",
424
429
  setup(__props, { expose: __expose }) {
425
430
  __expose();
426
- const { sessionListCollapsed: collapsed, sessionItems: sessions, loadingSessionList, handleCreateSession, handleSelectSession, handleDeleteSession, sessionKey } = useOpenCodeWidgetContext();
431
+ const { sessionListCollapsed: collapsed, sessionItems: sessions, loadingSessionList, showSessionListSkeleton, handleCreateSession, handleSelectSession, handleDeleteSession, sessionKey } = useOpenCodeWidgetContext();
427
432
  const isAnimating = ref(false);
428
433
  let animTimer = null;
429
434
  watch(collapsed, () => {
@@ -437,6 +442,7 @@ var __vue_sfc__$2 = /* @__PURE__ */ defineComponent({
437
442
  collapsed,
438
443
  sessions,
439
444
  loadingSessionList,
445
+ showSessionListSkeleton,
440
446
  handleCreateSession,
441
447
  handleSelectSession,
442
448
  handleDeleteSession,
@@ -450,6 +456,7 @@ var __vue_sfc__$2 = /* @__PURE__ */ defineComponent({
450
456
  },
451
457
  showSkeleton: computed(() => {
452
458
  if (isAnimating.value) return true;
459
+ if (showSessionListSkeleton.value) return true;
453
460
  return false;
454
461
  })
455
462
  };
@@ -597,10 +604,6 @@ var __async$1 = (__this, __arguments, generator) => {
597
604
  step((generator = generator.apply(__this, __arguments)).next());
598
605
  });
599
606
  };
600
- function truncate$1(value, maxLength) {
601
- if (value.length <= maxLength) return value;
602
- return `${value.slice(0, maxLength)}...`;
603
- }
604
607
  function getElementKey(element, index) {
605
608
  var _a;
606
609
  if (element.filePath && element.line) return `${element.filePath}:${element.line}:${(_a = element.column) != null ? _a : 0}`;
@@ -614,7 +617,7 @@ function getPanelFileText(element) {
614
617
  var _a, _b;
615
618
  const fileName = ((_a = element.filePath) == null ? void 0 : _a.split("/").pop()) || "未知文件";
616
619
  const lineInfo = element.line ? `:${element.line}${element.column ? `:${element.column}` : ""}` : "";
617
- return `${((_b = element.innerText) == null ? void 0 : _b.trim()) ? `${truncate$1(element.innerText.trim(), 30)} \xB7 ` : ""}${fileName}${lineInfo}`;
620
+ return `${((_b = element.innerText) == null ? void 0 : _b.trim()) ? `${truncate(element.innerText.trim(), 30)} \xB7 ` : ""}${fileName}${lineInfo}`;
618
621
  }
619
622
  function useSelection(options) {
620
623
  const bubbleVisible = computed(() => options.selectMode.value);
@@ -834,10 +837,6 @@ function useWidget(options) {
834
837
  }
835
838
  //#endregion
836
839
  //#region es/open-code-widget/composables/use-inspector.js
837
- function truncate(str, maxLength) {
838
- if (!str) return "";
839
- return str.length > maxLength ? str.substring(0, maxLength) + "..." : str;
840
- }
841
840
  function getDirectText(element) {
842
841
  let text = "";
843
842
  for (let i = 0; i < element.childNodes.length; i++) {
@@ -1103,7 +1102,7 @@ var __vue_sfc__ = /* @__PURE__ */ defineComponent(__spreadProps(__spreadValues({
1103
1102
  required: false,
1104
1103
  default: "id"
1105
1104
  },
1106
- loading: {
1105
+ frameLoading: {
1107
1106
  type: Boolean,
1108
1107
  required: false,
1109
1108
  default: false
@@ -1112,11 +1111,31 @@ var __vue_sfc__ = /* @__PURE__ */ defineComponent(__spreadProps(__spreadValues({
1112
1111
  type: Boolean,
1113
1112
  required: false
1114
1113
  },
1114
+ showSessionListSkeleton: {
1115
+ type: Boolean,
1116
+ required: false,
1117
+ default: false
1118
+ },
1115
1119
  showEmptyState: {
1116
1120
  type: Boolean,
1117
1121
  required: false,
1118
1122
  default: false
1119
1123
  },
1124
+ showError: {
1125
+ type: Boolean,
1126
+ required: false,
1127
+ default: false
1128
+ },
1129
+ emptyStateText: {
1130
+ type: String,
1131
+ required: false,
1132
+ default: "当前项目暂无会话"
1133
+ },
1134
+ emptyStateActionText: {
1135
+ type: String,
1136
+ required: false,
1137
+ default: "立即创建"
1138
+ },
1120
1139
  iframeSrc: {
1121
1140
  type: String,
1122
1141
  required: false,
@@ -1146,16 +1165,6 @@ var __vue_sfc__ = /* @__PURE__ */ defineComponent(__spreadProps(__spreadValues({
1146
1165
  type: Boolean,
1147
1166
  required: false,
1148
1167
  default: true
1149
- },
1150
- emptyStateText: {
1151
- type: String,
1152
- required: false,
1153
- default: "当前项目暂无会话"
1154
- },
1155
- emptyStateActionText: {
1156
- type: String,
1157
- required: false,
1158
- default: "立即创建"
1159
1168
  }
1160
1169
  },
1161
1170
  emits: [
@@ -1176,7 +1185,8 @@ var __vue_sfc__ = /* @__PURE__ */ defineComponent(__spreadProps(__spreadValues({
1176
1185
  "click-selected-node",
1177
1186
  "remove-selected-node",
1178
1187
  "clear-selected-nodes",
1179
- "empty-action"
1188
+ "empty-action",
1189
+ "frame-loaded"
1180
1190
  ],
1181
1191
  setup(__props, { expose: __expose, emit: __emit }) {
1182
1192
  const props = __props;
@@ -1211,6 +1221,9 @@ var __vue_sfc__ = /* @__PURE__ */ defineComponent(__spreadProps(__spreadValues({
1211
1221
  dialogVisible.value = false;
1212
1222
  if (dialogResolve) dialogResolve(false);
1213
1223
  };
1224
+ const handleFrameLoaded = () => {
1225
+ emit("frame-loaded");
1226
+ };
1214
1227
  __expose({
1215
1228
  showNotification,
1216
1229
  showConfirmDialog
@@ -1301,9 +1314,11 @@ var __vue_sfc__ = /* @__PURE__ */ defineComponent(__spreadProps(__spreadValues({
1301
1314
  selectEnabled: toRef(props, "selectEnabled"),
1302
1315
  sessionListCollapsed: localSessionListCollapsed,
1303
1316
  sessionKey: toRef(props, "sessionKey"),
1304
- loading: toRef(props, "loading"),
1317
+ frameLoading: toRef(props, "frameLoading"),
1305
1318
  loadingSessionList: toRef(props, "loadingSessionList"),
1319
+ showSessionListSkeleton: toRef(props, "showSessionListSkeleton"),
1306
1320
  showEmptyState: toRef(props, "showEmptyState"),
1321
+ showError: toRef(props, "showError"),
1307
1322
  emptyStateText: toRef(props, "emptyStateText"),
1308
1323
  emptyStateActionText: toRef(props, "emptyStateActionText"),
1309
1324
  showClearAll: toRef(props, "showClearAll"),
@@ -1326,7 +1341,8 @@ var __vue_sfc__ = /* @__PURE__ */ defineComponent(__spreadProps(__spreadValues({
1326
1341
  handleToggleSelectMode,
1327
1342
  handleClickSelectedNode,
1328
1343
  handleRemoveSelectedNode: (payload) => handleRemoveSelectedNode(payload.item, payload.index, payload.source),
1329
- handleClearSelectedNodes
1344
+ handleClearSelectedNodes,
1345
+ handleFrameLoaded
1330
1346
  });
1331
1347
  const __returned__ = {
1332
1348
  props,
@@ -1352,6 +1368,7 @@ var __vue_sfc__ = /* @__PURE__ */ defineComponent(__spreadProps(__spreadValues({
1352
1368
  showConfirmDialog,
1353
1369
  handleDialogConfirm,
1354
1370
  handleDialogCancel,
1371
+ handleFrameLoaded,
1355
1372
  localSessionListCollapsed,
1356
1373
  buttonActive,
1357
1374
  containerClasses,
@@ -1457,10 +1474,15 @@ function __vue_render__(_ctx, _cache, $props, $setup, $data, $options) {
1457
1474
  fn: withCtx(() => [renderSlot(_ctx.$slots, "loading")]),
1458
1475
  key: "1"
1459
1476
  } : void 0,
1477
+ $setup.slots.error ? {
1478
+ name: "error",
1479
+ fn: withCtx(() => [renderSlot(_ctx.$slots, "error")]),
1480
+ key: "2"
1481
+ } : void 0,
1460
1482
  $setup.slots.content ? {
1461
1483
  name: "content",
1462
1484
  fn: withCtx(() => [renderSlot(_ctx.$slots, "content")]),
1463
- key: "2"
1485
+ key: "3"
1464
1486
  } : void 0
1465
1487
  ]), 1024),
1466
1488
  createVNode($setup["SelectedNodes"])
@@ -1493,7 +1515,7 @@ __vue_sfc__.render = __vue_render__;
1493
1515
  var open_code_widget_default = __vue_sfc__;
1494
1516
  //#endregion
1495
1517
  //#region es/index.js
1496
- var version = "1.0.13";
1518
+ var version = "1.0.15";
1497
1519
  function install(app, options) {
1498
1520
  [open_code_widget_default].forEach((item) => {
1499
1521
  if (item.install) app.use(item, options);
@@ -1,7 +1,7 @@
1
1
  .opencode-widget{--oc-bg-main: #ffffff;--oc-bg-secondary: #f8f9fa;--oc-bg-tertiary: #f3f4f6;--oc-overlay-bg: rgba(255, 255, 255, .9);--oc-bg-inverse: #1e1e1e;--oc-text-primary: #282828;--oc-text-secondary: #4b5563;--oc-text-tertiary: #6b7280;--oc-text-placeholder: #9ca3af;--oc-text-inverse: #ffffff;--oc-border-primary: #e5e7eb;--oc-border-secondary: #d1d5db;--oc-primary: #3b82f6;--oc-primary-hover: #2563eb;--oc-primary-bg: rgba(59, 130, 246, .1);--oc-danger: #ef4444;--oc-danger-hover: #dc2626;--oc-danger-active: #b91c1c;--oc-success: #10b981;--oc-overlay: rgba(0, 0, 0, .5);--oc-tooltip-bg: #1e1e1e;--oc-dialog-overlay: rgba(0, 0, 0, .5);--oc-skeleton-bg: #e5e7eb;--oc-skeleton-gradient: linear-gradient(90deg, #e5e7eb 25%, #f3f4f6 50%, #e5e7eb 75%);--oc-shadow-sm: 0 2px 4px rgba(0, 0, 0, .1);--oc-shadow-md: 0 4px 12px rgba(0, 0, 0, .15);--oc-shadow-lg: 0 8px 32px rgba(0, 0, 0, .12);--oc-shadow-xl: 0 20px 60px rgba(0, 0, 0, .3);--oc-shadow-primary: 0 2px 4px rgba(59, 130, 246, .2);--oc-shadow-primary-hover: 0 4px 6px rgba(59, 130, 246, .3);--oc-shadow-danger: 0 4px 12px rgba(239, 68, 68, .3);--oc-trigger-bg: linear-gradient(135deg, #667eea 0%, #764ba2 100%);--oc-trigger-bg-hover: linear-gradient(135deg, #764ba2 0%, #667eea 100%);--oc-trigger-bg-active: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);--oc-trigger-shadow: 0 4px 15px rgba(102, 126, 234, .4);--oc-trigger-shadow-hover: 0 6px 20px rgba(102, 126, 234, .6);--oc-trigger-shadow-active: 0 6px 20px rgba(240, 147, 251, .4);position:fixed;z-index:999999;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif}.opencode-widget.opencode-theme-dark{--oc-bg-main: #1a1a1a;--oc-bg-secondary: #1e1e1e;--oc-bg-tertiary: #282828;--oc-overlay-bg: rgba(26, 26, 26, .9);--oc-bg-inverse: #ffffff;--oc-text-primary: #f3f4f6;--oc-text-secondary: #d1d5db;--oc-text-tertiary: #9ca3af;--oc-text-placeholder: #6b7280;--oc-text-inverse: #282828;--oc-border-primary: #282828;--oc-border-secondary: #4b5563;--oc-primary: #3b82f6;--oc-primary-hover: #2563eb;--oc-primary-bg: rgba(59, 130, 246, .15);--oc-danger: #ef4444;--oc-danger-hover: #dc2626;--oc-danger-active: #b91c1c;--oc-success: #10b981;--oc-overlay: rgba(26, 26, 26, .9);--oc-tooltip-bg: #282828;--oc-dialog-overlay: rgba(0, 0, 0, .7);--oc-skeleton-bg: #151515;--oc-skeleton-gradient: linear-gradient(90deg, #282828 25%, #4b5563 50%, #282828 75%);--oc-shadow-sm: 0 2px 4px rgba(0, 0, 0, .3);--oc-shadow-md: 0 4px 12px rgba(0, 0, 0, .4);--oc-shadow-lg: 0 8px 32px rgba(0, 0, 0, .4);--oc-shadow-xl: 0 20px 60px rgba(0, 0, 0, .6);--oc-shadow-primary: 0 2px 4px rgba(59, 130, 246, .3);--oc-shadow-primary-hover: 0 4px 6px rgba(59, 130, 246, .4);--oc-shadow-danger: 0 4px 12px rgba(239, 68, 68, .4);--oc-trigger-bg: linear-gradient(135deg, #667eea 0%, #764ba2 100%);--oc-trigger-bg-hover: linear-gradient(135deg, #764ba2 0%, #667eea 100%);--oc-trigger-bg-active: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);--oc-trigger-shadow: 0 4px 15px rgba(102, 126, 234, .5);--oc-trigger-shadow-hover: 0 6px 20px rgba(102, 126, 234, .7);--oc-trigger-shadow-active: 0 6px 20px rgba(240, 147, 251, .5)}.opencode-widget.bottom-right{bottom:20px;right:20px}.opencode-widget.bottom-left{bottom:20px;left:20px}.opencode-widget.top-right{top:20px;right:20px}.opencode-widget.top-left{top:20px;left:20px}.opencode-chat{position:absolute;width:700px;height:86vh;background:var(--oc-bg-main);border-radius:16px;box-shadow:var(--oc-shadow-lg);overflow:hidden;opacity:0;visibility:hidden;transform:translateY(20px) scale(.95);transition:all .3s ease;display:flex;flex-direction:column}.opencode-chat-content{display:flex;flex:1;overflow:hidden}.opencode-widget.bottom-right .opencode-chat{bottom:56px;right:0}.opencode-widget.bottom-left .opencode-chat{bottom:56px;left:0}.opencode-widget.top-right .opencode-chat{top:56px;right:0}.opencode-widget.top-left .opencode-chat{top:56px;left:0}.opencode-widget.bottom-right .opencode-selected-bubbles{bottom:56px;right:0}.opencode-widget.bottom-left .opencode-selected-bubbles{bottom:56px;left:0}.opencode-widget.top-right .opencode-selected-bubbles{top:56px;bottom:auto;right:0}.opencode-widget.top-left .opencode-selected-bubbles{top:56px;bottom:auto;left:0}.opencode-chat.open{opacity:1;visibility:visible;transform:translateY(0) scale(1)}.opencode-notification{position:absolute;top:20px;left:50%;transform:translate(-50%);padding:12px 24px;background:linear-gradient(135deg,#3b82f6,#2563eb);color:#fff;border-radius:10px;font-size:14px;font-weight:500;box-shadow:0 4px 16px rgba(59,130,246,.4),0 0 0 2px rgba(59,130,246,.2);animation:slideDown .3s ease;z-index:10000000;display:flex;align-items:center;gap:10px}.opencode-notification:before{content:"\1f4a1";font-size:16px}.opencode-dialog-overlay{position:fixed;top:0;left:0;right:0;bottom:0;background:var(--oc-dialog-overlay);display:flex;align-items:center;justify-content:center;z-index:9999999;animation:fadeIn .2s ease}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}.opencode-dialog{background:var(--oc-bg-main);border-radius:12px;padding:24px;min-width:320px;max-width:400px;box-shadow:var(--oc-shadow-xl);animation:scaleIn .2s ease}@keyframes scaleIn{0%{transform:scale(.9);opacity:0}to{transform:scale(1);opacity:1}}.opencode-dialog-content{margin-bottom:20px}.opencode-dialog-message{font-size:15px;color:var(--oc-text-primary);line-height:1.5}.opencode-dialog-actions{display:flex;gap:12px;justify-content:flex-end}.opencode-dialog-btn{padding:10px 20px;border-radius:8px;border:none;font-size:14px;font-weight:500;cursor:pointer;transition:all .2s}.opencode-dialog-btn.cancel{background:var(--oc-bg-tertiary);color:var(--oc-text-primary)}.opencode-dialog-btn.cancel:hover{background:var(--oc-text-primary);color:var(--oc-bg-main)}.opencode-dialog-btn.confirm{background:var(--oc-danger);color:#fff}.opencode-dialog-btn.confirm:hover{background:var(--oc-danger-hover)}@keyframes slideDown{0%{transform:translate(-50%) translateY(-100%);opacity:0}to{transform:translate(-50%) translateY(0);opacity:1}}.opencode-element-highlight{position:fixed;pointer-events:none;z-index:999998;display:none;transition:all .1s ease;border-radius:4px}#vue-inspector-container{display:none!important}.opencode-element-tooltip{position:fixed;background:var(--oc-tooltip-bg);color:#fff;padding:8px 12px;border-radius:6px;font-size:12px;z-index:9999998;display:none;box-shadow:var(--oc-shadow-md);max-width:300px;pointer-events:none}.opencode-tooltip-tag{font-weight:500;margin-bottom:4px;word-break:break-all}.opencode-tooltip-file{font-size:11px;color:var(--oc-text-placeholder);word-break:break-all}.opencode-element-highlight-temp{position:absolute;pointer-events:none;z-index:999998;border-radius:4px;animation:highlight-pulse 2s ease-out forwards}@keyframes highlight-pulse{0%{opacity:1;transform:scale(1)}50%{opacity:.8;transform:scale(1.02)}to{opacity:0;transform:scale(1)}}@media(max-width:768px){.opencode-chat{width:calc(100vw - 40px);height:calc(100vh - 100px)}}
2
- .opencode-iframe-container{flex:1;position:relative;overflow:hidden;display:flex;flex-direction:column;margin-top:-42px}.opencode-loading-overlay{position:absolute;top:0;left:0;right:0;bottom:0;background:var(--oc-overlay-bg);display:none;flex-direction:column;align-items:center;justify-content:center;z-index:10;transition:opacity .3s ease}.opencode-loading-overlay.visible{display:flex}.opencode-loading-spinner{width:40px;height:40px;border:3px solid var(--oc-border-primary);border-top-color:var(--oc-primary);border-radius:50%;animation:spin .8s linear infinite}@keyframes spin{to{transform:rotate(360deg)}}.opencode-loading-text{margin-top:12px;font-size:14px;color:var(--oc-text-placeholder)}.opencode-empty-state-overlay{position:absolute;top:0;left:0;right:0;bottom:0;background:var(--oc-bg-secondary);display:none;flex-direction:column;align-items:center;justify-content:center;z-index:5;transition:opacity .3s ease;margin-top:42px}.opencode-empty-state-overlay.visible{display:flex}.opencode-empty-state-icon{color:var(--oc-text-placeholder);margin-bottom:16px}.opencode-empty-state-text{color:var(--oc-text-primary);font-size:16px;font-weight:500;margin-bottom:24px}.opencode-empty-state-btn{padding:10px 24px;border-radius:8px;border:none;background:var(--oc-primary);color:#fff;font-size:14px;font-weight:500;cursor:pointer;transition:all .2s;box-shadow:var(--oc-shadow-primary)}.opencode-empty-state-btn:hover{background:var(--oc-primary-hover);transform:translateY(-1px);box-shadow:var(--oc-shadow-primary-hover)}.opencode-empty-state-btn:active{transform:translateY(0)}.opencode-iframe{width:100%;height:100%;border:none}
2
+ .opencode-iframe-container{flex:1;position:relative;overflow:hidden;display:flex;flex-direction:column;margin-top:-42px}.opencode-loading-overlay{position:absolute;top:0;left:0;right:0;bottom:0;background:var(--oc-overlay-bg);display:none;flex-direction:column;align-items:center;justify-content:center;z-index:10;transition:opacity .3s ease}.opencode-loading-overlay.visible{display:flex}.opencode-loading-spinner{width:40px;height:40px;border:3px solid var(--oc-border-primary);border-top-color:var(--oc-primary);border-radius:50%;animation:spin .8s linear infinite}@keyframes spin{to{transform:rotate(360deg)}}.opencode-loading-text{margin-top:12px;font-size:14px;color:var(--oc-text-placeholder)}.opencode-error-overlay{position:absolute;top:0;left:0;right:0;bottom:0;z-index:15;margin-top:42px;display:none}.opencode-error-overlay.visible{display:flex}.opencode-empty-state-overlay{position:absolute;top:0;left:0;right:0;bottom:0;background:var(--oc-bg-secondary);display:none;flex-direction:column;align-items:center;justify-content:center;z-index:5;transition:opacity .3s ease;margin-top:42px}.opencode-empty-state-overlay.visible{display:flex}.opencode-empty-state-icon{color:var(--oc-text-placeholder);margin-bottom:16px}.opencode-empty-state-text{color:var(--oc-text-primary);font-size:16px;font-weight:500;margin-bottom:24px}.opencode-empty-state-btn{padding:10px 24px;border-radius:8px;border:none;background:var(--oc-primary);color:#fff;font-size:14px;font-weight:500;cursor:pointer;transition:all .2s;box-shadow:var(--oc-shadow-primary)}.opencode-empty-state-btn:hover{background:var(--oc-primary-hover);transform:translateY(-1px);box-shadow:var(--oc-shadow-primary-hover)}.opencode-empty-state-btn:active{transform:translateY(0)}.opencode-iframe{width:100%;height:100%;border:none}
3
3
  .opencode-chat-header{position:relative;flex-shrink:0;display:flex;align-items:center;justify-content:space-between;padding:0 12px;height:40px;background:var(--oc-bg-secondary);border-bottom:1px solid var(--oc-border-primary);z-index:5}.opencode-chat-header-left{display:flex;align-items:center;gap:4px}.opencode-chat-header-title{font-size:14px;font-weight:600;color:var(--oc-text-primary);position:absolute;left:50%;transform:translate(-50%)}.opencode-chat-header-actions{display:flex;gap:4px}.opencode-header-btn{width:28px;height:28px;border-radius:6px;border:none;background:transparent;color:var(--oc-text-placeholder);cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all .2s}.opencode-header-btn:hover{background:var(--oc-bg-tertiary);color:var(--oc-text-primary)}.opencode-header-btn.close:hover{background:var(--oc-danger);color:#fff}.opencode-header-btn.select-btn.active,.opencode-header-btn.session-toggle.active{background:var(--oc-primary);color:#fff}
4
- .opencode-select-mode-hint{position:fixed;top:20px;left:50%;transform:translate(-50%);padding:14px 20px;background:linear-gradient(135deg,#ef4444,#dc2626);color:#fff;border-radius:12px;font-size:15px;font-weight:500;box-shadow:0 6px 20px rgba(239,68,68,.5),0 0 0 3px rgba(239,68,68,.3);z-index:9999999;display:none;align-items:center;gap:12px;border:2px solid rgba(255,255,255,.3)}.opencode-select-mode-hint.visible{display:flex;animation:slideDown .3s ease,pulseHint 2s ease-in-out infinite}.opencode-hint-shortcut{padding:4px 10px;background:rgba(255,255,255,.25);border-radius:6px;font-size:13px;font-weight:600;border:1px solid rgba(255,255,255,.4)}@keyframes pulseHint{0%,to{box-shadow:0 6px 20px rgba(239,68,68,.5),0 0 0 3px rgba(239,68,68,.3)}50%{box-shadow:0 6px 20px rgba(239,68,68,.6),0 0 0 6px rgba(239,68,68,.4)}}
4
+ .opencode-select-mode-hint{position:fixed;top:20px;left:50%;transform:translate(-50%);padding:10px;background:linear-gradient(135deg,#ef4444,#dc2626);color:#fff;border-radius:12px;font-size:14px;font-weight:500;box-shadow:0 6px 20px rgba(239,68,68,.5),0 0 0 3px rgba(239,68,68,.3);z-index:9999999;display:none;align-items:center;gap:12px;border:1px solid rgba(255,255,255,.3)}.opencode-select-mode-hint.visible{display:flex;animation:slideDown .3s ease,pulseHint 2s ease-in-out infinite}.opencode-hint-shortcut{padding:4px 10px;background:rgba(255,255,255,.25);border-radius:6px;font-size:13px;font-weight:600;border:1px solid rgba(255,255,255,.4)}@keyframes pulseHint{0%,to{box-shadow:0 6px 20px rgba(239,68,68,.5),0 0 0 3px rgba(239,68,68,.3)}50%{box-shadow:0 6px 20px rgba(239,68,68,.6),0 0 0 6px rgba(239,68,68,.4)}}
5
5
  .opencode-selected-bubbles{position:absolute;display:none;flex-direction:column;gap:6px;max-width:220px;max-height:300px;overflow-y:auto}.opencode-selected-bubbles.visible{display:flex}.opencode-selected-bubble{display:flex;flex-direction:column;gap:2px;padding:8px 24px 8px 10px;background:var(--oc-bg-main);border:1px solid var(--oc-border-primary);border-radius:8px;font-size:12px;box-shadow:var(--oc-shadow-sm);position:relative;cursor:pointer;transition:all .2s}.opencode-selected-bubble:hover{border-color:var(--oc-primary);box-shadow:var(--oc-shadow-primary)}.opencode-bubble-text{color:var(--oc-text-primary);font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.opencode-bubble-file{color:var(--oc-text-placeholder);font-size:11px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.opencode-bubble-remove{position:absolute;top:8px;right:6px;width:16px;height:16px;border-radius:50%;border:none;background:transparent;color:var(--oc-text-placeholder);cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:12px;transition:all .2s}.opencode-bubble-remove:hover{background:var(--oc-danger);color:#fff}.opencode-bubble-empty{padding:8px 12px;background:var(--oc-bg-main);border:1px dashed var(--oc-border-secondary);border-radius:8px;color:var(--oc-text-placeholder);font-size:12px;text-align:center}
6
6
  .opencode-right-toolbar{width:140px;background:var(--oc-bg-secondary);border-left:1px solid var(--oc-border-primary);display:flex;flex-direction:column;flex-shrink:0;transition:width .2s ease;overflow:hidden}.opencode-right-toolbar.collapsed{width:0;overflow:hidden}.opencode-right-toolbar.collapsed .opencode-selected-nodes-header,.opencode-right-toolbar.collapsed .opencode-selected-nodes,.opencode-right-toolbar.collapsed .opencode-clear-all-btn{display:none}.opencode-selected-nodes-header{padding:12px 8px 8px;border-bottom:1px solid var(--oc-border-primary)}.opencode-selected-nodes-title{font-size:14px;font-weight:600;color:var(--oc-text-primary);margin-bottom:4px}.opencode-selected-nodes-desc{font-size:11px;color:var(--oc-text-placeholder);line-height:1.4}.opencode-selected-nodes{flex:1;display:flex;flex-direction:column;padding:8px;gap:6px;overflow-y:auto;overflow-x:hidden}.opencode-selected-nodes:empty:before{content:"\6682\65e0\9009\4e2d\5143\7d20";color:var(--oc-text-placeholder);font-size:12px;text-align:center;padding:20px 10px}.opencode-selected-node{display:flex;align-items:center;gap:8px;padding:8px 10px;background:var(--oc-bg-main);border:1px solid var(--oc-border-primary);border-radius:6px;font-size:12px;transition:all .2s}.opencode-selected-node:hover{border-color:var(--oc-primary);box-shadow:var(--oc-shadow-primary)}.opencode-node-content{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}.opencode-node-text{color:var(--oc-text-primary);font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.opencode-node-file{color:var(--oc-text-placeholder);font-size:11px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.opencode-node-remove{width:18px;height:18px;border-radius:4px;border:none;background:transparent;color:var(--oc-text-placeholder);cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:14px;transition:all .2s;flex-shrink:0}.opencode-node-remove:hover{background:var(--oc-danger);color:#fff}.opencode-clear-all-btn{width:calc(100% - 16px);margin:8px;padding:8px 12px;border-radius:6px;border:none;background:var(--oc-danger);color:#fff;font-size:12px;font-weight:500;cursor:pointer;display:flex;align-items:center;justify-content:center;gap:4px;transition:all .2s}.opencode-clear-all-btn:hover{background:var(--oc-danger-hover);transform:scale(1.02)}
7
7
  .opencode-session-list{width:240px;background:var(--oc-bg-secondary);border-right:1px solid var(--oc-border-primary);display:flex;flex-direction:column;flex-shrink:0;transition:width .2s ease}.opencode-session-list.collapsed{width:0;overflow:hidden}.opencode-session-list.collapsed .opencode-session-list-header,.opencode-session-list.collapsed .opencode-session-list-content{display:none}.opencode-session-list-header{padding:16px;border-bottom:1px solid var(--oc-border-primary);display:flex;justify-content:space-between;align-items:center;font-weight:600;font-size:14px;color:var(--oc-text-primary)}.opencode-new-session-btn{width:28px;height:28px;border-radius:6px;border:none;background:var(--oc-primary);color:#fff;font-size:18px;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all .2s}.opencode-new-session-btn:hover{background:var(--oc-primary-hover);transform:scale(1.05)}.opencode-session-list-content{flex:1;overflow-y:auto;padding:8px;position:relative}.opencode-session-list-loading-overlay{position:absolute;top:0;left:0;right:0;bottom:0;background:var(--oc-overlay-bg);display:flex;align-items:center;justify-content:center;z-index:10;border-radius:8px}.opencode-loading-spinner.small{width:24px;height:24px;border-width:2px}.opencode-session-item{padding:12px;border-radius:8px;cursor:pointer;transition:transform .2s;margin-bottom:4px;color:var(--oc-text-primary)}.opencode-session-item:hover{background:var(--oc-bg-tertiary)}.opencode-session-item.active{background:var(--oc-primary);color:#fff;transition:none}.opencode-session-title{font-size:14px;font-weight:500;margin-bottom:4px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.opencode-session-meta{font-size:12px;opacity:.6}.opencode-session-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:4px}.opencode-session-delete-btn{width:20px;height:20px;border-radius:4px;border:none;background:transparent;color:var(--oc-text-placeholder);font-size:16px;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all .2s;opacity:0;flex-shrink:0}.opencode-session-item:hover .opencode-session-delete-btn{opacity:1}.opencode-session-delete-btn:hover{background:var(--oc-danger);color:#fff}.opencode-session-item.active .opencode-session-delete-btn{color:rgba(255,255,255,.7)}.opencode-session-item.active .opencode-session-delete-btn:hover{background:rgba(255,255,255,.2);color:#fff}.opencode-session-header-skeleton{padding:16px;border-bottom:1px solid var(--oc-border-primary);display:none;justify-content:space-between;align-items:center}.opencode-session-header-skeleton.visible{display:flex}.opencode-skeleton-header-title{height:18px;width:80px;background:var(--oc-skeleton-gradient);background-size:200% 100%;animation:skeleton-loading 1.5s ease-in-out infinite;border-radius:4px}.opencode-skeleton-header-btn{width:28px;height:28px;background:var(--oc-skeleton-gradient);background-size:200% 100%;animation:skeleton-loading 1.5s ease-in-out infinite;border-radius:6px}.opencode-session-skeleton{flex:1;overflow-y:auto;padding:8px;display:none}.opencode-session-skeleton.visible{display:block}.opencode-skeleton-item{padding:12px;border-radius:8px;margin-bottom:4px;background:var(--oc-skeleton-bg)}.opencode-skeleton-title{height:16px;background:var(--oc-skeleton-gradient);background-size:200% 100%;animation:skeleton-loading 1.5s ease-in-out infinite;border-radius:4px;margin-bottom:8px;width:70%}.opencode-skeleton-meta{height:12px;background:var(--oc-skeleton-gradient);background-size:200% 100%;animation:skeleton-loading 1.5s ease-in-out infinite;border-radius:4px;width:50%}.opencode-session-empty{padding:32px 16px;text-align:center;color:var(--oc-text-placeholder);font-size:13px}@keyframes skeleton-loading{0%{background-position:200% 0}to{background-position:-200% 0}}
package/lib/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import OpenCodeWidget from './open-code-widget';
2
2
  import type { App } from 'vue';
3
- declare const version = "1.0.13";
3
+ declare const version = "1.0.15";
4
4
  declare function install(app: App<any>, options?: any): void;
5
5
  export { install, version, OpenCodeWidget };
6
6
  export default install;
package/lib/index.js CHANGED
@@ -34,7 +34,7 @@ __export(lib_exports, {
34
34
  });
35
35
  module.exports = __toCommonJS(lib_exports);
36
36
  var import_open_code_widget = __toESM(require("./open-code-widget"));
37
- const version = "1.0.13";
37
+ const version = "1.0.15";
38
38
  function install(app, options) {
39
39
  const components = [
40
40
  import_open_code_widget.default
@@ -21,10 +21,7 @@ __export(use_inspector_exports, {
21
21
  });
22
22
  module.exports = __toCommonJS(use_inspector_exports);
23
23
  var import_vue = require("vue");
24
- function truncate(str, maxLength) {
25
- if (!str) return "";
26
- return str.length > maxLength ? str.substring(0, maxLength) + "..." : str;
27
- }
24
+ var import_shared = require("@vite-plugin-opencode-assistant/shared");
28
25
  function getDirectText(element) {
29
26
  let text = "";
30
27
  for (let i = 0; i < element.childNodes.length; i++) {
@@ -169,7 +166,7 @@ function useInspector(options) {
169
166
  filePath: (_a = params.file) != null ? _a : null,
170
167
  line: (_b = params.line) != null ? _b : null,
171
168
  column: (_c = params.column) != null ? _c : null,
172
- innerText: truncate(innerText, 200),
169
+ innerText: (0, import_shared.truncate)(innerText, 200),
173
170
  description
174
171
  };
175
172
  options.onAddSelectedNode(elementInfo);
@@ -41,12 +41,7 @@ __export(use_selection_exports, {
41
41
  });
42
42
  module.exports = __toCommonJS(use_selection_exports);
43
43
  var import_vue = require("vue");
44
- function truncate(value, maxLength) {
45
- if (value.length <= maxLength) {
46
- return value;
47
- }
48
- return `${value.slice(0, maxLength)}...`;
49
- }
44
+ var import_shared = require("@vite-plugin-opencode-assistant/shared");
50
45
  function getElementKey(element, index) {
51
46
  var _a;
52
47
  if (element.filePath && element.line) {
@@ -64,7 +59,7 @@ function getPanelFileText(element) {
64
59
  var _a, _b;
65
60
  const fileName = ((_a = element.filePath) == null ? void 0 : _a.split("/").pop()) || "\u672A\u77E5\u6587\u4EF6";
66
61
  const lineInfo = element.line ? `:${element.line}${element.column ? `:${element.column}` : ""}` : "";
67
- const textPreview = ((_b = element.innerText) == null ? void 0 : _b.trim()) ? `${truncate(element.innerText.trim(), 30)} \xB7 ` : "";
62
+ const textPreview = ((_b = element.innerText) == null ? void 0 : _b.trim()) ? `${(0, import_shared.truncate)(element.innerText.trim(), 30)} \xB7 ` : "";
68
63
  return `${textPreview}${fileName}${lineInfo}`;
69
64
  }
70
65
  function useSelection(options) {
@@ -1 +1 @@
1
- .opencode-iframe-container{flex:1;position:relative;overflow:hidden;display:flex;flex-direction:column;margin-top:-42px}.opencode-loading-overlay{position:absolute;top:0;left:0;right:0;bottom:0;background:var(--oc-overlay-bg);display:none;flex-direction:column;align-items:center;justify-content:center;z-index:10;transition:opacity .3s ease}.opencode-loading-overlay.visible{display:flex}.opencode-loading-spinner{width:40px;height:40px;border:3px solid var(--oc-border-primary);border-top-color:var(--oc-primary);border-radius:50%;animation:spin .8s linear infinite}@keyframes spin{to{transform:rotate(360deg)}}.opencode-loading-text{margin-top:12px;font-size:14px;color:var(--oc-text-placeholder)}.opencode-empty-state-overlay{position:absolute;top:0;left:0;right:0;bottom:0;background:var(--oc-bg-secondary);display:none;flex-direction:column;align-items:center;justify-content:center;z-index:5;transition:opacity .3s ease;margin-top:42px}.opencode-empty-state-overlay.visible{display:flex}.opencode-empty-state-icon{color:var(--oc-text-placeholder);margin-bottom:16px}.opencode-empty-state-text{color:var(--oc-text-primary);font-size:16px;font-weight:500;margin-bottom:24px}.opencode-empty-state-btn{padding:10px 24px;border-radius:8px;border:none;background:var(--oc-primary);color:#fff;font-size:14px;font-weight:500;cursor:pointer;transition:all .2s;box-shadow:var(--oc-shadow-primary)}.opencode-empty-state-btn:hover{background:var(--oc-primary-hover);transform:translateY(-1px);box-shadow:var(--oc-shadow-primary-hover)}.opencode-empty-state-btn:active{transform:translateY(0)}.opencode-iframe{width:100%;height:100%;border:none}
1
+ .opencode-iframe-container{flex:1;position:relative;overflow:hidden;display:flex;flex-direction:column;margin-top:-42px}.opencode-loading-overlay{position:absolute;top:0;left:0;right:0;bottom:0;background:var(--oc-overlay-bg);display:none;flex-direction:column;align-items:center;justify-content:center;z-index:10;transition:opacity .3s ease}.opencode-loading-overlay.visible{display:flex}.opencode-loading-spinner{width:40px;height:40px;border:3px solid var(--oc-border-primary);border-top-color:var(--oc-primary);border-radius:50%;animation:spin .8s linear infinite}@keyframes spin{to{transform:rotate(360deg)}}.opencode-loading-text{margin-top:12px;font-size:14px;color:var(--oc-text-placeholder)}.opencode-error-overlay{position:absolute;top:0;left:0;right:0;bottom:0;z-index:15;margin-top:42px;display:none}.opencode-error-overlay.visible{display:flex}.opencode-empty-state-overlay{position:absolute;top:0;left:0;right:0;bottom:0;background:var(--oc-bg-secondary);display:none;flex-direction:column;align-items:center;justify-content:center;z-index:5;transition:opacity .3s ease;margin-top:42px}.opencode-empty-state-overlay.visible{display:flex}.opencode-empty-state-icon{color:var(--oc-text-placeholder);margin-bottom:16px}.opencode-empty-state-text{color:var(--oc-text-primary);font-size:16px;font-weight:500;margin-bottom:24px}.opencode-empty-state-btn{padding:10px 24px;border-radius:8px;border:none;background:var(--oc-primary);color:#fff;font-size:14px;font-weight:500;cursor:pointer;transition:all .2s;box-shadow:var(--oc-shadow-primary)}.opencode-empty-state-btn:hover{background:var(--oc-primary-hover);transform:translateY(-1px);box-shadow:var(--oc-shadow-primary-hover)}.opencode-empty-state-btn:active{transform:translateY(0)}.opencode-iframe{width:100%;height:100%;border:none}
@@ -1,10 +1,12 @@
1
- declare var __VLS_1: {}, __VLS_3: {}, __VLS_5: {};
1
+ declare var __VLS_1: {}, __VLS_3: {}, __VLS_5: {}, __VLS_7: {};
2
2
  type __VLS_Slots = {} & {
3
3
  'empty-state'?: (props: typeof __VLS_1) => any;
4
4
  } & {
5
5
  loading?: (props: typeof __VLS_3) => any;
6
6
  } & {
7
- content?: (props: typeof __VLS_5) => any;
7
+ error?: (props: typeof __VLS_5) => any;
8
+ } & {
9
+ content?: (props: typeof __VLS_7) => any;
8
10
  };
9
11
  declare const __VLS_component: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
10
12
  declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;