vite-plugin-opencode-assistant 1.0.30 → 1.0.31
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/App.vue.js +7 -12
- package/es/core/proxy-server.js +1 -1
- package/es/core/service.d.ts +1 -1
- package/es/core/service.js +6 -4
- package/es/endpoints/index.d.ts +2 -0
- package/es/endpoints/index.js +3 -0
- package/es/endpoints/logs.d.ts +11 -0
- package/es/endpoints/logs.js +107 -0
- package/es/index.js +8 -4
- package/lib/client/App.vue.js +7 -12
- package/lib/client.js +5 -10
- package/lib/core/proxy-server.js +1 -1
- package/lib/core/service.d.ts +1 -1
- package/lib/core/service.js +6 -4
- package/lib/endpoints/index.d.ts +2 -0
- package/lib/endpoints/index.js +4 -0
- package/lib/endpoints/logs.d.ts +11 -0
- package/lib/endpoints/logs.js +129 -0
- package/lib/index.js +5 -2
- package/package.json +4 -4
package/es/client/App.vue.js
CHANGED
|
@@ -88,15 +88,8 @@ const __vue_sfc__ = /* @__PURE__ */ _defineComponent({
|
|
|
88
88
|
updateStatusFromTask,
|
|
89
89
|
setStarting
|
|
90
90
|
} = useServiceStatus();
|
|
91
|
-
const {
|
|
92
|
-
|
|
93
|
-
removeElement,
|
|
94
|
-
clearElements
|
|
95
|
-
} = useSelectedElements();
|
|
96
|
-
const {
|
|
97
|
-
theme,
|
|
98
|
-
sendThemeToIframe
|
|
99
|
-
} = useTheme(widgetTheme, widgetRef);
|
|
91
|
+
const { selectedElements, removeElement, clearElements } = useSelectedElements();
|
|
92
|
+
const { theme, sendThemeToIframe } = useTheme(widgetTheme, widgetRef);
|
|
100
93
|
const {
|
|
101
94
|
sessions,
|
|
102
95
|
loadingSessionList,
|
|
@@ -211,13 +204,13 @@ const __vue_sfc__ = /* @__PURE__ */ _defineComponent({
|
|
|
211
204
|
}
|
|
212
205
|
});
|
|
213
206
|
onMounted(() => {
|
|
214
|
-
if (serviceStatus.value
|
|
207
|
+
if (serviceStatus.value === "ready") {
|
|
215
208
|
loadSessions();
|
|
216
209
|
serverSSE.connect();
|
|
217
210
|
opencodeSSE.connect();
|
|
218
211
|
updateContext(true);
|
|
219
212
|
}
|
|
220
|
-
if (autoOpen && serviceStatus.value
|
|
213
|
+
if (autoOpen && serviceStatus.value === "ready") {
|
|
221
214
|
setTimeout(() => {
|
|
222
215
|
open.value = true;
|
|
223
216
|
}, 1e3);
|
|
@@ -252,7 +245,9 @@ const __vue_sfc__ = /* @__PURE__ */ _defineComponent({
|
|
|
252
245
|
previewPageUrl: window.location.href,
|
|
253
246
|
previewPageTitle: document.title
|
|
254
247
|
});
|
|
255
|
-
(_a = widgetRef.value) == null ? void 0 : _a.sendMessageToIframe("OPENCODE_INSERT_FILE_PART", {
|
|
248
|
+
(_a = widgetRef.value) == null ? void 0 : _a.sendMessageToIframe("OPENCODE_INSERT_FILE_PART", {
|
|
249
|
+
element: elementWithContext
|
|
250
|
+
});
|
|
256
251
|
showNotification(`\u8282\u70B9\u5DF2\u6DFB\u52A0\u5230\u5BF9\u8BDD\u6846`, { mode: "page" });
|
|
257
252
|
};
|
|
258
253
|
const handleClearSelected = () => {
|
package/es/core/proxy-server.js
CHANGED
|
@@ -430,7 +430,7 @@ function startProxyServer(targetUrl, port, options = {}) {
|
|
|
430
430
|
server.listen(port, () => {
|
|
431
431
|
const address = server.address();
|
|
432
432
|
const actualPort = typeof address === "object" && address ? address.port : port;
|
|
433
|
-
log.
|
|
433
|
+
log.debug(`Proxy server started on port ${actualPort} -> ${targetUrl}`);
|
|
434
434
|
resolve({ server, actualPort });
|
|
435
435
|
});
|
|
436
436
|
});
|
package/es/core/service.d.ts
CHANGED
|
@@ -25,7 +25,7 @@ export declare class OpenCodeService {
|
|
|
25
25
|
workspaceRoot: string | null;
|
|
26
26
|
constructor(config: Required<OpenCodeOptions>, api: OpenCodeAPI, sseClients: Set<http.ServerResponse>, onPortAllocated: (port: number) => void, onProxyPortAllocated: (port: number) => void);
|
|
27
27
|
private sendTaskUpdate;
|
|
28
|
-
start(corsOrigins?: string[], contextApiUrl?: string, viteOrigin?: string): Promise<void>;
|
|
28
|
+
start(corsOrigins?: string[], contextApiUrl?: string, logsApiUrl?: string, viteOrigin?: string): Promise<void>;
|
|
29
29
|
retryWarmupChromeMcp(viteOrigin?: string): Promise<{
|
|
30
30
|
success: boolean;
|
|
31
31
|
errorType?: string;
|
package/es/core/service.js
CHANGED
|
@@ -86,7 +86,7 @@ class OpenCodeService {
|
|
|
86
86
|
}
|
|
87
87
|
});
|
|
88
88
|
}
|
|
89
|
-
start(corsOrigins, contextApiUrl, viteOrigin) {
|
|
89
|
+
start(corsOrigins, contextApiUrl, logsApiUrl, viteOrigin) {
|
|
90
90
|
return __async(this, null, function* () {
|
|
91
91
|
if (this.isStarted && this.webProcess) {
|
|
92
92
|
log.debug("Services already started, skipping");
|
|
@@ -101,6 +101,7 @@ class OpenCodeService {
|
|
|
101
101
|
const timer = log.timer("startServices", {
|
|
102
102
|
corsOrigins,
|
|
103
103
|
contextApiUrl,
|
|
104
|
+
logsApiUrl,
|
|
104
105
|
viteOrigin
|
|
105
106
|
});
|
|
106
107
|
log.info("Starting OpenCode services...");
|
|
@@ -144,7 +145,7 @@ Please install OpenCode first:
|
|
|
144
145
|
}
|
|
145
146
|
timer.checkpoint("Port allocated");
|
|
146
147
|
this.workspaceRoot = findGitRoot(process.cwd());
|
|
147
|
-
log.
|
|
148
|
+
log.debug(`Using workspace root: ${this.workspaceRoot}`);
|
|
148
149
|
this.sendTaskUpdate("preparing_runtime");
|
|
149
150
|
const configDir = prepareOpenCodeRuntime(this.workspaceRoot);
|
|
150
151
|
timer.checkpoint("Plugin setup complete");
|
|
@@ -161,11 +162,12 @@ Please install OpenCode first:
|
|
|
161
162
|
cwd: this.workspaceRoot,
|
|
162
163
|
configDir,
|
|
163
164
|
corsOrigins,
|
|
164
|
-
contextApiUrl
|
|
165
|
+
contextApiUrl,
|
|
166
|
+
logsApiUrl
|
|
165
167
|
});
|
|
166
168
|
timer.checkpoint("Web process started");
|
|
167
169
|
const webUrl = `http://${this.config.hostname}:${this.actualWebPort}`;
|
|
168
|
-
log.
|
|
170
|
+
log.debug(`Waiting for OpenCode Web to become ready at ${webUrl}...`);
|
|
169
171
|
this.sendTaskUpdate("waiting_web_ready");
|
|
170
172
|
try {
|
|
171
173
|
yield waitForServer(webUrl, SERVER_START_TIMEOUT, this.webProcess);
|
package/es/endpoints/index.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import type { ViteDevServer } from "vite";
|
|
2
2
|
import type { EndpointContext } from "./types.js";
|
|
3
|
+
import { LOGS_API_PATH } from "./logs.js";
|
|
3
4
|
export * from "./types.js";
|
|
5
|
+
export { LOGS_API_PATH };
|
|
4
6
|
export declare function setupMiddlewares(server: ViteDevServer, ctx: EndpointContext): void;
|
package/es/endpoints/index.js
CHANGED
|
@@ -4,6 +4,7 @@ import { setupStartEndpoint } from "./start.js";
|
|
|
4
4
|
import { setupSseEndpoint } from "./sse.js";
|
|
5
5
|
import { setupSessionsEndpoint } from "./sessions.js";
|
|
6
6
|
import { setupWarmupEndpoint } from "./warmup.js";
|
|
7
|
+
import { setupLogsEndpoint, LOGS_API_PATH } from "./logs.js";
|
|
7
8
|
export * from "./types.js";
|
|
8
9
|
function setupMiddlewares(server, ctx) {
|
|
9
10
|
setupWidgetEndpoints(server, ctx);
|
|
@@ -12,7 +13,9 @@ function setupMiddlewares(server, ctx) {
|
|
|
12
13
|
setupSseEndpoint(server, ctx);
|
|
13
14
|
setupSessionsEndpoint(server, ctx);
|
|
14
15
|
setupWarmupEndpoint(server, ctx);
|
|
16
|
+
setupLogsEndpoint(server);
|
|
15
17
|
}
|
|
16
18
|
export {
|
|
19
|
+
LOGS_API_PATH,
|
|
17
20
|
setupMiddlewares
|
|
18
21
|
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview 进程日志端点
|
|
3
|
+
* @description 提供 HTTP API 获取 Vite 进程日志缓冲区内容
|
|
4
|
+
*/
|
|
5
|
+
import type { ViteDevServer } from "vite";
|
|
6
|
+
/** 日志 API 路径 */
|
|
7
|
+
export declare const LOGS_API_PATH = "/__opencode_process_logs__";
|
|
8
|
+
/**
|
|
9
|
+
* 设置日志端点
|
|
10
|
+
*/
|
|
11
|
+
export declare function setupLogsEndpoint(server: ViteDevServer): void;
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
var __async = (__this, __arguments, generator) => {
|
|
2
|
+
return new Promise((resolve, reject) => {
|
|
3
|
+
var fulfilled = (value) => {
|
|
4
|
+
try {
|
|
5
|
+
step(generator.next(value));
|
|
6
|
+
} catch (e) {
|
|
7
|
+
reject(e);
|
|
8
|
+
}
|
|
9
|
+
};
|
|
10
|
+
var rejected = (value) => {
|
|
11
|
+
try {
|
|
12
|
+
step(generator.throw(value));
|
|
13
|
+
} catch (e) {
|
|
14
|
+
reject(e);
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
|
18
|
+
step((generator = generator.apply(__this, __arguments)).next());
|
|
19
|
+
});
|
|
20
|
+
};
|
|
21
|
+
import {
|
|
22
|
+
getProcessLogBuffer
|
|
23
|
+
} from "@vite-plugin-opencode-assistant/shared";
|
|
24
|
+
import { RequestContext, createLogger } from "@vite-plugin-opencode-assistant/shared";
|
|
25
|
+
const log = createLogger("Endpoints:Logs");
|
|
26
|
+
const LOGS_API_PATH = "/__opencode_process_logs__";
|
|
27
|
+
function setupLogsEndpoint(server) {
|
|
28
|
+
server.middlewares.use(LOGS_API_PATH, (req, res) => __async(null, null, function* () {
|
|
29
|
+
const reqCtx = new RequestContext(req.method || "GET", LOGS_API_PATH);
|
|
30
|
+
res.setHeader("Content-Type", "application/json");
|
|
31
|
+
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
32
|
+
res.setHeader("Access-Control-Allow-Methods", "GET, DELETE, OPTIONS");
|
|
33
|
+
res.setHeader("Access-Control-Allow-Headers", "Content-Type");
|
|
34
|
+
if (req.method === "OPTIONS") {
|
|
35
|
+
res.writeHead(200);
|
|
36
|
+
res.end();
|
|
37
|
+
reqCtx.end(200);
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
const buffer = getProcessLogBuffer();
|
|
41
|
+
if (req.method === "GET") {
|
|
42
|
+
try {
|
|
43
|
+
const url = new URL(req.url || "", `http://${req.headers.host || "localhost"}`);
|
|
44
|
+
const levelParam = url.searchParams.get("level");
|
|
45
|
+
const limitParam = url.searchParams.get("limit");
|
|
46
|
+
const sourceParam = url.searchParams.get("source");
|
|
47
|
+
const sinceParam = url.searchParams.get("since");
|
|
48
|
+
const options = {};
|
|
49
|
+
if (levelParam) {
|
|
50
|
+
const levels = levelParam.split(",").map((l) => l.trim());
|
|
51
|
+
options.level = levels.length === 1 ? levels[0] : levels;
|
|
52
|
+
}
|
|
53
|
+
if (limitParam) {
|
|
54
|
+
const limit = parseInt(limitParam, 10);
|
|
55
|
+
if (limit > 0 && limit <= 1e3) {
|
|
56
|
+
options.limit = limit;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
if (sourceParam) {
|
|
60
|
+
options.source = sourceParam;
|
|
61
|
+
}
|
|
62
|
+
if (sinceParam) {
|
|
63
|
+
options.since = sinceParam;
|
|
64
|
+
}
|
|
65
|
+
const logs = buffer.getLogs(options);
|
|
66
|
+
log.debug("Logs requested", {
|
|
67
|
+
params: { level: levelParam, limit: limitParam, source: sourceParam, since: sinceParam },
|
|
68
|
+
resultCount: logs.length,
|
|
69
|
+
bufferSize: buffer.size()
|
|
70
|
+
});
|
|
71
|
+
res.writeHead(200);
|
|
72
|
+
res.end(
|
|
73
|
+
JSON.stringify({
|
|
74
|
+
logs,
|
|
75
|
+
meta: {
|
|
76
|
+
total: buffer.size(),
|
|
77
|
+
returned: logs.length,
|
|
78
|
+
filters: options
|
|
79
|
+
}
|
|
80
|
+
})
|
|
81
|
+
);
|
|
82
|
+
reqCtx.end(200);
|
|
83
|
+
} catch (e) {
|
|
84
|
+
log.error("Failed to get logs", { error: e });
|
|
85
|
+
res.writeHead(500);
|
|
86
|
+
res.end(JSON.stringify({ error: "Internal server error" }));
|
|
87
|
+
reqCtx.error(e);
|
|
88
|
+
}
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
if (req.method === "DELETE") {
|
|
92
|
+
buffer.clear();
|
|
93
|
+
log.info("Log buffer cleared");
|
|
94
|
+
res.writeHead(200);
|
|
95
|
+
res.end(JSON.stringify({ success: true, message: "Log buffer cleared" }));
|
|
96
|
+
reqCtx.end(200);
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
res.writeHead(405);
|
|
100
|
+
res.end(JSON.stringify({ error: "Method not allowed" }));
|
|
101
|
+
reqCtx.end(405);
|
|
102
|
+
}));
|
|
103
|
+
}
|
|
104
|
+
export {
|
|
105
|
+
LOGS_API_PATH,
|
|
106
|
+
setupLogsEndpoint
|
|
107
|
+
};
|
package/es/index.js
CHANGED
|
@@ -40,9 +40,10 @@ import {
|
|
|
40
40
|
DEFAULT_CONFIG,
|
|
41
41
|
DEFAULT_PROXY_PORT,
|
|
42
42
|
createLogger,
|
|
43
|
-
setVerbose
|
|
43
|
+
setVerbose,
|
|
44
|
+
initProcessLogCapture
|
|
44
45
|
} from "@vite-plugin-opencode-assistant/shared";
|
|
45
|
-
import { setupMiddlewares } from "./endpoints/index.js";
|
|
46
|
+
import { setupMiddlewares, LOGS_API_PATH } from "./endpoints/index.js";
|
|
46
47
|
import { injectWidget } from "./core/injector.js";
|
|
47
48
|
import { OpenCodeAPI } from "./core/api.js";
|
|
48
49
|
import { OpenCodeService } from "./core/service.js";
|
|
@@ -63,6 +64,7 @@ function createOpenCodePlugin(options = {}) {
|
|
|
63
64
|
var _a;
|
|
64
65
|
const config = __spreadValues(__spreadValues({}, DEFAULT_CONFIG), options);
|
|
65
66
|
setVerbose(config.verbose);
|
|
67
|
+
initProcessLogCapture({ maxSize: 500 });
|
|
66
68
|
const log = createLogger("Plugin");
|
|
67
69
|
let actualWebPort = config.webPort;
|
|
68
70
|
let actualProxyPort = (_a = config.proxyPort) != null ? _a : DEFAULT_PROXY_PORT;
|
|
@@ -144,14 +146,16 @@ function createOpenCodePlugin(options = {}) {
|
|
|
144
146
|
}
|
|
145
147
|
viteOrigin = `http://${viteHost}:${vitePort}`;
|
|
146
148
|
const contextApiUrl = `http://${viteHost}:${vitePort}${CONTEXT_API_PATH}`;
|
|
149
|
+
const logsApiUrl = `http://${viteHost}:${vitePort}${LOGS_API_PATH}`;
|
|
147
150
|
log.debug("Vite server ready", {
|
|
148
151
|
vitePort,
|
|
149
152
|
viteHost,
|
|
150
153
|
viteOrigin,
|
|
151
|
-
contextApiUrl
|
|
154
|
+
contextApiUrl,
|
|
155
|
+
logsApiUrl
|
|
152
156
|
});
|
|
153
157
|
try {
|
|
154
|
-
yield service.start([viteOrigin], contextApiUrl, viteOrigin);
|
|
158
|
+
yield service.start([viteOrigin], contextApiUrl, logsApiUrl, viteOrigin);
|
|
155
159
|
} catch (e) {
|
|
156
160
|
log.error("Failed to start services", { error: e });
|
|
157
161
|
}
|
package/lib/client/App.vue.js
CHANGED
|
@@ -119,15 +119,8 @@ const __vue_sfc__ = /* @__PURE__ */ (0, import_vue.defineComponent)({
|
|
|
119
119
|
updateStatusFromTask,
|
|
120
120
|
setStarting
|
|
121
121
|
} = (0, import_useServiceStatus.useServiceStatus)();
|
|
122
|
-
const {
|
|
123
|
-
|
|
124
|
-
removeElement,
|
|
125
|
-
clearElements
|
|
126
|
-
} = (0, import_useSelectedElements.useSelectedElements)();
|
|
127
|
-
const {
|
|
128
|
-
theme,
|
|
129
|
-
sendThemeToIframe
|
|
130
|
-
} = (0, import_useTheme.useTheme)(widgetTheme, widgetRef);
|
|
122
|
+
const { selectedElements, removeElement, clearElements } = (0, import_useSelectedElements.useSelectedElements)();
|
|
123
|
+
const { theme, sendThemeToIframe } = (0, import_useTheme.useTheme)(widgetTheme, widgetRef);
|
|
131
124
|
const {
|
|
132
125
|
sessions,
|
|
133
126
|
loadingSessionList,
|
|
@@ -242,13 +235,13 @@ const __vue_sfc__ = /* @__PURE__ */ (0, import_vue.defineComponent)({
|
|
|
242
235
|
}
|
|
243
236
|
});
|
|
244
237
|
(0, import_vue2.onMounted)(() => {
|
|
245
|
-
if (serviceStatus.value
|
|
238
|
+
if (serviceStatus.value === "ready") {
|
|
246
239
|
loadSessions();
|
|
247
240
|
serverSSE.connect();
|
|
248
241
|
opencodeSSE.connect();
|
|
249
242
|
updateContext(true);
|
|
250
243
|
}
|
|
251
|
-
if (autoOpen && serviceStatus.value
|
|
244
|
+
if (autoOpen && serviceStatus.value === "ready") {
|
|
252
245
|
setTimeout(() => {
|
|
253
246
|
open.value = true;
|
|
254
247
|
}, 1e3);
|
|
@@ -283,7 +276,9 @@ const __vue_sfc__ = /* @__PURE__ */ (0, import_vue.defineComponent)({
|
|
|
283
276
|
previewPageUrl: window.location.href,
|
|
284
277
|
previewPageTitle: document.title
|
|
285
278
|
});
|
|
286
|
-
(_a = widgetRef.value) == null ? void 0 : _a.sendMessageToIframe("OPENCODE_INSERT_FILE_PART", {
|
|
279
|
+
(_a = widgetRef.value) == null ? void 0 : _a.sendMessageToIframe("OPENCODE_INSERT_FILE_PART", {
|
|
280
|
+
element: elementWithContext
|
|
281
|
+
});
|
|
287
282
|
showNotification(`\u8282\u70B9\u5DF2\u6DFB\u52A0\u5230\u5BF9\u8BDD\u6846`, { mode: "page" });
|
|
288
283
|
};
|
|
289
284
|
const handleClearSelected = () => {
|
package/lib/client.js
CHANGED
|
@@ -7138,14 +7138,7 @@ const Uf = { class: "opencode-custom-loading" }, qf = { class: "opencode-loading
|
|
|
7138
7138
|
loadingText: b,
|
|
7139
7139
|
updateStatusFromTask: B,
|
|
7140
7140
|
setStarting: k
|
|
7141
|
-
} = Wf(), {
|
|
7142
|
-
selectedElements: N,
|
|
7143
|
-
removeElement: R,
|
|
7144
|
-
clearElements: Q
|
|
7145
|
-
} = Vf(), {
|
|
7146
|
-
theme: X,
|
|
7147
|
-
sendThemeToIframe: ue
|
|
7148
|
-
} = Hf(_, l), {
|
|
7141
|
+
} = Wf(), { selectedElements: N, removeElement: R, clearElements: Q } = Vf(), { theme: X, sendThemeToIframe: ue } = Hf(_, l), {
|
|
7149
7142
|
sessions: pe,
|
|
7150
7143
|
loadingSessionList: P,
|
|
7151
7144
|
currentSessionId: G,
|
|
@@ -7200,7 +7193,7 @@ const Uf = { class: "opencode-custom-loading" }, qf = { class: "opencode-loading
|
|
|
7200
7193
|
}), ft(D, (g, v) => {
|
|
7201
7194
|
g !== "idle" && v === "idle" && (Pe.connect(), Ne.connect());
|
|
7202
7195
|
}), nt(() => {
|
|
7203
|
-
D.value
|
|
7196
|
+
D.value === "ready" && (xe(), Pe.connect(), Ne.connect(), me(!0)), u && D.value === "ready" && setTimeout(() => {
|
|
7204
7197
|
n.value = !0;
|
|
7205
7198
|
}, 1e3);
|
|
7206
7199
|
const g = (v) => {
|
|
@@ -7224,7 +7217,9 @@ const Uf = { class: "opencode-custom-loading" }, qf = { class: "opencode-loading
|
|
|
7224
7217
|
previewPageUrl: window.location.href,
|
|
7225
7218
|
previewPageTitle: document.title
|
|
7226
7219
|
};
|
|
7227
|
-
l.value?.sendMessageToIframe("OPENCODE_INSERT_FILE_PART", {
|
|
7220
|
+
l.value?.sendMessageToIframe("OPENCODE_INSERT_FILE_PART", {
|
|
7221
|
+
element: v
|
|
7222
|
+
}), S("节点已添加到对话框", { mode: "page" });
|
|
7228
7223
|
}, m = () => {
|
|
7229
7224
|
Q(), me(!0), S("已清除所有选中元素");
|
|
7230
7225
|
}, E = (g) => {
|
package/lib/core/proxy-server.js
CHANGED
|
@@ -456,7 +456,7 @@ function startProxyServer(targetUrl, port, options = {}) {
|
|
|
456
456
|
server.listen(port, () => {
|
|
457
457
|
const address = server.address();
|
|
458
458
|
const actualPort = typeof address === "object" && address ? address.port : port;
|
|
459
|
-
log.
|
|
459
|
+
log.debug(`Proxy server started on port ${actualPort} -> ${targetUrl}`);
|
|
460
460
|
resolve({ server, actualPort });
|
|
461
461
|
});
|
|
462
462
|
});
|
package/lib/core/service.d.ts
CHANGED
|
@@ -25,7 +25,7 @@ export declare class OpenCodeService {
|
|
|
25
25
|
workspaceRoot: string | null;
|
|
26
26
|
constructor(config: Required<OpenCodeOptions>, api: OpenCodeAPI, sseClients: Set<http.ServerResponse>, onPortAllocated: (port: number) => void, onProxyPortAllocated: (port: number) => void);
|
|
27
27
|
private sendTaskUpdate;
|
|
28
|
-
start(corsOrigins?: string[], contextApiUrl?: string, viteOrigin?: string): Promise<void>;
|
|
28
|
+
start(corsOrigins?: string[], contextApiUrl?: string, logsApiUrl?: string, viteOrigin?: string): Promise<void>;
|
|
29
29
|
retryWarmupChromeMcp(viteOrigin?: string): Promise<{
|
|
30
30
|
success: boolean;
|
|
31
31
|
errorType?: string;
|
package/lib/core/service.js
CHANGED
|
@@ -94,7 +94,7 @@ class OpenCodeService {
|
|
|
94
94
|
}
|
|
95
95
|
});
|
|
96
96
|
}
|
|
97
|
-
start(corsOrigins, contextApiUrl, viteOrigin) {
|
|
97
|
+
start(corsOrigins, contextApiUrl, logsApiUrl, viteOrigin) {
|
|
98
98
|
return __async(this, null, function* () {
|
|
99
99
|
if (this.isStarted && this.webProcess) {
|
|
100
100
|
log.debug("Services already started, skipping");
|
|
@@ -109,6 +109,7 @@ class OpenCodeService {
|
|
|
109
109
|
const timer = log.timer("startServices", {
|
|
110
110
|
corsOrigins,
|
|
111
111
|
contextApiUrl,
|
|
112
|
+
logsApiUrl,
|
|
112
113
|
viteOrigin
|
|
113
114
|
});
|
|
114
115
|
log.info("Starting OpenCode services...");
|
|
@@ -152,7 +153,7 @@ Please install OpenCode first:
|
|
|
152
153
|
}
|
|
153
154
|
timer.checkpoint("Port allocated");
|
|
154
155
|
this.workspaceRoot = (0, import_system.findGitRoot)(process.cwd());
|
|
155
|
-
log.
|
|
156
|
+
log.debug(`Using workspace root: ${this.workspaceRoot}`);
|
|
156
157
|
this.sendTaskUpdate("preparing_runtime");
|
|
157
158
|
const configDir = (0, import_opencode.prepareOpenCodeRuntime)(this.workspaceRoot);
|
|
158
159
|
timer.checkpoint("Plugin setup complete");
|
|
@@ -169,11 +170,12 @@ Please install OpenCode first:
|
|
|
169
170
|
cwd: this.workspaceRoot,
|
|
170
171
|
configDir,
|
|
171
172
|
corsOrigins,
|
|
172
|
-
contextApiUrl
|
|
173
|
+
contextApiUrl,
|
|
174
|
+
logsApiUrl
|
|
173
175
|
});
|
|
174
176
|
timer.checkpoint("Web process started");
|
|
175
177
|
const webUrl = `http://${this.config.hostname}:${this.actualWebPort}`;
|
|
176
|
-
log.
|
|
178
|
+
log.debug(`Waiting for OpenCode Web to become ready at ${webUrl}...`);
|
|
177
179
|
this.sendTaskUpdate("waiting_web_ready");
|
|
178
180
|
try {
|
|
179
181
|
yield (0, import_system.waitForServer)(webUrl, import_shared.SERVER_START_TIMEOUT, this.webProcess);
|
package/lib/endpoints/index.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import type { ViteDevServer } from "vite";
|
|
2
2
|
import type { EndpointContext } from "./types.js";
|
|
3
|
+
import { LOGS_API_PATH } from "./logs.js";
|
|
3
4
|
export * from "./types.js";
|
|
5
|
+
export { LOGS_API_PATH };
|
|
4
6
|
export declare function setupMiddlewares(server: ViteDevServer, ctx: EndpointContext): void;
|
package/lib/endpoints/index.js
CHANGED
|
@@ -18,6 +18,7 @@ var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "defau
|
|
|
18
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
19
|
var endpoints_exports = {};
|
|
20
20
|
__export(endpoints_exports, {
|
|
21
|
+
LOGS_API_PATH: () => import_logs.LOGS_API_PATH,
|
|
21
22
|
setupMiddlewares: () => setupMiddlewares
|
|
22
23
|
});
|
|
23
24
|
module.exports = __toCommonJS(endpoints_exports);
|
|
@@ -27,6 +28,7 @@ var import_start = require("./start.js");
|
|
|
27
28
|
var import_sse = require("./sse.js");
|
|
28
29
|
var import_sessions = require("./sessions.js");
|
|
29
30
|
var import_warmup = require("./warmup.js");
|
|
31
|
+
var import_logs = require("./logs.js");
|
|
30
32
|
__reExport(endpoints_exports, require("./types.js"), module.exports);
|
|
31
33
|
function setupMiddlewares(server, ctx) {
|
|
32
34
|
(0, import_widget.setupWidgetEndpoints)(server, ctx);
|
|
@@ -35,9 +37,11 @@ function setupMiddlewares(server, ctx) {
|
|
|
35
37
|
(0, import_sse.setupSseEndpoint)(server, ctx);
|
|
36
38
|
(0, import_sessions.setupSessionsEndpoint)(server, ctx);
|
|
37
39
|
(0, import_warmup.setupWarmupEndpoint)(server, ctx);
|
|
40
|
+
(0, import_logs.setupLogsEndpoint)(server);
|
|
38
41
|
}
|
|
39
42
|
// Annotate the CommonJS export names for ESM import in node:
|
|
40
43
|
0 && (module.exports = {
|
|
44
|
+
LOGS_API_PATH,
|
|
41
45
|
setupMiddlewares,
|
|
42
46
|
...require("./types.js")
|
|
43
47
|
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview 进程日志端点
|
|
3
|
+
* @description 提供 HTTP API 获取 Vite 进程日志缓冲区内容
|
|
4
|
+
*/
|
|
5
|
+
import type { ViteDevServer } from "vite";
|
|
6
|
+
/** 日志 API 路径 */
|
|
7
|
+
export declare const LOGS_API_PATH = "/__opencode_process_logs__";
|
|
8
|
+
/**
|
|
9
|
+
* 设置日志端点
|
|
10
|
+
*/
|
|
11
|
+
export declare function setupLogsEndpoint(server: ViteDevServer): void;
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __export = (target, all) => {
|
|
6
|
+
for (var name in all)
|
|
7
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
8
|
+
};
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
|
+
var __async = (__this, __arguments, generator) => {
|
|
19
|
+
return new Promise((resolve, reject) => {
|
|
20
|
+
var fulfilled = (value) => {
|
|
21
|
+
try {
|
|
22
|
+
step(generator.next(value));
|
|
23
|
+
} catch (e) {
|
|
24
|
+
reject(e);
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
var rejected = (value) => {
|
|
28
|
+
try {
|
|
29
|
+
step(generator.throw(value));
|
|
30
|
+
} catch (e) {
|
|
31
|
+
reject(e);
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
|
35
|
+
step((generator = generator.apply(__this, __arguments)).next());
|
|
36
|
+
});
|
|
37
|
+
};
|
|
38
|
+
var logs_exports = {};
|
|
39
|
+
__export(logs_exports, {
|
|
40
|
+
LOGS_API_PATH: () => LOGS_API_PATH,
|
|
41
|
+
setupLogsEndpoint: () => setupLogsEndpoint
|
|
42
|
+
});
|
|
43
|
+
module.exports = __toCommonJS(logs_exports);
|
|
44
|
+
var import_shared = require("@vite-plugin-opencode-assistant/shared");
|
|
45
|
+
var import_shared2 = require("@vite-plugin-opencode-assistant/shared");
|
|
46
|
+
const log = (0, import_shared2.createLogger)("Endpoints:Logs");
|
|
47
|
+
const LOGS_API_PATH = "/__opencode_process_logs__";
|
|
48
|
+
function setupLogsEndpoint(server) {
|
|
49
|
+
server.middlewares.use(LOGS_API_PATH, (req, res) => __async(null, null, function* () {
|
|
50
|
+
const reqCtx = new import_shared2.RequestContext(req.method || "GET", LOGS_API_PATH);
|
|
51
|
+
res.setHeader("Content-Type", "application/json");
|
|
52
|
+
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
53
|
+
res.setHeader("Access-Control-Allow-Methods", "GET, DELETE, OPTIONS");
|
|
54
|
+
res.setHeader("Access-Control-Allow-Headers", "Content-Type");
|
|
55
|
+
if (req.method === "OPTIONS") {
|
|
56
|
+
res.writeHead(200);
|
|
57
|
+
res.end();
|
|
58
|
+
reqCtx.end(200);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
const buffer = (0, import_shared.getProcessLogBuffer)();
|
|
62
|
+
if (req.method === "GET") {
|
|
63
|
+
try {
|
|
64
|
+
const url = new URL(req.url || "", `http://${req.headers.host || "localhost"}`);
|
|
65
|
+
const levelParam = url.searchParams.get("level");
|
|
66
|
+
const limitParam = url.searchParams.get("limit");
|
|
67
|
+
const sourceParam = url.searchParams.get("source");
|
|
68
|
+
const sinceParam = url.searchParams.get("since");
|
|
69
|
+
const options = {};
|
|
70
|
+
if (levelParam) {
|
|
71
|
+
const levels = levelParam.split(",").map((l) => l.trim());
|
|
72
|
+
options.level = levels.length === 1 ? levels[0] : levels;
|
|
73
|
+
}
|
|
74
|
+
if (limitParam) {
|
|
75
|
+
const limit = parseInt(limitParam, 10);
|
|
76
|
+
if (limit > 0 && limit <= 1e3) {
|
|
77
|
+
options.limit = limit;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
if (sourceParam) {
|
|
81
|
+
options.source = sourceParam;
|
|
82
|
+
}
|
|
83
|
+
if (sinceParam) {
|
|
84
|
+
options.since = sinceParam;
|
|
85
|
+
}
|
|
86
|
+
const logs = buffer.getLogs(options);
|
|
87
|
+
log.debug("Logs requested", {
|
|
88
|
+
params: { level: levelParam, limit: limitParam, source: sourceParam, since: sinceParam },
|
|
89
|
+
resultCount: logs.length,
|
|
90
|
+
bufferSize: buffer.size()
|
|
91
|
+
});
|
|
92
|
+
res.writeHead(200);
|
|
93
|
+
res.end(
|
|
94
|
+
JSON.stringify({
|
|
95
|
+
logs,
|
|
96
|
+
meta: {
|
|
97
|
+
total: buffer.size(),
|
|
98
|
+
returned: logs.length,
|
|
99
|
+
filters: options
|
|
100
|
+
}
|
|
101
|
+
})
|
|
102
|
+
);
|
|
103
|
+
reqCtx.end(200);
|
|
104
|
+
} catch (e) {
|
|
105
|
+
log.error("Failed to get logs", { error: e });
|
|
106
|
+
res.writeHead(500);
|
|
107
|
+
res.end(JSON.stringify({ error: "Internal server error" }));
|
|
108
|
+
reqCtx.error(e);
|
|
109
|
+
}
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
if (req.method === "DELETE") {
|
|
113
|
+
buffer.clear();
|
|
114
|
+
log.info("Log buffer cleared");
|
|
115
|
+
res.writeHead(200);
|
|
116
|
+
res.end(JSON.stringify({ success: true, message: "Log buffer cleared" }));
|
|
117
|
+
reqCtx.end(200);
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
res.writeHead(405);
|
|
121
|
+
res.end(JSON.stringify({ error: "Method not allowed" }));
|
|
122
|
+
reqCtx.end(405);
|
|
123
|
+
}));
|
|
124
|
+
}
|
|
125
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
126
|
+
0 && (module.exports = {
|
|
127
|
+
LOGS_API_PATH,
|
|
128
|
+
setupLogsEndpoint
|
|
129
|
+
});
|
package/lib/index.js
CHANGED
|
@@ -87,6 +87,7 @@ function createOpenCodePlugin(options = {}) {
|
|
|
87
87
|
var _a;
|
|
88
88
|
const config = __spreadValues(__spreadValues({}, import_shared.DEFAULT_CONFIG), options);
|
|
89
89
|
(0, import_shared.setVerbose)(config.verbose);
|
|
90
|
+
(0, import_shared.initProcessLogCapture)({ maxSize: 500 });
|
|
90
91
|
const log = (0, import_shared.createLogger)("Plugin");
|
|
91
92
|
let actualWebPort = config.webPort;
|
|
92
93
|
let actualProxyPort = (_a = config.proxyPort) != null ? _a : import_shared.DEFAULT_PROXY_PORT;
|
|
@@ -168,14 +169,16 @@ function createOpenCodePlugin(options = {}) {
|
|
|
168
169
|
}
|
|
169
170
|
viteOrigin = `http://${viteHost}:${vitePort}`;
|
|
170
171
|
const contextApiUrl = `http://${viteHost}:${vitePort}${import_shared.CONTEXT_API_PATH}`;
|
|
172
|
+
const logsApiUrl = `http://${viteHost}:${vitePort}${import_endpoints.LOGS_API_PATH}`;
|
|
171
173
|
log.debug("Vite server ready", {
|
|
172
174
|
vitePort,
|
|
173
175
|
viteHost,
|
|
174
176
|
viteOrigin,
|
|
175
|
-
contextApiUrl
|
|
177
|
+
contextApiUrl,
|
|
178
|
+
logsApiUrl
|
|
176
179
|
});
|
|
177
180
|
try {
|
|
178
|
-
yield service.start([viteOrigin], contextApiUrl, viteOrigin);
|
|
181
|
+
yield service.start([viteOrigin], contextApiUrl, logsApiUrl, viteOrigin);
|
|
179
182
|
} catch (e) {
|
|
180
183
|
log.error("Failed to start services", { error: e });
|
|
181
184
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vite-plugin-opencode-assistant",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.31",
|
|
4
4
|
"description": "Embed OpenCode Web UI in your Vite dev server for real-time code modification and preview",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -36,9 +36,9 @@
|
|
|
36
36
|
"license": "MIT",
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"unplugin-vue-inspector": "^2.4.0",
|
|
39
|
-
"@vite-plugin-opencode-assistant/
|
|
40
|
-
"@vite-plugin-opencode-assistant/
|
|
41
|
-
"@vite-plugin-opencode-assistant/components": "1.0.
|
|
39
|
+
"@vite-plugin-opencode-assistant/shared": "1.0.31",
|
|
40
|
+
"@vite-plugin-opencode-assistant/opencode": "1.0.31",
|
|
41
|
+
"@vite-plugin-opencode-assistant/components": "1.0.31"
|
|
42
42
|
},
|
|
43
43
|
"peerDependencies": {
|
|
44
44
|
"vite": ">=4.0.0"
|