@oro.ad/nuxt-claude-devtools 1.3.0 → 1.5.1

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 (111) hide show
  1. package/README.md +2 -1
  2. package/dist/client/200.html +1 -1
  3. package/dist/client/404.html +1 -1
  4. package/dist/client/_nuxt/{COus5Ssl.js → 0BAoaFXM.js} +1 -1
  5. package/dist/client/_nuxt/{B_BoWmnX.js → 88aFj9mk.js} +1 -1
  6. package/dist/client/_nuxt/{DolUcBed.js → B5vRr8Ti.js} +1 -1
  7. package/dist/client/_nuxt/{CDQtmRaX.js → BI4BFakr.js} +1 -1
  8. package/dist/client/_nuxt/{CPA0s6N9.js → BJuQJ8yP.js} +1 -1
  9. package/dist/client/_nuxt/{BB1-kxmm.js → BMxGt8ZG.js} +1 -1
  10. package/dist/client/_nuxt/{TQi6eIO6.js → Baq9Hzkz.js} +1 -1
  11. package/dist/client/_nuxt/{DbJLoP3G.js → Bf779K50.js} +1 -1
  12. package/dist/client/_nuxt/BmF8r-gh.js +1 -0
  13. package/dist/client/_nuxt/BryQ1L4F.js +1 -0
  14. package/dist/client/_nuxt/{V4UvAcd3.js → BsG0VKct.js} +1 -1
  15. package/dist/client/_nuxt/Bt-DdLhQ.js +12 -0
  16. package/dist/client/_nuxt/{CHeJJZL9.js → C6Xm_PzB.js} +1 -1
  17. package/dist/client/_nuxt/{DC_XB519.js → C8AkZ-W3.js} +1 -1
  18. package/dist/client/_nuxt/{BSVkH7b6.js → CEM1iRz_.js} +1 -1
  19. package/dist/client/_nuxt/{BcZxFXBD.js → CETmet01.js} +1 -1
  20. package/dist/client/_nuxt/CG1tBJBN.js +1 -0
  21. package/dist/client/_nuxt/{D2l4TRxW.js → CXOn8Upj.js} +1 -1
  22. package/dist/client/_nuxt/CYomf6PL.js +1 -0
  23. package/dist/client/_nuxt/{DEys9N1G.js → CrhTgxiU.js} +1 -1
  24. package/dist/client/_nuxt/{BYp73eMl.js → CtWfW1XP.js} +1 -1
  25. package/dist/client/_nuxt/{d8BPa19J.js → CuUOvg0u.js} +1 -1
  26. package/dist/client/_nuxt/CxYvL5O5.js +1 -0
  27. package/dist/client/_nuxt/D8DUrd91.js +1 -0
  28. package/dist/client/_nuxt/{DSt96JPY.js → DFkDlupw.js} +2 -2
  29. package/dist/client/_nuxt/{B8uzckkK.js → DG-9quB_.js} +1 -1
  30. package/dist/client/_nuxt/DHlhBFAg.js +1 -0
  31. package/dist/client/_nuxt/{BnXQTjo-.js → DJw5U4z8.js} +1 -1
  32. package/dist/client/_nuxt/{M6QPYocW.js → DRReoGGV.js} +1 -1
  33. package/dist/client/_nuxt/{DGQ4s7ae.js → DSMailoF.js} +1 -1
  34. package/dist/client/_nuxt/{qbS8UemQ.js → DUPgidXP.js} +1 -1
  35. package/dist/client/_nuxt/{QumocfwJ.js → D_JyZ6Hh.js} +1 -1
  36. package/dist/client/_nuxt/{BAb1fJOF.js → Dgm9zqhP.js} +2 -2
  37. package/dist/client/_nuxt/builds/latest.json +1 -1
  38. package/dist/client/_nuxt/builds/meta/024950b2-9b05-4789-9918-c859c91d6b13.json +1 -0
  39. package/dist/client/_nuxt/{C--9REmc.js → h1c4XpR7.js} +1 -1
  40. package/dist/client/_nuxt/kN0L7CSs.js +1 -0
  41. package/dist/client/_nuxt/{BMZIbUUD.js → n4TwJfzb.js} +1 -1
  42. package/dist/client/_nuxt/zY60w9UT.js +1 -0
  43. package/dist/client/agents/index.html +1 -1
  44. package/dist/client/commands/index.html +1 -1
  45. package/dist/client/docs/index.html +1 -1
  46. package/dist/client/index.html +1 -1
  47. package/dist/client/mcp/index.html +1 -1
  48. package/dist/client/plugins/index.html +1 -1
  49. package/dist/client/settings/index.html +1 -1
  50. package/dist/client/skills/index.html +1 -1
  51. package/dist/module.json +1 -1
  52. package/dist/module.mjs +10 -4
  53. package/dist/runtime/overlay/components/ChatOverlay.d.vue.ts +0 -1
  54. package/dist/runtime/overlay/components/ChatOverlay.vue +221 -731
  55. package/dist/runtime/overlay/components/ChatOverlay.vue.d.ts +0 -1
  56. package/dist/runtime/overlay/components/MarkdownContent.vue +1 -1
  57. package/dist/runtime/overlay/components/ToolCallBlock.vue +1 -1
  58. package/dist/runtime/overlay/components/chat/ChatHeader.d.vue.ts +18 -0
  59. package/dist/runtime/overlay/components/chat/ChatHeader.vue +82 -0
  60. package/dist/runtime/overlay/components/chat/ChatHeader.vue.d.ts +18 -0
  61. package/dist/runtime/overlay/components/chat/ChatInput.d.vue.ts +22 -0
  62. package/dist/runtime/overlay/components/chat/ChatInput.vue +526 -0
  63. package/dist/runtime/overlay/components/chat/ChatInput.vue.d.ts +22 -0
  64. package/dist/runtime/overlay/components/chat/ChatMessages.d.vue.ts +13 -0
  65. package/dist/runtime/overlay/components/chat/ChatMessages.vue +160 -0
  66. package/dist/runtime/overlay/components/chat/ChatMessages.vue.d.ts +13 -0
  67. package/dist/runtime/overlay/components/chat/ClaudeBadge.d.vue.ts +22 -0
  68. package/dist/runtime/overlay/components/chat/ClaudeBadge.vue +85 -0
  69. package/dist/runtime/overlay/components/chat/ClaudeBadge.vue.d.ts +22 -0
  70. package/dist/runtime/overlay/components/chat/HistoryPanel.d.vue.ts +17 -0
  71. package/dist/runtime/overlay/components/chat/HistoryPanel.vue +65 -0
  72. package/dist/runtime/overlay/components/chat/HistoryPanel.vue.d.ts +17 -0
  73. package/dist/runtime/overlay/components/chat/NicknameModal.d.vue.ts +13 -0
  74. package/dist/runtime/overlay/components/chat/NicknameModal.vue +89 -0
  75. package/dist/runtime/overlay/components/chat/NicknameModal.vue.d.ts +13 -0
  76. package/dist/runtime/overlay/components/chat/index.d.ts +6 -0
  77. package/dist/runtime/overlay/components/chat/index.js +6 -0
  78. package/dist/runtime/overlay/composables/index.d.ts +3 -0
  79. package/dist/runtime/overlay/composables/index.js +3 -0
  80. package/dist/runtime/overlay/composables/useMessageContext.d.ts +25 -0
  81. package/dist/runtime/overlay/composables/useMessageContext.js +29 -0
  82. package/dist/runtime/overlay/composables/useMobileSwipe.d.ts +15 -0
  83. package/dist/runtime/overlay/composables/useMobileSwipe.js +79 -0
  84. package/dist/runtime/overlay/composables/usePanelInteraction.d.ts +30 -0
  85. package/dist/runtime/overlay/composables/usePanelInteraction.js +184 -0
  86. package/dist/runtime/overlay/composables/usePanelPosition.d.ts +69 -0
  87. package/dist/runtime/overlay/composables/usePanelPosition.js +147 -0
  88. package/dist/runtime/server/claude-session.d.ts +11 -0
  89. package/dist/runtime/server/claude-session.js +166 -6
  90. package/dist/runtime/shared/composables/useClaudeChat.d.ts +7 -3
  91. package/dist/runtime/shared/composables/useClaudeChat.js +27 -251
  92. package/dist/runtime/shared/composables/useClaudeChatCore.d.ts +40 -0
  93. package/dist/runtime/shared/composables/useClaudeChatCore.js +350 -0
  94. package/dist/runtime/shared/composables/useMessageContext.d.ts +54 -0
  95. package/dist/runtime/shared/composables/useMessageContext.js +195 -0
  96. package/dist/runtime/shared/composables/useShare.d.ts +14 -4
  97. package/dist/runtime/shared/composables/useShare.js +57 -35
  98. package/dist/runtime/shared/composables/useVoiceInput.js +40 -11
  99. package/dist/runtime/shared/types.d.ts +36 -0
  100. package/dist/runtime/types.d.ts +14 -0
  101. package/package.json +1 -1
  102. package/dist/client/_nuxt/BSF2Vz9o.js +0 -1
  103. package/dist/client/_nuxt/BflmC3YB.js +0 -1
  104. package/dist/client/_nuxt/CRkq21kc.js +0 -1
  105. package/dist/client/_nuxt/Cgba93Y9.js +0 -1
  106. package/dist/client/_nuxt/DH8Ugy8E.js +0 -1
  107. package/dist/client/_nuxt/DeGmaFBY.js +0 -1
  108. package/dist/client/_nuxt/DgfRwrFR.js +0 -1
  109. package/dist/client/_nuxt/builds/meta/2be12f06-336a-4fdd-b982-2f6c682c14a6.json +0 -1
  110. package/dist/client/_nuxt/wDw60tEC.js +0 -10
  111. package/dist/client/_nuxt/xEjB6ozD.js +0 -1
