@vite-plugin-opencode-assistant/components 1.0.37 → 1.0.38

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/es/index.d.ts +1 -1
  2. package/es/index.js +1 -1
  3. package/es/open-code-widget/composables/use-persist-state.d.ts +2 -0
  4. package/es/open-code-widget/composables/use-persist-state.js +24 -9
  5. package/es/open-code-widget/composables/use-split.d.ts +24 -0
  6. package/es/open-code-widget/composables/use-split.js +90 -0
  7. package/es/open-code-widget/src/components/ChatPanel-sfc.css +1 -0
  8. package/es/open-code-widget/src/components/ChatPanel.vue.d.ts +180 -0
  9. package/es/open-code-widget/src/components/ChatPanel.vue.js +288 -0
  10. package/es/open-code-widget/src/components/Header.vue.js +13 -8
  11. package/es/open-code-widget/src/components/ResizeHandle-sfc.css +1 -0
  12. package/es/open-code-widget/src/components/ResizeHandle.vue.d.ts +19 -0
  13. package/es/open-code-widget/src/components/ResizeHandle.vue.js +91 -0
  14. package/es/open-code-widget/src/components/SplitTrigger-sfc.css +1 -0
  15. package/es/open-code-widget/src/components/SplitTrigger.vue.d.ts +17 -0
  16. package/es/open-code-widget/src/components/SplitTrigger.vue.js +130 -0
  17. package/es/open-code-widget/src/context.d.ts +1 -0
  18. package/es/open-code-widget/src/index-sfc.css +1 -1
  19. package/es/open-code-widget/src/index.vue.d.ts +16 -53
  20. package/es/open-code-widget/src/index.vue.js +150 -140
  21. package/es/open-code-widget/src/types.d.ts +1 -1
  22. package/lib/@vite-plugin-opencode-assistant/components.cjs.js +806 -248
  23. package/lib/@vite-plugin-opencode-assistant/components.es.js +802 -244
  24. package/lib/components.css +5 -3
  25. package/lib/index.d.ts +1 -1
  26. package/lib/index.js +1 -1
  27. package/lib/open-code-widget/composables/use-persist-state.d.ts +2 -0
  28. package/lib/open-code-widget/composables/use-persist-state.js +24 -9
  29. package/lib/open-code-widget/composables/use-split.d.ts +24 -0
  30. package/lib/open-code-widget/composables/use-split.js +109 -0
  31. package/lib/open-code-widget/src/components/ChatPanel-sfc.css +1 -0
  32. package/lib/open-code-widget/src/components/ChatPanel.vue.d.ts +180 -0
  33. package/lib/open-code-widget/src/components/ChatPanel.vue.js +315 -0
  34. package/lib/open-code-widget/src/components/Header.vue.js +12 -7
  35. package/lib/open-code-widget/src/components/ResizeHandle-sfc.css +1 -0
  36. package/lib/open-code-widget/src/components/ResizeHandle.vue.d.ts +19 -0
  37. package/lib/open-code-widget/src/components/ResizeHandle.vue.js +108 -0
  38. package/lib/open-code-widget/src/components/SplitTrigger-sfc.css +1 -0
  39. package/lib/open-code-widget/src/components/SplitTrigger.vue.d.ts +17 -0
  40. package/lib/open-code-widget/src/components/SplitTrigger.vue.js +147 -0
  41. package/lib/open-code-widget/src/context.d.ts +1 -0
  42. package/lib/open-code-widget/src/index-sfc.css +1 -1
  43. package/lib/open-code-widget/src/index.vue.d.ts +16 -53
  44. package/lib/open-code-widget/src/index.vue.js +149 -139
  45. package/lib/open-code-widget/src/types.d.ts +1 -1
  46. package/lib/web-types.json +1 -1
  47. package/package.json +2 -2
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.37";
3
+ declare const version = "1.0.38";
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.37";
2
+ const version = "1.0.38";
3
3
  function install(app, options) {
4
4
  const components = [
5
5
  OpenCodeWidget
@@ -8,6 +8,7 @@ export interface WidgetPersistState {
8
8
  bubbleOffset?: FloatingBubbleOffset;
9
9
  theme: OpenCodeWidgetTheme;
10
10
  sessionListCollapsed: boolean;
11
+ splitPanelWidth?: number;
11
12
  }
12
13
  export interface UsePersistStateOptions {
13
14
  open: Ref<boolean>;
@@ -16,6 +17,7 @@ export interface UsePersistStateOptions {
16
17
  bubbleOffset: Ref<FloatingBubbleOffset | undefined>;
17
18
  theme: Ref<OpenCodeWidgetTheme>;
18
19
  sessionListCollapsed: Ref<boolean>;
20
+ splitPanelWidth?: Ref<number>;
19
21
  onRestore?: (state: Partial<WidgetPersistState>) => void;
20
22
  }
21
23
  export declare function usePersistState(options: UsePersistStateOptions): {
@@ -28,21 +28,36 @@ function usePersistState(options) {
28
28
  }
29
29
  return saved;
30
30
  };
31
- const getCurrentState = () => ({
32
- open: options.open.value,
33
- minimized: options.minimized.value,
34
- promptDockVisible: options.promptDockVisible.value,
35
- bubbleOffset: options.bubbleOffset.value,
36
- theme: options.theme.value,
37
- sessionListCollapsed: options.sessionListCollapsed.value
38
- });
31
+ const getCurrentState = () => {
32
+ var _a;
33
+ return {
34
+ open: options.open.value,
35
+ minimized: options.minimized.value,
36
+ promptDockVisible: options.promptDockVisible.value,
37
+ bubbleOffset: options.bubbleOffset.value,
38
+ theme: options.theme.value,
39
+ sessionListCollapsed: options.sessionListCollapsed.value,
40
+ splitPanelWidth: (_a = options.splitPanelWidth) == null ? void 0 : _a.value
41
+ };
42
+ };
39
43
  const persistState = () => {
40
44
  saveState(getCurrentState());
41
45
  };
46
+ const watchers = [
47
+ options.open,
48
+ options.minimized,
49
+ options.promptDockVisible,
50
+ options.bubbleOffset,
51
+ options.theme,
52
+ options.sessionListCollapsed
53
+ ];
54
+ if (options.splitPanelWidth) {
55
+ watchers.push(options.splitPanelWidth);
56
+ }
42
57
  onMounted(() => {
43
58
  restoreState();
44
59
  watch(
45
- [options.open, options.minimized, options.promptDockVisible, options.bubbleOffset, options.theme, options.sessionListCollapsed],
60
+ watchers,
46
61
  () => {
47
62
  persistState();
48
63
  },
@@ -0,0 +1,24 @@
1
+ import { type Ref } from "vue";
2
+ import type { DisplayMode, SplitModeOptions } from "@vite-plugin-opencode-assistant/shared";
3
+ export interface UseSplitModeOptions {
4
+ displayMode: Ref<DisplayMode>;
5
+ splitMode: Ref<SplitModeOptions | undefined>;
6
+ open: Ref<boolean>;
7
+ onOpenChange?: (open: boolean) => void;
8
+ onWidthChange?: (width: number) => void;
9
+ }
10
+ export declare function useSplitMode(options: UseSplitModeOptions): {
11
+ effectiveMode: import("vue").ComputedRef<"bubble" | "split">;
12
+ isSplitMode: import("vue").ComputedRef<boolean>;
13
+ panelWidth: Ref<number, number>;
14
+ splitConfig: import("vue").ComputedRef<{
15
+ width: number;
16
+ minWidth: number;
17
+ maxWidth: number;
18
+ resizable: boolean;
19
+ shrinkPage: boolean;
20
+ defaultOpen: boolean;
21
+ }>;
22
+ handleResize: (width: number) => void;
23
+ handleToggle: () => void;
24
+ };
@@ -0,0 +1,90 @@
1
+ import { ref, computed, watch, onMounted, onUnmounted } from "vue";
2
+ const AUTO_MODE_THRESHOLD = 1440;
3
+ function useSplitMode(options) {
4
+ const windowWidth = ref(typeof window !== "undefined" ? window.innerWidth : 0);
5
+ const splitConfig = computed(() => {
6
+ var _a, _b, _c, _d, _e, _f;
7
+ const config = options.splitMode.value || {};
8
+ return {
9
+ width: (_a = config.width) != null ? _a : 500,
10
+ minWidth: (_b = config.minWidth) != null ? _b : 400,
11
+ maxWidth: (_c = config.maxWidth) != null ? _c : 800,
12
+ resizable: (_d = config.resizable) != null ? _d : true,
13
+ shrinkPage: (_e = config.shrinkPage) != null ? _e : true,
14
+ defaultOpen: (_f = config.defaultOpen) != null ? _f : true
15
+ };
16
+ });
17
+ const panelWidth = ref(splitConfig.value.width);
18
+ const effectiveMode = computed(() => {
19
+ if (options.displayMode.value === "bubble") {
20
+ return "bubble";
21
+ }
22
+ if (options.displayMode.value === "split") {
23
+ return "split";
24
+ }
25
+ return windowWidth.value >= AUTO_MODE_THRESHOLD ? "split" : "bubble";
26
+ });
27
+ const isSplitMode = computed(() => effectiveMode.value === "split");
28
+ const handleResize = (width) => {
29
+ var _a;
30
+ panelWidth.value = width;
31
+ (_a = options.onWidthChange) == null ? void 0 : _a.call(options, width);
32
+ };
33
+ const handleToggle = () => {
34
+ var _a;
35
+ const nextOpen = !options.open.value;
36
+ (_a = options.onOpenChange) == null ? void 0 : _a.call(options, nextOpen);
37
+ };
38
+ const handleWindowResize = () => {
39
+ if (typeof window !== "undefined") {
40
+ windowWidth.value = window.innerWidth;
41
+ }
42
+ };
43
+ const updateBodyClass = () => {
44
+ if (typeof document === "undefined") return;
45
+ const shouldShrink = isSplitMode.value && options.open.value && splitConfig.value.shrinkPage;
46
+ if (shouldShrink) {
47
+ document.body.classList.add("has-opencode-split");
48
+ document.body.style.setProperty("--opencode-split-width", `${panelWidth.value}px`);
49
+ } else {
50
+ document.body.classList.remove("has-opencode-split");
51
+ document.body.style.removeProperty("--opencode-split-width");
52
+ }
53
+ };
54
+ watch([isSplitMode, options.open, panelWidth], updateBodyClass, { immediate: true });
55
+ watch(splitConfig, (config) => {
56
+ if (panelWidth.value < config.minWidth) {
57
+ panelWidth.value = config.minWidth;
58
+ }
59
+ if (panelWidth.value > config.maxWidth) {
60
+ panelWidth.value = config.maxWidth;
61
+ }
62
+ });
63
+ onMounted(() => {
64
+ var _a;
65
+ if (typeof window !== "undefined") {
66
+ window.addEventListener("resize", handleWindowResize);
67
+ if (isSplitMode.value && splitConfig.value.defaultOpen && !options.open.value) {
68
+ (_a = options.onOpenChange) == null ? void 0 : _a.call(options, true);
69
+ }
70
+ }
71
+ });
72
+ onUnmounted(() => {
73
+ if (typeof window !== "undefined") {
74
+ window.removeEventListener("resize", handleWindowResize);
75
+ document.body.classList.remove("has-opencode-split");
76
+ document.body.style.removeProperty("--opencode-split-width");
77
+ }
78
+ });
79
+ return {
80
+ effectiveMode,
81
+ isSplitMode,
82
+ panelWidth,
83
+ splitConfig,
84
+ handleResize,
85
+ handleToggle
86
+ };
87
+ }
88
+ export {
89
+ useSplitMode
90
+ };
@@ -0,0 +1 @@
1
+ .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;display:flex;flex-direction:column;z-index:99999}.opencode-chat:not(.split-mode){opacity:0;visibility:hidden;transition:all .3s ease;transform:translate3d(var(---animationOrigin\.x),var(---animationOrigin\.y),0) scale(.95)}.opencode-chat.split-mode{position:fixed;right:0;top:0;bottom:0;height:100vh;max-height:100vh;border-radius:0;border-left:1px solid var(--oc-border-primary);box-shadow:var(--oc-shadow-lg);transform:translate(100%);overflow:visible;opacity:1;visibility:visible;transition:transform .3s ease}.opencode-chat.split-mode .opencode-chat-content{overflow:hidden;flex:1}.opencode-chat.split-mode.open{transform:translate(0)}.opencode-chat.split-mode.dragging{transition:none}.opencode-chat.dragging .opencode-iframe{pointer-events:none}.opencode-chat:not(.split-mode){opacity:0;visibility:hidden;transition:all .3s ease}.opencode-chat:not(.split-mode).open{opacity:1;visibility:visible;transform:translateZ(0) scale(1)}.opencode-chat.no-transition,.opencode-chat.no-transition.open{transition:none!important}.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-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;z-index:100;animation:opencode-notification-fade-in .3s ease}@keyframes opencode-notification-fade-in{0%{opacity:0;transform:translate(-50%) translateY(-10px)}to{opacity:1;transform:translate(-50%) translateY(0)}}.opencode-session-empty{padding:24px;text-align:center;color:var(--oc-text-placeholder);font-size:14px}.opencode-split-toggle-btn{position:absolute;left:-21px;top:50%;transform:translateY(-50%);width:20px;height:48px;background:#fff;border:none;border-radius:8px 0 0 8px;cursor:pointer;display:flex;align-items:center;justify-content:center;color:#667eea;box-shadow:0 4px 12px rgba(102,126,234,.4);transition:all .3s ease;z-index:5;transform-origin:right center}.opencode-split-toggle-btn:hover{transform:translateY(-50%) scale(1.1);box-shadow:0 6px 16px rgba(102,126,234,.5)}.opencode-split-toggle-btn.opencode-theme-dark{background:linear-gradient(135deg,#667eea,#764ba2);color:#fff;box-shadow:0 4px 12px rgba(102,126,234,.3)}.opencode-split-toggle-btn.opencode-theme-dark:before{content:"";position:absolute;left:-2px;top:-2px;right:0;bottom:-2px;border-radius:8px 0 0 8px;background:linear-gradient(135deg,#8b9cf5,#9d6bc7);z-index:-1}.opencode-split-toggle-btn.opencode-theme-dark:hover{box-shadow:0 6px 16px rgba(102,126,234,.4)}.opencode-split-toggle-btn.thinking{background:linear-gradient(135deg,#667eea,#764ba2);color:#fff;animation:split-thinking-glow 2s ease-in-out infinite,split-thinking-pulse 2s 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-split-toggle-btn.thinking:before{content:"";position:absolute;left:-2px;top:-2px;right:0;bottom:-2px;border-radius:8px 0 0 8px;background:linear-gradient(135deg,#8b9cf5,#9d6bc7);z-index:-1}.opencode-split-toggle-btn.thinking:after{content:"";position:absolute;left:-3px;top:-3px;right:-1px;bottom:-3px;border-radius:8px 0 0 8px;background:conic-gradient(from 180deg,transparent,rgba(102,126,234,.3),transparent,rgba(118,75,162,.3),transparent);z-index:-2;animation:split-thinking-rotate 2s linear infinite reverse;filter:blur(8px)}@keyframes split-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 split-thinking-rotate{0%{transform:rotate(0)}to{transform:rotate(360deg)}}@keyframes split-thinking-pulse{0%,to{transform:translateY(-50%) scale(1)}50%{transform:translateY(-50%) scale(.92)}}.opencode-split-toggle-icon{display:flex;align-items:center;justify-content:center;transition:transform .25s ease}.opencode-split-toggle-btn:hover .opencode-split-toggle-icon{transform:scale(1.1)}
@@ -0,0 +1,180 @@
1
+ type __VLS_Props = {
2
+ mode?: "bubble" | "split";
3
+ open?: boolean;
4
+ minimized?: boolean;
5
+ positionStyle?: Record<string, string>;
6
+ animationOrigin?: {
7
+ x: string;
8
+ y: string;
9
+ };
10
+ panelWidth?: number;
11
+ resizable?: boolean;
12
+ minWidth?: number;
13
+ maxWidth?: number;
14
+ noTransition?: boolean;
15
+ dragging?: boolean;
16
+ notificationVisible?: boolean;
17
+ notificationMessage?: string;
18
+ notificationMode?: "widget" | "page";
19
+ thinking?: boolean;
20
+ resolvedTheme?: "light" | "dark";
21
+ };
22
+ declare var __VLS_13: {}, __VLS_15: {}, __VLS_17: {}, __VLS_22: {}, __VLS_29: {}, __VLS_31: {}, __VLS_33: {}, __VLS_35: {};
23
+ type __VLS_Slots = {} & {
24
+ 'session-toggle-icon'?: (props: typeof __VLS_13) => any;
25
+ } & {
26
+ 'select-icon'?: (props: typeof __VLS_15) => any;
27
+ } & {
28
+ 'close-icon'?: (props: typeof __VLS_17) => any;
29
+ } & {
30
+ 'sessions-empty'?: (props: typeof __VLS_22) => any;
31
+ } & {
32
+ 'empty-state'?: (props: typeof __VLS_29) => any;
33
+ } & {
34
+ loading?: (props: typeof __VLS_31) => any;
35
+ } & {
36
+ error?: (props: typeof __VLS_33) => any;
37
+ } & {
38
+ content?: (props: typeof __VLS_35) => any;
39
+ };
40
+ declare const __VLS_component: import("vue").DefineComponent<__VLS_Props, {
41
+ sendMessageToIframe: (type: string, data?: Record<string, unknown>) => void;
42
+ frameRef: import("vue").Ref<({
43
+ $: import("vue").ComponentInternalInstance;
44
+ $data: {};
45
+ $props: Partial<{}> & Omit<{} & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, never>;
46
+ $attrs: import("vue").Attrs;
47
+ $refs: {
48
+ [x: string]: unknown;
49
+ };
50
+ $slots: Readonly<{
51
+ [name: string]: import("vue").Slot<any> | undefined;
52
+ }>;
53
+ $root: import("vue").ComponentPublicInstance | null;
54
+ $parent: import("vue").ComponentPublicInstance | null;
55
+ $host: Element | null;
56
+ $emit: (event: string, ...args: any[]) => void;
57
+ $el: any;
58
+ $options: import("vue").ComponentOptionsBase<Readonly<{}> & Readonly<{}>, {
59
+ sendMessageToIframe: (type: string, data?: Record<string, unknown>) => void;
60
+ }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, {}, {}, string, {}, import("vue").GlobalComponents, import("vue").GlobalDirectives, string, import("vue").ComponentProvideOptions> & {
61
+ beforeCreate?: (() => void) | (() => void)[];
62
+ created?: (() => void) | (() => void)[];
63
+ beforeMount?: (() => void) | (() => void)[];
64
+ mounted?: (() => void) | (() => void)[];
65
+ beforeUpdate?: (() => void) | (() => void)[];
66
+ updated?: (() => void) | (() => void)[];
67
+ activated?: (() => void) | (() => void)[];
68
+ deactivated?: (() => void) | (() => void)[];
69
+ beforeDestroy?: (() => void) | (() => void)[];
70
+ beforeUnmount?: (() => void) | (() => void)[];
71
+ destroyed?: (() => void) | (() => void)[];
72
+ unmounted?: (() => void) | (() => void)[];
73
+ renderTracked?: ((e: import("vue").DebuggerEvent) => void) | ((e: import("vue").DebuggerEvent) => void)[];
74
+ renderTriggered?: ((e: import("vue").DebuggerEvent) => void) | ((e: import("vue").DebuggerEvent) => void)[];
75
+ errorCaptured?: ((err: unknown, instance: import("vue").ComponentPublicInstance | null, info: string) => boolean | void) | ((err: unknown, instance: import("vue").ComponentPublicInstance | null, info: string) => boolean | void)[];
76
+ };
77
+ $forceUpdate: () => void;
78
+ $nextTick: typeof import("vue").nextTick;
79
+ $watch<T extends string | ((...args: any) => any)>(source: T, cb: T extends (...args: any) => infer R ? (...args: [R, R, import("@vue/reactivity").OnCleanup]) => any : (...args: [any, any, import("@vue/reactivity").OnCleanup]) => any, options?: import("vue").WatchOptions): import("vue").WatchStopHandle;
80
+ } & Readonly<{}> & Omit<Readonly<{}> & Readonly<{}>, "sendMessageToIframe"> & {
81
+ sendMessageToIframe: (type: string, data?: Record<string, unknown>) => void;
82
+ } & {} & import("vue").ComponentCustomProperties & {} & {
83
+ $slots: {
84
+ 'empty-state'?: (props: {}) => any;
85
+ } & {
86
+ loading?: (props: {}) => any;
87
+ } & {
88
+ error?: (props: {}) => any;
89
+ } & {
90
+ content?: (props: {}) => any;
91
+ };
92
+ }) | null, ({
93
+ $: import("vue").ComponentInternalInstance;
94
+ $data: {};
95
+ $props: Partial<{}> & Omit<{} & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, never>;
96
+ $attrs: import("vue").Attrs;
97
+ $refs: {
98
+ [x: string]: unknown;
99
+ };
100
+ $slots: Readonly<{
101
+ [name: string]: import("vue").Slot<any> | undefined;
102
+ }>;
103
+ $root: import("vue").ComponentPublicInstance | null;
104
+ $parent: import("vue").ComponentPublicInstance | null;
105
+ $host: Element | null;
106
+ $emit: (event: string, ...args: any[]) => void;
107
+ $el: any;
108
+ $options: import("vue").ComponentOptionsBase<Readonly<{}> & Readonly<{}>, {
109
+ sendMessageToIframe: (type: string, data?: Record<string, unknown>) => void;
110
+ }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, {}, {}, string, {}, import("vue").GlobalComponents, import("vue").GlobalDirectives, string, import("vue").ComponentProvideOptions> & {
111
+ beforeCreate?: (() => void) | (() => void)[];
112
+ created?: (() => void) | (() => void)[];
113
+ beforeMount?: (() => void) | (() => void)[];
114
+ mounted?: (() => void) | (() => void)[];
115
+ beforeUpdate?: (() => void) | (() => void)[];
116
+ updated?: (() => void) | (() => void)[];
117
+ activated?: (() => void) | (() => void)[];
118
+ deactivated?: (() => void) | (() => void)[];
119
+ beforeDestroy?: (() => void) | (() => void)[];
120
+ beforeUnmount?: (() => void) | (() => void)[];
121
+ destroyed?: (() => void) | (() => void)[];
122
+ unmounted?: (() => void) | (() => void)[];
123
+ renderTracked?: ((e: import("vue").DebuggerEvent) => void) | ((e: import("vue").DebuggerEvent) => void)[];
124
+ renderTriggered?: ((e: import("vue").DebuggerEvent) => void) | ((e: import("vue").DebuggerEvent) => void)[];
125
+ errorCaptured?: ((err: unknown, instance: import("vue").ComponentPublicInstance | null, info: string) => boolean | void) | ((err: unknown, instance: import("vue").ComponentPublicInstance | null, info: string) => boolean | void)[];
126
+ };
127
+ $forceUpdate: () => void;
128
+ $nextTick: typeof import("vue").nextTick;
129
+ $watch<T extends string | ((...args: any) => any)>(source: T, cb: T extends (...args: any) => infer R ? (...args: [R, R, import("@vue/reactivity").OnCleanup]) => any : (...args: [any, any, import("@vue/reactivity").OnCleanup]) => any, options?: import("vue").WatchOptions): import("vue").WatchStopHandle;
130
+ } & Readonly<{}> & Omit<Readonly<{}> & Readonly<{}>, "sendMessageToIframe"> & {
131
+ sendMessageToIframe: (type: string, data?: Record<string, unknown>) => void;
132
+ } & {} & import("vue").ComponentCustomProperties & {} & {
133
+ $slots: {
134
+ 'empty-state'?: (props: {}) => any;
135
+ } & {
136
+ loading?: (props: {}) => any;
137
+ } & {
138
+ error?: (props: {}) => any;
139
+ } & {
140
+ content?: (props: {}) => any;
141
+ };
142
+ }) | null>;
143
+ }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
144
+ resize: (width: number) => any;
145
+ toggle: () => any;
146
+ "resize-start": () => any;
147
+ "resize-end": () => any;
148
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
149
+ onResize?: ((width: number) => any) | undefined;
150
+ onToggle?: (() => any) | undefined;
151
+ "onResize-start"?: (() => any) | undefined;
152
+ "onResize-end"?: (() => any) | undefined;
153
+ }>, {
154
+ resolvedTheme: "light" | "dark";
155
+ minimized: boolean;
156
+ mode: "bubble" | "split";
157
+ thinking: boolean;
158
+ minWidth: number;
159
+ maxWidth: number;
160
+ open: boolean;
161
+ positionStyle: Record<string, string>;
162
+ animationOrigin: {
163
+ x: string;
164
+ y: string;
165
+ };
166
+ panelWidth: number;
167
+ resizable: boolean;
168
+ noTransition: boolean;
169
+ dragging: boolean;
170
+ notificationVisible: boolean;
171
+ notificationMessage: string;
172
+ notificationMode: "widget" | "page";
173
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
174
+ declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
175
+ export default _default;
176
+ type __VLS_WithSlots<T, S> = T & {
177
+ new (): {
178
+ $slots: S;
179
+ };
180
+ };
@@ -0,0 +1,288 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __defProps = Object.defineProperties;
3
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
7
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8
+ var __spreadValues = (a, b) => {
9
+ for (var prop in b || (b = {}))
10
+ if (__hasOwnProp.call(b, prop))
11
+ __defNormalProp(a, prop, b[prop]);
12
+ if (__getOwnPropSymbols)
13
+ for (var prop of __getOwnPropSymbols(b)) {
14
+ if (__propIsEnum.call(b, prop))
15
+ __defNormalProp(a, prop, b[prop]);
16
+ }
17
+ return a;
18
+ };
19
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
20
+ import "./ChatPanel-sfc.css";
21
+ import { useCssVars as _useCssVars, defineComponent as _defineComponent } from "vue";
22
+ import { ref, computed, useSlots } from "vue";
23
+ import Frame from "./Frame.vue.js";
24
+ import Header from "./Header.vue.js";
25
+ import SessionList from "./SessionList.vue.js";
26
+ import SelectedNodes from "./SelectedNodes.vue.js";
27
+ import ResizeHandle from "./ResizeHandle.vue.js";
28
+ const __vue_sfc__ = /* @__PURE__ */ _defineComponent(__spreadProps(__spreadValues({}, {
29
+ name: "ChatPanel"
30
+ }), {
31
+ __name: "ChatPanel",
32
+ props: {
33
+ mode: { type: String, required: false, default: "bubble" },
34
+ open: { type: Boolean, required: false, default: false },
35
+ minimized: { type: Boolean, required: false, default: false },
36
+ positionStyle: { type: Object, required: false, default: () => ({}) },
37
+ animationOrigin: { type: Object, required: false, default: () => ({ x: "20px", y: "20px" }) },
38
+ panelWidth: { type: Number, required: false, default: 500 },
39
+ resizable: { type: Boolean, required: false, default: true },
40
+ minWidth: { type: Number, required: false, default: 400 },
41
+ maxWidth: { type: Number, required: false, default: 800 },
42
+ noTransition: { type: Boolean, required: false, default: false },
43
+ dragging: { type: Boolean, required: false, default: false },
44
+ notificationVisible: { type: Boolean, required: false, default: false },
45
+ notificationMessage: { type: String, required: false, default: "" },
46
+ notificationMode: { type: String, required: false, default: "widget" },
47
+ thinking: { type: Boolean, required: false, default: false },
48
+ resolvedTheme: { type: String, required: false, default: "light" }
49
+ },
50
+ emits: ["resize", "resize-start", "resize-end", "toggle"],
51
+ setup(__props, { expose: __expose, emit: __emit }) {
52
+ _useCssVars((_ctx) => ({
53
+ "-animationOrigin.x": _ctx.animationOrigin.x,
54
+ "-animationOrigin.y": _ctx.animationOrigin.y
55
+ }));
56
+ const props = __props;
57
+ const emit = __emit;
58
+ const slots = useSlots();
59
+ const frameRef = ref(null);
60
+ const sendMessageToIframe = (type, data) => {
61
+ var _a;
62
+ (_a = frameRef.value) == null ? void 0 : _a.sendMessageToIframe(type, data);
63
+ };
64
+ __expose({
65
+ sendMessageToIframe,
66
+ frameRef
67
+ });
68
+ const handleResizeStart = () => {
69
+ emit("resize-start");
70
+ };
71
+ const handleResize = (width) => {
72
+ emit("resize", width);
73
+ };
74
+ const handleResizeEnd = () => {
75
+ emit("resize-end");
76
+ };
77
+ const handleToggle = () => {
78
+ emit("toggle");
79
+ };
80
+ const panelStyle = computed(() => {
81
+ if (props.mode === "split") {
82
+ return {
83
+ width: `${props.panelWidth}px`
84
+ };
85
+ }
86
+ return props.positionStyle;
87
+ });
88
+ const panelClasses = computed(() => [
89
+ "opencode-chat",
90
+ {
91
+ open: props.open,
92
+ minimized: props.minimized,
93
+ dragging: props.dragging,
94
+ "no-transition": props.noTransition,
95
+ "split-mode": props.mode === "split"
96
+ }
97
+ ]);
98
+ const __returned__ = { props, emit, slots, frameRef, sendMessageToIframe, handleResizeStart, handleResize, handleResizeEnd, handleToggle, panelStyle, panelClasses, Frame, Header, SessionList, SelectedNodes, ResizeHandle };
99
+ Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
100
+ return __returned__;
101
+ }
102
+ }));
103
+ import { openBlock as _openBlock, createBlock as _createBlock, createCommentVNode as _createCommentVNode, createElementVNode as _createElementVNode, createElementBlock as _createElementBlock, normalizeClass as _normalizeClass, renderSlot as _renderSlot, withCtx as _withCtx, createSlots as _createSlots, createVNode as _createVNode, toDisplayString as _toDisplayString, normalizeStyle as _normalizeStyle } from "vue";
104
+ const _hoisted_1 = ["aria-expanded"];
105
+ const _hoisted_2 = { class: "opencode-split-toggle-icon" };
106
+ const _hoisted_3 = {
107
+ key: 0,
108
+ viewBox: "0 0 24 24",
109
+ width: "16",
110
+ height: "16",
111
+ fill: "none",
112
+ stroke: "currentColor",
113
+ "stroke-width": "2"
114
+ };
115
+ const _hoisted_4 = {
116
+ key: 1,
117
+ viewBox: "0 0 24 24",
118
+ width: "16",
119
+ height: "16",
120
+ fill: "none",
121
+ stroke: "currentColor",
122
+ "stroke-width": "2"
123
+ };
124
+ const _hoisted_5 = {
125
+ key: 2,
126
+ class: "opencode-notification",
127
+ role: "alert"
128
+ };
129
+ const _hoisted_6 = { class: "opencode-chat-content" };
130
+ function __vue_render__(_ctx, _cache, $props, $setup, $data, $options) {
131
+ return _openBlock(), _createElementBlock(
132
+ "div",
133
+ {
134
+ class: _normalizeClass($setup.panelClasses),
135
+ style: _normalizeStyle($setup.panelStyle)
136
+ },
137
+ [
138
+ $props.mode === "split" && $props.resizable && $props.open ? (_openBlock(), _createBlock($setup["ResizeHandle"], {
139
+ key: 0,
140
+ width: $props.panelWidth,
141
+ "min-width": $props.minWidth,
142
+ "max-width": $props.maxWidth,
143
+ onResize: $setup.handleResize,
144
+ onResizeStart: $setup.handleResizeStart,
145
+ onResizeEnd: $setup.handleResizeEnd
146
+ }, null, 8, ["width", "min-width", "max-width"])) : _createCommentVNode("v-if", true),
147
+ $props.mode === "split" ? (_openBlock(), _createElementBlock("button", {
148
+ key: 1,
149
+ type: "button",
150
+ class: _normalizeClass(["opencode-split-toggle-btn", { open: $setup.props.open, thinking: $setup.props.thinking, "opencode-theme-dark": $props.resolvedTheme === "dark" }]),
151
+ "aria-expanded": $props.open,
152
+ "aria-label": "\u5207\u6362\u9762\u677F",
153
+ onClick: $setup.handleToggle
154
+ }, [
155
+ _createElementVNode("span", _hoisted_2, [
156
+ $props.open ? (_openBlock(), _createElementBlock("svg", _hoisted_3, [..._cache[0] || (_cache[0] = [
157
+ _createElementVNode(
158
+ "path",
159
+ {
160
+ d: "M9 18l6-6-6-6",
161
+ "stroke-linecap": "round",
162
+ "stroke-linejoin": "round"
163
+ },
164
+ null,
165
+ -1
166
+ /* CACHED */
167
+ )
168
+ ])])) : (_openBlock(), _createElementBlock("svg", _hoisted_4, [..._cache[1] || (_cache[1] = [
169
+ _createElementVNode(
170
+ "path",
171
+ {
172
+ d: "M15 18l-6-6 6-6",
173
+ "stroke-linecap": "round",
174
+ "stroke-linejoin": "round"
175
+ },
176
+ null,
177
+ -1
178
+ /* CACHED */
179
+ )
180
+ ])]))
181
+ ])
182
+ ], 10, _hoisted_1)) : _createCommentVNode("v-if", true),
183
+ _createVNode(
184
+ $setup["Header"],
185
+ null,
186
+ _createSlots({
187
+ _: 2
188
+ /* DYNAMIC */
189
+ }, [
190
+ $setup.slots["session-toggle-icon"] ? {
191
+ name: "session-toggle-icon",
192
+ fn: _withCtx(() => [
193
+ _renderSlot(_ctx.$slots, "session-toggle-icon")
194
+ ]),
195
+ key: "0"
196
+ } : void 0,
197
+ $setup.slots["select-icon"] ? {
198
+ name: "select-icon",
199
+ fn: _withCtx(() => [
200
+ _renderSlot(_ctx.$slots, "select-icon")
201
+ ]),
202
+ key: "1"
203
+ } : void 0,
204
+ $setup.slots["close-icon"] ? {
205
+ name: "close-icon",
206
+ fn: _withCtx(() => [
207
+ _renderSlot(_ctx.$slots, "close-icon")
208
+ ]),
209
+ key: "2"
210
+ } : void 0
211
+ ]),
212
+ 1024
213
+ /* DYNAMIC_SLOTS */
214
+ ),
215
+ $props.notificationVisible && $props.notificationMode === "widget" ? (_openBlock(), _createElementBlock(
216
+ "div",
217
+ _hoisted_5,
218
+ _toDisplayString($props.notificationMessage),
219
+ 1
220
+ /* TEXT */
221
+ )) : _createCommentVNode("v-if", true),
222
+ _createElementVNode("div", _hoisted_6, [
223
+ _createVNode($setup["SessionList"], null, {
224
+ empty: _withCtx(() => [
225
+ _renderSlot(_ctx.$slots, "sessions-empty", {}, () => [
226
+ _cache[2] || (_cache[2] = _createElementVNode(
227
+ "div",
228
+ { class: "opencode-session-empty" },
229
+ "\u6682\u65E0\u4F1A\u8BDD",
230
+ -1
231
+ /* CACHED */
232
+ ))
233
+ ])
234
+ ]),
235
+ _: 3
236
+ /* FORWARDED */
237
+ }),
238
+ _createVNode(
239
+ $setup["Frame"],
240
+ { ref: "frameRef" },
241
+ _createSlots({
242
+ _: 2
243
+ /* DYNAMIC */
244
+ }, [
245
+ $setup.slots["empty-state"] ? {
246
+ name: "empty-state",
247
+ fn: _withCtx(() => [
248
+ _renderSlot(_ctx.$slots, "empty-state")
249
+ ]),
250
+ key: "0"
251
+ } : void 0,
252
+ $setup.slots.loading ? {
253
+ name: "loading",
254
+ fn: _withCtx(() => [
255
+ _renderSlot(_ctx.$slots, "loading")
256
+ ]),
257
+ key: "1"
258
+ } : void 0,
259
+ $setup.slots.error ? {
260
+ name: "error",
261
+ fn: _withCtx(() => [
262
+ _renderSlot(_ctx.$slots, "error")
263
+ ]),
264
+ key: "2"
265
+ } : void 0,
266
+ $setup.slots.content ? {
267
+ name: "content",
268
+ fn: _withCtx(() => [
269
+ _renderSlot(_ctx.$slots, "content")
270
+ ]),
271
+ key: "3"
272
+ } : void 0
273
+ ]),
274
+ 1536
275
+ /* NEED_PATCH, DYNAMIC_SLOTS */
276
+ ),
277
+ _createVNode($setup["SelectedNodes"])
278
+ ])
279
+ ],
280
+ 6
281
+ /* CLASS, STYLE */
282
+ );
283
+ }
284
+ __vue_sfc__.render = __vue_render__;
285
+ var ChatPanel_vue_default = __vue_sfc__;
286
+ export {
287
+ ChatPanel_vue_default as default
288
+ };