@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.
- package/README.md +2 -1
- package/dist/client/200.html +1 -1
- package/dist/client/404.html +1 -1
- package/dist/client/_nuxt/{COus5Ssl.js → 0BAoaFXM.js} +1 -1
- package/dist/client/_nuxt/{B_BoWmnX.js → 88aFj9mk.js} +1 -1
- package/dist/client/_nuxt/{DolUcBed.js → B5vRr8Ti.js} +1 -1
- package/dist/client/_nuxt/{CDQtmRaX.js → BI4BFakr.js} +1 -1
- package/dist/client/_nuxt/{CPA0s6N9.js → BJuQJ8yP.js} +1 -1
- package/dist/client/_nuxt/{BB1-kxmm.js → BMxGt8ZG.js} +1 -1
- package/dist/client/_nuxt/{TQi6eIO6.js → Baq9Hzkz.js} +1 -1
- package/dist/client/_nuxt/{DbJLoP3G.js → Bf779K50.js} +1 -1
- package/dist/client/_nuxt/BmF8r-gh.js +1 -0
- package/dist/client/_nuxt/BryQ1L4F.js +1 -0
- package/dist/client/_nuxt/{V4UvAcd3.js → BsG0VKct.js} +1 -1
- package/dist/client/_nuxt/Bt-DdLhQ.js +12 -0
- package/dist/client/_nuxt/{CHeJJZL9.js → C6Xm_PzB.js} +1 -1
- package/dist/client/_nuxt/{DC_XB519.js → C8AkZ-W3.js} +1 -1
- package/dist/client/_nuxt/{BSVkH7b6.js → CEM1iRz_.js} +1 -1
- package/dist/client/_nuxt/{BcZxFXBD.js → CETmet01.js} +1 -1
- package/dist/client/_nuxt/CG1tBJBN.js +1 -0
- package/dist/client/_nuxt/{D2l4TRxW.js → CXOn8Upj.js} +1 -1
- package/dist/client/_nuxt/CYomf6PL.js +1 -0
- package/dist/client/_nuxt/{DEys9N1G.js → CrhTgxiU.js} +1 -1
- package/dist/client/_nuxt/{BYp73eMl.js → CtWfW1XP.js} +1 -1
- package/dist/client/_nuxt/{d8BPa19J.js → CuUOvg0u.js} +1 -1
- package/dist/client/_nuxt/CxYvL5O5.js +1 -0
- package/dist/client/_nuxt/D8DUrd91.js +1 -0
- package/dist/client/_nuxt/{DSt96JPY.js → DFkDlupw.js} +2 -2
- package/dist/client/_nuxt/{B8uzckkK.js → DG-9quB_.js} +1 -1
- package/dist/client/_nuxt/DHlhBFAg.js +1 -0
- package/dist/client/_nuxt/{BnXQTjo-.js → DJw5U4z8.js} +1 -1
- package/dist/client/_nuxt/{M6QPYocW.js → DRReoGGV.js} +1 -1
- package/dist/client/_nuxt/{DGQ4s7ae.js → DSMailoF.js} +1 -1
- package/dist/client/_nuxt/{qbS8UemQ.js → DUPgidXP.js} +1 -1
- package/dist/client/_nuxt/{QumocfwJ.js → D_JyZ6Hh.js} +1 -1
- package/dist/client/_nuxt/{BAb1fJOF.js → Dgm9zqhP.js} +2 -2
- package/dist/client/_nuxt/builds/latest.json +1 -1
- package/dist/client/_nuxt/builds/meta/024950b2-9b05-4789-9918-c859c91d6b13.json +1 -0
- package/dist/client/_nuxt/{C--9REmc.js → h1c4XpR7.js} +1 -1
- package/dist/client/_nuxt/kN0L7CSs.js +1 -0
- package/dist/client/_nuxt/{BMZIbUUD.js → n4TwJfzb.js} +1 -1
- package/dist/client/_nuxt/zY60w9UT.js +1 -0
- package/dist/client/agents/index.html +1 -1
- package/dist/client/commands/index.html +1 -1
- package/dist/client/docs/index.html +1 -1
- package/dist/client/index.html +1 -1
- package/dist/client/mcp/index.html +1 -1
- package/dist/client/plugins/index.html +1 -1
- package/dist/client/settings/index.html +1 -1
- package/dist/client/skills/index.html +1 -1
- package/dist/module.json +1 -1
- package/dist/module.mjs +10 -4
- package/dist/runtime/overlay/components/ChatOverlay.d.vue.ts +0 -1
- package/dist/runtime/overlay/components/ChatOverlay.vue +221 -731
- package/dist/runtime/overlay/components/ChatOverlay.vue.d.ts +0 -1
- package/dist/runtime/overlay/components/MarkdownContent.vue +1 -1
- package/dist/runtime/overlay/components/ToolCallBlock.vue +1 -1
- package/dist/runtime/overlay/components/chat/ChatHeader.d.vue.ts +18 -0
- package/dist/runtime/overlay/components/chat/ChatHeader.vue +82 -0
- package/dist/runtime/overlay/components/chat/ChatHeader.vue.d.ts +18 -0
- package/dist/runtime/overlay/components/chat/ChatInput.d.vue.ts +22 -0
- package/dist/runtime/overlay/components/chat/ChatInput.vue +526 -0
- package/dist/runtime/overlay/components/chat/ChatInput.vue.d.ts +22 -0
- package/dist/runtime/overlay/components/chat/ChatMessages.d.vue.ts +13 -0
- package/dist/runtime/overlay/components/chat/ChatMessages.vue +160 -0
- package/dist/runtime/overlay/components/chat/ChatMessages.vue.d.ts +13 -0
- package/dist/runtime/overlay/components/chat/ClaudeBadge.d.vue.ts +22 -0
- package/dist/runtime/overlay/components/chat/ClaudeBadge.vue +85 -0
- package/dist/runtime/overlay/components/chat/ClaudeBadge.vue.d.ts +22 -0
- package/dist/runtime/overlay/components/chat/HistoryPanel.d.vue.ts +17 -0
- package/dist/runtime/overlay/components/chat/HistoryPanel.vue +65 -0
- package/dist/runtime/overlay/components/chat/HistoryPanel.vue.d.ts +17 -0
- package/dist/runtime/overlay/components/chat/NicknameModal.d.vue.ts +13 -0
- package/dist/runtime/overlay/components/chat/NicknameModal.vue +89 -0
- package/dist/runtime/overlay/components/chat/NicknameModal.vue.d.ts +13 -0
- package/dist/runtime/overlay/components/chat/index.d.ts +6 -0
- package/dist/runtime/overlay/components/chat/index.js +6 -0
- package/dist/runtime/overlay/composables/index.d.ts +3 -0
- package/dist/runtime/overlay/composables/index.js +3 -0
- package/dist/runtime/overlay/composables/useMessageContext.d.ts +25 -0
- package/dist/runtime/overlay/composables/useMessageContext.js +29 -0
- package/dist/runtime/overlay/composables/useMobileSwipe.d.ts +15 -0
- package/dist/runtime/overlay/composables/useMobileSwipe.js +79 -0
- package/dist/runtime/overlay/composables/usePanelInteraction.d.ts +30 -0
- package/dist/runtime/overlay/composables/usePanelInteraction.js +184 -0
- package/dist/runtime/overlay/composables/usePanelPosition.d.ts +69 -0
- package/dist/runtime/overlay/composables/usePanelPosition.js +147 -0
- package/dist/runtime/server/claude-session.d.ts +11 -0
- package/dist/runtime/server/claude-session.js +166 -6
- package/dist/runtime/shared/composables/useClaudeChat.d.ts +7 -3
- package/dist/runtime/shared/composables/useClaudeChat.js +27 -251
- package/dist/runtime/shared/composables/useClaudeChatCore.d.ts +40 -0
- package/dist/runtime/shared/composables/useClaudeChatCore.js +350 -0
- package/dist/runtime/shared/composables/useMessageContext.d.ts +54 -0
- package/dist/runtime/shared/composables/useMessageContext.js +195 -0
- package/dist/runtime/shared/composables/useShare.d.ts +14 -4
- package/dist/runtime/shared/composables/useShare.js +57 -35
- package/dist/runtime/shared/composables/useVoiceInput.js +40 -11
- package/dist/runtime/shared/types.d.ts +36 -0
- package/dist/runtime/types.d.ts +14 -0
- package/package.json +1 -1
- package/dist/client/_nuxt/BSF2Vz9o.js +0 -1
- package/dist/client/_nuxt/BflmC3YB.js +0 -1
- package/dist/client/_nuxt/CRkq21kc.js +0 -1
- package/dist/client/_nuxt/Cgba93Y9.js +0 -1
- package/dist/client/_nuxt/DH8Ugy8E.js +0 -1
- package/dist/client/_nuxt/DeGmaFBY.js +0 -1
- package/dist/client/_nuxt/DgfRwrFR.js +0 -1
- package/dist/client/_nuxt/builds/meta/2be12f06-336a-4fdd-b982-2f6c682c14a6.json +0 -1
- package/dist/client/_nuxt/wDw60tEC.js +0 -10
- 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;
|