@@ -0,0 +1,79 @@
1
+ import { nextTick, ref } from "vue";
2
+ export function useMobileSwipe(options) {
3
+ const {
4
+ panelRef,
5
+ headerRef,
6
+ onSwipeClose,
7
+ threshold = 100,
8
+ mobileBreakpoint = 640
9
+ } = options;
10
+ const touchStartY = ref(0);
11
+ const touchDeltaY = ref(0);
12
+ const isSwiping = ref(false);
13
+ const isSwipeClosing = ref(false);
14
+ function handleTouchStart(e) {
15
+ if (window.innerWidth > mobileBreakpoint) return;
16
+ touchStartY.value = e.touches[0].clientY;
17
+ touchDeltaY.value = 0;
18
+ isSwiping.value = true;
19
+ }
20
+ function handleTouchMove(e) {
21
+ if (!isSwiping.value || window.innerWidth > mobileBreakpoint) return;
22
+ const currentY = e.touches[0].clientY;
23
+ const delta = currentY - touchStartY.value;
24
+ if (delta > 0) {
25
+ e.preventDefault();
26
+ touchDeltaY.value = delta;
27
+ if (panelRef.value) {
28
+ panelRef.value.style.transform = `translateY(${delta}px)`;
29
+ panelRef.value.style.transition = "none";
30
+ }
31
+ }
32
+ }
33
+ function handleTouchEnd() {
34
+ if (!isSwiping.value || window.innerWidth > mobileBreakpoint) return;
35
+ isSwiping.value = false;
36
+ if (panelRef.value) {
37
+ panelRef.value.style.transition = "transform 0.3s ease-out";
38
+ if (touchDeltaY.value > threshold) {
39
+ isSwipeClosing.value = true;
40
+ panelRef.value.style.transform = "translateY(100%)";
41
+ setTimeout(() => {
42
+ onSwipeClose();
43
+ nextTick(() => {
44
+ isSwipeClosing.value = false;
45
+ if (panelRef.value) {
46
+ panelRef.value.style.transform = "";
47
+ panelRef.value.style.transition = "";
48
+ }
49
+ });
50
+ }, 300);
51
+ } else {
52
+ panelRef.value.style.transform = "translateY(0)";
53
+ setTimeout(() => {
54
+ if (panelRef.value) {
55
+ panelRef.value.style.transition = "";
56
+ }
57
+ }, 300);
58
+ }
59
+ }
60
+ touchDeltaY.value = 0;
61
+ }
62
+ function setupTouchMoveListener() {
63
+ if (headerRef.value) {
64
+ headerRef.value.addEventListener("touchmove", handleTouchMove, { passive: false });
65
+ }
66
+ }
67
+ function cleanupTouchMoveListener() {
68
+ if (headerRef.value) {
69
+ headerRef.value.removeEventListener("touchmove", handleTouchMove);
70
+ }
71
+ }
72
+ return {
73
+ isSwipeClosing,
74
+ handleTouchStart,
75
+ handleTouchEnd,
76
+ setupTouchMoveListener,
77
+ cleanupTouchMoveListener
78
+ };
79
+ }
@@ -0,0 +1,30 @@
1
+ import { type Ref } from 'vue';
2
+ export interface PanelInteractionOptions {
3
+ panelScreenPos: Ref<{
4
+ left: number;
5
+ top: number;
6
+ }>;
7
+ panelSize: Ref<{
8
+ width: number;
9
+ height: number;
10
+ }>;
11
+ panelRef: Ref<HTMLElement | null>;
12
+ isMobile: Ref<boolean>;
13
+ minSize?: {
14
+ width: number;
15
+ height: number;
16
+ };
17
+ padding?: number;
18
+ edgeThreshold?: number;
19
+ }
20
+ export declare function usePanelInteraction(options: PanelInteractionOptions): {
21
+ isDragging: Ref<boolean, boolean>;
22
+ isResizing: Ref<boolean, boolean>;
23
+ activeEdge: Ref<string | null, string | null>;
24
+ hoveredEdge: Ref<string | null, string | null>;
25
+ cursor: import("vue").ComputedRef<string>;
26
+ startDrag: (e: MouseEvent) => void;
27
+ startResize: (edge: string, e: MouseEvent) => void;
28
+ onMouseMove: (e: MouseEvent) => void;
29
+ onMouseLeave: () => void;
30
+ };
@@ -0,0 +1,184 @@
1
+ import { computed, ref } from "vue";
2
+ const DEFAULTS = {
3
+ minSize: { width: 320, height: 400 },
4
+ padding: 20,
5
+ edgeThreshold: 12
6
+ };
7
+ export function usePanelInteraction(options) {
8
+ const {
9
+ panelScreenPos,
10
+ panelSize,
11
+ panelRef,
12
+ isMobile,
13
+ minSize = DEFAULTS.minSize,
14
+ padding = DEFAULTS.padding,
15
+ edgeThreshold = DEFAULTS.edgeThreshold
16
+ } = options;
17
+ const isDragging = ref(false);
18
+ const dragStart = ref({ x: 0, y: 0, panelX: 0, panelY: 0 });
19
+ const isResizing = ref(false);
20
+ const activeEdge = ref(null);
21
+ const resizeStart = ref({ x: 0, y: 0, width: 0, height: 0, panelX: 0, panelY: 0 });
22
+ const hoveredEdge = ref(null);
23
+ const cursor = computed(() => {
24
+ const edge = hoveredEdge.value || activeEdge.value;
25
+ if (!edge) return "default";
26
+ const cursors = {
27
+ n: "ns-resize",
28
+ s: "ns-resize",
29
+ e: "ew-resize",
30
+ w: "ew-resize",
31
+ ne: "nesw-resize",
32
+ sw: "nesw-resize",
33
+ nw: "nwse-resize",
34
+ se: "nwse-resize"
35
+ };
36
+ return cursors[edge] || "default";
37
+ });
38
+ function startDrag(e) {
39
+ if (isMobile.value) return;
40
+ e.preventDefault();
41
+ dragStart.value = {
42
+ x: e.clientX,
43
+ y: e.clientY,
44
+ panelX: panelScreenPos.value.left,
45
+ panelY: panelScreenPos.value.top
46
+ };
47
+ isDragging.value = true;
48
+ window.addEventListener("mousemove", onDragMove);
49
+ window.addEventListener("mouseup", endDrag);
50
+ }
51
+ function onDragMove(e) {
52
+ if (!isDragging.value) return;
53
+ const vw = window.innerWidth;
54
+ const vh = window.innerHeight;
55
+ const deltaX = e.clientX - dragStart.value.x;
56
+ const deltaY = e.clientY - dragStart.value.y;
57
+ let newLeft = dragStart.value.panelX + deltaX;
58
+ let newTop = dragStart.value.panelY + deltaY;
59
+ newLeft = Math.max(padding, Math.min(vw - panelSize.value.width - padding, newLeft));
60
+ newTop = Math.max(padding, Math.min(vh - panelSize.value.height - padding, newTop));
61
+ panelScreenPos.value.left = newLeft;
62
+ panelScreenPos.value.top = newTop;
63
+ }
64
+ function endDrag() {
65
+ isDragging.value = false;
66
+ window.removeEventListener("mousemove", onDragMove);
67
+ window.removeEventListener("mouseup", endDrag);
68
+ }
69
+ function startResize(edge, e) {
70
+ if (isMobile.value) return;
71
+ e.preventDefault();
72
+ e.stopPropagation();
73
+ activeEdge.value = edge;
74
+ resizeStart.value = {
75
+ x: e.clientX,
76
+ y: e.clientY,
77
+ width: panelSize.value.width,
78
+ height: panelSize.value.height,
79
+ panelX: panelScreenPos.value.left,
80
+ panelY: panelScreenPos.value.top
81
+ };
82
+ isResizing.value = true;
83
+ window.addEventListener("mousemove", onResizeMove);
84
+ window.addEventListener("mouseup", endResize);
85
+ }
86
+ function onResizeMove(e) {
87
+ if (!isResizing.value || !activeEdge.value) return;
88
+ const edge = activeEdge.value;
89
+ const vw = window.innerWidth;
90
+ const vh = window.innerHeight;
91
+ const deltaX = e.clientX - resizeStart.value.x;
92
+ const deltaY = e.clientY - resizeStart.value.y;
93
+ let newWidth = resizeStart.value.width;
94
+ let newHeight = resizeStart.value.height;
95
+ let newLeft = resizeStart.value.panelX;
96
+ let newTop = resizeStart.value.panelY;
97
+ if (edge.includes("w")) {
98
+ newLeft = resizeStart.value.panelX + deltaX;
99
+ newWidth = resizeStart.value.width - deltaX;
100
+ }
101
+ if (edge.includes("e")) {
102
+ newWidth = resizeStart.value.width + deltaX;
103
+ }
104
+ if (edge.includes("n")) {
105
+ newTop = resizeStart.value.panelY + deltaY;
106
+ newHeight = resizeStart.value.height - deltaY;
107
+ }
108
+ if (edge.includes("s")) {
109
+ newHeight = resizeStart.value.height + deltaY;
110
+ }
111
+ if (newWidth < minSize.width) {
112
+ if (edge.includes("w")) {
113
+ newLeft = resizeStart.value.panelX + resizeStart.value.width - minSize.width;
114
+ }
115
+ newWidth = minSize.width;
116
+ }
117
+ if (newHeight < minSize.height) {
118
+ if (edge.includes("n")) {
119
+ newTop = resizeStart.value.panelY + resizeStart.value.height - minSize.height;
120
+ }
121
+ newHeight = minSize.height;
122
+ }
123
+ newLeft = Math.max(padding, newLeft);
124
+ newTop = Math.max(padding, newTop);
125
+ if (newLeft + newWidth > vw - padding) {
126
+ newWidth = vw - padding - newLeft;
127
+ }
128
+ if (newTop + newHeight > vh - padding) {
129
+ newHeight = vh - padding - newTop;
130
+ }
131
+ panelScreenPos.value.left = newLeft;
132
+ panelScreenPos.value.top = newTop;
133
+ panelSize.value.width = newWidth;
134
+ panelSize.value.height = newHeight;
135
+ }
136
+ function endResize() {
137
+ isResizing.value = false;
138
+ activeEdge.value = null;
139
+ window.removeEventListener("mousemove", onResizeMove);
140
+ window.removeEventListener("mouseup", endResize);
141
+ }
142
+ function onMouseMove(e) {
143
+ if (isMobile.value || isResizing.value || isDragging.value) return;
144
+ if (!panelRef.value) return;
145
+ const rect = panelRef.value.getBoundingClientRect();
146
+ const x = e.clientX - rect.left;
147
+ const y = e.clientY - rect.top;
148
+ const w = rect.width;
149
+ const h = rect.height;
150
+ const nearLeft = x < edgeThreshold;
151
+ const nearRight = x > w - edgeThreshold;
152
+ const nearTop = y < edgeThreshold;
153
+ const nearBottom = y > h - edgeThreshold;
154
+ if (nearTop && nearLeft) hoveredEdge.value = "nw";
155
+ else if (nearTop && nearRight) hoveredEdge.value = "ne";
156
+ else if (nearBottom && nearLeft) hoveredEdge.value = "sw";
157
+ else if (nearBottom && nearRight) hoveredEdge.value = "se";
158
+ else if (nearTop) hoveredEdge.value = "n";
159
+ else if (nearBottom) hoveredEdge.value = "s";
160
+ else if (nearLeft) hoveredEdge.value = "w";
161
+ else if (nearRight) hoveredEdge.value = "e";
162
+ else hoveredEdge.value = null;
163
+ }
164
+ function onMouseLeave() {
165
+ if (!isResizing.value) {
166
+ hoveredEdge.value = null;
167
+ }
168
+ }
169
+ return {
170
+ // State
171
+ isDragging,
172
+ isResizing,
173
+ activeEdge,
174
+ hoveredEdge,
175
+ cursor,
176
+ // Drag methods
177
+ startDrag,
178
+ // Resize methods
179
+ startResize,
180
+ // Mouse handlers
181
+ onMouseMove,
182
+ onMouseLeave
183
+ };
184
+ }
@@ -0,0 +1,69 @@
1
+ export type PanelAnchor = 'br' | 'bl' | 'tr' | 'tl';
2
+ export interface PanelPositionOptions {
3
+ storageKey?: string;
4
+ defaultBadgePos?: {
5
+ x: number;
6
+ y: number;
7
+ };
8
+ defaultSize?: {
9
+ width: number;
10
+ height: number;
11
+ };
12
+ minSize?: {
13
+ width: number;
14
+ height: number;
15
+ };
16
+ padding?: number;
17
+ badgeDimensions?: {
18
+ width: number;
19
+ height: number;
20
+ };
21
+ }
22
+ export declare function usePanelPosition(options?: PanelPositionOptions): {
23
+ badgePos: import("vue").Ref<{
24
+ x: number;
25
+ y: number;
26
+ }, {
27
+ x: number;
28
+ y: number;
29
+ } | {
30
+ x: number;
31
+ y: number;
32
+ }>;
33
+ panelSize: import("vue").Ref<{
34
+ width: number;
35
+ height: number;
36
+ }, {
37
+ width: number;
38
+ height: number;
39
+ } | {
40
+ width: number;
41
+ height: number;
42
+ }>;
43
+ panelScreenPos: import("vue").Ref<{
44
+ left: number;
45
+ top: number;
46
+ }, {
47
+ left: number;
48
+ top: number;
49
+ } | {
50
+ left: number;
51
+ top: number;
52
+ }>;
53
+ panelAnchor: import("vue").Ref<PanelAnchor, PanelAnchor>;
54
+ load: () => void;
55
+ save: () => void;
56
+ openPanel: () => void;
57
+ closePanel: () => void;
58
+ onBadgeDragEnd: (pos: {
59
+ x: number;
60
+ y: number;
61
+ }) => void;
62
+ getPanelStyle: () => {
63
+ left: string;
64
+ top: string;
65
+ width: string;
66
+ height: string;
67
+ transformOrigin: string;
68
+ };
69
+ };
@@ -0,0 +1,147 @@
1
+ import { ref } from "vue";
2
+ const DEFAULTS = {
3
+ storageKey: "claude-overlay-panel-state",
4
+ badgePos: { x: 24, y: 24 },
5
+ size: { width: 440, height: 600 },
6
+ minSize: { width: 320, height: 400 },
7
+ padding: 20,
8
+ badgeDimensions: { width: 100, height: 40 }
9
+ };
10
+ export function usePanelPosition(options = {}) {
11
+ const config = {
12
+ storageKey: options.storageKey ?? DEFAULTS.storageKey,
13
+ minSize: options.minSize ?? DEFAULTS.minSize,
14
+ padding: options.padding ?? DEFAULTS.padding,
15
+ badgeDimensions: options.badgeDimensions ?? DEFAULTS.badgeDimensions
16
+ };
17
+ const badgePos = ref(options.defaultBadgePos ?? { ...DEFAULTS.badgePos });
18
+ const panelSize = ref(options.defaultSize ?? { ...DEFAULTS.size });
19
+ const panelScreenPos = ref({ left: 0, top: 0 });
20
+ const panelAnchor = ref("br");
21
+ function load() {
22
+ try {
23
+ const saved = localStorage.getItem(config.storageKey);
24
+ if (saved) {
25
+ const parsed = JSON.parse(saved);
26
+ if (parsed.x !== void 0 && parsed.y !== void 0) {
27
+ badgePos.value = { x: parsed.x, y: parsed.y };
28
+ }
29
+ if (parsed.width !== void 0 && parsed.height !== void 0) {
30
+ panelSize.value = { width: parsed.width, height: parsed.height };
31
+ }
32
+ if (parsed.anchor) {
33
+ panelAnchor.value = parsed.anchor;
34
+ }
35
+ }
36
+ } catch {
37
+ }
38
+ }
39
+ function save() {
40
+ try {
41
+ localStorage.setItem(config.storageKey, JSON.stringify({
42
+ x: badgePos.value.x,
43
+ y: badgePos.value.y,
44
+ width: panelSize.value.width,
45
+ height: panelSize.value.height,
46
+ anchor: panelAnchor.value
47
+ }));
48
+ } catch {
49
+ }
50
+ }
51
+ function getBadgeCorners() {
52
+ const vw = window.innerWidth;
53
+ const vh = window.innerHeight;
54
+ const { width: bw, height: bh } = config.badgeDimensions;
55
+ const right = vw - badgePos.value.x;
56
+ const left = right - bw;
57
+ const bottom = vh - badgePos.value.y;
58
+ const top = bottom - bh;
59
+ return { left, right, top, bottom, centerX: left + bw / 2, centerY: top + bh / 2 };
60
+ }
61
+ function calculateAnchor(pos) {
62
+ const vw = window.innerWidth;
63
+ const vh = window.innerHeight;
64
+ const { width: bw, height: bh } = config.badgeDimensions;
65
+ const badgeRight = vw - pos.x;
66
+ const badgeLeft = badgeRight - bw;
67
+ const badgeBottom = vh - pos.y;
68
+ const badgeTop = badgeBottom - bh;
69
+ const centerX = badgeLeft + bw / 2;
70
+ const centerY = badgeTop + bh / 2;
71
+ const moreSpaceLeft = centerX > vw / 2;
72
+ const moreSpaceAbove = centerY > vh / 2;
73
+ if (moreSpaceLeft && moreSpaceAbove) return "br";
74
+ if (!moreSpaceLeft && moreSpaceAbove) return "bl";
75
+ if (moreSpaceLeft && !moreSpaceAbove) return "tr";
76
+ return "tl";
77
+ }
78
+ function openPanel() {
79
+ const vw = window.innerWidth;
80
+ const vh = window.innerHeight;
81
+ const { padding, minSize } = config;
82
+ const badge = getBadgeCorners();
83
+ const anchor = panelAnchor.value;
84
+ const maxWidth = anchor === "br" || anchor === "tr" ? badge.right - padding : vw - badge.left - padding;
85
+ const maxHeight = anchor === "br" || anchor === "bl" ? badge.bottom - padding : vh - badge.top - padding;
86
+ panelSize.value.width = Math.max(minSize.width, Math.min(panelSize.value.width, maxWidth));
87
+ panelSize.value.height = Math.max(minSize.height, Math.min(panelSize.value.height, maxHeight));
88
+ const positions = {
89
+ br: { left: badge.right - panelSize.value.width, top: badge.bottom - panelSize.value.height },
90
+ bl: { left: badge.left, top: badge.bottom - panelSize.value.height },
91
+ tr: { left: badge.right - panelSize.value.width, top: badge.top },
92
+ tl: { left: badge.left, top: badge.top }
93
+ };
94
+ panelScreenPos.value = positions[anchor];
95
+ }
96
+ function closePanel() {
97
+ const vw = window.innerWidth;
98
+ const vh = window.innerHeight;
99
+ const anchor = panelAnchor.value;
100
+ const { width: bw, height: bh } = config.badgeDimensions;
101
+ const { left, top } = panelScreenPos.value;
102
+ const { width, height } = panelSize.value;
103
+ const edgePositions = {
104
+ br: { right: left + width, bottom: top + height },
105
+ bl: { right: left + bw, bottom: top + height },
106
+ tr: { right: left + width, bottom: top + bh },
107
+ tl: { right: left + bw, bottom: top + bh }
108
+ };
109
+ const edges = edgePositions[anchor];
110
+ badgePos.value = { x: vw - edges.right, y: vh - edges.bottom };
111
+ save();
112
+ }
113
+ function onBadgeDragEnd(pos) {
114
+ badgePos.value = { x: pos.x, y: pos.y };
115
+ panelAnchor.value = calculateAnchor(pos);
116
+ save();
117
+ }
118
+ function getPanelStyle() {
119
+ const origins = {
120
+ br: "bottom right",
121
+ bl: "bottom left",
122
+ tr: "top right",
123
+ tl: "top left"
124
+ };
125
+ return {
126
+ left: `${panelScreenPos.value.left}px`,
127
+ top: `${panelScreenPos.value.top}px`,
128
+ width: `${panelSize.value.width}px`,
129
+ height: `${panelSize.value.height}px`,
130
+ transformOrigin: origins[panelAnchor.value]
131
+ };
132
+ }
133
+ return {
134
+ // State
135
+ badgePos,
136
+ panelSize,
137
+ panelScreenPos,
138
+ panelAnchor,
139
+ // Methods
140
+ load,
141
+ save,
142
+ openPanel,
143
+ closePanel,
144
+ onBadgeDragEnd,
145
+ getPanelStyle
146
+ };
147
+ }
@@ -29,10 +29,21 @@ export declare class ClaudeSession {
29
29
  private currentModel;
30
30
  private accumulatedText;
31
31
  private pendingCriticalFiles;
32
+ private currentProcess;
33
+ private wasStopped;
32
34
  constructor(config: ClaudeSessionConfig);
33
35
  attachSocketIO(io: SocketServer): void;
34
36
  destroy(): void;
37
+ private stopGeneration;
35
38
  private resetStreamState;
39
+ /**
40
+ * Save image attachments to disk and return metadata
41
+ */
42
+ private saveAttachments;
43
+ /**
44
+ * Get file extension from MIME type or filename
45
+ */
46
+ private getExtensionFromMimeType;
36
47
  getDocsManager(): DocsManager;
37
48
  getSettingsManager(): SettingsManager;
38
49
  private forceSaveCurrentState;