@oro.ad/nuxt-claude-devtools 1.2.0 → 1.5.0
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 +107 -14
- package/dist/client/200.html +1 -1
- package/dist/client/404.html +1 -1
- package/dist/client/_nuxt/{CSlPuO5s.js → 0BAoaFXM.js} +1 -1
- package/dist/client/_nuxt/88aFj9mk.js +1 -0
- package/dist/client/_nuxt/{CLKqRoht.js → B5vRr8Ti.js} +1 -1
- package/dist/client/_nuxt/BI4BFakr.js +1 -0
- package/dist/client/_nuxt/{o1jjB-UO.js → BJuQJ8yP.js} +1 -1
- package/dist/client/_nuxt/BMxGt8ZG.js +1 -0
- package/dist/client/_nuxt/Baq9Hzkz.js +1 -0
- package/dist/client/_nuxt/Bf779K50.js +1 -0
- package/dist/client/_nuxt/BmF8r-gh.js +1 -0
- package/dist/client/_nuxt/BryQ1L4F.js +1 -0
- package/dist/client/_nuxt/BsG0VKct.js +1 -0
- package/dist/client/_nuxt/Bt-DdLhQ.js +12 -0
- package/dist/client/_nuxt/C6Xm_PzB.js +1 -0
- package/dist/client/_nuxt/C8AkZ-W3.js +1 -0
- package/dist/client/_nuxt/CEM1iRz_.js +1 -0
- package/dist/client/_nuxt/CETmet01.js +1 -0
- package/dist/client/_nuxt/CG1tBJBN.js +1 -0
- package/dist/client/_nuxt/CXOn8Upj.js +1 -0
- package/dist/client/_nuxt/CYomf6PL.js +1 -0
- package/dist/client/_nuxt/CrhTgxiU.js +1 -0
- package/dist/client/_nuxt/{08Mb3FOO.js → CtWfW1XP.js} +1 -1
- package/dist/client/_nuxt/CuUOvg0u.js +1 -0
- package/dist/client/_nuxt/CxYvL5O5.js +1 -0
- package/dist/client/_nuxt/D8DUrd91.js +1 -0
- package/dist/client/_nuxt/DFkDlupw.js +4 -0
- package/dist/client/_nuxt/DG-9quB_.js +1 -0
- package/dist/client/_nuxt/DHlhBFAg.js +1 -0
- package/dist/client/_nuxt/DJw5U4z8.js +1 -0
- package/dist/client/_nuxt/DRReoGGV.js +1 -0
- package/dist/client/_nuxt/{b4Upel01.js → DSMailoF.js} +1 -1
- package/dist/client/_nuxt/DUPgidXP.js +1 -0
- package/dist/client/_nuxt/D_JyZ6Hh.js +1 -0
- package/dist/client/_nuxt/Dgm9zqhP.js +12 -0
- package/dist/client/_nuxt/builds/latest.json +1 -1
- package/dist/client/_nuxt/builds/meta/9c3f4183-f791-4377-86dc-370ce38cc49b.json +1 -0
- package/dist/client/_nuxt/entry.BMxUr06A.css +1 -0
- package/dist/client/_nuxt/h1c4XpR7.js +1 -0
- package/dist/client/_nuxt/kN0L7CSs.js +1 -0
- package/dist/client/_nuxt/n4TwJfzb.js +1 -0
- 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 -0
- package/dist/client/settings/index.html +1 -0
- package/dist/client/skills/index.html +1 -1
- package/dist/module.d.mts +12 -1
- package/dist/module.json +1 -1
- package/dist/module.mjs +23 -5
- package/dist/runtime/constants.d.ts +29 -0
- package/dist/runtime/constants.js +5 -0
- package/dist/runtime/overlay/components/ChatOverlay.d.vue.ts +6 -0
- package/dist/runtime/overlay/components/ChatOverlay.vue +383 -0
- package/dist/runtime/overlay/components/ChatOverlay.vue.d.ts +6 -0
- package/dist/runtime/overlay/components/MarkdownContent.d.vue.ts +6 -0
- package/dist/runtime/overlay/components/MarkdownContent.vue +31 -0
- package/dist/runtime/overlay/components/MarkdownContent.vue.d.ts +6 -0
- package/dist/runtime/overlay/components/ToolCallBlock.d.vue.ts +8 -0
- package/dist/runtime/overlay/components/ToolCallBlock.vue +77 -0
- package/dist/runtime/overlay/components/ToolCallBlock.vue.d.ts +8 -0
- 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/overlay/plugin.client.d.ts +6 -0
- package/dist/runtime/overlay/plugin.client.js +29 -0
- package/dist/runtime/server/agents-manager.d.ts +17 -4
- package/dist/runtime/server/agents-manager.js +38 -109
- package/dist/runtime/server/base-resource-manager.d.ts +90 -0
- package/dist/runtime/server/base-resource-manager.js +201 -0
- package/dist/runtime/server/claude-session.d.ts +22 -1
- package/dist/runtime/server/claude-session.js +408 -29
- package/dist/runtime/server/commands-manager.d.ts +12 -4
- package/dist/runtime/server/commands-manager.js +25 -100
- package/dist/runtime/server/constants.d.ts +94 -0
- package/dist/runtime/server/constants.js +18 -0
- package/dist/runtime/server/docs-manager.d.ts +7 -0
- package/dist/runtime/server/docs-manager.js +112 -3
- package/dist/runtime/server/history-manager.d.ts +1 -0
- package/dist/runtime/server/history-manager.js +25 -3
- package/dist/runtime/server/plugins/socket.io.js +5 -3
- package/dist/runtime/server/plugins-manager.d.ts +84 -0
- package/dist/runtime/server/plugins-manager.js +338 -0
- package/dist/runtime/server/settings-manager.d.ts +17 -0
- package/dist/runtime/server/settings-manager.js +70 -0
- package/dist/runtime/server/share-manager.d.ts +24 -0
- package/dist/runtime/server/share-manager.js +96 -0
- package/dist/runtime/server/skills-manager.d.ts +18 -4
- package/dist/runtime/server/skills-manager.js +32 -159
- package/dist/runtime/shared/composables/useClaudeChat.d.ts +39 -0
- package/dist/runtime/shared/composables/useClaudeChat.js +40 -0
- 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 +52 -0
- package/dist/runtime/shared/composables/useShare.js +214 -0
- package/dist/runtime/shared/composables/useVoiceInput.d.ts +8 -0
- package/dist/runtime/shared/composables/useVoiceInput.js +106 -0
- package/dist/runtime/shared/constants.d.ts +28 -0
- package/dist/runtime/shared/constants.js +6 -0
- package/dist/runtime/shared/index.d.ts +9 -0
- package/dist/runtime/shared/index.js +5 -0
- package/dist/runtime/shared/types.d.ts +84 -0
- package/dist/runtime/shared/types.js +0 -0
- package/dist/runtime/types.d.ts +16 -0
- package/dist/types.d.mts +1 -1
- package/package.json +5 -3
- package/dist/client/_nuxt/BMi2eT6G.js +0 -1
- package/dist/client/_nuxt/BiBLVxWh.js +0 -1
- package/dist/client/_nuxt/BnRGpZsC.js +0 -8
- package/dist/client/_nuxt/C2GhPw5d.js +0 -7
- package/dist/client/_nuxt/CPQSDiF7.js +0 -12
- package/dist/client/_nuxt/D8683igF.js +0 -7
- package/dist/client/_nuxt/DBIw6BGF.js +0 -1
- package/dist/client/_nuxt/DCgjfr8H.js +0 -9
- package/dist/client/_nuxt/bl5iU4Kz.js +0 -1
- package/dist/client/_nuxt/builds/meta/35284331-5e85-46e0-9058-988fea05336c.json +0 -1
- package/dist/client/_nuxt/entry.BhHeZ_Nj.css +0 -1
- package/dist/client/_nuxt/nKfsBgPE.js +0 -4
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
import { computed, ref } from "vue";
|
|
2
|
+
import {
|
|
3
|
+
STORAGE_KEY_NICKNAME,
|
|
4
|
+
STORAGE_KEY_USER_ID,
|
|
5
|
+
URL_PARAM_SHARE,
|
|
6
|
+
URL_PARAM_SHARE_NICKNAME
|
|
7
|
+
} from "../constants.js";
|
|
8
|
+
function defaultGetUrlParam(param) {
|
|
9
|
+
if (typeof window === "undefined") return null;
|
|
10
|
+
const params = new URLSearchParams(window.location.search);
|
|
11
|
+
return params.get(param);
|
|
12
|
+
}
|
|
13
|
+
function defaultGetBaseUrl() {
|
|
14
|
+
if (typeof window === "undefined") return "";
|
|
15
|
+
return window.location.origin;
|
|
16
|
+
}
|
|
17
|
+
export function useShare(options = {}) {
|
|
18
|
+
const {
|
|
19
|
+
getUrlParam = defaultGetUrlParam,
|
|
20
|
+
getBaseUrl = defaultGetBaseUrl,
|
|
21
|
+
log = () => {
|
|
22
|
+
}
|
|
23
|
+
} = options;
|
|
24
|
+
const userId = ref(null);
|
|
25
|
+
const nickname = ref(null);
|
|
26
|
+
const users = ref([]);
|
|
27
|
+
const showNicknameModal = ref(false);
|
|
28
|
+
const nicknameError = ref(null);
|
|
29
|
+
const isShareMode = computed(() => users.value.length > 1);
|
|
30
|
+
const wasInvited = ref(false);
|
|
31
|
+
const sharingActiveOnServer = ref(false);
|
|
32
|
+
const nicknameFromUrl = ref(false);
|
|
33
|
+
function generateId() {
|
|
34
|
+
return Math.random().toString(36).substring(2, 10);
|
|
35
|
+
}
|
|
36
|
+
function getUserIdFromUrl() {
|
|
37
|
+
return getUrlParam(URL_PARAM_SHARE);
|
|
38
|
+
}
|
|
39
|
+
function getNicknameFromUrl() {
|
|
40
|
+
return getUrlParam(URL_PARAM_SHARE_NICKNAME);
|
|
41
|
+
}
|
|
42
|
+
function cleanShareParamsFromUrl() {
|
|
43
|
+
if (typeof window === "undefined") return;
|
|
44
|
+
if (window.location.search.includes(URL_PARAM_SHARE) || window.location.search.includes(URL_PARAM_SHARE_NICKNAME)) {
|
|
45
|
+
const url = new URL(window.location.href);
|
|
46
|
+
url.searchParams.delete(URL_PARAM_SHARE);
|
|
47
|
+
url.searchParams.delete(URL_PARAM_SHARE_NICKNAME);
|
|
48
|
+
window.history.replaceState({}, "", url.toString());
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
function initShare() {
|
|
52
|
+
if (typeof window === "undefined") return;
|
|
53
|
+
const urlUserId = getUserIdFromUrl();
|
|
54
|
+
const urlNickname = getNicknameFromUrl();
|
|
55
|
+
log("initShare", { urlUserId, urlNickname });
|
|
56
|
+
if (urlUserId) {
|
|
57
|
+
userId.value = urlUserId;
|
|
58
|
+
wasInvited.value = true;
|
|
59
|
+
localStorage.setItem(STORAGE_KEY_USER_ID, urlUserId);
|
|
60
|
+
} else {
|
|
61
|
+
const storedUserId = localStorage.getItem(STORAGE_KEY_USER_ID);
|
|
62
|
+
if (storedUserId) {
|
|
63
|
+
userId.value = storedUserId;
|
|
64
|
+
} else {
|
|
65
|
+
const newId = generateId();
|
|
66
|
+
userId.value = newId;
|
|
67
|
+
localStorage.setItem(STORAGE_KEY_USER_ID, newId);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
if (urlNickname) {
|
|
71
|
+
nickname.value = urlNickname;
|
|
72
|
+
localStorage.setItem(STORAGE_KEY_NICKNAME, urlNickname);
|
|
73
|
+
nicknameFromUrl.value = true;
|
|
74
|
+
} else {
|
|
75
|
+
const storedNickname = localStorage.getItem(STORAGE_KEY_NICKNAME);
|
|
76
|
+
if (storedNickname && storedNickname.trim()) {
|
|
77
|
+
nickname.value = storedNickname;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
cleanShareParamsFromUrl();
|
|
81
|
+
}
|
|
82
|
+
function createShareLink(includeNickname = false) {
|
|
83
|
+
if (typeof window === "undefined") return "";
|
|
84
|
+
const inviteeId = generateId();
|
|
85
|
+
const baseUrl = getBaseUrl();
|
|
86
|
+
const url = new URL(baseUrl);
|
|
87
|
+
url.searchParams.set(URL_PARAM_SHARE, inviteeId);
|
|
88
|
+
if (includeNickname && nickname.value) {
|
|
89
|
+
url.searchParams.set(URL_PARAM_SHARE_NICKNAME, nickname.value);
|
|
90
|
+
}
|
|
91
|
+
return url.toString();
|
|
92
|
+
}
|
|
93
|
+
function setNickname(name) {
|
|
94
|
+
nickname.value = name;
|
|
95
|
+
nicknameError.value = null;
|
|
96
|
+
if (typeof window !== "undefined") {
|
|
97
|
+
localStorage.setItem(STORAGE_KEY_NICKNAME, name);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
function needsNicknameImmediate() {
|
|
101
|
+
return wasInvited.value && !nickname.value && !nicknameFromUrl.value;
|
|
102
|
+
}
|
|
103
|
+
function needsNicknameForMessage() {
|
|
104
|
+
return sharingActiveOnServer.value && !nickname.value;
|
|
105
|
+
}
|
|
106
|
+
function needsNicknameForShare() {
|
|
107
|
+
return !nickname.value;
|
|
108
|
+
}
|
|
109
|
+
function checkSharingStatus(socket) {
|
|
110
|
+
if (!socket) return;
|
|
111
|
+
socket.emit("share:is_active");
|
|
112
|
+
}
|
|
113
|
+
function syncCredentials(socket) {
|
|
114
|
+
if (!socket || !userId.value || !nickname.value) return;
|
|
115
|
+
socket.emit("share:sync", {
|
|
116
|
+
userId: userId.value,
|
|
117
|
+
nickname: nickname.value
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
function registerUser(socket) {
|
|
121
|
+
if (!socket || !userId.value || !nickname.value) return;
|
|
122
|
+
socket.emit("share:register", {
|
|
123
|
+
userId: userId.value,
|
|
124
|
+
nickname: nickname.value
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
function setupSocketListeners(socket) {
|
|
128
|
+
socket.on("share:users", (data) => {
|
|
129
|
+
users.value = data;
|
|
130
|
+
sharingActiveOnServer.value = data.length > 0;
|
|
131
|
+
});
|
|
132
|
+
socket.on("share:is_active", (data) => {
|
|
133
|
+
sharingActiveOnServer.value = data.active;
|
|
134
|
+
});
|
|
135
|
+
socket.on("share:user_joined", (user) => {
|
|
136
|
+
const existingIndex = users.value.findIndex((u) => u.id === user.id);
|
|
137
|
+
if (existingIndex >= 0) {
|
|
138
|
+
users.value[existingIndex] = user;
|
|
139
|
+
} else {
|
|
140
|
+
users.value.push(user);
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
socket.on("share:registered", (user) => {
|
|
144
|
+
nickname.value = user.nickname;
|
|
145
|
+
nicknameError.value = null;
|
|
146
|
+
showNicknameModal.value = false;
|
|
147
|
+
if (typeof window !== "undefined") {
|
|
148
|
+
localStorage.setItem(STORAGE_KEY_NICKNAME, user.nickname);
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
socket.on("share:nickname_taken", () => {
|
|
152
|
+
nicknameError.value = "This nickname is already taken";
|
|
153
|
+
showNicknameModal.value = true;
|
|
154
|
+
});
|
|
155
|
+
socket.on("share:synced", (data) => {
|
|
156
|
+
if (data.status === "nickname_conflict") {
|
|
157
|
+
nickname.value = null;
|
|
158
|
+
if (typeof window !== "undefined") {
|
|
159
|
+
localStorage.removeItem(STORAGE_KEY_NICKNAME);
|
|
160
|
+
}
|
|
161
|
+
nicknameError.value = "Your nickname is already used by another user in this project";
|
|
162
|
+
showNicknameModal.value = true;
|
|
163
|
+
} else if (data.user) {
|
|
164
|
+
nickname.value = data.user.nickname;
|
|
165
|
+
if (typeof window !== "undefined") {
|
|
166
|
+
localStorage.setItem(STORAGE_KEY_NICKNAME, data.user.nickname);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
function getNicknameById(id) {
|
|
172
|
+
const user = users.value.find((u) => u.id === id);
|
|
173
|
+
return user?.nickname || null;
|
|
174
|
+
}
|
|
175
|
+
function isOwnMessage(senderId) {
|
|
176
|
+
if (!senderId || !userId.value) return true;
|
|
177
|
+
return senderId === userId.value;
|
|
178
|
+
}
|
|
179
|
+
async function copyShareLink(includeNickname = false) {
|
|
180
|
+
const link = createShareLink(includeNickname);
|
|
181
|
+
try {
|
|
182
|
+
await navigator.clipboard.writeText(link);
|
|
183
|
+
return true;
|
|
184
|
+
} catch {
|
|
185
|
+
return false;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return {
|
|
189
|
+
// State
|
|
190
|
+
userId,
|
|
191
|
+
nickname,
|
|
192
|
+
users,
|
|
193
|
+
showNicknameModal,
|
|
194
|
+
nicknameError,
|
|
195
|
+
isShareMode,
|
|
196
|
+
wasInvited,
|
|
197
|
+
sharingActiveOnServer,
|
|
198
|
+
nicknameFromUrl,
|
|
199
|
+
// Methods
|
|
200
|
+
initShare,
|
|
201
|
+
createShareLink,
|
|
202
|
+
setNickname,
|
|
203
|
+
needsNicknameImmediate,
|
|
204
|
+
needsNicknameForMessage,
|
|
205
|
+
needsNicknameForShare,
|
|
206
|
+
checkSharingStatus,
|
|
207
|
+
syncCredentials,
|
|
208
|
+
registerUser,
|
|
209
|
+
setupSocketListeners,
|
|
210
|
+
getNicknameById,
|
|
211
|
+
isOwnMessage,
|
|
212
|
+
copyShareLink
|
|
213
|
+
};
|
|
214
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare function useVoiceInput(): {
|
|
2
|
+
isRecording: import("vue").Ref<boolean, boolean>;
|
|
3
|
+
isSpeechSupported: import("vue").Ref<boolean, boolean>;
|
|
4
|
+
initSpeechRecognition: (onResult: (transcript: string) => void) => void;
|
|
5
|
+
toggleVoiceInput: (onResult: (transcript: string) => void) => void;
|
|
6
|
+
stopRecording: () => void;
|
|
7
|
+
cleanup: () => void;
|
|
8
|
+
};
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { ref } from "vue";
|
|
2
|
+
export function useVoiceInput() {
|
|
3
|
+
const isRecording = ref(false);
|
|
4
|
+
const speechRecognition = ref(null);
|
|
5
|
+
const isSpeechSupported = ref(false);
|
|
6
|
+
const userStopped = ref(false);
|
|
7
|
+
if (typeof window !== "undefined") {
|
|
8
|
+
const SpeechRecognitionAPI = window.SpeechRecognition || window.webkitSpeechRecognition;
|
|
9
|
+
isSpeechSupported.value = !!SpeechRecognitionAPI;
|
|
10
|
+
}
|
|
11
|
+
function initSpeechRecognition(onResult) {
|
|
12
|
+
const SpeechRecognitionAPI = window.SpeechRecognition || window.webkitSpeechRecognition;
|
|
13
|
+
if (!SpeechRecognitionAPI) {
|
|
14
|
+
isSpeechSupported.value = false;
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
isSpeechSupported.value = true;
|
|
18
|
+
const recognition = new SpeechRecognitionAPI();
|
|
19
|
+
recognition.continuous = true;
|
|
20
|
+
recognition.interimResults = false;
|
|
21
|
+
recognition.lang = navigator.language || "en-US";
|
|
22
|
+
let processedResultCount = 0;
|
|
23
|
+
recognition.onresult = (event) => {
|
|
24
|
+
for (let i = event.resultIndex; i < event.results.length; i++) {
|
|
25
|
+
const result = event.results[i];
|
|
26
|
+
if (result.isFinal && i >= processedResultCount) {
|
|
27
|
+
const transcript = result[0].transcript;
|
|
28
|
+
if (transcript.trim()) {
|
|
29
|
+
onResult(transcript);
|
|
30
|
+
}
|
|
31
|
+
processedResultCount = i + 1;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
recognition.onerror = (event) => {
|
|
36
|
+
if (event.error === "no-speech" || event.error === "aborted") {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
console.error("Speech recognition error:", event.error);
|
|
40
|
+
isRecording.value = false;
|
|
41
|
+
};
|
|
42
|
+
recognition.onend = () => {
|
|
43
|
+
if (isRecording.value && !userStopped.value) {
|
|
44
|
+
setTimeout(() => {
|
|
45
|
+
if (isRecording.value && !userStopped.value && speechRecognition.value) {
|
|
46
|
+
processedResultCount = 0;
|
|
47
|
+
try {
|
|
48
|
+
speechRecognition.value.start();
|
|
49
|
+
} catch {
|
|
50
|
+
isRecording.value = false;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}, 100);
|
|
54
|
+
} else {
|
|
55
|
+
isRecording.value = false;
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
recognition.onstart = () => {
|
|
59
|
+
processedResultCount = 0;
|
|
60
|
+
};
|
|
61
|
+
speechRecognition.value = recognition;
|
|
62
|
+
}
|
|
63
|
+
function toggleVoiceInput(onResult) {
|
|
64
|
+
if (!speechRecognition.value) {
|
|
65
|
+
initSpeechRecognition(onResult);
|
|
66
|
+
}
|
|
67
|
+
if (!speechRecognition.value) {
|
|
68
|
+
alert("Speech recognition is not supported in this browser. Try Chrome or Edge.");
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
if (isRecording.value) {
|
|
72
|
+
userStopped.value = true;
|
|
73
|
+
speechRecognition.value.stop();
|
|
74
|
+
isRecording.value = false;
|
|
75
|
+
} else {
|
|
76
|
+
userStopped.value = false;
|
|
77
|
+
try {
|
|
78
|
+
speechRecognition.value.start();
|
|
79
|
+
isRecording.value = true;
|
|
80
|
+
} catch (e) {
|
|
81
|
+
console.error("Failed to start speech recognition:", e);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
function stopRecording() {
|
|
86
|
+
userStopped.value = true;
|
|
87
|
+
if (isRecording.value && speechRecognition.value) {
|
|
88
|
+
speechRecognition.value.stop();
|
|
89
|
+
isRecording.value = false;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
function cleanup() {
|
|
93
|
+
userStopped.value = true;
|
|
94
|
+
if (speechRecognition.value && isRecording.value) {
|
|
95
|
+
speechRecognition.value.stop();
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return {
|
|
99
|
+
isRecording,
|
|
100
|
+
isSpeechSupported,
|
|
101
|
+
initSpeechRecognition,
|
|
102
|
+
toggleVoiceInput,
|
|
103
|
+
stopRecording,
|
|
104
|
+
cleanup
|
|
105
|
+
};
|
|
106
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared constants for Claude DevTools
|
|
3
|
+
* Used by server, client, and overlay
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Socket.IO endpoint path for real-time communication
|
|
7
|
+
*/
|
|
8
|
+
export declare const SOCKET_PATH = "/__claude_devtools_socket";
|
|
9
|
+
/**
|
|
10
|
+
* DevTools UI iframe route
|
|
11
|
+
*/
|
|
12
|
+
export declare const DEVTOOLS_UI_ROUTE = "/__claude-devtools";
|
|
13
|
+
/**
|
|
14
|
+
* Unique user identifier for collaborative sessions
|
|
15
|
+
*/
|
|
16
|
+
export declare const STORAGE_KEY_USER_ID = "claude-devtools-user-id";
|
|
17
|
+
/**
|
|
18
|
+
* User's display name for collaborative sessions
|
|
19
|
+
*/
|
|
20
|
+
export declare const STORAGE_KEY_NICKNAME = "claude-devtools-nickname";
|
|
21
|
+
/**
|
|
22
|
+
* URL parameter for sharing collaborative session links
|
|
23
|
+
*/
|
|
24
|
+
export declare const URL_PARAM_SHARE = "oro_share";
|
|
25
|
+
/**
|
|
26
|
+
* URL parameter for auto-setting nickname from share link
|
|
27
|
+
*/
|
|
28
|
+
export declare const URL_PARAM_SHARE_NICKNAME = "oro_share_nickname";
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export const SOCKET_PATH = "/__claude_devtools_socket";
|
|
2
|
+
export const DEVTOOLS_UI_ROUTE = "/__claude-devtools";
|
|
3
|
+
export const STORAGE_KEY_USER_ID = "claude-devtools-user-id";
|
|
4
|
+
export const STORAGE_KEY_NICKNAME = "claude-devtools-nickname";
|
|
5
|
+
export const URL_PARAM_SHARE = "oro_share";
|
|
6
|
+
export const URL_PARAM_SHARE_NICKNAME = "oro_share_nickname";
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared exports for Claude DevTools
|
|
3
|
+
* Used by both overlay and potentially external integrations
|
|
4
|
+
*/
|
|
5
|
+
export * from './types.js';
|
|
6
|
+
export * from './constants.js';
|
|
7
|
+
export { useClaudeChat } from './composables/useClaudeChat.js';
|
|
8
|
+
export { useVoiceInput } from './composables/useVoiceInput.js';
|
|
9
|
+
export { useShare } from './composables/useShare.js';
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared types for Claude DevTools
|
|
3
|
+
* Used by both DevTools client and Overlay
|
|
4
|
+
*/
|
|
5
|
+
export interface ContentBlock {
|
|
6
|
+
type: 'text' | 'tool_use' | 'tool_result' | 'thinking';
|
|
7
|
+
text?: string;
|
|
8
|
+
thinking?: string;
|
|
9
|
+
id?: string;
|
|
10
|
+
name?: string;
|
|
11
|
+
input?: Record<string, unknown>;
|
|
12
|
+
tool_use_id?: string;
|
|
13
|
+
content?: string | unknown[];
|
|
14
|
+
is_error?: boolean;
|
|
15
|
+
}
|
|
16
|
+
export interface Message {
|
|
17
|
+
id: string;
|
|
18
|
+
role: 'user' | 'assistant' | 'system';
|
|
19
|
+
content: string;
|
|
20
|
+
contentBlocks?: ContentBlock[];
|
|
21
|
+
timestamp: Date | string;
|
|
22
|
+
streaming?: boolean;
|
|
23
|
+
model?: string;
|
|
24
|
+
senderId?: string;
|
|
25
|
+
senderNickname?: string;
|
|
26
|
+
attachments?: MessageAttachment[];
|
|
27
|
+
}
|
|
28
|
+
export interface Conversation {
|
|
29
|
+
id: string;
|
|
30
|
+
title?: string;
|
|
31
|
+
messages: Message[];
|
|
32
|
+
createdAt: string;
|
|
33
|
+
updatedAt: string;
|
|
34
|
+
projectPath: string;
|
|
35
|
+
}
|
|
36
|
+
export interface DocFile {
|
|
37
|
+
path: string;
|
|
38
|
+
name: string;
|
|
39
|
+
}
|
|
40
|
+
export interface SlashCommand {
|
|
41
|
+
name: string;
|
|
42
|
+
description?: string;
|
|
43
|
+
}
|
|
44
|
+
export interface ShareUser {
|
|
45
|
+
id: string;
|
|
46
|
+
nickname: string;
|
|
47
|
+
joinedAt: string;
|
|
48
|
+
lastSeen: string;
|
|
49
|
+
}
|
|
50
|
+
export interface MessageContextData {
|
|
51
|
+
viewport?: {
|
|
52
|
+
width: number;
|
|
53
|
+
height: number;
|
|
54
|
+
};
|
|
55
|
+
userAgent?: string;
|
|
56
|
+
routing?: {
|
|
57
|
+
path: string;
|
|
58
|
+
fullPath?: string;
|
|
59
|
+
query?: Record<string, string | string[]>;
|
|
60
|
+
params?: Record<string, string>;
|
|
61
|
+
name?: string;
|
|
62
|
+
pageComponent?: string;
|
|
63
|
+
};
|
|
64
|
+
components?: string[];
|
|
65
|
+
}
|
|
66
|
+
export interface ContextChip {
|
|
67
|
+
id: 'viewport' | 'user-agent' | 'routing';
|
|
68
|
+
label: string;
|
|
69
|
+
icon: string;
|
|
70
|
+
active: boolean;
|
|
71
|
+
}
|
|
72
|
+
export interface ImageAttachment {
|
|
73
|
+
id: string;
|
|
74
|
+
filename: string;
|
|
75
|
+
mimeType: string;
|
|
76
|
+
data: string;
|
|
77
|
+
size: number;
|
|
78
|
+
}
|
|
79
|
+
export interface MessageAttachment {
|
|
80
|
+
type: 'image';
|
|
81
|
+
path: string;
|
|
82
|
+
filename: string;
|
|
83
|
+
mimeType: string;
|
|
84
|
+
}
|
|
File without changes
|
package/dist/runtime/types.d.ts
CHANGED
|
@@ -19,6 +19,19 @@ export interface ThinkingBlock {
|
|
|
19
19
|
thinking: string;
|
|
20
20
|
}
|
|
21
21
|
export type ContentBlock = TextBlock | ToolUseBlock | ToolResultBlock | ThinkingBlock;
|
|
22
|
+
export interface ImageAttachment {
|
|
23
|
+
id: string;
|
|
24
|
+
filename: string;
|
|
25
|
+
mimeType: string;
|
|
26
|
+
data: string;
|
|
27
|
+
size: number;
|
|
28
|
+
}
|
|
29
|
+
export interface MessageAttachment {
|
|
30
|
+
type: 'image';
|
|
31
|
+
path: string;
|
|
32
|
+
filename: string;
|
|
33
|
+
mimeType: string;
|
|
34
|
+
}
|
|
22
35
|
export interface Message {
|
|
23
36
|
id: string;
|
|
24
37
|
role: 'user' | 'assistant' | 'system';
|
|
@@ -27,6 +40,9 @@ export interface Message {
|
|
|
27
40
|
timestamp: Date | string;
|
|
28
41
|
streaming?: boolean;
|
|
29
42
|
model?: string;
|
|
43
|
+
senderId?: string;
|
|
44
|
+
senderNickname?: string;
|
|
45
|
+
attachments?: MessageAttachment[];
|
|
30
46
|
}
|
|
31
47
|
export interface Conversation {
|
|
32
48
|
id: string;
|
package/dist/types.d.mts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oro.ad/nuxt-claude-devtools",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"description": "Nuxt DevTools integration for Claude Code AI assistant",
|
|
5
5
|
"license": "GPL-3.0-only",
|
|
6
6
|
"type": "module",
|
|
@@ -56,7 +56,8 @@
|
|
|
56
56
|
"@oro.ad/nuxt-claude-devtools-bc": "^1.0.5",
|
|
57
57
|
"marked": "^17.0.1",
|
|
58
58
|
"sirv": "^3.0.2",
|
|
59
|
-
"socket.io": "^4.8.1"
|
|
59
|
+
"socket.io": "^4.8.1",
|
|
60
|
+
"socket.io-client": "^4.8.1"
|
|
60
61
|
},
|
|
61
62
|
"devDependencies": {
|
|
62
63
|
"@iconify-json/carbon": "^1.2.15",
|
|
@@ -69,7 +70,8 @@
|
|
|
69
70
|
"@nuxtjs/i18n": "^10.2.1",
|
|
70
71
|
"changelogen": "^0.6.2",
|
|
71
72
|
"eslint": "^9.39.2",
|
|
72
|
-
"nuxt": "^4.2.2"
|
|
73
|
+
"nuxt": "^4.2.2",
|
|
74
|
+
"vue-tsc": "^3.2.4"
|
|
73
75
|
},
|
|
74
76
|
"publishConfig": {
|
|
75
77
|
"access": "public"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{_ as B}from"./bl5iU4Kz.js";import{u as R,a as E,_ as q,b as D,c as H,l as I}from"./BiBLVxWh.js";import{_ as z}from"./DBIw6BGF.js";import{_ as G}from"./CLKqRoht.js";import{g as J,r as p,j as K,k as O,c as r,o as u,a as t,b as s,w as i,d as a,n as Q,l as V,t as v,m as b,v as x,F as S,p as W}from"./nKfsBgPE.js";const X={class:"relative flex flex-col h-screen n-bg-base"},Y={class:"flex items-center justify-between p-4"},Z={class:"flex items-center gap-3"},h={class:"text-xl font-bold flex items-center gap-2"},ee={class:"flex items-center gap-2"},te={class:"flex-1 overflow-auto p-4"},le={class:"space-y-4"},oe={key:0,class:"n-bg-active rounded-lg p-4"},se={key:0,class:"mb-4"},ne={class:"space-y-4"},ae={class:"flex gap-4"},re={class:"flex items-center gap-2"},ue={class:"flex items-center gap-2"},ie={class:"flex items-center gap-2"},de={key:1},me={class:"flex gap-4"},pe={class:"flex items-center gap-2"},ve={class:"flex items-center gap-2"},ce={class:"flex gap-2 pt-2"},fe={key:1,class:"n-bg-active rounded-lg p-4 opacity-50"},ge={key:2,class:"space-y-2"},be={class:"font-bold flex items-center gap-2"},xe={class:"text-sm opacity-70 font-mono"},Ue=J({__name:"mcp",setup(_e){const w=R(),{log:_}=E("mcp"),n=p(null),k=p(!1),c=p(!1),U=p([]),f=p(!1),l=p({name:"",transport:"stdio",command:"",args:"",url:"",scope:"local"}),m=p("");function T(){return w.isActive.value&&w.origin.value?w.origin.value:window.location.origin}function $(){const d=T();_("Connecting to socket at",d),n.value=I(d,{path:"/__claude_devtools_socket",transports:["websocket","polling"],reconnection:!0,reconnectionAttempts:5}),n.value.on("connect",()=>{_("Connected to socket"),k.value=!0,N()}),n.value.on("disconnect",()=>{_("Disconnected from socket"),k.value=!1}),n.value.on("mcp:list",e=>{_("MCP list received",e),U.value=e,c.value=!1}),n.value.on("mcp:added",e=>{e.success?(f.value=!1,M()):m.value=e.error||"Failed to add MCP server"}),n.value.on("mcp:removed",e=>{e.success||alert(`Failed to remove: ${e.error}`)})}function N(){n.value&&(c.value=!0,n.value.emit("mcp:list"))}function M(){l.value={name:"",transport:"stdio",command:"",args:"",url:"",scope:"local"},m.value=""}function L(){if(!l.value.name){m.value="Name is required";return}if(l.value.transport==="stdio"&&!l.value.command){m.value="Command is required for stdio transport";return}if((l.value.transport==="http"||l.value.transport==="sse")&&!l.value.url){m.value="URL is required for HTTP/SSE transport";return}if(n.value){const d=l.value.args.split(" ").map(e=>e.trim()).filter(e=>e.length>0);n.value.emit("mcp:add",{name:l.value.name,transport:l.value.transport,command:l.value.command,args:d,url:l.value.url,scope:l.value.scope})}}function j(d){confirm(`Remove MCP server "${d.name}"?`)&&n.value&&n.value.emit("mcp:remove",{name:d.name})}return K(()=>{$()}),O(()=>{n.value&&n.value.disconnect()}),(d,e)=>{const F=B,y=q,g=D,P=H,C=z,A=G;return u(),r("div",X,[t("div",Y,[t("div",Z,[s(F,{class:"text-sm opacity-50 hover:opacity-100",to:"/"},{default:i(()=>[...e[11]||(e[11]=[a(" ← Chat ",-1)])]),_:1}),t("h1",h,[s(y,{class:"text-blue",icon:"carbon:plug"}),e[12]||(e[12]=a(" MCP Servers ",-1))])]),t("div",ee,[s(g,{disabled:!k.value,n:"blue",onClick:e[0]||(e[0]=o=>f.value=!0)},{default:i(()=>[s(y,{class:"mr-1",icon:"carbon:add"}),e[13]||(e[13]=a(" Add Server ",-1))]),_:1},8,["disabled"]),s(g,{disabled:!k.value||c.value,n:"gray",onClick:N},{default:i(()=>[s(y,{class:Q([{"animate-spin":c.value},"mr-1"]),icon:"carbon:restart"},null,8,["class"]),e[14]||(e[14]=a(" Refresh ",-1))]),_:1},8,["disabled"])])]),t("div",te,[t("div",le,[s(P,{class:"text-sm",icon:"carbon:information",n:"blue"},{default:i(()=>[...e[15]||(e[15]=[a(" Model Context Protocol (MCP) servers extend Claude's capabilities with custom tools and data sources. ",-1)])]),_:1}),f.value?(u(),r("div",oe,[e[29]||(e[29]=t("h3",{class:"font-bold mb-4"}," Add MCP Server ",-1)),m.value?(u(),r("div",se,[s(P,{icon:"carbon:warning",n:"red"},{default:i(()=>[a(v(m.value),1)]),_:1})])):V("",!0),t("div",ne,[t("div",null,[e[16]||(e[16]=t("label",{class:"block text-sm font-medium mb-1"},"Name",-1)),s(C,{modelValue:l.value.name,"onUpdate:modelValue":e[1]||(e[1]=o=>l.value.name=o),class:"w-full",placeholder:"e.g. github, nuxt-ui-remote"},null,8,["modelValue"])]),t("div",null,[e[20]||(e[20]=t("label",{class:"block text-sm font-medium mb-1"},"Transport",-1)),t("div",ae,[t("label",re,[b(t("input",{"onUpdate:modelValue":e[2]||(e[2]=o=>l.value.transport=o),name:"transport",type:"radio",value:"stdio"},null,512),[[x,l.value.transport]]),e[17]||(e[17]=t("span",null,"stdio",-1))]),t("label",ue,[b(t("input",{"onUpdate:modelValue":e[3]||(e[3]=o=>l.value.transport=o),name:"transport",type:"radio",value:"http"},null,512),[[x,l.value.transport]]),e[18]||(e[18]=t("span",null,"HTTP",-1))]),t("label",ie,[b(t("input",{"onUpdate:modelValue":e[4]||(e[4]=o=>l.value.transport=o),name:"transport",type:"radio",value:"sse"},null,512),[[x,l.value.transport]]),e[19]||(e[19]=t("span",null,"SSE",-1))])])]),l.value.transport==="stdio"?(u(),r(S,{key:0},[t("div",null,[e[21]||(e[21]=t("label",{class:"block text-sm font-medium mb-1"},"Command",-1)),s(C,{modelValue:l.value.command,"onUpdate:modelValue":e[5]||(e[5]=o=>l.value.command=o),class:"w-full font-mono",placeholder:"e.g. npx"},null,8,["modelValue"])]),t("div",null,[e[22]||(e[22]=t("label",{class:"block text-sm font-medium mb-1"},"Arguments",-1)),s(C,{modelValue:l.value.args,"onUpdate:modelValue":e[6]||(e[6]=o=>l.value.args=o),class:"w-full font-mono",placeholder:"e.g. -y @modelcontextprotocol/server-github"},null,8,["modelValue"])])],64)):V("",!0),l.value.transport==="http"||l.value.transport==="sse"?(u(),r("div",de,[e[23]||(e[23]=t("label",{class:"block text-sm font-medium mb-1"},"URL",-1)),s(C,{modelValue:l.value.url,"onUpdate:modelValue":e[7]||(e[7]=o=>l.value.url=o),class:"w-full font-mono",placeholder:"e.g. https://ui.nuxt.com/mcp"},null,8,["modelValue"])])):V("",!0),t("div",null,[e[26]||(e[26]=t("label",{class:"block text-sm font-medium mb-1"},"Scope",-1)),t("div",me,[t("label",pe,[b(t("input",{"onUpdate:modelValue":e[8]||(e[8]=o=>l.value.scope=o),name:"scope",type:"radio",value:"local"},null,512),[[x,l.value.scope]]),e[24]||(e[24]=t("span",null,"Local (this project)",-1))]),t("label",ve,[b(t("input",{"onUpdate:modelValue":e[9]||(e[9]=o=>l.value.scope=o),name:"scope",type:"radio",value:"global"},null,512),[[x,l.value.scope]]),e[25]||(e[25]=t("span",null,"User (all projects)",-1))])])]),t("div",ce,[s(g,{n:"green",onClick:L},{default:i(()=>[...e[27]||(e[27]=[a(" Add Server ",-1)])]),_:1}),s(g,{n:"gray",onClick:e[10]||(e[10]=o=>{f.value=!1,M()})},{default:i(()=>[...e[28]||(e[28]=[a(" Cancel ",-1)])]),_:1})])])])):V("",!0),U.value.length===0&&!f.value&&!c.value?(u(),r("div",fe,' No MCP servers configured. Click "Add Server" to get started. ')):(u(),r("div",ge,[(u(!0),r(S,null,W(U.value,o=>(u(),r("div",{key:o.name,class:"n-bg-active rounded-lg p-4 flex items-center justify-between"},[t("div",null,[t("div",be,[a(v(o.name)+" ",1),s(A,{n:o.transport==="stdio"?"gray":"blue",class:"text-xs"},{default:i(()=>[a(v(o.transport),1)]),_:2},1032,["n"]),s(A,{n:o.scope==="local"?"green":"purple",class:"text-xs"},{default:i(()=>[a(v(o.scope),1)]),_:2},1032,["n"])]),t("div",xe,[o.transport==="stdio"?(u(),r(S,{key:0},[a(v(o.command)+" "+v(o.args?.join(" ")),1)],64)):(u(),r(S,{key:1},[a(v(o.url),1)],64))])]),s(g,{n:"red",onClick:ke=>j(o)},{default:i(()=>[s(y,{icon:"carbon:trash-can"})]),_:1},8,["onClick"])]))),128))]))])])])}}});export{Ue as default};
|