vite-plugin-opencode-assistant 1.1.17 → 1.1.19
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/core/opencode-web.mjs +6 -25
- package/es/endpoints/context.mjs +19 -11
- package/es/endpoints/types.d.ts +8 -2
- package/es/index.mjs +26 -6
- package/lib/client.js +2003 -1998
- package/lib/core/opencode-web.cjs +6 -25
- package/lib/endpoints/context.cjs +19 -11
- package/lib/endpoints/types.d.ts +8 -2
- package/lib/index.cjs +26 -6
- package/package.json +5 -5
package/es/core/opencode-web.mjs
CHANGED
|
@@ -62,31 +62,14 @@ function startOpenCodeWeb(options) {
|
|
|
62
62
|
var _a, _b;
|
|
63
63
|
const { port, hostname, cwd, configDir, corsOrigins, contextApiUrl, logsApiUrl, logFilesJson } = options;
|
|
64
64
|
const stateDir = createStateDirectory(cwd);
|
|
65
|
-
const pluginsDir = path.join(stateDir, "plugins");
|
|
66
|
-
const pluginPaths = [
|
|
67
|
-
path.join(pluginsDir, "page-context.js"),
|
|
68
|
-
path.join(pluginsDir, "vite-logs.js")
|
|
69
|
-
];
|
|
70
|
-
if (logFilesJson) {
|
|
71
|
-
pluginPaths.push(path.join(pluginsDir, "service-logs.js"));
|
|
72
|
-
}
|
|
73
|
-
const pluginPathsStr = pluginPaths.join(",");
|
|
74
65
|
log.debug("Building process environment", {
|
|
75
66
|
stateDir,
|
|
76
67
|
configDir,
|
|
77
68
|
contextApiUrl,
|
|
78
69
|
logsApiUrl,
|
|
79
|
-
logFilesJson,
|
|
80
|
-
pluginPathsStr
|
|
81
|
-
});
|
|
82
|
-
const env = buildProcessEnv(
|
|
83
|
-
stateDir,
|
|
84
|
-
configDir,
|
|
85
|
-
contextApiUrl,
|
|
86
|
-
logsApiUrl,
|
|
87
|
-
pluginPathsStr,
|
|
88
70
|
logFilesJson
|
|
89
|
-
);
|
|
71
|
+
});
|
|
72
|
+
const env = buildProcessEnv(stateDir, configDir, contextApiUrl, logsApiUrl, logFilesJson);
|
|
90
73
|
const args = ["serve", "--port", String(port), "--hostname", hostname];
|
|
91
74
|
if (corsOrigins && corsOrigins.length > 0) {
|
|
92
75
|
corsOrigins.forEach((origin) => {
|
|
@@ -153,11 +136,13 @@ function copyPluginFiles(sourceDir, targetDir) {
|
|
|
153
136
|
}
|
|
154
137
|
log.debug("All plugin files copied", { count: files.length, files });
|
|
155
138
|
}
|
|
156
|
-
function buildProcessEnv(stateDir, configDir, contextApiUrl, logsApiUrl,
|
|
139
|
+
function buildProcessEnv(stateDir, configDir, contextApiUrl, logsApiUrl, logFilesJson) {
|
|
157
140
|
const env = __spreadProps(__spreadValues({}, Object.fromEntries(
|
|
158
141
|
Object.entries(process.env).filter(([, v]) => v !== void 0)
|
|
159
142
|
)), {
|
|
160
|
-
XDG_STATE_HOME: stateDir
|
|
143
|
+
XDG_STATE_HOME: stateDir,
|
|
144
|
+
// 指向缓存目录,OpenCode 会从 <stateDir>/plugins/ 自动发现插件
|
|
145
|
+
OPENCODE_CONFIG_DIR: stateDir
|
|
161
146
|
});
|
|
162
147
|
if (configDir) {
|
|
163
148
|
env.OPENCODE_CONFIG_DIR = configDir;
|
|
@@ -171,10 +156,6 @@ function buildProcessEnv(stateDir, configDir, contextApiUrl, logsApiUrl, pluginP
|
|
|
171
156
|
env.OPENCODE_VITE_LOGS_API_URL = logsApiUrl;
|
|
172
157
|
log.debug("Set OPENCODE_VITE_LOGS_API_URL", { logsApiUrl });
|
|
173
158
|
}
|
|
174
|
-
if (pluginPaths) {
|
|
175
|
-
env.OPENCODE_PLUGINS = pluginPaths;
|
|
176
|
-
log.debug("Set OPENCODE_PLUGINS", { pluginPaths });
|
|
177
|
-
}
|
|
178
159
|
if (logFilesJson) {
|
|
179
160
|
env.OPENCODE_LOG_FILES_JSON = logFilesJson;
|
|
180
161
|
log.debug("Set OPENCODE_LOG_FILES_JSON", { logFilesJson });
|
package/es/endpoints/context.mjs
CHANGED
|
@@ -35,13 +35,15 @@ function setupContextEndpoint(server, ctx) {
|
|
|
35
35
|
return;
|
|
36
36
|
}
|
|
37
37
|
if (req.method === "GET") {
|
|
38
|
+
const pc = ctx.getPageContext();
|
|
39
|
+
log.debug(`[Context] GET \u2192 url=${pc.url} title=${pc.title} tabId=${pc.tabId}`);
|
|
38
40
|
res.writeHead(200);
|
|
39
|
-
res.end(JSON.stringify(
|
|
41
|
+
res.end(JSON.stringify(pc));
|
|
40
42
|
reqCtx.end(200);
|
|
41
43
|
return;
|
|
42
44
|
}
|
|
43
45
|
if (req.method === "DELETE") {
|
|
44
|
-
ctx.
|
|
46
|
+
ctx.clearSelectedElements();
|
|
45
47
|
log.debug("Selected elements cleared", { sseClients: ctx.sseClients.size });
|
|
46
48
|
let sentCount = 0;
|
|
47
49
|
ctx.sseClients.forEach((client) => {
|
|
@@ -70,22 +72,28 @@ function setupContextEndpoint(server, ctx) {
|
|
|
70
72
|
var _a, _b, _c;
|
|
71
73
|
try {
|
|
72
74
|
const data = JSON.parse(body);
|
|
73
|
-
|
|
75
|
+
const tabId = data.tabId != null ? String(data.tabId) : "default";
|
|
76
|
+
const existing = ctx.getPageContext();
|
|
77
|
+
const newCtx = {
|
|
74
78
|
url: data.url || "",
|
|
75
79
|
title: data.title || "",
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
tabIndex: (_b = data.tabIndex) != null ? _b : ctx.pageContext.tabIndex,
|
|
80
|
+
tabId: (_a = data.tabId) != null ? _a : existing.tabId,
|
|
81
|
+
tabIndex: (_b = data.tabIndex) != null ? _b : existing.tabIndex,
|
|
79
82
|
selectedElements: data.selectedElements || []
|
|
80
83
|
};
|
|
84
|
+
ctx.setPageContext(tabId, newCtx);
|
|
85
|
+
if (data.active) {
|
|
86
|
+
ctx.setActiveTabId(tabId);
|
|
87
|
+
}
|
|
81
88
|
log.debug("Context updated", {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
89
|
+
tabId,
|
|
90
|
+
url: newCtx.url,
|
|
91
|
+
title: newCtx.title,
|
|
92
|
+
selectedElementsCount: ((_c = newCtx.selectedElements) == null ? void 0 : _c.length) || 0
|
|
85
93
|
});
|
|
86
|
-
if (
|
|
94
|
+
if (newCtx.selectedElements && newCtx.selectedElements.length > 0) {
|
|
87
95
|
log.debug("Selected elements details", {
|
|
88
|
-
elements:
|
|
96
|
+
elements: newCtx.selectedElements.map((el) => {
|
|
89
97
|
var _a2;
|
|
90
98
|
return {
|
|
91
99
|
filePath: el.filePath,
|
package/es/endpoints/types.d.ts
CHANGED
|
@@ -3,8 +3,14 @@ import type http from "http";
|
|
|
3
3
|
export interface EndpointContext {
|
|
4
4
|
get webUrl(): string | null;
|
|
5
5
|
get sseClients(): Set<http.ServerResponse>;
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
/** 获取当前活跃 Tab 的上下文(扩展模式)或默认上下文(非扩展模式) */
|
|
7
|
+
getPageContext(): PageContext;
|
|
8
|
+
/** 写入某个 Tab 的上下文 */
|
|
9
|
+
setPageContext(tabId: string, ctx: PageContext): void;
|
|
10
|
+
/** 设置当前活跃 Tab ID */
|
|
11
|
+
setActiveTabId(tabId: string): void;
|
|
12
|
+
/** 清除选中元素(活跃 Tab) */
|
|
13
|
+
clearSelectedElements(): void;
|
|
8
14
|
get isServiceStarted(): boolean;
|
|
9
15
|
get currentTask(): {
|
|
10
16
|
task: ServiceStartupTask;
|
package/es/index.mjs
CHANGED
|
@@ -69,7 +69,10 @@ function createOpenCodePlugin(options = {}) {
|
|
|
69
69
|
let actualWebPort = config.webPort;
|
|
70
70
|
let actualProxyPort = (_a = config.proxyPort) != null ? _a : DEFAULT_PROXY_PORT;
|
|
71
71
|
let projectRoot = "";
|
|
72
|
-
|
|
72
|
+
const pageContext = { url: "", title: "" };
|
|
73
|
+
const DEFAULT_TAB = "default";
|
|
74
|
+
const pageContexts = /* @__PURE__ */ new Map([[DEFAULT_TAB, pageContext]]);
|
|
75
|
+
let activeTabId = DEFAULT_TAB;
|
|
73
76
|
const serviceInstanceId = crypto.randomUUID();
|
|
74
77
|
const sseClients = /* @__PURE__ */ new Set();
|
|
75
78
|
const api = new OpenCodeAPI(
|
|
@@ -110,11 +113,25 @@ function createOpenCodePlugin(options = {}) {
|
|
|
110
113
|
get sseClients() {
|
|
111
114
|
return sseClients;
|
|
112
115
|
},
|
|
113
|
-
|
|
114
|
-
return
|
|
116
|
+
getPageContext() {
|
|
117
|
+
return pageContexts.get(activeTabId) || pageContexts.get(DEFAULT_TAB) || { url: "", title: "" };
|
|
115
118
|
},
|
|
116
|
-
|
|
117
|
-
|
|
119
|
+
setPageContext(tabId, ctx) {
|
|
120
|
+
pageContexts.set(tabId || DEFAULT_TAB, ctx);
|
|
121
|
+
},
|
|
122
|
+
setActiveTabId(tabId) {
|
|
123
|
+
activeTabId = tabId;
|
|
124
|
+
},
|
|
125
|
+
clearSelectedElements() {
|
|
126
|
+
const ctx = pageContexts.get(activeTabId);
|
|
127
|
+
if (ctx) {
|
|
128
|
+
ctx.selectedElements = [];
|
|
129
|
+
pageContexts.set(activeTabId, ctx);
|
|
130
|
+
}
|
|
131
|
+
const defaultCtx = pageContexts.get(DEFAULT_TAB);
|
|
132
|
+
if (defaultCtx) {
|
|
133
|
+
defaultCtx.selectedElements = [];
|
|
134
|
+
}
|
|
118
135
|
},
|
|
119
136
|
get isServiceStarted() {
|
|
120
137
|
return service.isStarted;
|
|
@@ -203,8 +220,11 @@ function createOpenCodePlugin(options = {}) {
|
|
|
203
220
|
projectRoot,
|
|
204
221
|
verbose: config.verbose
|
|
205
222
|
});
|
|
223
|
+
const pageKey = Math.random().toString(36).slice(2, 5);
|
|
224
|
+
const titleInject = `<script>(function(){var k="[${pageKey}]",d=document,p=!1,f=function(){if(p)return;var t=d.title;if(t.indexOf(k)===0)return;p=!0;d.title=k+t.replace(k,"");p=!1};f();new MutationObserver(f).observe(d.querySelector("title")||d.head,{childList:!0})})();</script>`;
|
|
206
225
|
timer.end();
|
|
207
|
-
return html.replace("</body>", `${
|
|
226
|
+
return html.replace("</body>", `${titleInject}
|
|
227
|
+
${widget}</body>`);
|
|
208
228
|
}
|
|
209
229
|
};
|
|
210
230
|
}
|