@vite-plugin-opencode-assistant/components 1.0.24 → 1.0.26

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.
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.24";
3
+ declare const version = "1.0.26";
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.24";
2
+ const version = "1.0.26";
3
3
  function install(app, options) {
4
4
  const components = [
5
5
  OpenCodeWidget
@@ -1 +1 @@
1
- .floating-bubble{position:fixed;top:0;left:0;z-index:999999;cursor:grab;-webkit-user-select:none;-moz-user-select:none;user-select:none;touch-action:none;visibility:hidden;will-change:transform}.floating-bubble[style*=translate3d]{visibility:visible}.floating-bubble:active{cursor:grabbing}
1
+ .floating-bubble{position:fixed;top:0;left:0;z-index:999999;cursor:grab;-webkit-user-select:none;-moz-user-select:none;user-select:none;touch-action:none;will-change:transform}.floating-bubble:active{cursor:grabbing}
@@ -11,7 +11,6 @@ type __VLS_Slots = {} & {
11
11
  default?: (props: typeof __VLS_5) => any;
12
12
  };
13
13
  declare const __VLS_component: import("vue").DefineComponent<__VLS_Props, {
14
- isOnRightSide: import("vue").ComputedRef<boolean>;
15
14
  offset: import("vue").ComputedRef<{
16
15
  x: number;
17
16
  y: number;
@@ -19,7 +19,7 @@ var __spreadValues = (a, b) => {
19
19
  var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
20
20
  import "./FloatingBubble-sfc.css";
21
21
  import { defineComponent as _defineComponent } from "vue";
22
- import { ref, computed, watch, onMounted, onUnmounted, nextTick } from "vue";
22
+ import { ref, computed, watch, onMounted, onUnmounted } from "vue";
23
23
  const __vue_sfc__ = /* @__PURE__ */ _defineComponent(__spreadProps(__spreadValues({}, {
24
24
  name: "FloatingBubble"
25
25
  }), {
@@ -71,9 +71,8 @@ const __vue_sfc__ = /* @__PURE__ */ _defineComponent(__spreadProps(__spreadValue
71
71
  }
72
72
  return style;
73
73
  });
74
- const show = ref(true);
75
74
  const updateState = () => {
76
- if (!show.value || !rootRef.value || typeof window === "undefined") return;
75
+ if (!rootRef.value || typeof window === "undefined") return;
77
76
  const rect = rootRef.value.getBoundingClientRect();
78
77
  const { offset } = props;
79
78
  let x = offset ? offset.x : windowWidth.value - rect.width - gapX.value;
@@ -211,7 +210,7 @@ const __vue_sfc__ = /* @__PURE__ */ _defineComponent(__spreadProps(__spreadValue
211
210
  };
212
211
  onMounted(() => {
213
212
  updateState();
214
- nextTick(() => {
213
+ requestAnimationFrame(() => {
215
214
  initialized.value = true;
216
215
  });
217
216
  if (typeof window !== "undefined") {
@@ -238,14 +237,10 @@ const __vue_sfc__ = /* @__PURE__ */ _defineComponent(__spreadProps(__spreadValue
238
237
  updateState,
239
238
  { deep: true }
240
239
  );
241
- const isOnRightSide = computed(() => {
242
- return state.value.x > windowWidth.value / 2;
243
- });
244
240
  __expose({
245
- isOnRightSide,
246
241
  offset: computed(() => ({ x: state.value.x, y: state.value.y }))
247
242
  });
248
- const __returned__ = { props, emit, rootRef, state, isObject, gapX, gapY, windowWidth, windowHeight, boundary, dragging, initialized, rootStyle, show, updateState, touch, get prevX() {
243
+ const __returned__ = { props, emit, rootRef, state, isObject, gapX, gapY, windowWidth, windowHeight, boundary, dragging, initialized, rootStyle, updateState, touch, get prevX() {
249
244
  return prevX;
250
245
  }, set prevX(v) {
251
246
  prevX = v;
@@ -253,15 +248,15 @@ const __vue_sfc__ = /* @__PURE__ */ _defineComponent(__spreadProps(__spreadValue
253
248
  return prevY;
254
249
  }, set prevY(v) {
255
250
  prevY = v;
256
- }, onTouchStart, onTouchMove, closest, onTouchEnd, onClick, handleResize, isOnRightSide };
251
+ }, onTouchStart, onTouchMove, closest, onTouchEnd, onClick, handleResize };
257
252
  Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
258
253
  return __returned__;
259
254
  }
260
255
  }));
261
- import { renderSlot as _renderSlot, vShow as _vShow, normalizeStyle as _normalizeStyle, createElementVNode as _createElementVNode, withDirectives as _withDirectives, Teleport as _Teleport, openBlock as _openBlock, createBlock as _createBlock } from "vue";
256
+ import { renderSlot as _renderSlot, normalizeStyle as _normalizeStyle, createElementVNode as _createElementVNode, Teleport as _Teleport, openBlock as _openBlock, createBlock as _createBlock } from "vue";
262
257
  function __vue_render__(_ctx, _cache, $props, $setup, $data, $options) {
263
258
  return _openBlock(), _createBlock(_Teleport, { to: $props.teleport }, [
264
- _withDirectives(_createElementVNode(
259
+ _createElementVNode(
265
260
  "div",
266
261
  {
267
262
  ref: "rootRef",
@@ -278,9 +273,7 @@ function __vue_render__(_ctx, _cache, $props, $setup, $data, $options) {
278
273
  ],
279
274
  36
280
275
  /* STYLE, NEED_HYDRATION */
281
- ), [
282
- [_vShow, $setup.show]
283
- ])
276
+ )
284
277
  ], 8, ["to"]);
285
278
  }
286
279
  __vue_sfc__.render = __vue_render__;
@@ -4,20 +4,19 @@ type __VLS_Slots = {} & {
4
4
  default?: (props: typeof __VLS_13) => any;
5
5
  };
6
6
  declare const __VLS_component: import("vue").DefineComponent<{}, {
7
- isOnRightSide: import("vue").ComputedRef<boolean>;
8
7
  offset: import("vue").Ref<{
9
8
  x: number;
10
9
  y: number;
11
- }, FloatingBubbleOffset | {
10
+ } | undefined, FloatingBubbleOffset | {
12
11
  x: number;
13
12
  y: number;
14
- }>;
13
+ } | undefined>;
15
14
  }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
16
- "offset-change": (offset: FloatingBubbleOffset) => any;
15
+ "offset-change": (offset: FloatingBubbleOffset | undefined) => any;
17
16
  "drag-start": () => any;
18
17
  "drag-end": () => any;
19
18
  }, string, import("vue").PublicProps, Readonly<{}> & Readonly<{
20
- "onOffset-change"?: ((offset: FloatingBubbleOffset) => any) | undefined;
19
+ "onOffset-change"?: ((offset: FloatingBubbleOffset | undefined) => any) | undefined;
21
20
  "onDrag-start"?: (() => any) | undefined;
22
21
  "onDrag-end"?: (() => any) | undefined;
23
22
  }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
@@ -1,6 +1,6 @@
1
1
  import "./Trigger-sfc.css";
2
2
  import { defineComponent as _defineComponent } from "vue";
3
- import { ref, computed, onMounted } from "vue";
3
+ import { ref, watch } from "vue";
4
4
  import { useOpenCodeWidgetContext } from "../context";
5
5
  import FloatingBubble from "./FloatingBubble/FloatingBubble.vue.js";
6
6
  const STORAGE_KEY = "opencode-bubble-offset";
@@ -27,7 +27,7 @@ const __vue_sfc__ = /* @__PURE__ */ _defineComponent({
27
27
  }
28
28
  } catch (e) {
29
29
  }
30
- return { x: 0, y: 0 };
30
+ return void 0;
31
31
  };
32
32
  const offset = ref(loadOffset());
33
33
  const emit = __emit;
@@ -42,22 +42,11 @@ const __vue_sfc__ = /* @__PURE__ */ _defineComponent({
42
42
  saveOffset(value);
43
43
  emit("offset-change", value);
44
44
  };
45
- const bubbleRef = ref(null);
46
- const isOnRightSide = computed(() => {
47
- if (typeof window === "undefined") return true;
48
- const centerX = window.innerWidth / 2;
49
- return offset.value.x > centerX;
50
- });
51
- onMounted(() => {
52
- if (offset.value.x !== 0 || offset.value.y !== 0) {
53
- emit("offset-change", offset.value);
54
- }
55
- });
45
+ watch(offset, handleOffsetChange, { immediate: true });
56
46
  __expose({
57
- isOnRightSide,
58
47
  offset
59
48
  });
60
- const __returned__ = { active, open, hotkeyLabel, thinking, resolvedTheme, handleToggle, STORAGE_KEY, loadOffset, offset, emit, saveOffset, handleOffsetChange, bubbleRef, isOnRightSide, FloatingBubble };
49
+ const __returned__ = { active, open, hotkeyLabel, thinking, resolvedTheme, handleToggle, STORAGE_KEY, loadOffset, offset, emit, saveOffset, handleOffsetChange, FloatingBubble };
61
50
  Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
62
51
  return __returned__;
63
52
  }
@@ -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-thinking-gradient-1: #10b981;--oc-thinking-gradient-2: #059669;--oc-thinking-glow: rgba(16, 185, 129, .3);--oc-thinking-glow-strong: rgba(16, 185, 129, .6);--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: #3b82f6;--oc-trigger-bg-hover: #2563eb;--oc-trigger-bg-active: #1d4ed8;--oc-trigger-shadow: 0 2px 8px rgba(59, 130, 246, .3);--oc-trigger-shadow-hover: 0 4px 12px rgba(59, 130, 246, .4);--oc-trigger-shadow-active: 0 4px 12px rgba(59, 130, 246, .5);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-thinking-gradient-1: #34d399;--oc-thinking-gradient-2: #10b981;--oc-thinking-glow: rgba(52, 211, 153, .3);--oc-thinking-glow-strong: rgba(52, 211, 153, .6);--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: #60a5fa;--oc-trigger-bg-hover: #3b82f6;--oc-trigger-bg-active: #2563eb;--oc-trigger-shadow: 0 2px 8px rgba(96, 165, 250, .4);--oc-trigger-shadow-hover: 0 4px 12px rgba(96, 165, 250, .5);--oc-trigger-shadow-active: 0 4px 12px rgba(96, 165, 250, .6)}.opencode-chat{position:fixed;bottom:20px;width:700px;height:86vh;max-height:calc(100vh - 40px);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;z-index:99999}.opencode-chat.minimized{width:300px;height:300px}.opencode-chat.minimized .opencode-iframe-container{margin-top:-146px}.opencode-chat-content{display:flex;flex:1;overflow:hidden}.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-page-notification{position:fixed;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:2147483647;display:flex;align-items:center;gap:10px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif}.opencode-page-notification:before{content:"\1f4a1";font-size:16px}.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-thinking-gradient-1: #10b981;--oc-thinking-gradient-2: #059669;--oc-thinking-glow: rgba(16, 185, 129, .3);--oc-thinking-glow-strong: rgba(16, 185, 129, .6);--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: #3b82f6;--oc-trigger-bg-hover: #2563eb;--oc-trigger-bg-active: #1d4ed8;--oc-trigger-shadow: 0 2px 8px rgba(59, 130, 246, .3);--oc-trigger-shadow-hover: 0 4px 12px rgba(59, 130, 246, .4);--oc-trigger-shadow-active: 0 4px 12px rgba(59, 130, 246, .5);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-thinking-gradient-1: #34d399;--oc-thinking-gradient-2: #10b981;--oc-thinking-glow: rgba(52, 211, 153, .3);--oc-thinking-glow-strong: rgba(52, 211, 153, .6);--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: #60a5fa;--oc-trigger-bg-hover: #3b82f6;--oc-trigger-bg-active: #2563eb;--oc-trigger-shadow: 0 2px 8px rgba(96, 165, 250, .4);--oc-trigger-shadow-hover: 0 4px 12px rgba(96, 165, 250, .5);--oc-trigger-shadow-active: 0 4px 12px rgba(96, 165, 250, .6)}.opencode-chat{position:fixed;bottom:20px;width:700px;height:86vh;max-height:calc(100vh - 40px);background:var(--oc-bg-main);border-radius:16px;box-shadow:var(--oc-shadow-lg);overflow:hidden;opacity:0;visibility:hidden;transform:translate3d(var(---chatAnimationOrigin\.x),var(---chatAnimationOrigin\.y),0) scale(.95);transition:all .3s ease;display:flex;flex-direction:column;z-index:99999}.opencode-chat.minimized{width:300px;height:300px}.opencode-chat.minimized .opencode-iframe-container{margin-top:-146px}.opencode-chat-content{display:flex;flex:1;overflow:hidden}.opencode-chat.open{opacity:1;visibility:visible;transform:translateZ(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-page-notification{position:fixed;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:2147483647;display:flex;align-items:center;gap:10px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif}.opencode-page-notification:before{content:"\1f4a1";font-size:16px}.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)}}
@@ -18,7 +18,7 @@ var __spreadValues = (a, b) => {
18
18
  };
19
19
  var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
20
20
  import "./index-sfc.css";
21
- import { defineComponent as _defineComponent } from "vue";
21
+ import { useCssVars as _useCssVars, defineComponent as _defineComponent } from "vue";
22
22
  import { useSlots, toRef, ref, watch, computed } from "vue";
23
23
  import Frame from "./components/Frame.vue.js";
24
24
  import Header from "./components/Header.vue.js";
@@ -61,6 +61,10 @@ const __vue_sfc__ = /* @__PURE__ */ _defineComponent(__spreadProps(__spreadValue
61
61
  },
62
62
  emits: ["update:open", "update:selectMode", "update:sessionListCollapsed", "update:currentSessionId", "update:selectedElements", "update:theme", "update:thinking", "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", "frame-loaded", "thinking-change"],
63
63
  setup(__props, { expose: __expose, emit: __emit }) {
64
+ _useCssVars((_ctx) => ({
65
+ "-chatAnimationOrigin.x": chatAnimationOrigin.value.x,
66
+ "-chatAnimationOrigin.y": chatAnimationOrigin.value.y
67
+ }));
64
68
  const props = __props;
65
69
  const emit = __emit;
66
70
  const slots = useSlots();
@@ -219,13 +223,31 @@ const __vue_sfc__ = /* @__PURE__ */ _defineComponent(__spreadProps(__spreadValue
219
223
  promptDockVisible.value = !promptDockVisible.value;
220
224
  sendMessageToIframe("prompt-dock-visibility-change", { visible: promptDockVisible.value });
221
225
  };
222
- const bubbleOffset = ref({ x: 0, y: 0 });
223
- const isBubbleOnRightSide = computed(() => {
224
- if (typeof window === "undefined") return true;
226
+ const bubbleOffset = ref(void 0);
227
+ const bubbleQuadrant = computed(() => {
228
+ var _a, _b, _c, _d;
229
+ if (typeof window === "undefined") return "bottom-right";
225
230
  const centerX = window.innerWidth / 2;
226
- return bubbleOffset.value.x > centerX;
231
+ const centerY = window.innerHeight / 2;
232
+ const bubbleSize = 44;
233
+ const effectiveX = ((_b = (_a = bubbleOffset.value) == null ? void 0 : _a.x) != null ? _b : window.innerWidth - bubbleSize - 24) + bubbleSize / 2;
234
+ const effectiveY = ((_d = (_c = bubbleOffset.value) == null ? void 0 : _c.y) != null ? _d : window.innerHeight - bubbleSize - 24) + bubbleSize / 2;
235
+ if (effectiveX >= centerX && effectiveY >= centerY) {
236
+ return "bottom-right";
237
+ } else if (effectiveX < centerX && effectiveY >= centerY) {
238
+ return "bottom-left";
239
+ } else if (effectiveX >= centerX && effectiveY < centerY) {
240
+ return "top-right";
241
+ } else {
242
+ return "top-left";
243
+ }
244
+ });
245
+ const isBubbleOnRightSide = computed(() => {
246
+ const quadrant = bubbleQuadrant.value;
247
+ return quadrant === "top-right" || quadrant === "bottom-right";
227
248
  });
228
249
  const chatPositionStyle = computed(() => {
250
+ var _a;
229
251
  if (typeof window === "undefined") return {};
230
252
  const windowWidth = window.innerWidth;
231
253
  const windowHeight = window.innerHeight;
@@ -234,9 +256,10 @@ const __vue_sfc__ = /* @__PURE__ */ _defineComponent(__spreadProps(__spreadValue
234
256
  const gap = 24;
235
257
  const bubbleSize = 44;
236
258
  const screenMargin = 20;
259
+ const effectiveOffset = (_a = bubbleOffset.value) != null ? _a : { x: windowWidth - bubbleSize - gap, y: windowHeight - bubbleSize - gap };
237
260
  const style = {};
238
261
  if (isBubbleOnRightSide.value) {
239
- let rightPos = windowWidth - bubbleOffset.value.x + gap;
262
+ let rightPos = windowWidth - effectiveOffset.x + gap;
240
263
  const maxRight = windowWidth - chatWidth - screenMargin;
241
264
  if (rightPos > maxRight) {
242
265
  rightPos = maxRight;
@@ -244,7 +267,7 @@ const __vue_sfc__ = /* @__PURE__ */ _defineComponent(__spreadProps(__spreadValue
244
267
  style.right = `${rightPos}px`;
245
268
  style.left = "auto";
246
269
  } else {
247
- let leftPos = bubbleOffset.value.x + bubbleSize + gap;
270
+ let leftPos = effectiveOffset.x + bubbleSize + gap;
248
271
  const maxLeft = windowWidth - chatWidth - screenMargin;
249
272
  if (leftPos > maxLeft) {
250
273
  leftPos = maxLeft;
@@ -252,7 +275,7 @@ const __vue_sfc__ = /* @__PURE__ */ _defineComponent(__spreadProps(__spreadValue
252
275
  style.left = `${leftPos}px`;
253
276
  style.right = "auto";
254
277
  }
255
- let bottomPos = windowHeight - bubbleOffset.value.y - bubbleSize;
278
+ let bottomPos = windowHeight - effectiveOffset.y - bubbleSize;
256
279
  const maxBottom = windowHeight - chatHeight - screenMargin;
257
280
  if (bottomPos > maxBottom) {
258
281
  bottomPos = maxBottom;
@@ -266,6 +289,20 @@ const __vue_sfc__ = /* @__PURE__ */ _defineComponent(__spreadProps(__spreadValue
266
289
  const handleBubbleOffsetChange = (offset) => {
267
290
  bubbleOffset.value = offset;
268
291
  };
292
+ const chatAnimationOrigin = computed(() => {
293
+ const quadrant = bubbleQuadrant.value;
294
+ switch (quadrant) {
295
+ case "top-left":
296
+ return { x: "-20px", y: "-20px" };
297
+ case "top-right":
298
+ return { x: "20px", y: "-20px" };
299
+ case "bottom-left":
300
+ return { x: "-20px", y: "20px" };
301
+ case "bottom-right":
302
+ default:
303
+ return { x: "20px", y: "20px" };
304
+ }
305
+ });
269
306
  const isDragging = ref(false);
270
307
  let wasOpenBeforeDrag = false;
271
308
  const handleDragStart = () => {
@@ -334,7 +371,7 @@ const __vue_sfc__ = /* @__PURE__ */ _defineComponent(__spreadProps(__spreadValue
334
371
  return dialogResolve;
335
372
  }, set dialogResolve(v) {
336
373
  dialogResolve = v;
337
- }, showConfirmDialog, handleDialogConfirm, handleDialogCancel, frameRef, triggerRef, sendMessageToIframe, handleFrameLoaded, localSessionListCollapsed, minimized, promptDockVisible, 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, handleToggleMinimize, handleTogglePromptDock, bubbleOffset, isBubbleOnRightSide, chatPositionStyle, handleBubbleOffsetChange, isDragging, get wasOpenBeforeDrag() {
374
+ }, showConfirmDialog, handleDialogConfirm, handleDialogCancel, frameRef, triggerRef, sendMessageToIframe, handleFrameLoaded, localSessionListCollapsed, minimized, promptDockVisible, 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, handleToggleMinimize, handleTogglePromptDock, bubbleOffset, bubbleQuadrant, isBubbleOnRightSide, chatPositionStyle, handleBubbleOffsetChange, chatAnimationOrigin, isDragging, get wasOpenBeforeDrag() {
338
375
  return wasOpenBeforeDrag;
339
376
  }, set wasOpenBeforeDrag(v) {
340
377
  wasOpenBeforeDrag = v;
@@ -618,9 +618,8 @@ var __vue_sfc__$2 = /* @__PURE__ */ (0, vue.defineComponent)(__spreadProps$1(__s
618
618
  else style.transition = "transform 0.3s ease";
619
619
  return style;
620
620
  });
621
- const show = (0, vue.ref)(true);
622
621
  const updateState = () => {
623
- if (!show.value || !rootRef.value || typeof window === "undefined") return;
622
+ if (!rootRef.value || typeof window === "undefined") return;
624
623
  const rect = rootRef.value.getBoundingClientRect();
625
624
  const { offset } = props;
626
625
  let x = offset ? offset.x : windowWidth.value - rect.width - gapX.value;
@@ -744,7 +743,7 @@ var __vue_sfc__$2 = /* @__PURE__ */ (0, vue.defineComponent)(__spreadProps$1(__s
744
743
  };
745
744
  (0, vue.onMounted)(() => {
746
745
  updateState();
747
- (0, vue.nextTick)(() => {
746
+ requestAnimationFrame(() => {
748
747
  initialized.value = true;
749
748
  });
750
749
  if (typeof window !== "undefined") window.addEventListener("resize", handleResize);
@@ -765,16 +764,10 @@ var __vue_sfc__$2 = /* @__PURE__ */ (0, vue.defineComponent)(__spreadProps$1(__s
765
764
  gapY,
766
765
  () => props.offset
767
766
  ], updateState, { deep: true });
768
- const isOnRightSide = (0, vue.computed)(() => {
769
- return state.value.x > windowWidth.value / 2;
770
- });
771
- __expose({
772
- isOnRightSide,
773
- offset: (0, vue.computed)(() => ({
774
- x: state.value.x,
775
- y: state.value.y
776
- }))
777
- });
767
+ __expose({ offset: (0, vue.computed)(() => ({
768
+ x: state.value.x,
769
+ y: state.value.y
770
+ })) });
778
771
  const __returned__ = {
779
772
  props,
780
773
  emit,
@@ -789,7 +782,6 @@ var __vue_sfc__$2 = /* @__PURE__ */ (0, vue.defineComponent)(__spreadProps$1(__s
789
782
  dragging,
790
783
  initialized,
791
784
  rootStyle,
792
- show,
793
785
  updateState,
794
786
  touch,
795
787
  get prevX() {
@@ -809,8 +801,7 @@ var __vue_sfc__$2 = /* @__PURE__ */ (0, vue.defineComponent)(__spreadProps$1(__s
809
801
  closest,
810
802
  onTouchEnd,
811
803
  onClick,
812
- handleResize,
813
- isOnRightSide
804
+ handleResize
814
805
  };
815
806
  Object.defineProperty(__returned__, "__isScriptSetup", {
816
807
  enumerable: false,
@@ -820,7 +811,7 @@ var __vue_sfc__$2 = /* @__PURE__ */ (0, vue.defineComponent)(__spreadProps$1(__s
820
811
  }
821
812
  }));
822
813
  function __vue_render__$2(_ctx, _cache, $props, $setup, $data, $options) {
823
- return (0, vue.openBlock)(), (0, vue.createBlock)(vue.Teleport, { to: $props.teleport }, [(0, vue.withDirectives)((0, vue.createElementVNode)("div", {
814
+ return (0, vue.openBlock)(), (0, vue.createBlock)(vue.Teleport, { to: $props.teleport }, [(0, vue.createElementVNode)("div", {
824
815
  ref: "rootRef",
825
816
  class: "floating-bubble",
826
817
  style: (0, vue.normalizeStyle)($setup.rootStyle),
@@ -829,7 +820,7 @@ function __vue_render__$2(_ctx, _cache, $props, $setup, $data, $options) {
829
820
  onTouchcancel: $setup.onTouchEnd,
830
821
  onMousedown: $setup.onTouchStart,
831
822
  onClickCapture: $setup.onClick
832
- }, [(0, vue.renderSlot)(_ctx.$slots, "default")], 36), [[vue.vShow, $setup.show]])], 8, ["to"]);
823
+ }, [(0, vue.renderSlot)(_ctx.$slots, "default")], 36)], 8, ["to"]);
833
824
  }
834
825
  __vue_sfc__$2.render = __vue_render__$2;
835
826
  var FloatingBubble_vue_default = __vue_sfc__$2;
@@ -853,10 +844,6 @@ var __vue_sfc__$1 = /* @__PURE__ */ (0, vue.defineComponent)({
853
844
  if (parsed && (parsed.x !== 0 || parsed.y !== 0)) return parsed;
854
845
  }
855
846
  } catch (e) {}
856
- return {
857
- x: 0,
858
- y: 0
859
- };
860
847
  };
861
848
  const offset = (0, vue.ref)(loadOffset());
862
849
  const emit = __emit;
@@ -870,19 +857,8 @@ var __vue_sfc__$1 = /* @__PURE__ */ (0, vue.defineComponent)({
870
857
  saveOffset(value);
871
858
  emit("offset-change", value);
872
859
  };
873
- const bubbleRef = (0, vue.ref)(null);
874
- const isOnRightSide = (0, vue.computed)(() => {
875
- if (typeof window === "undefined") return true;
876
- const centerX = window.innerWidth / 2;
877
- return offset.value.x > centerX;
878
- });
879
- (0, vue.onMounted)(() => {
880
- if (offset.value.x !== 0 || offset.value.y !== 0) emit("offset-change", offset.value);
881
- });
882
- __expose({
883
- isOnRightSide,
884
- offset
885
- });
860
+ (0, vue.watch)(offset, handleOffsetChange, { immediate: true });
861
+ __expose({ offset });
886
862
  const __returned__ = {
887
863
  active,
888
864
  open,
@@ -896,8 +872,6 @@ var __vue_sfc__$1 = /* @__PURE__ */ (0, vue.defineComponent)({
896
872
  emit,
897
873
  saveOffset,
898
874
  handleOffsetChange,
899
- bubbleRef,
900
- isOnRightSide,
901
875
  FloatingBubble: FloatingBubble_vue_default
902
876
  };
903
877
  Object.defineProperty(__returned__, "__isScriptSetup", {
@@ -1768,6 +1742,10 @@ var __vue_sfc__ = /* @__PURE__ */ (0, vue.defineComponent)(__spreadProps(__sprea
1768
1742
  "thinking-change"
1769
1743
  ],
1770
1744
  setup(__props, { expose: __expose, emit: __emit }) {
1745
+ (0, vue.useCssVars)((_ctx) => ({
1746
+ "-chatAnimationOrigin.x": chatAnimationOrigin.value.x,
1747
+ "-chatAnimationOrigin.y": chatAnimationOrigin.value.y
1748
+ }));
1771
1749
  const props = __props;
1772
1750
  const emit = __emit;
1773
1751
  const slots = (0, vue.useSlots)();
@@ -1904,16 +1882,26 @@ var __vue_sfc__ = /* @__PURE__ */ (0, vue.defineComponent)(__spreadProps(__sprea
1904
1882
  promptDockVisible.value = !promptDockVisible.value;
1905
1883
  sendMessageToIframe("prompt-dock-visibility-change", { visible: promptDockVisible.value });
1906
1884
  };
1907
- const bubbleOffset = (0, vue.ref)({
1908
- x: 0,
1909
- y: 0
1885
+ const bubbleOffset = (0, vue.ref)(void 0);
1886
+ const bubbleQuadrant = (0, vue.computed)(() => {
1887
+ var _a, _b, _c, _d;
1888
+ if (typeof window === "undefined") return "bottom-right";
1889
+ const centerX = window.innerWidth / 2;
1890
+ const centerY = window.innerHeight / 2;
1891
+ const bubbleSize = 44;
1892
+ const effectiveX = ((_b = (_a = bubbleOffset.value) == null ? void 0 : _a.x) != null ? _b : window.innerWidth - bubbleSize - 24) + bubbleSize / 2;
1893
+ const effectiveY = ((_d = (_c = bubbleOffset.value) == null ? void 0 : _c.y) != null ? _d : window.innerHeight - bubbleSize - 24) + bubbleSize / 2;
1894
+ if (effectiveX >= centerX && effectiveY >= centerY) return "bottom-right";
1895
+ else if (effectiveX < centerX && effectiveY >= centerY) return "bottom-left";
1896
+ else if (effectiveX >= centerX && effectiveY < centerY) return "top-right";
1897
+ else return "top-left";
1910
1898
  });
1911
1899
  const isBubbleOnRightSide = (0, vue.computed)(() => {
1912
- if (typeof window === "undefined") return true;
1913
- const centerX = window.innerWidth / 2;
1914
- return bubbleOffset.value.x > centerX;
1900
+ const quadrant = bubbleQuadrant.value;
1901
+ return quadrant === "top-right" || quadrant === "bottom-right";
1915
1902
  });
1916
1903
  const chatPositionStyle = (0, vue.computed)(() => {
1904
+ var _a;
1917
1905
  if (typeof window === "undefined") return {};
1918
1906
  const windowWidth = window.innerWidth;
1919
1907
  const windowHeight = window.innerHeight;
@@ -1922,21 +1910,25 @@ var __vue_sfc__ = /* @__PURE__ */ (0, vue.defineComponent)(__spreadProps(__sprea
1922
1910
  const gap = 24;
1923
1911
  const bubbleSize = 44;
1924
1912
  const screenMargin = 20;
1913
+ const effectiveOffset = (_a = bubbleOffset.value) != null ? _a : {
1914
+ x: windowWidth - bubbleSize - gap,
1915
+ y: windowHeight - bubbleSize - gap
1916
+ };
1925
1917
  const style = {};
1926
1918
  if (isBubbleOnRightSide.value) {
1927
- let rightPos = windowWidth - bubbleOffset.value.x + gap;
1919
+ let rightPos = windowWidth - effectiveOffset.x + gap;
1928
1920
  const maxRight = windowWidth - chatWidth - screenMargin;
1929
1921
  if (rightPos > maxRight) rightPos = maxRight;
1930
1922
  style.right = `${rightPos}px`;
1931
1923
  style.left = "auto";
1932
1924
  } else {
1933
- let leftPos = bubbleOffset.value.x + bubbleSize + gap;
1925
+ let leftPos = effectiveOffset.x + bubbleSize + gap;
1934
1926
  const maxLeft = windowWidth - chatWidth - screenMargin;
1935
1927
  if (leftPos > maxLeft) leftPos = maxLeft;
1936
1928
  style.left = `${leftPos}px`;
1937
1929
  style.right = "auto";
1938
1930
  }
1939
- let bottomPos = windowHeight - bubbleOffset.value.y - bubbleSize;
1931
+ let bottomPos = windowHeight - effectiveOffset.y - bubbleSize;
1940
1932
  const maxBottom = windowHeight - chatHeight - screenMargin;
1941
1933
  if (bottomPos > maxBottom) bottomPos = maxBottom;
1942
1934
  if (bottomPos < screenMargin) bottomPos = screenMargin;
@@ -1946,6 +1938,26 @@ var __vue_sfc__ = /* @__PURE__ */ (0, vue.defineComponent)(__spreadProps(__sprea
1946
1938
  const handleBubbleOffsetChange = (offset) => {
1947
1939
  bubbleOffset.value = offset;
1948
1940
  };
1941
+ const chatAnimationOrigin = (0, vue.computed)(() => {
1942
+ switch (bubbleQuadrant.value) {
1943
+ case "top-left": return {
1944
+ x: "-20px",
1945
+ y: "-20px"
1946
+ };
1947
+ case "top-right": return {
1948
+ x: "20px",
1949
+ y: "-20px"
1950
+ };
1951
+ case "bottom-left": return {
1952
+ x: "-20px",
1953
+ y: "20px"
1954
+ };
1955
+ default: return {
1956
+ x: "20px",
1957
+ y: "20px"
1958
+ };
1959
+ }
1960
+ });
1949
1961
  const isDragging = (0, vue.ref)(false);
1950
1962
  let wasOpenBeforeDrag = false;
1951
1963
  const handleDragStart = () => {
@@ -2063,9 +2075,11 @@ var __vue_sfc__ = /* @__PURE__ */ (0, vue.defineComponent)(__spreadProps(__sprea
2063
2075
  handleToggleMinimize,
2064
2076
  handleTogglePromptDock,
2065
2077
  bubbleOffset,
2078
+ bubbleQuadrant,
2066
2079
  isBubbleOnRightSide,
2067
2080
  chatPositionStyle,
2068
2081
  handleBubbleOffsetChange,
2082
+ chatAnimationOrigin,
2069
2083
  isDragging,
2070
2084
  get wasOpenBeforeDrag() {
2071
2085
  return wasOpenBeforeDrag;
@@ -2206,7 +2220,7 @@ __vue_sfc__.render = __vue_render__;
2206
2220
  var open_code_widget_default = __vue_sfc__;
2207
2221
  //#endregion
2208
2222
  //#region es/index.js
2209
- var version = "1.0.24";
2223
+ var version = "1.0.26";
2210
2224
  function install(app, options) {
2211
2225
  [open_code_widget_default].forEach((item) => {
2212
2226
  if (item.install) app.use(item, options);
@@ -1,4 +1,4 @@
1
- import { Fragment, Teleport, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createSlots, createStaticVNode, createVNode, defineComponent, inject, nextTick, normalizeClass, normalizeStyle, onMounted, onUnmounted, openBlock, provide, ref, renderList, renderSlot, toDisplayString, toRef, useSlots, vShow, watch, withCtx, withDirectives, withModifiers } from "vue";
1
+ import { Fragment, Teleport, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createSlots, createStaticVNode, createVNode, defineComponent, inject, normalizeClass, normalizeStyle, onMounted, onUnmounted, openBlock, provide, ref, renderList, renderSlot, toDisplayString, toRef, useCssVars, useSlots, vShow, watch, withCtx, withDirectives, withModifiers } from "vue";
2
2
  import { truncate } from "@vite-plugin-opencode-assistant/shared";
3
3
  import getCssSelector from "css-selector-generator";
4
4
  //#region es/open-code-widget/src/context.js
@@ -591,9 +591,8 @@ var __vue_sfc__$2 = /* @__PURE__ */ defineComponent(__spreadProps$1(__spreadValu
591
591
  else style.transition = "transform 0.3s ease";
592
592
  return style;
593
593
  });
594
- const show = ref(true);
595
594
  const updateState = () => {
596
- if (!show.value || !rootRef.value || typeof window === "undefined") return;
595
+ if (!rootRef.value || typeof window === "undefined") return;
597
596
  const rect = rootRef.value.getBoundingClientRect();
598
597
  const { offset } = props;
599
598
  let x = offset ? offset.x : windowWidth.value - rect.width - gapX.value;
@@ -717,7 +716,7 @@ var __vue_sfc__$2 = /* @__PURE__ */ defineComponent(__spreadProps$1(__spreadValu
717
716
  };
718
717
  onMounted(() => {
719
718
  updateState();
720
- nextTick(() => {
719
+ requestAnimationFrame(() => {
721
720
  initialized.value = true;
722
721
  });
723
722
  if (typeof window !== "undefined") window.addEventListener("resize", handleResize);
@@ -738,16 +737,10 @@ var __vue_sfc__$2 = /* @__PURE__ */ defineComponent(__spreadProps$1(__spreadValu
738
737
  gapY,
739
738
  () => props.offset
740
739
  ], updateState, { deep: true });
741
- const isOnRightSide = computed(() => {
742
- return state.value.x > windowWidth.value / 2;
743
- });
744
- __expose({
745
- isOnRightSide,
746
- offset: computed(() => ({
747
- x: state.value.x,
748
- y: state.value.y
749
- }))
750
- });
740
+ __expose({ offset: computed(() => ({
741
+ x: state.value.x,
742
+ y: state.value.y
743
+ })) });
751
744
  const __returned__ = {
752
745
  props,
753
746
  emit,
@@ -762,7 +755,6 @@ var __vue_sfc__$2 = /* @__PURE__ */ defineComponent(__spreadProps$1(__spreadValu
762
755
  dragging,
763
756
  initialized,
764
757
  rootStyle,
765
- show,
766
758
  updateState,
767
759
  touch,
768
760
  get prevX() {
@@ -782,8 +774,7 @@ var __vue_sfc__$2 = /* @__PURE__ */ defineComponent(__spreadProps$1(__spreadValu
782
774
  closest,
783
775
  onTouchEnd,
784
776
  onClick,
785
- handleResize,
786
- isOnRightSide
777
+ handleResize
787
778
  };
788
779
  Object.defineProperty(__returned__, "__isScriptSetup", {
789
780
  enumerable: false,
@@ -793,7 +784,7 @@ var __vue_sfc__$2 = /* @__PURE__ */ defineComponent(__spreadProps$1(__spreadValu
793
784
  }
794
785
  }));
795
786
  function __vue_render__$2(_ctx, _cache, $props, $setup, $data, $options) {
796
- return openBlock(), createBlock(Teleport, { to: $props.teleport }, [withDirectives(createElementVNode("div", {
787
+ return openBlock(), createBlock(Teleport, { to: $props.teleport }, [createElementVNode("div", {
797
788
  ref: "rootRef",
798
789
  class: "floating-bubble",
799
790
  style: normalizeStyle($setup.rootStyle),
@@ -802,7 +793,7 @@ function __vue_render__$2(_ctx, _cache, $props, $setup, $data, $options) {
802
793
  onTouchcancel: $setup.onTouchEnd,
803
794
  onMousedown: $setup.onTouchStart,
804
795
  onClickCapture: $setup.onClick
805
- }, [renderSlot(_ctx.$slots, "default")], 36), [[vShow, $setup.show]])], 8, ["to"]);
796
+ }, [renderSlot(_ctx.$slots, "default")], 36)], 8, ["to"]);
806
797
  }
807
798
  __vue_sfc__$2.render = __vue_render__$2;
808
799
  var FloatingBubble_vue_default = __vue_sfc__$2;
@@ -826,10 +817,6 @@ var __vue_sfc__$1 = /* @__PURE__ */ defineComponent({
826
817
  if (parsed && (parsed.x !== 0 || parsed.y !== 0)) return parsed;
827
818
  }
828
819
  } catch (e) {}
829
- return {
830
- x: 0,
831
- y: 0
832
- };
833
820
  };
834
821
  const offset = ref(loadOffset());
835
822
  const emit = __emit;
@@ -843,19 +830,8 @@ var __vue_sfc__$1 = /* @__PURE__ */ defineComponent({
843
830
  saveOffset(value);
844
831
  emit("offset-change", value);
845
832
  };
846
- const bubbleRef = ref(null);
847
- const isOnRightSide = computed(() => {
848
- if (typeof window === "undefined") return true;
849
- const centerX = window.innerWidth / 2;
850
- return offset.value.x > centerX;
851
- });
852
- onMounted(() => {
853
- if (offset.value.x !== 0 || offset.value.y !== 0) emit("offset-change", offset.value);
854
- });
855
- __expose({
856
- isOnRightSide,
857
- offset
858
- });
833
+ watch(offset, handleOffsetChange, { immediate: true });
834
+ __expose({ offset });
859
835
  const __returned__ = {
860
836
  active,
861
837
  open,
@@ -869,8 +845,6 @@ var __vue_sfc__$1 = /* @__PURE__ */ defineComponent({
869
845
  emit,
870
846
  saveOffset,
871
847
  handleOffsetChange,
872
- bubbleRef,
873
- isOnRightSide,
874
848
  FloatingBubble: FloatingBubble_vue_default
875
849
  };
876
850
  Object.defineProperty(__returned__, "__isScriptSetup", {
@@ -1741,6 +1715,10 @@ var __vue_sfc__ = /* @__PURE__ */ defineComponent(__spreadProps(__spreadValues({
1741
1715
  "thinking-change"
1742
1716
  ],
1743
1717
  setup(__props, { expose: __expose, emit: __emit }) {
1718
+ useCssVars((_ctx) => ({
1719
+ "-chatAnimationOrigin.x": chatAnimationOrigin.value.x,
1720
+ "-chatAnimationOrigin.y": chatAnimationOrigin.value.y
1721
+ }));
1744
1722
  const props = __props;
1745
1723
  const emit = __emit;
1746
1724
  const slots = useSlots();
@@ -1877,16 +1855,26 @@ var __vue_sfc__ = /* @__PURE__ */ defineComponent(__spreadProps(__spreadValues({
1877
1855
  promptDockVisible.value = !promptDockVisible.value;
1878
1856
  sendMessageToIframe("prompt-dock-visibility-change", { visible: promptDockVisible.value });
1879
1857
  };
1880
- const bubbleOffset = ref({
1881
- x: 0,
1882
- y: 0
1858
+ const bubbleOffset = ref(void 0);
1859
+ const bubbleQuadrant = computed(() => {
1860
+ var _a, _b, _c, _d;
1861
+ if (typeof window === "undefined") return "bottom-right";
1862
+ const centerX = window.innerWidth / 2;
1863
+ const centerY = window.innerHeight / 2;
1864
+ const bubbleSize = 44;
1865
+ const effectiveX = ((_b = (_a = bubbleOffset.value) == null ? void 0 : _a.x) != null ? _b : window.innerWidth - bubbleSize - 24) + bubbleSize / 2;
1866
+ const effectiveY = ((_d = (_c = bubbleOffset.value) == null ? void 0 : _c.y) != null ? _d : window.innerHeight - bubbleSize - 24) + bubbleSize / 2;
1867
+ if (effectiveX >= centerX && effectiveY >= centerY) return "bottom-right";
1868
+ else if (effectiveX < centerX && effectiveY >= centerY) return "bottom-left";
1869
+ else if (effectiveX >= centerX && effectiveY < centerY) return "top-right";
1870
+ else return "top-left";
1883
1871
  });
1884
1872
  const isBubbleOnRightSide = computed(() => {
1885
- if (typeof window === "undefined") return true;
1886
- const centerX = window.innerWidth / 2;
1887
- return bubbleOffset.value.x > centerX;
1873
+ const quadrant = bubbleQuadrant.value;
1874
+ return quadrant === "top-right" || quadrant === "bottom-right";
1888
1875
  });
1889
1876
  const chatPositionStyle = computed(() => {
1877
+ var _a;
1890
1878
  if (typeof window === "undefined") return {};
1891
1879
  const windowWidth = window.innerWidth;
1892
1880
  const windowHeight = window.innerHeight;
@@ -1895,21 +1883,25 @@ var __vue_sfc__ = /* @__PURE__ */ defineComponent(__spreadProps(__spreadValues({
1895
1883
  const gap = 24;
1896
1884
  const bubbleSize = 44;
1897
1885
  const screenMargin = 20;
1886
+ const effectiveOffset = (_a = bubbleOffset.value) != null ? _a : {
1887
+ x: windowWidth - bubbleSize - gap,
1888
+ y: windowHeight - bubbleSize - gap
1889
+ };
1898
1890
  const style = {};
1899
1891
  if (isBubbleOnRightSide.value) {
1900
- let rightPos = windowWidth - bubbleOffset.value.x + gap;
1892
+ let rightPos = windowWidth - effectiveOffset.x + gap;
1901
1893
  const maxRight = windowWidth - chatWidth - screenMargin;
1902
1894
  if (rightPos > maxRight) rightPos = maxRight;
1903
1895
  style.right = `${rightPos}px`;
1904
1896
  style.left = "auto";
1905
1897
  } else {
1906
- let leftPos = bubbleOffset.value.x + bubbleSize + gap;
1898
+ let leftPos = effectiveOffset.x + bubbleSize + gap;
1907
1899
  const maxLeft = windowWidth - chatWidth - screenMargin;
1908
1900
  if (leftPos > maxLeft) leftPos = maxLeft;
1909
1901
  style.left = `${leftPos}px`;
1910
1902
  style.right = "auto";
1911
1903
  }
1912
- let bottomPos = windowHeight - bubbleOffset.value.y - bubbleSize;
1904
+ let bottomPos = windowHeight - effectiveOffset.y - bubbleSize;
1913
1905
  const maxBottom = windowHeight - chatHeight - screenMargin;
1914
1906
  if (bottomPos > maxBottom) bottomPos = maxBottom;
1915
1907
  if (bottomPos < screenMargin) bottomPos = screenMargin;
@@ -1919,6 +1911,26 @@ var __vue_sfc__ = /* @__PURE__ */ defineComponent(__spreadProps(__spreadValues({
1919
1911
  const handleBubbleOffsetChange = (offset) => {
1920
1912
  bubbleOffset.value = offset;
1921
1913
  };
1914
+ const chatAnimationOrigin = computed(() => {
1915
+ switch (bubbleQuadrant.value) {
1916
+ case "top-left": return {
1917
+ x: "-20px",
1918
+ y: "-20px"
1919
+ };
1920
+ case "top-right": return {
1921
+ x: "20px",
1922
+ y: "-20px"
1923
+ };
1924
+ case "bottom-left": return {
1925
+ x: "-20px",
1926
+ y: "20px"
1927
+ };
1928
+ default: return {
1929
+ x: "20px",
1930
+ y: "20px"
1931
+ };
1932
+ }
1933
+ });
1922
1934
  const isDragging = ref(false);
1923
1935
  let wasOpenBeforeDrag = false;
1924
1936
  const handleDragStart = () => {
@@ -2036,9 +2048,11 @@ var __vue_sfc__ = /* @__PURE__ */ defineComponent(__spreadProps(__spreadValues({
2036
2048
  handleToggleMinimize,
2037
2049
  handleTogglePromptDock,
2038
2050
  bubbleOffset,
2051
+ bubbleQuadrant,
2039
2052
  isBubbleOnRightSide,
2040
2053
  chatPositionStyle,
2041
2054
  handleBubbleOffsetChange,
2055
+ chatAnimationOrigin,
2042
2056
  isDragging,
2043
2057
  get wasOpenBeforeDrag() {
2044
2058
  return wasOpenBeforeDrag;
@@ -2179,7 +2193,7 @@ __vue_sfc__.render = __vue_render__;
2179
2193
  var open_code_widget_default = __vue_sfc__;
2180
2194
  //#endregion
2181
2195
  //#region es/index.js
2182
- var version = "1.0.24";
2196
+ var version = "1.0.26";
2183
2197
  function install(app, options) {
2184
2198
  [open_code_widget_default].forEach((item) => {
2185
2199
  if (item.install) app.use(item, options);
@@ -1,9 +1,9 @@
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-thinking-gradient-1: #10b981;--oc-thinking-gradient-2: #059669;--oc-thinking-glow: rgba(16, 185, 129, .3);--oc-thinking-glow-strong: rgba(16, 185, 129, .6);--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: #3b82f6;--oc-trigger-bg-hover: #2563eb;--oc-trigger-bg-active: #1d4ed8;--oc-trigger-shadow: 0 2px 8px rgba(59, 130, 246, .3);--oc-trigger-shadow-hover: 0 4px 12px rgba(59, 130, 246, .4);--oc-trigger-shadow-active: 0 4px 12px rgba(59, 130, 246, .5);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-thinking-gradient-1: #34d399;--oc-thinking-gradient-2: #10b981;--oc-thinking-glow: rgba(52, 211, 153, .3);--oc-thinking-glow-strong: rgba(52, 211, 153, .6);--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: #60a5fa;--oc-trigger-bg-hover: #3b82f6;--oc-trigger-bg-active: #2563eb;--oc-trigger-shadow: 0 2px 8px rgba(96, 165, 250, .4);--oc-trigger-shadow-hover: 0 4px 12px rgba(96, 165, 250, .5);--oc-trigger-shadow-active: 0 4px 12px rgba(96, 165, 250, .6)}.opencode-chat{position:fixed;bottom:20px;width:700px;height:86vh;max-height:calc(100vh - 40px);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;z-index:99999}.opencode-chat.minimized{width:300px;height:300px}.opencode-chat.minimized .opencode-iframe-container{margin-top:-146px}.opencode-chat-content{display:flex;flex:1;overflow:hidden}.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-page-notification{position:fixed;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:2147483647;display:flex;align-items:center;gap:10px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif}.opencode-page-notification:before{content:"\1f4a1";font-size:16px}.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-thinking-gradient-1: #10b981;--oc-thinking-gradient-2: #059669;--oc-thinking-glow: rgba(16, 185, 129, .3);--oc-thinking-glow-strong: rgba(16, 185, 129, .6);--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: #3b82f6;--oc-trigger-bg-hover: #2563eb;--oc-trigger-bg-active: #1d4ed8;--oc-trigger-shadow: 0 2px 8px rgba(59, 130, 246, .3);--oc-trigger-shadow-hover: 0 4px 12px rgba(59, 130, 246, .4);--oc-trigger-shadow-active: 0 4px 12px rgba(59, 130, 246, .5);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-thinking-gradient-1: #34d399;--oc-thinking-gradient-2: #10b981;--oc-thinking-glow: rgba(52, 211, 153, .3);--oc-thinking-glow-strong: rgba(52, 211, 153, .6);--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: #60a5fa;--oc-trigger-bg-hover: #3b82f6;--oc-trigger-bg-active: #2563eb;--oc-trigger-shadow: 0 2px 8px rgba(96, 165, 250, .4);--oc-trigger-shadow-hover: 0 4px 12px rgba(96, 165, 250, .5);--oc-trigger-shadow-active: 0 4px 12px rgba(96, 165, 250, .6)}.opencode-chat{position:fixed;bottom:20px;width:700px;height:86vh;max-height:calc(100vh - 40px);background:var(--oc-bg-main);border-radius:16px;box-shadow:var(--oc-shadow-lg);overflow:hidden;opacity:0;visibility:hidden;transform:translate3d(var(---chatAnimationOrigin\.x),var(---chatAnimationOrigin\.y),0) scale(.95);transition:all .3s ease;display:flex;flex-direction:column;z-index:99999}.opencode-chat.minimized{width:300px;height:300px}.opencode-chat.minimized .opencode-iframe-container{margin-top:-146px}.opencode-chat-content{display:flex;flex:1;overflow:hidden}.opencode-chat.open{opacity:1;visibility:visible;transform:translateZ(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-page-notification{position:fixed;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:2147483647;display:flex;align-items:center;gap:10px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif}.opencode-page-notification:before{content:"\1f4a1";font-size:16px}.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
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
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-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)}
6
6
  .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}}
7
7
  .opencode-button{width:42px;height:42px;border-radius:50%;background:#fff;border:none;cursor:pointer;box-shadow:0 4px 12px rgba(102,126,234,.4);transition:all .3s ease;display:flex;align-items:center;justify-content:center;padding:0;position:relative}.opencode-button svg{transform:rotate(180deg) scale(1.1);transition:transform .3s ease;width:100%;height:100%;display:block}.opencode-button:hover svg{transform:rotate(180deg) scale(1.1)}.opencode-button:hover{transform:scale(1.1);box-shadow:0 6px 16px rgba(102,126,234,.5)}.opencode-button.thinking{background:linear-gradient(135deg,#667eea,#764ba2);animation:thinking-glow 1.5s ease-in-out infinite,thinking-pulse 1.5s ease-in-out infinite;box-shadow:0 0 20px rgba(102,126,234,.6),0 0 40px rgba(118,75,162,.4),0 0 60px rgba(102,126,234,.2)}.opencode-button.thinking svg path{fill:#fff}.opencode-button.thinking:before{content:"";position:absolute;top:-2px;right:-2px;bottom:-2px;left:-2px;border-radius:50%;background:linear-gradient(135deg,#8b9cf5,#9d6bc7);z-index:-1}.opencode-button.thinking:after{content:"";position:absolute;top:-3px;right:-3px;bottom:-3px;left:-3px;border-radius:50%;background:conic-gradient(from 180deg,transparent,rgba(102,126,234,.3),transparent,rgba(118,75,162,.3),transparent);z-index:-2;animation:thinking-rotate 2s linear infinite reverse;filter:blur(8px)}@keyframes thinking-glow{0%,to{box-shadow:0 0 20px rgba(102,126,234,.6),0 0 40px rgba(118,75,162,.4),0 0 60px rgba(102,126,234,.2)}50%{box-shadow:0 0 30px rgba(102,126,234,.8),0 0 60px rgba(118,75,162,.6),0 0 90px rgba(102,126,234,.3)}}@keyframes thinking-rotate{0%{transform:rotate(0)}to{transform:rotate(360deg)}}@keyframes thinking-pulse{0%,to{transform:scale(1)}50%{transform:scale(.95)}}.opencode-button.opencode-theme-dark{background:linear-gradient(135deg,#667eea,#764ba2);box-shadow:0 4px 12px rgba(102,126,234,.3)}.opencode-button.opencode-theme-dark:before{content:"";position:absolute;top:-2px;right:-2px;bottom:-2px;left:-2px;border-radius:50%;background:linear-gradient(135deg,#8b9cf5,#9d6bc7);z-index:-1}.opencode-button.opencode-theme-dark:hover{box-shadow:0 6px 16px rgba(102,126,234,.4)}.opencode-button.opencode-theme-dark svg path{fill:#fff}
8
- .floating-bubble{position:fixed;top:0;left:0;z-index:999999;cursor:grab;-webkit-user-select:none;-moz-user-select:none;user-select:none;touch-action:none;visibility:hidden;will-change:transform}.floating-bubble[style*=translate3d]{visibility:visible}.floating-bubble:active{cursor:grabbing}
8
+ .floating-bubble{position:fixed;top:0;left:0;z-index:999999;cursor:grab;-webkit-user-select:none;-moz-user-select:none;user-select:none;touch-action:none;will-change:transform}.floating-bubble:active{cursor:grabbing}
9
9
  /*$vite$:1*/
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.24";
3
+ declare const version = "1.0.26";
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.24";
37
+ const version = "1.0.26";
38
38
  function install(app, options) {
39
39
  const components = [
40
40
  import_open_code_widget.default
@@ -1 +1 @@
1
- .floating-bubble{position:fixed;top:0;left:0;z-index:999999;cursor:grab;-webkit-user-select:none;-moz-user-select:none;user-select:none;touch-action:none;visibility:hidden;will-change:transform}.floating-bubble[style*=translate3d]{visibility:visible}.floating-bubble:active{cursor:grabbing}
1
+ .floating-bubble{position:fixed;top:0;left:0;z-index:999999;cursor:grab;-webkit-user-select:none;-moz-user-select:none;user-select:none;touch-action:none;will-change:transform}.floating-bubble:active{cursor:grabbing}
@@ -11,7 +11,6 @@ type __VLS_Slots = {} & {
11
11
  default?: (props: typeof __VLS_5) => any;
12
12
  };
13
13
  declare const __VLS_component: import("vue").DefineComponent<__VLS_Props, {
14
- isOnRightSide: import("vue").ComputedRef<boolean>;
15
14
  offset: import("vue").ComputedRef<{
16
15
  x: number;
17
16
  y: number;
@@ -92,9 +92,8 @@ const __vue_sfc__ = /* @__PURE__ */ (0, import_vue.defineComponent)(__spreadProp
92
92
  }
93
93
  return style;
94
94
  });
95
- const show = (0, import_vue2.ref)(true);
96
95
  const updateState = () => {
97
- if (!show.value || !rootRef.value || typeof window === "undefined") return;
96
+ if (!rootRef.value || typeof window === "undefined") return;
98
97
  const rect = rootRef.value.getBoundingClientRect();
99
98
  const { offset } = props;
100
99
  let x = offset ? offset.x : windowWidth.value - rect.width - gapX.value;
@@ -232,7 +231,7 @@ const __vue_sfc__ = /* @__PURE__ */ (0, import_vue.defineComponent)(__spreadProp
232
231
  };
233
232
  (0, import_vue2.onMounted)(() => {
234
233
  updateState();
235
- (0, import_vue2.nextTick)(() => {
234
+ requestAnimationFrame(() => {
236
235
  initialized.value = true;
237
236
  });
238
237
  if (typeof window !== "undefined") {
@@ -259,14 +258,10 @@ const __vue_sfc__ = /* @__PURE__ */ (0, import_vue.defineComponent)(__spreadProp
259
258
  updateState,
260
259
  { deep: true }
261
260
  );
262
- const isOnRightSide = (0, import_vue2.computed)(() => {
263
- return state.value.x > windowWidth.value / 2;
264
- });
265
261
  __expose({
266
- isOnRightSide,
267
262
  offset: (0, import_vue2.computed)(() => ({ x: state.value.x, y: state.value.y }))
268
263
  });
269
- const __returned__ = { props, emit, rootRef, state, isObject, gapX, gapY, windowWidth, windowHeight, boundary, dragging, initialized, rootStyle, show, updateState, touch, get prevX() {
264
+ const __returned__ = { props, emit, rootRef, state, isObject, gapX, gapY, windowWidth, windowHeight, boundary, dragging, initialized, rootStyle, updateState, touch, get prevX() {
270
265
  return prevX;
271
266
  }, set prevX(v) {
272
267
  prevX = v;
@@ -274,14 +269,14 @@ const __vue_sfc__ = /* @__PURE__ */ (0, import_vue.defineComponent)(__spreadProp
274
269
  return prevY;
275
270
  }, set prevY(v) {
276
271
  prevY = v;
277
- }, onTouchStart, onTouchMove, closest, onTouchEnd, onClick, handleResize, isOnRightSide };
272
+ }, onTouchStart, onTouchMove, closest, onTouchEnd, onClick, handleResize };
278
273
  Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
279
274
  return __returned__;
280
275
  }
281
276
  }));
282
277
  function __vue_render__(_ctx, _cache, $props, $setup, $data, $options) {
283
278
  return (0, import_vue3.openBlock)(), (0, import_vue3.createBlock)(import_vue3.Teleport, { to: $props.teleport }, [
284
- (0, import_vue3.withDirectives)((0, import_vue3.createElementVNode)(
279
+ (0, import_vue3.createElementVNode)(
285
280
  "div",
286
281
  {
287
282
  ref: "rootRef",
@@ -298,9 +293,7 @@ function __vue_render__(_ctx, _cache, $props, $setup, $data, $options) {
298
293
  ],
299
294
  36
300
295
  /* STYLE, NEED_HYDRATION */
301
- ), [
302
- [import_vue3.vShow, $setup.show]
303
- ])
296
+ )
304
297
  ], 8, ["to"]);
305
298
  }
306
299
  __vue_sfc__.render = __vue_render__;
@@ -4,20 +4,19 @@ type __VLS_Slots = {} & {
4
4
  default?: (props: typeof __VLS_13) => any;
5
5
  };
6
6
  declare const __VLS_component: import("vue").DefineComponent<{}, {
7
- isOnRightSide: import("vue").ComputedRef<boolean>;
8
7
  offset: import("vue").Ref<{
9
8
  x: number;
10
9
  y: number;
11
- }, FloatingBubbleOffset | {
10
+ } | undefined, FloatingBubbleOffset | {
12
11
  x: number;
13
12
  y: number;
14
- }>;
13
+ } | undefined>;
15
14
  }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
16
- "offset-change": (offset: FloatingBubbleOffset) => any;
15
+ "offset-change": (offset: FloatingBubbleOffset | undefined) => any;
17
16
  "drag-start": () => any;
18
17
  "drag-end": () => any;
19
18
  }, string, import("vue").PublicProps, Readonly<{}> & Readonly<{
20
- "onOffset-change"?: ((offset: FloatingBubbleOffset) => any) | undefined;
19
+ "onOffset-change"?: ((offset: FloatingBubbleOffset | undefined) => any) | undefined;
21
20
  "onDrag-start"?: (() => any) | undefined;
22
21
  "onDrag-end"?: (() => any) | undefined;
23
22
  }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
@@ -60,7 +60,7 @@ const __vue_sfc__ = /* @__PURE__ */ (0, import_vue.defineComponent)({
60
60
  }
61
61
  } catch (e) {
62
62
  }
63
- return { x: 0, y: 0 };
63
+ return void 0;
64
64
  };
65
65
  const offset = (0, import_vue2.ref)(loadOffset());
66
66
  const emit = __emit;
@@ -75,22 +75,11 @@ const __vue_sfc__ = /* @__PURE__ */ (0, import_vue.defineComponent)({
75
75
  saveOffset(value);
76
76
  emit("offset-change", value);
77
77
  };
78
- const bubbleRef = (0, import_vue2.ref)(null);
79
- const isOnRightSide = (0, import_vue2.computed)(() => {
80
- if (typeof window === "undefined") return true;
81
- const centerX = window.innerWidth / 2;
82
- return offset.value.x > centerX;
83
- });
84
- (0, import_vue2.onMounted)(() => {
85
- if (offset.value.x !== 0 || offset.value.y !== 0) {
86
- emit("offset-change", offset.value);
87
- }
88
- });
78
+ (0, import_vue2.watch)(offset, handleOffsetChange, { immediate: true });
89
79
  __expose({
90
- isOnRightSide,
91
80
  offset
92
81
  });
93
- const __returned__ = { active, open, hotkeyLabel, thinking, resolvedTheme, handleToggle, STORAGE_KEY, loadOffset, offset, emit, saveOffset, handleOffsetChange, bubbleRef, isOnRightSide, FloatingBubble: import_FloatingBubble_vue.default };
82
+ const __returned__ = { active, open, hotkeyLabel, thinking, resolvedTheme, handleToggle, STORAGE_KEY, loadOffset, offset, emit, saveOffset, handleOffsetChange, FloatingBubble: import_FloatingBubble_vue.default };
94
83
  Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
95
84
  return __returned__;
96
85
  }
@@ -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-thinking-gradient-1: #10b981;--oc-thinking-gradient-2: #059669;--oc-thinking-glow: rgba(16, 185, 129, .3);--oc-thinking-glow-strong: rgba(16, 185, 129, .6);--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: #3b82f6;--oc-trigger-bg-hover: #2563eb;--oc-trigger-bg-active: #1d4ed8;--oc-trigger-shadow: 0 2px 8px rgba(59, 130, 246, .3);--oc-trigger-shadow-hover: 0 4px 12px rgba(59, 130, 246, .4);--oc-trigger-shadow-active: 0 4px 12px rgba(59, 130, 246, .5);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-thinking-gradient-1: #34d399;--oc-thinking-gradient-2: #10b981;--oc-thinking-glow: rgba(52, 211, 153, .3);--oc-thinking-glow-strong: rgba(52, 211, 153, .6);--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: #60a5fa;--oc-trigger-bg-hover: #3b82f6;--oc-trigger-bg-active: #2563eb;--oc-trigger-shadow: 0 2px 8px rgba(96, 165, 250, .4);--oc-trigger-shadow-hover: 0 4px 12px rgba(96, 165, 250, .5);--oc-trigger-shadow-active: 0 4px 12px rgba(96, 165, 250, .6)}.opencode-chat{position:fixed;bottom:20px;width:700px;height:86vh;max-height:calc(100vh - 40px);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;z-index:99999}.opencode-chat.minimized{width:300px;height:300px}.opencode-chat.minimized .opencode-iframe-container{margin-top:-146px}.opencode-chat-content{display:flex;flex:1;overflow:hidden}.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-page-notification{position:fixed;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:2147483647;display:flex;align-items:center;gap:10px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif}.opencode-page-notification:before{content:"\1f4a1";font-size:16px}.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-thinking-gradient-1: #10b981;--oc-thinking-gradient-2: #059669;--oc-thinking-glow: rgba(16, 185, 129, .3);--oc-thinking-glow-strong: rgba(16, 185, 129, .6);--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: #3b82f6;--oc-trigger-bg-hover: #2563eb;--oc-trigger-bg-active: #1d4ed8;--oc-trigger-shadow: 0 2px 8px rgba(59, 130, 246, .3);--oc-trigger-shadow-hover: 0 4px 12px rgba(59, 130, 246, .4);--oc-trigger-shadow-active: 0 4px 12px rgba(59, 130, 246, .5);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-thinking-gradient-1: #34d399;--oc-thinking-gradient-2: #10b981;--oc-thinking-glow: rgba(52, 211, 153, .3);--oc-thinking-glow-strong: rgba(52, 211, 153, .6);--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: #60a5fa;--oc-trigger-bg-hover: #3b82f6;--oc-trigger-bg-active: #2563eb;--oc-trigger-shadow: 0 2px 8px rgba(96, 165, 250, .4);--oc-trigger-shadow-hover: 0 4px 12px rgba(96, 165, 250, .5);--oc-trigger-shadow-active: 0 4px 12px rgba(96, 165, 250, .6)}.opencode-chat{position:fixed;bottom:20px;width:700px;height:86vh;max-height:calc(100vh - 40px);background:var(--oc-bg-main);border-radius:16px;box-shadow:var(--oc-shadow-lg);overflow:hidden;opacity:0;visibility:hidden;transform:translate3d(var(---chatAnimationOrigin\.x),var(---chatAnimationOrigin\.y),0) scale(.95);transition:all .3s ease;display:flex;flex-direction:column;z-index:99999}.opencode-chat.minimized{width:300px;height:300px}.opencode-chat.minimized .opencode-iframe-container{margin-top:-146px}.opencode-chat-content{display:flex;flex:1;overflow:hidden}.opencode-chat.open{opacity:1;visibility:visible;transform:translateZ(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-page-notification{position:fixed;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:2147483647;display:flex;align-items:center;gap:10px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif}.opencode-page-notification:before{content:"\1f4a1";font-size:16px}.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)}}
@@ -92,6 +92,10 @@ const __vue_sfc__ = /* @__PURE__ */ (0, import_vue.defineComponent)(__spreadProp
92
92
  },
93
93
  emits: ["update:open", "update:selectMode", "update:sessionListCollapsed", "update:currentSessionId", "update:selectedElements", "update:theme", "update:thinking", "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", "frame-loaded", "thinking-change"],
94
94
  setup(__props, { expose: __expose, emit: __emit }) {
95
+ (0, import_vue.useCssVars)((_ctx) => ({
96
+ "-chatAnimationOrigin.x": chatAnimationOrigin.value.x,
97
+ "-chatAnimationOrigin.y": chatAnimationOrigin.value.y
98
+ }));
95
99
  const props = __props;
96
100
  const emit = __emit;
97
101
  const slots = (0, import_vue2.useSlots)();
@@ -250,13 +254,31 @@ const __vue_sfc__ = /* @__PURE__ */ (0, import_vue.defineComponent)(__spreadProp
250
254
  promptDockVisible.value = !promptDockVisible.value;
251
255
  sendMessageToIframe("prompt-dock-visibility-change", { visible: promptDockVisible.value });
252
256
  };
253
- const bubbleOffset = (0, import_vue2.ref)({ x: 0, y: 0 });
254
- const isBubbleOnRightSide = (0, import_vue2.computed)(() => {
255
- if (typeof window === "undefined") return true;
257
+ const bubbleOffset = (0, import_vue2.ref)(void 0);
258
+ const bubbleQuadrant = (0, import_vue2.computed)(() => {
259
+ var _a, _b, _c, _d;
260
+ if (typeof window === "undefined") return "bottom-right";
256
261
  const centerX = window.innerWidth / 2;
257
- return bubbleOffset.value.x > centerX;
262
+ const centerY = window.innerHeight / 2;
263
+ const bubbleSize = 44;
264
+ const effectiveX = ((_b = (_a = bubbleOffset.value) == null ? void 0 : _a.x) != null ? _b : window.innerWidth - bubbleSize - 24) + bubbleSize / 2;
265
+ const effectiveY = ((_d = (_c = bubbleOffset.value) == null ? void 0 : _c.y) != null ? _d : window.innerHeight - bubbleSize - 24) + bubbleSize / 2;
266
+ if (effectiveX >= centerX && effectiveY >= centerY) {
267
+ return "bottom-right";
268
+ } else if (effectiveX < centerX && effectiveY >= centerY) {
269
+ return "bottom-left";
270
+ } else if (effectiveX >= centerX && effectiveY < centerY) {
271
+ return "top-right";
272
+ } else {
273
+ return "top-left";
274
+ }
275
+ });
276
+ const isBubbleOnRightSide = (0, import_vue2.computed)(() => {
277
+ const quadrant = bubbleQuadrant.value;
278
+ return quadrant === "top-right" || quadrant === "bottom-right";
258
279
  });
259
280
  const chatPositionStyle = (0, import_vue2.computed)(() => {
281
+ var _a;
260
282
  if (typeof window === "undefined") return {};
261
283
  const windowWidth = window.innerWidth;
262
284
  const windowHeight = window.innerHeight;
@@ -265,9 +287,10 @@ const __vue_sfc__ = /* @__PURE__ */ (0, import_vue.defineComponent)(__spreadProp
265
287
  const gap = 24;
266
288
  const bubbleSize = 44;
267
289
  const screenMargin = 20;
290
+ const effectiveOffset = (_a = bubbleOffset.value) != null ? _a : { x: windowWidth - bubbleSize - gap, y: windowHeight - bubbleSize - gap };
268
291
  const style = {};
269
292
  if (isBubbleOnRightSide.value) {
270
- let rightPos = windowWidth - bubbleOffset.value.x + gap;
293
+ let rightPos = windowWidth - effectiveOffset.x + gap;
271
294
  const maxRight = windowWidth - chatWidth - screenMargin;
272
295
  if (rightPos > maxRight) {
273
296
  rightPos = maxRight;
@@ -275,7 +298,7 @@ const __vue_sfc__ = /* @__PURE__ */ (0, import_vue.defineComponent)(__spreadProp
275
298
  style.right = `${rightPos}px`;
276
299
  style.left = "auto";
277
300
  } else {
278
- let leftPos = bubbleOffset.value.x + bubbleSize + gap;
301
+ let leftPos = effectiveOffset.x + bubbleSize + gap;
279
302
  const maxLeft = windowWidth - chatWidth - screenMargin;
280
303
  if (leftPos > maxLeft) {
281
304
  leftPos = maxLeft;
@@ -283,7 +306,7 @@ const __vue_sfc__ = /* @__PURE__ */ (0, import_vue.defineComponent)(__spreadProp
283
306
  style.left = `${leftPos}px`;
284
307
  style.right = "auto";
285
308
  }
286
- let bottomPos = windowHeight - bubbleOffset.value.y - bubbleSize;
309
+ let bottomPos = windowHeight - effectiveOffset.y - bubbleSize;
287
310
  const maxBottom = windowHeight - chatHeight - screenMargin;
288
311
  if (bottomPos > maxBottom) {
289
312
  bottomPos = maxBottom;
@@ -297,6 +320,20 @@ const __vue_sfc__ = /* @__PURE__ */ (0, import_vue.defineComponent)(__spreadProp
297
320
  const handleBubbleOffsetChange = (offset) => {
298
321
  bubbleOffset.value = offset;
299
322
  };
323
+ const chatAnimationOrigin = (0, import_vue2.computed)(() => {
324
+ const quadrant = bubbleQuadrant.value;
325
+ switch (quadrant) {
326
+ case "top-left":
327
+ return { x: "-20px", y: "-20px" };
328
+ case "top-right":
329
+ return { x: "20px", y: "-20px" };
330
+ case "bottom-left":
331
+ return { x: "-20px", y: "20px" };
332
+ case "bottom-right":
333
+ default:
334
+ return { x: "20px", y: "20px" };
335
+ }
336
+ });
300
337
  const isDragging = (0, import_vue2.ref)(false);
301
338
  let wasOpenBeforeDrag = false;
302
339
  const handleDragStart = () => {
@@ -365,7 +402,7 @@ const __vue_sfc__ = /* @__PURE__ */ (0, import_vue.defineComponent)(__spreadProp
365
402
  return dialogResolve;
366
403
  }, set dialogResolve(v) {
367
404
  dialogResolve = v;
368
- }, showConfirmDialog, handleDialogConfirm, handleDialogCancel, frameRef, triggerRef, sendMessageToIframe, handleFrameLoaded, localSessionListCollapsed, minimized, promptDockVisible, 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, handleToggleMinimize, handleTogglePromptDock, bubbleOffset, isBubbleOnRightSide, chatPositionStyle, handleBubbleOffsetChange, isDragging, get wasOpenBeforeDrag() {
405
+ }, showConfirmDialog, handleDialogConfirm, handleDialogCancel, frameRef, triggerRef, sendMessageToIframe, handleFrameLoaded, localSessionListCollapsed, minimized, promptDockVisible, 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, handleToggleMinimize, handleTogglePromptDock, bubbleOffset, bubbleQuadrant, isBubbleOnRightSide, chatPositionStyle, handleBubbleOffsetChange, chatAnimationOrigin, isDragging, get wasOpenBeforeDrag() {
369
406
  return wasOpenBeforeDrag;
370
407
  }, set wasOpenBeforeDrag(v) {
371
408
  wasOpenBeforeDrag = v;
@@ -1 +1 @@
1
- {"$schema":"https://raw.githubusercontent.com/JetBrains/web-types/master/schema/web-types.json","framework":"vue","name":"@vite-plugin-opencode-assistant/components","version":"1.0.24","contributions":{"html":{"tags":[{"name":"open-code","attributes":[{"name":"","default":"`'bottom-right'`","description":"挂件显示的位置","value":{"type":"`'bottom-right' | 'bottom-left' | 'top-right' | 'top-left'`","kind":"expression"}},{"name":"","default":"`false`","description":"挂件是否打开","value":{"type":"`boolean`","kind":"expression"}},{"name":"","default":"`'auto'`","description":"主题模式","value":{"type":"`'light' | 'dark' | 'auto'`","kind":"expression"}},{"name":"","default":"`'AI 助手'`","description":"助手头部显示的标题","value":{"type":"`string`","kind":"expression"}},{"name":"","default":"`'Ctrl+K'`","description":"快捷键提示文本","value":{"type":"`string`","kind":"expression"}},{"name":"","default":"`'按 ESC 或 Ctrl+P 退出'`","description":"选择模式快捷键提示文本","value":{"type":"`string`","kind":"expression"}},{"name":"","default":"`false`","description":"是否进入选择页面元素模式","value":{"type":"`boolean`","kind":"expression"}},{"name":"","default":"`true`","description":"会话列表是否折叠","value":{"type":"`boolean`","kind":"expression"}},{"name":"","default":"`'id'`","description":"会话列表项的唯一键字段","value":{"type":"`string`","kind":"expression"}},{"name":"","default":"`false`","description":"iframe 是否显示加载状态","value":{"type":"`boolean`","kind":"expression"}},{"name":"","default":"`undefined`","description":"会话列表是否加载中","value":{"type":"`boolean`","kind":"expression"}},{"name":"","default":"`false`","description":"是否显示会话列表骨架屏","value":{"type":"`boolean`","kind":"expression"}},{"name":"","default":"`false`","description":"是否显示空状态","value":{"type":"`boolean`","kind":"expression"}},{"name":"","default":"`false`","description":"是否显示错误状态","value":{"type":"`boolean`","kind":"expression"}},{"name":"","default":"`'当前项目暂无会话'`","description":"空状态显示的文本","value":{"type":"`string`","kind":"expression"}},{"name":"","default":"`'立即创建'`","description":"空状态操作按钮文本","value":{"type":"`string`","kind":"expression"}},{"name":"","default":"`''`","description":"Web UI 的 URL 来源","value":{"type":"`string`","kind":"expression"}},{"name":"","default":"`[]`","description":"会话列表数据","value":{"type":"`OpenCodeWidgetSession[]`","kind":"expression"}},{"name":"","default":"`null`","description":"当前选中的会话 ID","value":{"type":"`string | null`","kind":"expression"}},{"name":"","default":"`[]`","description":"已选中的元素列表","value":{"type":"`OpenCodeSelectedElement[]`","kind":"expression"}},{"name":"","default":"`true`","description":"是否显示\"一键清空\"按钮","value":{"type":"`boolean`","kind":"expression"}},{"name":"","default":"`true`","description":"是否启用选择模式","value":{"type":"`boolean`","kind":"expression"}},{"name":"","default":"`false`","description":"是否显示思考状态(加载中)","value":{"type":"`boolean`","kind":"expression"}}],"events":[{"name":"`update:open`","description":"当挂件打开或关闭时触发","arguments":[{"name":"open","type":"en"},{"name":"boolean"}]},{"name":"`update:selectMode`","description":"当选择模式切换时触发","arguments":[{"name":"mode","type":"de"},{"name":"boolean"}]},{"name":"`update:sessionListCollapsed`","description":"当会话列表折叠状态改变时触发","arguments":[{"name":"collapsed","type":"ed"},{"name":"boolean"}]},{"name":"`update:currentSessionId`","description":"当选中的会话 ID 改变时触发","arguments":[{"name":"sessionId","type":"Id"},{"name":"string | null"}]},{"name":"`update:selectedElements`","description":"当已选中的元素列表改变时触发","arguments":[{"name":"elements","type":"ts"},{"name":"OpenCodeSelectedElement[]"}]},{"name":"`update:theme`","description":"当主题模式改变时触发","arguments":[{"name":"theme","type":"me"},{"name":"'light' | 'dark' | 'auto'"}]},{"name":"`update:thinking`","description":"当思考状态改变时触发","arguments":[{"name":"thinking","type":"ng"},{"name":"boolean"}]},{"name":"","description":"点击触发挂件开关","arguments":[{"name":"open","type":"en"},{"name":"boolean"}]},{"name":"","description":"点击关闭按钮时触发","arguments":[]},{"name":"`toggle-session-list`","description":"点击会话列表切换按钮时触发","arguments":[{"name":"collapsed","type":"ed"},{"name":"boolean"}]},{"name":"`toggle-select-mode`","description":"点击选择模式切换按钮时触发","arguments":[{"name":"mode","type":"de"},{"name":"boolean"}]},{"name":"`toggle-theme`","description":"点击主题切换按钮时触发","arguments":[{"name":"theme","type":"me"},{"name":"'light' | 'dark' | 'auto'"}]},{"name":"`create-session`","description":"点击创建新会话时触发","arguments":[]},{"name":"`select-session`","description":"选中某个历史会话时触发","arguments":[{"name":"session","type":"on"},{"name":"OpenCodeWidgetSession"}]},{"name":"`delete-session`","description":"删除某个历史会话时触发","arguments":[{"name":"session","type":"on"},{"name":"OpenCodeWidgetSession"}]},{"name":"`click-selected-node`","description":"点击已选中的气泡或节点卡片时触发","arguments":[{"name":"element","type":"nt"},{"name":"OpenCodeSelectedElement"}]},{"name":"`remove-selected-node`","description":"删除已选中的元素时触发","arguments":[{"name":"payload","type":"ad"},{"name":"OpenCodeRemoveSelectedPayload"}]},{"name":"`clear-selected-nodes`","description":"清空所有选中元素时触发","arguments":[]},{"name":"`empty-action`","description":"点击空状态操作按钮时触发","arguments":[]},{"name":"`frame-loaded`","description":"iframe 加载完成时触发","arguments":[]},{"name":"`thinking-change`","description":"思考状态改变时触发(用于显示加载动画)","arguments":[{"name":"thinking","type":"ng"},{"name":"boolean"}]}],"slots":[{"name":"`button-icon`","description":"自定义触发按钮图标"},{"name":"`session-toggle-icon`","description":"自定义会话列表切换图标"},{"name":"`select-icon`","description":"自定义选择模式切换图标"},{"name":"`close-icon`","description":"自定义关闭按钮图标"},{"name":"`theme-icon`","description":"自定义主题切换图标"},{"name":"`sessions-empty`","description":"自定义会话列表空状态"},{"name":"`empty-state`","description":"自定义 iframe 空状态"},{"name":"","description":"自定义 iframe 加载状态"},{"name":"","description":"自定义错误状态"},{"name":"","description":"自定义 iframe 内容"}]}],"attributes":[]}},"js-types-syntax":"typescript"}
1
+ {"$schema":"https://raw.githubusercontent.com/JetBrains/web-types/master/schema/web-types.json","framework":"vue","name":"@vite-plugin-opencode-assistant/components","version":"1.0.26","contributions":{"html":{"tags":[{"name":"open-code","attributes":[{"name":"","default":"`'bottom-right'`","description":"挂件显示的位置","value":{"type":"`'bottom-right' | 'bottom-left' | 'top-right' | 'top-left'`","kind":"expression"}},{"name":"","default":"`false`","description":"挂件是否打开","value":{"type":"`boolean`","kind":"expression"}},{"name":"","default":"`'auto'`","description":"主题模式","value":{"type":"`'light' | 'dark' | 'auto'`","kind":"expression"}},{"name":"","default":"`'AI 助手'`","description":"助手头部显示的标题","value":{"type":"`string`","kind":"expression"}},{"name":"","default":"`'Ctrl+K'`","description":"快捷键提示文本","value":{"type":"`string`","kind":"expression"}},{"name":"","default":"`'按 ESC 或 Ctrl+P 退出'`","description":"选择模式快捷键提示文本","value":{"type":"`string`","kind":"expression"}},{"name":"","default":"`false`","description":"是否进入选择页面元素模式","value":{"type":"`boolean`","kind":"expression"}},{"name":"","default":"`true`","description":"会话列表是否折叠","value":{"type":"`boolean`","kind":"expression"}},{"name":"","default":"`'id'`","description":"会话列表项的唯一键字段","value":{"type":"`string`","kind":"expression"}},{"name":"","default":"`false`","description":"iframe 是否显示加载状态","value":{"type":"`boolean`","kind":"expression"}},{"name":"","default":"`undefined`","description":"会话列表是否加载中","value":{"type":"`boolean`","kind":"expression"}},{"name":"","default":"`false`","description":"是否显示会话列表骨架屏","value":{"type":"`boolean`","kind":"expression"}},{"name":"","default":"`false`","description":"是否显示空状态","value":{"type":"`boolean`","kind":"expression"}},{"name":"","default":"`false`","description":"是否显示错误状态","value":{"type":"`boolean`","kind":"expression"}},{"name":"","default":"`'当前项目暂无会话'`","description":"空状态显示的文本","value":{"type":"`string`","kind":"expression"}},{"name":"","default":"`'立即创建'`","description":"空状态操作按钮文本","value":{"type":"`string`","kind":"expression"}},{"name":"","default":"`''`","description":"Web UI 的 URL 来源","value":{"type":"`string`","kind":"expression"}},{"name":"","default":"`[]`","description":"会话列表数据","value":{"type":"`OpenCodeWidgetSession[]`","kind":"expression"}},{"name":"","default":"`null`","description":"当前选中的会话 ID","value":{"type":"`string | null`","kind":"expression"}},{"name":"","default":"`[]`","description":"已选中的元素列表","value":{"type":"`OpenCodeSelectedElement[]`","kind":"expression"}},{"name":"","default":"`true`","description":"是否显示\"一键清空\"按钮","value":{"type":"`boolean`","kind":"expression"}},{"name":"","default":"`true`","description":"是否启用选择模式","value":{"type":"`boolean`","kind":"expression"}},{"name":"","default":"`false`","description":"是否显示思考状态(加载中)","value":{"type":"`boolean`","kind":"expression"}}],"events":[{"name":"`update:open`","description":"当挂件打开或关闭时触发","arguments":[{"name":"open","type":"en"},{"name":"boolean"}]},{"name":"`update:selectMode`","description":"当选择模式切换时触发","arguments":[{"name":"mode","type":"de"},{"name":"boolean"}]},{"name":"`update:sessionListCollapsed`","description":"当会话列表折叠状态改变时触发","arguments":[{"name":"collapsed","type":"ed"},{"name":"boolean"}]},{"name":"`update:currentSessionId`","description":"当选中的会话 ID 改变时触发","arguments":[{"name":"sessionId","type":"Id"},{"name":"string | null"}]},{"name":"`update:selectedElements`","description":"当已选中的元素列表改变时触发","arguments":[{"name":"elements","type":"ts"},{"name":"OpenCodeSelectedElement[]"}]},{"name":"`update:theme`","description":"当主题模式改变时触发","arguments":[{"name":"theme","type":"me"},{"name":"'light' | 'dark' | 'auto'"}]},{"name":"`update:thinking`","description":"当思考状态改变时触发","arguments":[{"name":"thinking","type":"ng"},{"name":"boolean"}]},{"name":"","description":"点击触发挂件开关","arguments":[{"name":"open","type":"en"},{"name":"boolean"}]},{"name":"","description":"点击关闭按钮时触发","arguments":[]},{"name":"`toggle-session-list`","description":"点击会话列表切换按钮时触发","arguments":[{"name":"collapsed","type":"ed"},{"name":"boolean"}]},{"name":"`toggle-select-mode`","description":"点击选择模式切换按钮时触发","arguments":[{"name":"mode","type":"de"},{"name":"boolean"}]},{"name":"`toggle-theme`","description":"点击主题切换按钮时触发","arguments":[{"name":"theme","type":"me"},{"name":"'light' | 'dark' | 'auto'"}]},{"name":"`create-session`","description":"点击创建新会话时触发","arguments":[]},{"name":"`select-session`","description":"选中某个历史会话时触发","arguments":[{"name":"session","type":"on"},{"name":"OpenCodeWidgetSession"}]},{"name":"`delete-session`","description":"删除某个历史会话时触发","arguments":[{"name":"session","type":"on"},{"name":"OpenCodeWidgetSession"}]},{"name":"`click-selected-node`","description":"点击已选中的气泡或节点卡片时触发","arguments":[{"name":"element","type":"nt"},{"name":"OpenCodeSelectedElement"}]},{"name":"`remove-selected-node`","description":"删除已选中的元素时触发","arguments":[{"name":"payload","type":"ad"},{"name":"OpenCodeRemoveSelectedPayload"}]},{"name":"`clear-selected-nodes`","description":"清空所有选中元素时触发","arguments":[]},{"name":"`empty-action`","description":"点击空状态操作按钮时触发","arguments":[]},{"name":"`frame-loaded`","description":"iframe 加载完成时触发","arguments":[]},{"name":"`thinking-change`","description":"思考状态改变时触发(用于显示加载动画)","arguments":[{"name":"thinking","type":"ng"},{"name":"boolean"}]}],"slots":[{"name":"`button-icon`","description":"自定义触发按钮图标"},{"name":"`session-toggle-icon`","description":"自定义会话列表切换图标"},{"name":"`select-icon`","description":"自定义选择模式切换图标"},{"name":"`close-icon`","description":"自定义关闭按钮图标"},{"name":"`theme-icon`","description":"自定义主题切换图标"},{"name":"`sessions-empty`","description":"自定义会话列表空状态"},{"name":"`empty-state`","description":"自定义 iframe 空状态"},{"name":"","description":"自定义 iframe 加载状态"},{"name":"","description":"自定义错误状态"},{"name":"","description":"自定义 iframe 内容"}]}],"attributes":[]}},"js-types-syntax":"typescript"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vite-plugin-opencode-assistant/components",
3
- "version": "1.0.24",
3
+ "version": "1.0.26",
4
4
  "description": "Reusable OpenCode widget components built with Pagoda CLI",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
@@ -31,7 +31,7 @@
31
31
  },
32
32
  "dependencies": {
33
33
  "css-selector-generator": "^3.9.1",
34
- "@vite-plugin-opencode-assistant/shared": "1.0.24"
34
+ "@vite-plugin-opencode-assistant/shared": "1.0.26"
35
35
  },
36
36
  "devDependencies": {
37
37
  "@vitejs/plugin-vue": "^6.0.5",