@vite-plugin-opencode-assistant/components 1.0.10 → 1.0.12

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 (35) 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-widget.d.ts +4 -0
  4. package/es/open-code-widget/composables/use-widget.js +40 -3
  5. package/es/open-code-widget/src/components/Frame.vue.js +52 -2
  6. package/es/open-code-widget/src/components/Header-sfc.css +1 -1
  7. package/es/open-code-widget/src/components/Header.vue.d.ts +4 -2
  8. package/es/open-code-widget/src/components/Header.vue.js +87 -13
  9. package/es/open-code-widget/src/components/SelectHint-sfc.css +1 -1
  10. package/es/open-code-widget/src/components/SessionList-sfc.css +1 -1
  11. package/es/open-code-widget/src/context.d.ts +2 -0
  12. package/es/open-code-widget/src/index-sfc.css +1 -1
  13. package/es/open-code-widget/src/index.vue.d.ts +5 -1
  14. package/es/open-code-widget/src/index.vue.js +12 -4
  15. package/es/open-code-widget/src/types.d.ts +2 -0
  16. package/lib/@vite-plugin-opencode-assistant/components.cjs.js +207 -53
  17. package/lib/@vite-plugin-opencode-assistant/components.es.js +208 -54
  18. package/lib/components.css +4 -4
  19. package/lib/index.d.ts +1 -1
  20. package/lib/index.js +1 -1
  21. package/lib/open-code-widget/composables/use-widget.d.ts +4 -0
  22. package/lib/open-code-widget/composables/use-widget.js +39 -2
  23. package/lib/open-code-widget/src/components/Frame.vue.js +69 -21
  24. package/lib/open-code-widget/src/components/Header-sfc.css +1 -1
  25. package/lib/open-code-widget/src/components/Header.vue.d.ts +4 -2
  26. package/lib/open-code-widget/src/components/Header.vue.js +102 -28
  27. package/lib/open-code-widget/src/components/SelectHint-sfc.css +1 -1
  28. package/lib/open-code-widget/src/components/SessionList-sfc.css +1 -1
  29. package/lib/open-code-widget/src/context.d.ts +2 -0
  30. package/lib/open-code-widget/src/index-sfc.css +1 -1
  31. package/lib/open-code-widget/src/index.vue.d.ts +5 -1
  32. package/lib/open-code-widget/src/index.vue.js +12 -4
  33. package/lib/open-code-widget/src/types.d.ts +2 -0
  34. package/lib/web-types.json +1 -1
  35. package/package.json +1 -1
package/es/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.10";
3
+ declare const version = "1.0.12";
4
4
  declare function install(app: App<any>, options?: any): void;
5
5
  export { install, version, OpenCodeWidget };
6
6
  export default install;
