vite-plugin-opencode-assistant 1.0.4 → 1.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/es/client/index.d.ts +1 -0
- package/es/client/index.js +328 -0
- package/es/core/api.d.ts +14 -0
- package/es/core/api.js +294 -0
- package/es/core/injector.d.ts +2 -0
- package/es/core/injector.js +11 -0
- package/es/core/service.d.ts +18 -0
- package/es/core/service.js +163 -0
- package/es/endpoints/context.d.ts +3 -0
- package/es/endpoints/context.js +114 -0
- package/es/endpoints/index.d.ts +4 -0
- package/es/endpoints/index.js +16 -0
- package/es/endpoints/sessions.d.ts +3 -0
- package/es/endpoints/sessions.js +79 -0
- package/es/endpoints/sse.d.ts +3 -0
- package/es/endpoints/sse.js +56 -0
- package/es/endpoints/start.d.ts +3 -0
- package/es/endpoints/start.js +35 -0
- package/es/endpoints/types.d.ts +13 -0
- package/es/endpoints/widget.d.ts +3 -0
- package/es/endpoints/widget.js +57 -0
- package/{dist/vite → es}/index.d.ts +1 -1
- package/es/index.js +168 -0
- package/es/utils/paths.d.ts +3 -0
- package/es/utils/paths.js +38 -0
- package/es/utils/system.js +241 -0
- package/lib/client/index.d.ts +1 -0
- package/lib/client/index.js +328 -0
- package/lib/client.js +5597 -0
- package/lib/core/api.d.ts +14 -0
- package/lib/core/api.js +321 -0
- package/lib/core/injector.d.ts +2 -0
- package/lib/core/injector.js +34 -0
- package/lib/core/service.d.ts +18 -0
- package/lib/core/service.js +180 -0
- package/lib/endpoints/context.d.ts +3 -0
- package/lib/endpoints/context.js +137 -0
- package/lib/endpoints/index.d.ts +4 -0
- package/lib/endpoints/index.js +41 -0
- package/lib/endpoints/sessions.d.ts +3 -0
- package/lib/endpoints/sessions.js +102 -0
- package/lib/endpoints/sse.d.ts +3 -0
- package/lib/endpoints/sse.js +79 -0
- package/lib/endpoints/start.d.ts +3 -0
- package/lib/endpoints/start.js +58 -0
- package/lib/endpoints/types.d.ts +13 -0
- package/lib/endpoints/types.js +15 -0
- package/lib/endpoints/widget.d.ts +3 -0
- package/lib/endpoints/widget.js +90 -0
- package/lib/index.d.ts +3 -0
- package/lib/index.js +190 -0
- package/lib/style.css +1 -0
- package/lib/utils/paths.d.ts +3 -0
- package/lib/utils/paths.js +73 -0
- package/lib/utils/system.d.ts +5 -0
- package/lib/utils/system.js +274 -0
- package/package.json +28 -33
- package/README.md +0 -287
- package/dist/constants.d.ts +0 -74
- package/dist/constants.js +0 -75
- package/dist/constants.js.map +0 -1
- package/dist/logger.d.ts +0 -64
- package/dist/logger.js +0 -311
- package/dist/logger.js.map +0 -1
- package/dist/opencode/plugins/page-context.d.ts +0 -7
- package/dist/opencode/plugins/page-context.js +0 -372
- package/dist/opencode/plugins/page-context.js.map +0 -1
- package/dist/opencode/web.d.ts +0 -3
- package/dist/opencode/web.js +0 -81
- package/dist/opencode/web.js.map +0 -1
- package/dist/types.d.ts +0 -126
- package/dist/types.js +0 -2
- package/dist/types.js.map +0 -1
- package/dist/vite/client.js +0 -2468
- package/dist/vite/client.js.map +0 -1
- package/dist/vite/index.js +0 -697
- package/dist/vite/index.js.map +0 -1
- package/dist/vite/injector.d.ts +0 -2
- package/dist/vite/injector.js +0 -6
- package/dist/vite/injector.js.map +0 -1
- package/dist/vite/utils.js +0 -206
- package/dist/vite/utils.js.map +0 -1
- /package/{dist/vite/client.d.ts → es/endpoints/types.js} +0 -0
- /package/{dist/vite/utils.d.ts → es/utils/system.d.ts} +0 -0
|
@@ -0,0 +1,328 @@
|
|
|
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
|
+
var __async = (__this, __arguments, generator) => {
|
|
21
|
+
return new Promise((resolve, reject) => {
|
|
22
|
+
var fulfilled = (value) => {
|
|
23
|
+
try {
|
|
24
|
+
step(generator.next(value));
|
|
25
|
+
} catch (e) {
|
|
26
|
+
reject(e);
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
var rejected = (value) => {
|
|
30
|
+
try {
|
|
31
|
+
step(generator.throw(value));
|
|
32
|
+
} catch (e) {
|
|
33
|
+
reject(e);
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
|
37
|
+
step((generator = generator.apply(__this, __arguments)).next());
|
|
38
|
+
});
|
|
39
|
+
};
|
|
40
|
+
var import_vue = require("vue");
|
|
41
|
+
var import_components = require("@vite-plugin-opencode-assistant/components");
|
|
42
|
+
var import_style = require("@vite-plugin-opencode-assistant/components/style.css");
|
|
43
|
+
var import_shared = require("@vite-plugin-opencode-assistant/shared");
|
|
44
|
+
let config = {};
|
|
45
|
+
const scriptTag = document.querySelector(`script[${import_shared.CONFIG_DATA_ATTR}]`);
|
|
46
|
+
if (scriptTag) {
|
|
47
|
+
const configBase64 = scriptTag.getAttribute(import_shared.CONFIG_DATA_ATTR);
|
|
48
|
+
if (configBase64) {
|
|
49
|
+
try {
|
|
50
|
+
config = JSON.parse(atob(configBase64));
|
|
51
|
+
} catch (e) {
|
|
52
|
+
console.error("[OpenCode] Failed to parse config:", e);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
const App = {
|
|
57
|
+
setup() {
|
|
58
|
+
const open = (0, import_vue.ref)(false);
|
|
59
|
+
const selectMode = (0, import_vue.ref)(false);
|
|
60
|
+
const sessionListCollapsed = (0, import_vue.ref)(true);
|
|
61
|
+
const loading = (0, import_vue.ref)(false);
|
|
62
|
+
const loadingSessionList = (0, import_vue.ref)(void 0);
|
|
63
|
+
const iframeSrc = (0, import_vue.ref)("");
|
|
64
|
+
const currentSessionId = (0, import_vue.ref)(null);
|
|
65
|
+
const sessions = (0, import_vue.ref)([]);
|
|
66
|
+
const selectedElements = (0, import_vue.ref)([]);
|
|
67
|
+
const widgetRef = (0, import_vue.ref)(null);
|
|
68
|
+
const {
|
|
69
|
+
webUrl = "",
|
|
70
|
+
position = "bottom-right",
|
|
71
|
+
theme = "auto",
|
|
72
|
+
open: autoOpen = false,
|
|
73
|
+
sessionUrl: initialSessionUrl = "",
|
|
74
|
+
lazy = false,
|
|
75
|
+
hotkey = "ctrl+k",
|
|
76
|
+
cwd = ""
|
|
77
|
+
} = config;
|
|
78
|
+
const isWaitingForSession = (0, import_vue.ref)(!initialSessionUrl);
|
|
79
|
+
const computedLoading = (0, import_vue.computed)(() => loading.value || isWaitingForSession.value);
|
|
80
|
+
let servicesStarted = !lazy;
|
|
81
|
+
const extractSessionId = (url) => {
|
|
82
|
+
if (!url) return null;
|
|
83
|
+
const match = url.match(/\/session\/([^/?]+)/);
|
|
84
|
+
return match ? match[1] : null;
|
|
85
|
+
};
|
|
86
|
+
currentSessionId.value = extractSessionId(initialSessionUrl);
|
|
87
|
+
if (servicesStarted && initialSessionUrl) {
|
|
88
|
+
iframeSrc.value = initialSessionUrl;
|
|
89
|
+
}
|
|
90
|
+
try {
|
|
91
|
+
const stored = sessionStorage.getItem("__opencode_selected_elements__");
|
|
92
|
+
if (stored) {
|
|
93
|
+
selectedElements.value = JSON.parse(stored);
|
|
94
|
+
}
|
|
95
|
+
} catch (e) {
|
|
96
|
+
}
|
|
97
|
+
(0, import_vue.watch)(
|
|
98
|
+
selectedElements,
|
|
99
|
+
(val) => {
|
|
100
|
+
sessionStorage.setItem("__opencode_selected_elements__", JSON.stringify(val));
|
|
101
|
+
},
|
|
102
|
+
{ deep: true }
|
|
103
|
+
);
|
|
104
|
+
const showNotification = (msg) => {
|
|
105
|
+
var _a, _b;
|
|
106
|
+
(_b = (_a = widgetRef.value) == null ? void 0 : _a.showNotification) == null ? void 0 : _b.call(_a, msg);
|
|
107
|
+
};
|
|
108
|
+
const loadSessions = () => __async(null, null, function* () {
|
|
109
|
+
loadingSessionList.value = true;
|
|
110
|
+
try {
|
|
111
|
+
const response = yield fetch("/__opencode_sessions__");
|
|
112
|
+
const data = yield response.json();
|
|
113
|
+
sessions.value = data.filter((s) => s.directory === cwd && s.title !== "__chrome_mcp_warmup__").map((s) => {
|
|
114
|
+
var _a;
|
|
115
|
+
return __spreadProps(__spreadValues({}, s), {
|
|
116
|
+
updatedAt: ((_a = s.time) == null ? void 0 : _a.updated) || Date.now()
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
} catch (e) {
|
|
120
|
+
console.error("[OpenCode] Failed to load sessions:", e);
|
|
121
|
+
} finally {
|
|
122
|
+
loadingSessionList.value = false;
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
const createSession = () => __async(null, null, function* () {
|
|
126
|
+
try {
|
|
127
|
+
const response = yield fetch("/__opencode_sessions__", { method: "POST" });
|
|
128
|
+
const newSession = yield response.json();
|
|
129
|
+
yield loadSessions();
|
|
130
|
+
currentSessionId.value = newSession.id;
|
|
131
|
+
iframeSrc.value = `${webUrl}/${btoa(cwd)}/session/${newSession.id}`;
|
|
132
|
+
} catch (e) {
|
|
133
|
+
showNotification("\u521B\u5EFA\u4F1A\u8BDD\u5931\u8D25");
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
const deleteSession = (session) => __async(null, null, function* () {
|
|
137
|
+
try {
|
|
138
|
+
yield fetch(`/__opencode_sessions__?id=${session.id}`, { method: "DELETE" });
|
|
139
|
+
yield loadSessions();
|
|
140
|
+
showNotification("\u4F1A\u8BDD\u5DF2\u5220\u9664");
|
|
141
|
+
if (currentSessionId.value === session.id) {
|
|
142
|
+
if (sessions.value.length > 0) {
|
|
143
|
+
const nextSession = sessions.value[0];
|
|
144
|
+
currentSessionId.value = nextSession.id;
|
|
145
|
+
iframeSrc.value = `${webUrl}/${btoa(cwd)}/session/${nextSession.id}`;
|
|
146
|
+
} else {
|
|
147
|
+
currentSessionId.value = null;
|
|
148
|
+
iframeSrc.value = "";
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
} catch (e) {
|
|
152
|
+
showNotification("\u5220\u9664\u4F1A\u8BDD\u5931\u8D25");
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
const selectSession = (session) => {
|
|
156
|
+
if (currentSessionId.value === session.id) return;
|
|
157
|
+
currentSessionId.value = session.id;
|
|
158
|
+
loading.value = true;
|
|
159
|
+
iframeSrc.value = `${webUrl}/${btoa(cwd)}/session/${session.id}`;
|
|
160
|
+
setTimeout(() => {
|
|
161
|
+
loading.value = false;
|
|
162
|
+
}, 500);
|
|
163
|
+
};
|
|
164
|
+
let sseConnection = null;
|
|
165
|
+
const setupSSE = () => {
|
|
166
|
+
if (!servicesStarted || sseConnection) return;
|
|
167
|
+
sseConnection = new EventSource("/__opencode_events__");
|
|
168
|
+
sseConnection.onmessage = (event) => {
|
|
169
|
+
try {
|
|
170
|
+
const data = JSON.parse(event.data);
|
|
171
|
+
if (data.type === "CONNECTED") {
|
|
172
|
+
updateContext(true);
|
|
173
|
+
} else if (data.type === "SESSION_READY") {
|
|
174
|
+
if (data.sessionUrl && !iframeSrc.value) {
|
|
175
|
+
iframeSrc.value = data.sessionUrl;
|
|
176
|
+
currentSessionId.value = extractSessionId(data.sessionUrl);
|
|
177
|
+
}
|
|
178
|
+
isWaitingForSession.value = false;
|
|
179
|
+
} else if (data.type === "CLEAR_ELEMENTS") {
|
|
180
|
+
selectedElements.value = [];
|
|
181
|
+
}
|
|
182
|
+
} catch (e) {
|
|
183
|
+
}
|
|
184
|
+
};
|
|
185
|
+
};
|
|
186
|
+
let currentPageUrl = "";
|
|
187
|
+
let currentPageTitle = "";
|
|
188
|
+
const updateContext = (force = false) => {
|
|
189
|
+
if (!servicesStarted) return;
|
|
190
|
+
const newUrl = window.location.href;
|
|
191
|
+
const newTitle = document.title;
|
|
192
|
+
if (force || newUrl !== currentPageUrl || newTitle !== currentPageTitle) {
|
|
193
|
+
currentPageUrl = newUrl;
|
|
194
|
+
currentPageTitle = newTitle;
|
|
195
|
+
fetch("/__opencode_context__", {
|
|
196
|
+
method: "POST",
|
|
197
|
+
headers: { "Content-Type": "application/json" },
|
|
198
|
+
body: JSON.stringify({
|
|
199
|
+
url: newUrl,
|
|
200
|
+
title: newTitle,
|
|
201
|
+
selectedElements: selectedElements.value
|
|
202
|
+
})
|
|
203
|
+
}).catch(() => {
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
};
|
|
207
|
+
const ensureServicesStarted = () => __async(null, null, function* () {
|
|
208
|
+
if (servicesStarted) return true;
|
|
209
|
+
try {
|
|
210
|
+
const res = yield fetch("/__opencode_start__");
|
|
211
|
+
const data = yield res.json();
|
|
212
|
+
if (data.success) {
|
|
213
|
+
servicesStarted = true;
|
|
214
|
+
if (data.sessionUrl) {
|
|
215
|
+
iframeSrc.value = data.sessionUrl;
|
|
216
|
+
currentSessionId.value = extractSessionId(data.sessionUrl);
|
|
217
|
+
isWaitingForSession.value = false;
|
|
218
|
+
}
|
|
219
|
+
setupSSE();
|
|
220
|
+
return true;
|
|
221
|
+
}
|
|
222
|
+
} catch (e) {
|
|
223
|
+
}
|
|
224
|
+
return false;
|
|
225
|
+
});
|
|
226
|
+
(0, import_vue.onMounted)(() => {
|
|
227
|
+
if (servicesStarted) {
|
|
228
|
+
loadSessions();
|
|
229
|
+
setupSSE();
|
|
230
|
+
updateContext(true);
|
|
231
|
+
}
|
|
232
|
+
if (autoOpen && servicesStarted) {
|
|
233
|
+
setTimeout(() => {
|
|
234
|
+
open.value = true;
|
|
235
|
+
}, 1e3);
|
|
236
|
+
}
|
|
237
|
+
const originalPushState = history.pushState;
|
|
238
|
+
const originalReplaceState = history.replaceState;
|
|
239
|
+
history.pushState = function(...args) {
|
|
240
|
+
originalPushState.apply(this, args);
|
|
241
|
+
setTimeout(updateContext, 0);
|
|
242
|
+
};
|
|
243
|
+
history.replaceState = function(...args) {
|
|
244
|
+
originalReplaceState.apply(this, args);
|
|
245
|
+
setTimeout(updateContext, 0);
|
|
246
|
+
};
|
|
247
|
+
window.addEventListener("popstate", () => setTimeout(updateContext, 0));
|
|
248
|
+
window.addEventListener("hashchange", () => setTimeout(updateContext, 0));
|
|
249
|
+
const titleObserver = new MutationObserver(() => {
|
|
250
|
+
if (document.title !== currentPageTitle) updateContext();
|
|
251
|
+
});
|
|
252
|
+
if (document.head) {
|
|
253
|
+
titleObserver.observe(document.head, { childList: true, subtree: true });
|
|
254
|
+
}
|
|
255
|
+
});
|
|
256
|
+
const handleToggle = (val) => __async(null, null, function* () {
|
|
257
|
+
if (lazy && !servicesStarted && val) {
|
|
258
|
+
loading.value = true;
|
|
259
|
+
const started = yield ensureServicesStarted();
|
|
260
|
+
loading.value = false;
|
|
261
|
+
if (!started) {
|
|
262
|
+
showNotification("\u670D\u52A1\u542F\u52A8\u5931\u8D25");
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
open.value = val;
|
|
267
|
+
if (val) updateContext();
|
|
268
|
+
});
|
|
269
|
+
const handleSelectNode = (element) => {
|
|
270
|
+
const exists = selectedElements.value.some(
|
|
271
|
+
(el) => el.filePath === element.filePath && el.line === element.line
|
|
272
|
+
);
|
|
273
|
+
if (!exists) {
|
|
274
|
+
selectedElements.value.push(element);
|
|
275
|
+
showNotification(`\u5DF2\u9009\u4E2D\u5143\u7D20 (${selectedElements.value.length}\u4E2A)`);
|
|
276
|
+
updateContext(true);
|
|
277
|
+
} else {
|
|
278
|
+
showNotification("\u8BE5\u5143\u7D20\u5DF2\u9009\u4E2D");
|
|
279
|
+
}
|
|
280
|
+
};
|
|
281
|
+
const handleClearSelected = () => {
|
|
282
|
+
selectedElements.value = [];
|
|
283
|
+
updateContext(true);
|
|
284
|
+
showNotification("\u5DF2\u6E05\u9664\u6240\u6709\u9009\u4E2D\u5143\u7D20");
|
|
285
|
+
};
|
|
286
|
+
return () => {
|
|
287
|
+
return (0, import_vue.h)(import_components.OpenCodeWidget, {
|
|
288
|
+
ref: widgetRef,
|
|
289
|
+
position,
|
|
290
|
+
theme,
|
|
291
|
+
open: open.value,
|
|
292
|
+
selectMode: selectMode.value,
|
|
293
|
+
sessionListCollapsed: sessionListCollapsed.value,
|
|
294
|
+
loading: computedLoading.value,
|
|
295
|
+
loadingSessionList: loadingSessionList.value,
|
|
296
|
+
iframeSrc: iframeSrc.value,
|
|
297
|
+
currentSessionId: currentSessionId.value,
|
|
298
|
+
sessions: sessions.value,
|
|
299
|
+
selectedElements: selectedElements.value,
|
|
300
|
+
hotkeyLabel: hotkey,
|
|
301
|
+
"onUpdate:open": handleToggle,
|
|
302
|
+
"onUpdate:selectMode": (val) => {
|
|
303
|
+
selectMode.value = val;
|
|
304
|
+
},
|
|
305
|
+
"onUpdate:sessionListCollapsed": (val) => {
|
|
306
|
+
sessionListCollapsed.value = val;
|
|
307
|
+
},
|
|
308
|
+
"onCreate-session": createSession,
|
|
309
|
+
"onDelete-session": deleteSession,
|
|
310
|
+
"onSelect-session": selectSession,
|
|
311
|
+
"onClick-selected-node": handleSelectNode,
|
|
312
|
+
"onClear-selected-nodes": handleClearSelected,
|
|
313
|
+
"onRemove-selected-node": ({ index }) => {
|
|
314
|
+
selectedElements.value.splice(index, 1);
|
|
315
|
+
updateContext(true);
|
|
316
|
+
},
|
|
317
|
+
"onEmpty-action": createSession
|
|
318
|
+
});
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
};
|
|
322
|
+
const INIT_MARKER = "__OPENCODE_INITIALIZED__";
|
|
323
|
+
if (!window[INIT_MARKER]) {
|
|
324
|
+
window[INIT_MARKER] = true;
|
|
325
|
+
const container = document.createElement("div");
|
|
326
|
+
document.body.appendChild(container);
|
|
327
|
+
(0, import_vue.createApp)(App).mount(container);
|
|
328
|
+
}
|