package/es/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import OpenCodeWidget from "./open-code-widget";
2
- const version = "1.0.10";
2
+ const version = "1.0.12";
3
3
  function install(app, options) {
4
4
  const components = [
5
5
  OpenCodeWidget
@@ -1,4 +1,5 @@
1
1
  import { type Ref } from "vue";
2
+ import type { OpenCodeWidgetTheme } from "../src/types";
2
3
  export interface UseWidgetOptions {
3
4
  position: Ref<string>;
4
5
  theme: Ref<string>;
@@ -11,14 +12,17 @@ export interface UseWidgetOptions {
11
12
  onClose: () => void;
12
13
  onToggleSessionList: (collapsed: boolean) => void;
13
14
  onEmptyAction: () => void;
15
+ onToggleTheme?: (theme: OpenCodeWidgetTheme) => void;
14
16
  }
15
17
  export declare function useWidget(options: UseWidgetOptions): {
16
18
  buttonActive: import("vue").ComputedRef<boolean>;
17
19
  containerClasses: import("vue").ComputedRef<string[]>;
18
20
  iframeSource: import("vue").ComputedRef<string>;
19
21
  sessionListTitle: import("vue").ComputedRef<"展开会话列表" | "折叠会话列表">;
22
+ resolvedTheme: import("vue").ComputedRef<"light" | "dark">;
20
23
  handleClose: () => void;
21
24
  handleEmptyAction: () => void;
22
25
  handleToggle: () => void;
23
26
  handleToggleSessionList: () => void;
27
+ handleToggleTheme: () => void;
24
28
  };
@@ -1,9 +1,37 @@
1
- import { computed } from "vue";
1
+ import { computed, ref, onMounted, onUnmounted } from "vue";
2
+ const THEME_CYCLE = ["auto", "light", "dark"];
2
3
  function useWidget(options) {
4
+ const systemTheme = ref("light");
5
+ function getSystemTheme() {
6
+ if (typeof window === "undefined") return "light";
7
+ return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
8
+ }
9
+ let mediaQuery = null;
10
+ let handleChange = null;
11
+ onMounted(() => {
12
+ if (typeof window === "undefined") return;
13
+ systemTheme.value = getSystemTheme();
14
+ mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
15
+ handleChange = (e) => {
16
+ systemTheme.value = e.matches ? "dark" : "light";
17
+ };
18
+ mediaQuery.addEventListener("change", handleChange);
19
+ });
20
+ onUnmounted(() => {
21
+ if (mediaQuery && handleChange) {
22
+ mediaQuery.removeEventListener("change", handleChange);
23
+ }
24
+ });
25
+ const resolvedTheme = computed(() => {
26
+ if (options.theme.value === "auto") {
27
+ return systemTheme.value;
28
+ }
29
+ return options.theme.value;
30
+ });
3
31
  const containerClasses = computed(() => [
4
32
  "opencode-widget",
5
33
  options.position.value,
6
- `opencode-theme-${options.theme.value}`
34
+ `opencode-theme-${resolvedTheme.value}`
7
35
  ]);
8
36
  const buttonActive = computed(() => !!(options.open.value || options.selectMode.value));
9
37
  const iframeSource = computed(() => options.iframeSrc.value || "about:blank");
@@ -28,15 +56,24 @@ function useWidget(options) {
28
56
  function handleEmptyAction() {
29
57
  options.onEmptyAction();
30
58
  }
59
+ function handleToggleTheme() {
60
+ var _a;
61
+ const currentIndex = THEME_CYCLE.indexOf(options.theme.value);
62
+ const nextIndex = (currentIndex + 1) % THEME_CYCLE.length;
63
+ const nextTheme = THEME_CYCLE[nextIndex];
64
+ (_a = options.onToggleTheme) == null ? void 0 : _a.call(options, nextTheme);
65
+ }
31
66
  return {
32
67
  buttonActive,
33
68
  containerClasses,
34
69
  iframeSource,
35
70
  sessionListTitle,
71
+ resolvedTheme,
36
72
  handleClose,
37
73
  handleEmptyAction,
38
74
  handleToggle,
39
- handleToggleSessionList
75
+ handleToggleSessionList,
76
+ handleToggleTheme
40
77
  };
41
78
  }
42
79
  export {
@@ -1,19 +1,68 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
3
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
4
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
5
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
6
+ var __spreadValues = (a, b) => {
7
+ for (var prop in b || (b = {}))
8
+ if (__hasOwnProp.call(b, prop))
9
+ __defNormalProp(a, prop, b[prop]);
10
+ if (__getOwnPropSymbols)
11
+ for (var prop of __getOwnPropSymbols(b)) {
12
+ if (__propIsEnum.call(b, prop))
13
+ __defNormalProp(a, prop, b[prop]);
14
+ }
15
+ return a;
16
+ };
1
17
  import "./Frame-sfc.css";
2
18
  import { defineComponent as _defineComponent } from "vue";
19
+ import { ref, watch, onMounted, onUnmounted } from "vue";
3
20
  import { useOpenCodeWidgetContext } from "../context";
4
21
  const __vue_sfc__ = /* @__PURE__ */ _defineComponent({
5
22
  __name: "Frame",
6
23
  setup(__props, { expose: __expose }) {
7
24
  __expose();
25
+ const iframeRef = ref(null);
8
26
  const {
9
27
  loading,
10
28
  showEmptyState,
11
29
  iframeSource: iframeSrc,
12
30
  emptyStateText,
13
31
  emptyStateActionText,
14
- handleEmptyAction
32
+ handleEmptyAction,
33
+ theme,
34
+ resolvedTheme
15
35
  } = useOpenCodeWidgetContext();
16
- const __returned__ = { loading, showEmptyState, iframeSrc, emptyStateText, emptyStateActionText, handleEmptyAction };
36
+ const iframeReady = ref(false);
37
+ function sendMessageToIframe(type, data) {
38
+ var _a;
39
+ if (!((_a = iframeRef.value) == null ? void 0 : _a.contentWindow)) return;
40
+ iframeRef.value.contentWindow.postMessage(__spreadValues({ type }, data), "*");
41
+ }
42
+ function syncIframeTheme() {
43
+ sendMessageToIframe("OPENCODE_SET_THEME", { theme: resolvedTheme.value });
44
+ }
45
+ function handleIframeMessage(event) {
46
+ var _a;
47
+ if (((_a = event.data) == null ? void 0 : _a.type) === "OPENCODE_READY") {
48
+ syncIframeTheme();
49
+ }
50
+ }
51
+ watch([theme, resolvedTheme], () => {
52
+ syncIframeTheme();
53
+ });
54
+ onMounted(() => {
55
+ if (iframeRef.value) {
56
+ iframeRef.value.addEventListener("load", () => {
57
+ iframeReady.value = true;
58
+ });
59
+ }
60
+ window.addEventListener("message", handleIframeMessage);
61
+ });
62
+ onUnmounted(() => {
63
+ window.removeEventListener("message", handleIframeMessage);
64
+ });
65
+ const __returned__ = { iframeRef, loading, showEmptyState, iframeSrc, emptyStateText, emptyStateActionText, handleEmptyAction, theme, resolvedTheme, iframeReady, sendMessageToIframe, syncIframeTheme, handleIframeMessage };
17
66
  Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
18
67
  return __returned__;
19
68
  }
@@ -105,6 +154,7 @@ function __vue_render__(_ctx, _cache, $props, $setup, $data, $options) {
105
154
  ),
106
155
  _renderSlot(_ctx.$slots, "content", {}, () => [
107
156
  _createElementVNode("iframe", {
157
+ ref: "iframeRef",
108
158
  class: "opencode-iframe",
109
159
  src: $setup.iframeSrc,
110
160
  allow: "clipboard-write; clipboard-read",
@@ -1 +1 @@
1
- .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{background:var(--oc-primary);color:#fff}
1
+ .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}
@@ -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
  'session-toggle-icon'?: (props: typeof __VLS_1) => any;
4
4
  } & {
5
5
  'select-icon'?: (props: typeof __VLS_3) => any;
6
6
  } & {
7
- 'close-icon'?: (props: typeof __VLS_5) => any;
7
+ 'theme-icon'?: (props: typeof __VLS_5) => any;
8
+ } & {
9
+ 'close-icon'?: (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>;
@@ -1,5 +1,6 @@
1
1
  import "./Header-sfc.css";
2
2
  import { defineComponent as _defineComponent } from "vue";
3
+ import { computed } from "vue";
3
4
  import { useOpenCodeWidgetContext } from "../context";
4
5
  const __vue_sfc__ = /* @__PURE__ */ _defineComponent({
5
6
  __name: "Header",
@@ -11,27 +12,77 @@ const __vue_sfc__ = /* @__PURE__ */ _defineComponent({
11
12
  sessionListCollapsed,
12
13
  selectMode,
13
14
  selectEnabled,
15
+ theme,
16
+ resolvedTheme,
14
17
  handleToggleSessionList,
15
18
  handleToggleSelectMode,
19
+ handleToggleTheme,
16
20
  handleClose
17
21
  } = useOpenCodeWidgetContext();
18
- const __returned__ = { title, sessionListTitle, sessionListCollapsed, selectMode, selectEnabled, handleToggleSessionList, handleToggleSelectMode, handleClose };
22
+ const themeIconTitle = computed(() => {
23
+ const themeLabels = {
24
+ auto: "\u81EA\u52A8",
25
+ light: "\u4EAE\u8272",
26
+ dark: "\u6697\u8272"
27
+ };
28
+ return `\u4E3B\u9898: ${themeLabels[theme.value]} (${resolvedTheme.value})`;
29
+ });
30
+ const themeIconLabel = computed(() => {
31
+ const themeLabels = {
32
+ auto: "\u81EA\u52A8\u8DDF\u968F\u7CFB\u7EDF",
33
+ light: "\u4EAE\u8272\u4E3B\u9898",
34
+ dark: "\u6697\u8272\u4E3B\u9898"
35
+ };
36
+ return `\u5207\u6362\u4E3B\u9898 - \u5F53\u524D: ${themeLabels[theme.value]}`;
37
+ });
38
+ const __returned__ = { title, sessionListTitle, sessionListCollapsed, selectMode, selectEnabled, theme, resolvedTheme, handleToggleSessionList, handleToggleSelectMode, handleToggleTheme, handleClose, themeIconTitle, themeIconLabel };
19
39
  Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
20
40
  return __returned__;
21
41
  }
22
42
  });
23
- import { renderSlot as _renderSlot, createElementVNode as _createElementVNode, normalizeClass as _normalizeClass, toDisplayString as _toDisplayString, openBlock as _openBlock, createElementBlock as _createElementBlock } from "vue";
43
+ import { renderSlot as _renderSlot, createElementVNode as _createElementVNode, openBlock as _openBlock, createElementBlock as _createElementBlock, normalizeClass as _normalizeClass, toDisplayString as _toDisplayString, createStaticVNode as _createStaticVNode } from "vue";
24
44
  const _hoisted_1 = { class: "opencode-chat-header" };
25
45
  const _hoisted_2 = { class: "opencode-chat-header-left" };
26
46
  const _hoisted_3 = ["title", "aria-label", "aria-expanded"];
27
47
  const _hoisted_4 = ["aria-pressed", "disabled"];
28
- const _hoisted_5 = { class: "opencode-chat-header-title" };
29
- const _hoisted_6 = { class: "opencode-chat-header-actions" };
48
+ const _hoisted_5 = ["title", "aria-label"];
49
+ const _hoisted_6 = {
50
+ key: 0,
51
+ viewBox: "0 0 24 24",
52
+ width: "16",
53
+ height: "16",
54
+ fill: "none",
55
+ stroke: "currentColor",
56
+ "stroke-width": "2",
57
+ "aria-hidden": "true"
58
+ };
59
+ const _hoisted_7 = {
60
+ key: 1,
61
+ viewBox: "0 0 24 24",
62
+ width: "16",
63
+ height: "16",
64
+ fill: "none",
65
+ stroke: "currentColor",
66
+ "stroke-width": "2",
67
+ "aria-hidden": "true"
68
+ };
69
+ const _hoisted_8 = {
70
+ key: 2,
71
+ viewBox: "0 0 24 24",
72
+ width: "16",
73
+ height: "16",
74
+ fill: "none",
75
+ stroke: "currentColor",
76
+ "stroke-width": "2",
77
+ "aria-hidden": "true"
78
+ };
79
+ const _hoisted_9 = { class: "opencode-chat-header-title" };
80
+ const _hoisted_10 = { class: "opencode-chat-header-actions" };
30
81
  function __vue_render__(_ctx, _cache, $props, $setup, $data, $options) {
31
82
  return _openBlock(), _createElementBlock("div", _hoisted_1, [
32
83
  _createElementVNode("div", _hoisted_2, [
33
84
  _createElementVNode("button", {
34
- class: "opencode-header-btn session-toggle",
85
+ class: _normalizeClass(["opencode-header-btn session-toggle", { active: !$setup.sessionListCollapsed }]),
35
86
  type: "button",
36
87
  title: $setup.sessionListTitle,
37
88
  "aria-label": $setup.sessionListTitle,
@@ -39,7 +90,7 @@ function __vue_render__(_ctx, _cache, $props, $setup, $data, $options) {
39
90
  onClick: _cache[0] || (_cache[0] = (...args) => $setup.handleToggleSessionList && $setup.handleToggleSessionList(...args))
40
91
  }, [
41
92
  _renderSlot(_ctx.$slots, "session-toggle-icon", {}, () => [
42
- _cache[3] || (_cache[3] = _createElementVNode(
93
+ _cache[4] || (_cache[4] = _createElementVNode(
43
94
  "svg",
44
95
  {
45
96
  viewBox: "0 0 24 24",
@@ -60,7 +111,7 @@ function __vue_render__(_ctx, _cache, $props, $setup, $data, $options) {
60
111
  /* CACHED */
61
112
  ))
62
113
  ])
63
- ], 8, _hoisted_3),
114
+ ], 10, _hoisted_3),
64
115
  _createElementVNode("button", {
65
116
  class: _normalizeClass(["opencode-header-btn select-btn", { active: $setup.selectMode }]),
66
117
  type: "button",
@@ -71,7 +122,7 @@ function __vue_render__(_ctx, _cache, $props, $setup, $data, $options) {
71
122
  onClick: _cache[1] || (_cache[1] = (...args) => $setup.handleToggleSelectMode && $setup.handleToggleSelectMode(...args))
72
123
  }, [
73
124
  _renderSlot(_ctx.$slots, "select-icon", {}, () => [
74
- _cache[4] || (_cache[4] = _createElementVNode(
125
+ _cache[5] || (_cache[5] = _createElementVNode(
75
126
  "svg",
76
127
  {
77
128
  viewBox: "0 0 1024 1024",
@@ -93,25 +144,48 @@ function __vue_render__(_ctx, _cache, $props, $setup, $data, $options) {
93
144
  /* CACHED */
94
145
  ))
95
146
  ])
96
- ], 10, _hoisted_4)
147
+ ], 10, _hoisted_4),
148
+ _createElementVNode("button", {
149
+ class: "opencode-header-btn theme-btn",
150
+ type: "button",
151
+ title: $setup.themeIconTitle,
152
+ "aria-label": $setup.themeIconLabel,
153
+ onClick: _cache[2] || (_cache[2] = (...args) => $setup.handleToggleTheme && $setup.handleToggleTheme(...args))
154
+ }, [
155
+ _renderSlot(_ctx.$slots, "theme-icon", {}, () => [
156
+ $setup.theme === "light" ? (_openBlock(), _createElementBlock("svg", _hoisted_6, [..._cache[6] || (_cache[6] = [
157
+ _createStaticVNode('<circle cx="12" cy="12" r="5"></circle><line x1="12" y1="1" x2="12" y2="3"></line><line x1="12" y1="21" x2="12" y2="23"></line><line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line><line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line><line x1="1" y1="12" x2="3" y2="12"></line><line x1="21" y1="12" x2="23" y2="12"></line><line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line><line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line>', 9)
158
+ ])])) : $setup.theme === "dark" ? (_openBlock(), _createElementBlock("svg", _hoisted_7, [..._cache[7] || (_cache[7] = [
159
+ _createElementVNode(
160
+ "path",
161
+ { d: "M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" },
162
+ null,
163
+ -1
164
+ /* CACHED */
165
+ )
166
+ ])])) : (_openBlock(), _createElementBlock("svg", _hoisted_8, [..._cache[8] || (_cache[8] = [
167
+ _createStaticVNode('<rect x="2" y="3" width="20" height="14" rx="2" ry="2"></rect><line x1="8" y1="21" x2="16" y2="21"></line><line x1="12" y1="17" x2="12" y2="21"></line><circle cx="12" cy="10" r="3"></circle><path d="M7 7l2 2M17 7l-2 2M7 13l2-2M17 13l-2-2"></path>', 5)
168
+ ])]))
169
+ ])
170
+ ], 8, _hoisted_5)
97
171
  ]),
98
172
  _createElementVNode(
99
173
  "span",
100
- _hoisted_5,
174
+ _hoisted_9,
101
175
  _toDisplayString($setup.title),
102
176
  1
103
177
  /* TEXT */
104
178
  ),
105
- _createElementVNode("div", _hoisted_6, [
179
+ _createElementVNode("div", _hoisted_10, [
106
180
  _createElementVNode("button", {
107
181
  class: "opencode-header-btn close",
108
182
  type: "button",
109
183
  title: "\u5173\u95ED",
110
184
  "aria-label": "\u5173\u95ED\u9762\u677F",
111
- onClick: _cache[2] || (_cache[2] = (...args) => $setup.handleClose && $setup.handleClose(...args))
185
+ onClick: _cache[3] || (_cache[3] = (...args) => $setup.handleClose && $setup.handleClose(...args))
112
186
  }, [
113
187
  _renderSlot(_ctx.$slots, "close-icon", {}, () => [
114
- _cache[5] || (_cache[5] = _createElementVNode(
188
+ _cache[9] || (_cache[9] = _createElementVNode(
115
189
  "svg",
116
190
  {
117
191
  viewBox: "0 0 24 24",
@@ -1 +1 @@
1
- .opencode-select-mode-hint{position:fixed;top:20px;left:50%;transform:translate(-50%);padding:10px 16px;background:var(--oc-danger);color:#fff;border-radius:8px;font-size:13px;box-shadow:var(--oc-shadow-danger);z-index:9999999;display:none;align-items:center;gap:12px}.opencode-select-mode-hint.visible{display:flex;animation:slideDown .3s ease}.opencode-hint-shortcut{padding:2px 6px;background:rgba(255,255,255,.2);border-radius:4px;font-size:12px}
1
+ .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)}}
@@ -1 +1 @@
1
- .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:all .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}.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}}
1
+ .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}}
@@ -2,6 +2,7 @@ import { type Ref } from "vue";
2
2
  import type { OpenCodeWidgetSessionItem, OpenCodeSelectedElementItem, OpenCodeRemoveSelectedPayload } from "./types";
3
3
  export interface OpenCodeWidgetContext {
4
4
  theme: Ref<string>;
5
+ resolvedTheme: Ref<"light" | "dark">;
5
6
  title: Ref<string>;
6
7
  hotkeyLabel: Ref<string>;
7
8
  selectShortcutLabel: Ref<string>;
@@ -26,6 +27,7 @@ export interface OpenCodeWidgetContext {
26
27
  handleToggle: () => void;
27
28
  handleClose: () => void;
28
29
  handleToggleSessionList: () => void;
30
+ handleToggleTheme: () => void;
29
31
  handleEmptyAction: () => void;
30
32
  handleCreateSession: () => void;
31
33
  handleSelectSession: (item: OpenCodeWidgetSessionItem) => void;
@@ -1 +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 20px;background:var(--oc-bg-main);color:var(--oc-text-primary);border:1px solid var(--oc-border-primary);border-radius:8px;font-size:14px;box-shadow:var(--oc-shadow-lg);animation:slideDown .3s ease;z-index:10000000}.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)}}
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)}}
@@ -26,10 +26,12 @@ declare const __VLS_component: import("vue").DefineComponent<OpenCodeWidgetProps
26
26
  "update:sessionListCollapsed": (value: boolean) => any;
27
27
  "update:currentSessionId": (value: string | null) => any;
28
28
  "update:selectedElements": (value: import("./types").OpenCodeSelectedElement[]) => any;
29
+ "update:theme": (value: import("./types").OpenCodeWidgetTheme) => any;
29
30
  toggle: (value: boolean) => any;
30
31
  close: () => any;
31
32
  "toggle-session-list": (value: boolean) => any;
32
33
  "toggle-select-mode": (value: boolean) => any;
34
+ "toggle-theme": (value: import("./types").OpenCodeWidgetTheme) => any;
33
35
  "create-session": () => any;
34
36
  "select-session": (session: import("./types").OpenCodeWidgetSession) => any;
35
37
  "delete-session": (session: import("./types").OpenCodeWidgetSession) => any;
@@ -43,10 +45,12 @@ declare const __VLS_component: import("vue").DefineComponent<OpenCodeWidgetProps
43
45
  "onUpdate:sessionListCollapsed"?: ((value: boolean) => any) | undefined;
44
46
  "onUpdate:currentSessionId"?: ((value: string | null) => any) | undefined;
45
47
  "onUpdate:selectedElements"?: ((value: import("./types").OpenCodeSelectedElement[]) => any) | undefined;
48
+ "onUpdate:theme"?: ((value: import("./types").OpenCodeWidgetTheme) => any) | undefined;
46
49
  onToggle?: ((value: boolean) => any) | undefined;
47
50
  onClose?: (() => any) | undefined;
48
51
  "onToggle-session-list"?: ((value: boolean) => any) | undefined;
49
52
  "onToggle-select-mode"?: ((value: boolean) => any) | undefined;
53
+ "onToggle-theme"?: ((value: import("./types").OpenCodeWidgetTheme) => any) | undefined;
50
54
  "onCreate-session"?: (() => any) | undefined;
51
55
  "onSelect-session"?: ((session: import("./types").OpenCodeWidgetSession) => any) | undefined;
52
56
  "onDelete-session"?: ((session: import("./types").OpenCodeWidgetSession) => any) | undefined;
@@ -60,6 +64,7 @@ declare const __VLS_component: import("vue").DefineComponent<OpenCodeWidgetProps
60
64
  showEmptyState: boolean;
61
65
  emptyStateText: string;
62
66
  emptyStateActionText: string;
67
+ theme: import("./types").OpenCodeWidgetTheme;
63
68
  iframeSrc: string;
64
69
  sessionListCollapsed: boolean;
65
70
  selectMode: boolean;
@@ -71,7 +76,6 @@ declare const __VLS_component: import("vue").DefineComponent<OpenCodeWidgetProps
71
76
  open: boolean;
72
77
  hotkeyLabel: string;
73
78
  position: import("./types").OpenCodeWidgetPosition;
74
- theme: import("./types").OpenCodeWidgetTheme;
75
79
  currentSessionId: string | null;
76
80
  selectedElements: import("./types").OpenCodeSelectedElement[];
77
81
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
@@ -39,7 +39,7 @@ const __vue_sfc__ = /* @__PURE__ */ _defineComponent(__spreadProps(__spreadValue
39
39
  props: {
40
40
  position: { type: String, required: false, default: "bottom-right" },
41
41
  open: { type: Boolean, required: false, default: false },
42
- theme: { type: String, required: false, default: "light" },
42
+ theme: { type: String, required: false, default: "auto" },
43
43
  title: { type: String, required: false, default: "AI \u52A9\u624B" },
44
44
  hotkeyLabel: { type: String, required: false, default: "Ctrl+K" },
45
45
  selectShortcutLabel: { type: String, required: false, default: "\u6309 ESC \u6216 Ctrl+P \u9000\u51FA" },
@@ -58,7 +58,7 @@ const __vue_sfc__ = /* @__PURE__ */ _defineComponent(__spreadProps(__spreadValue
58
58
  emptyStateText: { type: String, required: false, default: "\u5F53\u524D\u9879\u76EE\u6682\u65E0\u4F1A\u8BDD" },
59
59
  emptyStateActionText: { type: String, required: false, default: "\u7ACB\u5373\u521B\u5EFA" }
60
60
  },
61
- emits: ["update:open", "update:selectMode", "update:sessionListCollapsed", "update:currentSessionId", "update:selectedElements", "toggle", "close", "toggle-session-list", "toggle-select-mode", "create-session", "select-session", "delete-session", "click-selected-node", "remove-selected-node", "clear-selected-nodes", "empty-action"],
61
+ emits: ["update:open", "update:selectMode", "update:sessionListCollapsed", "update:currentSessionId", "update:selectedElements", "update:theme", "toggle", "close", "toggle-session-list", "toggle-select-mode", "toggle-theme", "create-session", "select-session", "delete-session", "click-selected-node", "remove-selected-node", "clear-selected-nodes", "empty-action"],
62
62
  setup(__props, { expose: __expose, emit: __emit }) {
63
63
  const props = __props;
64
64
  const emit = __emit;
@@ -108,10 +108,12 @@ const __vue_sfc__ = /* @__PURE__ */ _defineComponent(__spreadProps(__spreadValue
108
108
  containerClasses,
109
109
  iframeSource,
110
110
  sessionListTitle,
111
+ resolvedTheme,
111
112
  handleClose,
112
113
  handleEmptyAction,
113
114
  handleToggle,
114
- handleToggleSessionList
115
+ handleToggleSessionList,
116
+ handleToggleTheme
115
117
  } = useWidget({
116
118
  position: toRef(props, "position"),
117
119
  theme: toRef(props, "theme"),
@@ -138,6 +140,10 @@ const __vue_sfc__ = /* @__PURE__ */ _defineComponent(__spreadProps(__spreadValue
138
140
  },
139
141
  onEmptyAction: () => {
140
142
  emit("empty-action");
143
+ },
144
+ onToggleTheme: (newTheme) => {
145
+ emit("update:theme", newTheme);
146
+ emit("toggle-theme", newTheme);
141
147
  }
142
148
  });
143
149
  const { sessionItems, handleCreateSession, handleDeleteSession, handleSelectSession } = useSession({
@@ -190,6 +196,7 @@ const __vue_sfc__ = /* @__PURE__ */ _defineComponent(__spreadProps(__spreadValue
190
196
  });
191
197
  provideOpenCodeWidgetContext({
192
198
  theme: toRef(props, "theme"),
199
+ resolvedTheme,
193
200
  title: toRef(props, "title"),
194
201
  hotkeyLabel: toRef(props, "hotkeyLabel"),
195
202
  selectShortcutLabel: toRef(props, "selectShortcutLabel"),
@@ -214,6 +221,7 @@ const __vue_sfc__ = /* @__PURE__ */ _defineComponent(__spreadProps(__spreadValue
214
221
  handleToggle,
215
222
  handleClose,
216
223
  handleToggleSessionList,
224
+ handleToggleTheme,
217
225
  handleEmptyAction,
218
226
  handleCreateSession,
219
227
  handleSelectSession,
@@ -231,7 +239,7 @@ const __vue_sfc__ = /* @__PURE__ */ _defineComponent(__spreadProps(__spreadValue
231
239
  return dialogResolve;
232
240
  }, set dialogResolve(v) {
233
241
  dialogResolve = v;
234
- }, showConfirmDialog, handleDialogConfirm, handleDialogCancel, localSessionListCollapsed, buttonActive, containerClasses, iframeSource, sessionListTitle, handleClose, handleEmptyAction, handleToggle, handleToggleSessionList, sessionItems, handleCreateSession, handleDeleteSession, handleSelectSession, bubbleVisible, hasSelectedElements, selectedElementItems, handleClearSelectedNodes, handleClickSelectedNode, handleRemoveSelectedNode, handleToggleSelectMode, highlightVisible, highlightStyle, tooltipVisible, tooltipStyle, tooltipContent, Frame, Header, SelectHint, SelectedBubbles, SelectedNodes, SessionList, Trigger };
242
+ }, showConfirmDialog, handleDialogConfirm, handleDialogCancel, localSessionListCollapsed, buttonActive, containerClasses, iframeSource, sessionListTitle, resolvedTheme, handleClose, handleEmptyAction, handleToggle, handleToggleSessionList, handleToggleTheme, sessionItems, handleCreateSession, handleDeleteSession, handleSelectSession, bubbleVisible, hasSelectedElements, selectedElementItems, handleClearSelectedNodes, handleClickSelectedNode, handleRemoveSelectedNode, handleToggleSelectMode, highlightVisible, highlightStyle, tooltipVisible, tooltipStyle, tooltipContent, Frame, Header, SelectHint, SelectedBubbles, SelectedNodes, SessionList, Trigger };
235
243
  Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
236
244
  return __returned__;
237
245
  }
@@ -42,10 +42,12 @@ export type OpenCodeWidgetEmits = {
42
42
  (e: "update:sessionListCollapsed", value: boolean): void;
43
43
  (e: "update:currentSessionId", value: string | null): void;
44
44
  (e: "update:selectedElements", value: OpenCodeSelectedElement[]): void;
45
+ (e: "update:theme", value: OpenCodeWidgetTheme): void;
45
46
  (e: "toggle", value: boolean): void;
46
47
  (e: "close"): void;
47
48
  (e: "toggle-session-list", value: boolean): void;
48
49
  (e: "toggle-select-mode", value: boolean): void;
50
+ (e: "toggle-theme", value: OpenCodeWidgetTheme): void;
49
51
  (e: "create-session"): void;
50
52
  (e: "select-session", session: OpenCodeWidgetSession): void;
51
53
  (e: "delete-session", session: OpenCodeWidgetSession): void;