vite-plugin-opencode-assistant 1.0.2 → 1.0.4

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.
@@ -1,121 +0,0 @@
1
- /**
2
- * @fileoverview OpenCode 页面上下文插件
3
- * @description 用于将页面上下文信息注入到 AI 对话中
4
- */
5
- /** 最大文本长度 */
6
- const MAX_TEXT_LENGTH = 10000;
7
- /** 上下文标记 */
8
- const CONTEXT_MARKER = '__OPENCODE_CONTEXT__';
9
- /**
10
- * OpenCode 页面上下文插件
11
- * @returns 插件钩子
12
- * @example
13
- * ```ts
14
- * // 在 opencode 配置中使用
15
- * import { PageContextPlugin } from './plugins/page-context'
16
- *
17
- * export default {
18
- * plugins: [PageContextPlugin]
19
- * }
20
- * ```
21
- */
22
- export const PageContextPlugin = async () => {
23
- const contextApiUrl = process.env.OPENCODE_CONTEXT_API_URL;
24
- if (!contextApiUrl) {
25
- console.warn('OPENCODE_CONTEXT_API_URL is not set, page context plugin will not work');
26
- return {};
27
- }
28
- const apiUrl = contextApiUrl;
29
- /**
30
- * 获取页面上下文
31
- * @returns 页面上下文数据,获取失败时返回 null
32
- */
33
- async function getPageContext() {
34
- try {
35
- const response = await fetch(apiUrl);
36
- const data = await response.json();
37
- return {
38
- url: data.url || "",
39
- title: data.title || "",
40
- selectedElements: data.selectedElements
41
- };
42
- }
43
- catch {
44
- return null;
45
- }
46
- }
47
- /**
48
- * 清除选中的元素
49
- */
50
- async function clearSelectedElements() {
51
- try {
52
- await fetch(apiUrl, { method: 'DELETE' });
53
- }
54
- catch {
55
- // 忽略错误
56
- }
57
- }
58
- /**
59
- * 格式化选中元素信息
60
- * @param element - 选中的元素
61
- * @returns 格式化后的元素信息字符串
62
- */
63
- function formatSelectedElement(element) {
64
- const parts = [];
65
- if (element.filePath) {
66
- let location = `文件: ${element.filePath}`;
67
- if (element.line) {
68
- location += `:${element.line}`;
69
- if (element.column) {
70
- location += `:${element.column}`;
71
- }
72
- }
73
- parts.push(location);
74
- }
75
- if (element.innerText?.trim()) {
76
- const text = element.innerText.trim().substring(0, MAX_TEXT_LENGTH);
77
- const suffix = element.innerText.length > MAX_TEXT_LENGTH ? '...' : '';
78
- parts.push(`节点文本: "${text}${suffix}"`);
79
- }
80
- return parts.join('\n') + '\n';
81
- }
82
- /**
83
- * 构建上下文前缀
84
- * @param context - 页面上下文
85
- * @returns 上下文前缀字符串
86
- */
87
- function buildContextPrefix(context) {
88
- let prefix = `我现在正在浏览这个页面:${context.url}\n\n`;
89
- if (context.selectedElements?.length) {
90
- prefix += `帮我找到以下节点,一定要精确到具体的节点:\n\n`;
91
- context.selectedElements.forEach((element) => {
92
- prefix += formatSelectedElement(element) + "\n";
93
- });
94
- }
95
- prefix += `请根据以上信息,完成以下任务:\n`;
96
- prefix += `\n`;
97
- return prefix;
98
- }
99
- return {
100
- "experimental.chat.messages.transform": async (_input, output) => {
101
- const context = await getPageContext();
102
- if (!context?.url)
103
- return;
104
- const lastUserMsg = [...output.messages].reverse().find(m => m.info.role === "user");
105
- if (!lastUserMsg)
106
- return;
107
- const textPart = lastUserMsg.parts.find(p => p.type === "text");
108
- if (!textPart || !("text" in textPart))
109
- return;
110
- if (textPart.text.includes(CONTEXT_MARKER))
111
- return;
112
- const prefix = buildContextPrefix(context);
113
- textPart.text = prefix + textPart.text;
114
- if (context.selectedElements?.length) {
115
- await clearSelectedElements();
116
- }
117
- }
118
- };
119
- };
120
- export default PageContextPlugin;
121
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFnZS1jb250ZXh0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3BsdWdpbnMvcGFnZS1jb250ZXh0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7R0FHRztBQUlILGFBQWE7QUFDYixNQUFNLGVBQWUsR0FBRyxLQUFLLENBQUE7QUFFN0IsWUFBWTtBQUNaLE1BQU0sY0FBYyxHQUFHLHNCQUFzQixDQUFBO0FBNEI3Qzs7Ozs7Ozs7Ozs7O0dBWUc7QUFDSCxNQUFNLENBQUMsTUFBTSxpQkFBaUIsR0FBVyxLQUFLLElBQW9CLEVBQUU7SUFDbEUsTUFBTSxhQUFhLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyx3QkFBd0IsQ0FBQTtJQUUxRCxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7UUFDbkIsT0FBTyxDQUFDLElBQUksQ0FBQyx3RUFBd0UsQ0FBQyxDQUFBO1FBQ3RGLE9BQU8sRUFBRSxDQUFBO0lBQ1gsQ0FBQztJQUVELE1BQU0sTUFBTSxHQUFHLGFBQXVCLENBQUE7SUFFdEM7OztPQUdHO0lBQ0gsS0FBSyxVQUFVLGNBQWM7UUFDM0IsSUFBSSxDQUFDO1lBQ0gsTUFBTSxRQUFRLEdBQUcsTUFBTSxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUE7WUFDcEMsTUFBTSxJQUFJLEdBQUcsTUFBTSxRQUFRLENBQUMsSUFBSSxFQUFxQixDQUFBO1lBQ3JELE9BQU87Z0JBQ0wsR0FBRyxFQUFFLElBQUksQ0FBQyxHQUFHLElBQUksRUFBRTtnQkFDbkIsS0FBSyxFQUFFLElBQUksQ0FBQyxLQUFLLElBQUksRUFBRTtnQkFDdkIsZ0JBQWdCLEVBQUUsSUFBSSxDQUFDLGdCQUFnQjthQUN4QyxDQUFBO1FBQ0gsQ0FBQztRQUFDLE1BQU0sQ0FBQztZQUNQLE9BQU8sSUFBSSxDQUFBO1FBQ2IsQ0FBQztJQUNILENBQUM7SUFFRDs7T0FFRztJQUNILEtBQUssVUFBVSxxQkFBcUI7UUFDbEMsSUFBSSxDQUFDO1lBQ0gsTUFBTSxLQUFL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SSxDQUFDLFFBQVEsQ0FBQyxjQUFjLENBQUM7Z0JBQUUsT0FBTTtZQUVsRCxNQUFNLE1BQU0sR0FBRyxrQkFBa0IsQ0FBQyxPQUFPLENBQUMsQ0FBQTtZQUMxQyxRQUFRLENBQUMsSUFBSSxHQUFHLE1BQU0sR0FBRyxRQUFRLENBQUMsSUFBSSxDQUFBO1lBRXRDLElBQUksT0FBTyxDQUFDLGdCQUFnQixFQUFFLE1BQU0sRUFBRSxDQUFDO2dCQUNyQyxNQUFNLHFCQUFxQixFQUFFLENBQUE7WUFDL0IsQ0FBQztRQUNILENBQUM7S0FDRixDQUFBO0FBQ0gsQ0FBQyxDQUFBO0FBRUQsZUFBZSxpQkFBaUIsQ0FBQSIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGZpbGVvdmVydmlldyBPcGVuQ29kZSDpobXpnaLkuIrkuIvmlofmj5Lku7ZcbiAqIEBkZXNjcmlwdGlvbiDnlKjkuo7lsIbpobXpnaLkuIrkuIvmlofkv6Hmga/ms6jlhaXliLAgQUkg5a+56K+d5LitXG4gKi9cblxuaW1wb3J0IHR5cGUgeyBQbHVnaW4sIEhvb2tzIH0gZnJvbSBcIkBvcGVuY29kZS1haS9wbHVnaW5cIlxuXG4vKiog5pyA5aSn5paH5pys6ZW/5bqmICovXG5jb25zdCBNQVhfVEVYVF9MRU5HVEggPSAxMDAwMFxuXG4vKiog5LiK5LiL5paH5qCH6K6wICovXG5jb25zdCBDT05URVhUX01BUktFUiA9ICdfX09QRU5DT0RFX0NPTlRFWFRfXydcblxuLyoqXG4gKiDpgInkuK3nmoTlhYPntKDkv6Hmga9cbiAqL1xuaW50ZXJmYWNlIFNlbGVjdGVkRWxlbWVudCB7XG4gIC8qKiDmlofku7bot6/lvoQgKi9cbiAgZmlsZVBhdGg6IHN0cmluZyB8IG51bGxcbiAgLyoqIOihjOWPtyAqL1xuICBsaW5lOiBudW1iZXIgfCBudWxsXG4gIC8qKiDliJflj7cgKi9cbiAgY29sdW1uOiBudW1iZXIgfCBudWxsXG4gIC8qKiDlhYPntKDlhoXpg6jmlofmnKwgKi9cbiAgaW5uZXJUZXh0OiBzdHJpbmdcbn1cblxuLyoqXG4gKiDpobXpnaLkuIrkuIvmlofmlbDmja5cbiAqL1xuaW50ZXJmYWNlIFBhZ2VDb250ZXh0RGF0YSB7XG4gIC8qKiDlvZPliY3pobXpnaIgVVJMICovXG4gIHVybDogc3RyaW5nXG4gIC8qKiDlvZPliY3pobXpnaLmoIfpopggKi9cbiAgdGl0bGU6IHN0cmluZ1xuICAvKiog6YCJ5Lit55qE5YWD57Sg5YiX6KGoICovXG4gIHNlbGVjdGVkRWxlbWVudHM/OiBTZWxlY3RlZEVsZW1lbnRbXVxufVxuXG4vKipcbiAqIE9wZW5Db2RlIOmhtemdouS4iuS4i+aWh+aPkuS7tlxuICogQHJldHVybnMg5o+S5Lu26ZKp5a2QXG4gKiBAZXhhbXBsZVxuICogYGBgdHNcbiAqIC8vIOWcqCBvcGVuY29kZSDphY3nva7kuK3kvb/nlKhcbiAqIGltcG9ydCB7IFBhZ2VDb250ZXh0UGx1Z2luIH0gZnJvbSAnLi9wbHVnaW5zL3BhZ2UtY29udGV4dCdcbiAqXG4gKiBleHBvcnQgZGVmYXVsdCB7XG4gKiAgIHBsdWdpbnM6IFtQYWdlQ29udGV4dFBsdWdpbl1cbiAqIH1cbiAqIGBgYFxuICovXG5leHBvcnQgY29uc3QgUGFnZUNvbnRleHRQbHVnaW46IFBsdWdpbiA9IGFzeW5jICgpOiBQcm9taXNlPEhvb2tzPiA9PiB7XG4gIGNvbnN0IGNvbnRleHRBcGlVcmwgPSBwcm9jZXNzLmVudi5PUEVOQ09ERV9DT05URVhUX0FQSV9VUkxcblxuICBpZiAoIWNvbnRleHRBcGlVcmwpIHtcbiAgICBjb25zb2xlLndhcm4oJ09QRU5DT0RFX0NPTlRFWFRfQVBJX1VSTCBpcyBub3Qgc2V0LCBwYWdlIGNvbnRleHQgcGx1Z2luIHdpbGwgbm90IHdvcmsnKVxuICAgIHJldHVybiB7fVxuICB9XG5cbiAgY29uc3QgYXBpVXJsID0gY29udGV4dEFwaVVybCBhcyBzdHJpbmdcblxuICAvKipcbiAgICog6I635Y+W6aG16Z2i5LiK5LiL5paHXG4gICAqIEByZXR1cm5zIOmhtemdouS4iuS4i+aWh+aVsOaNru+8jOiOt+WPluWksei0peaXtui/lOWbniBudWxsXG4gICAqL1xuICBhc3luYyBmdW5jdGlvbiBnZXRQYWdlQ29udGV4dCgpOiBQcm9taXNlPFBhZ2VDb250ZXh0RGF0YSB8IG51bGw+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaChhcGlVcmwpXG4gICAgICBjb25zdCBkYXRhID0gYXdhaXQgcmVzcG9uc2UuanNvbigpIGFzIFBhZ2VDb250ZXh0RGF0YVxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdXJsOiBkYXRhLnVybCB8fCBcIlwiLFxuICAgICAgICB0aXRsZTogZGF0YS50aXRsZSB8fCBcIlwiLFxuICAgICAgICBzZWxlY3RlZEVsZW1lbnRzOiBkYXRhLnNlbGVjdGVkRWxlbWVudHNcbiAgICAgIH1cbiAgICB9IGNhdGNoIHtcbiAgICAgIHJldHVybiBudWxsXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIOa4hemZpOmAieS4reeahOWFg+e0oFxuICAgKi9cbiAgYXN5bmMgZnVuY3Rpb24gY2xlYXJTZWxlY3RlZEVsZW1lbnRzKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCBmZXRjaChhcGlVcmwsIHsgbWV0aG9kOiAnREVMRVRFJyB9KVxuICAgIH0gY2F0Y2gge1xuICAgICAgLy8g5b+955Wl6ZSZ6K+vXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIOagvOW8j+WMlumAieS4reWFg+e0oOS/oeaBr1xuICAgKiBAcGFyYW0gZWxlbWVudCAtIOmAieS4reeahOWFg+e0oFxuICAgKiBAcmV0dXJucyDmoLzlvI/ljJblkI7nmoTlhYPntKDkv6Hmga/lrZfnrKbkuLJcbiAgICovXG4gIGZ1bmN0aW9uIGZvcm1hdFNlbGVjdGVkRWxlbWVudChlbGVtZW50OiBTZWxlY3RlZEVsZW1lbnQpOiBzdHJpbmcge1xuICAgIGNvbnN0IHBhcnRzOiBzdHJpbmdbXSA9IFtdXG5cbiAgICBpZiAoZWxlbWVudC5maWxlUGF0aCkge1xuICAgICAgbGV0IGxvY2F0aW9uID0gYOaWh+S7tjogJHtlbGVtZW50LmZpbGVQYXRofWBcbiAgICAgIGlmIChlbGVtZW50LmxpbmUpIHtcbiAgICAgICAgbG9jYXRpb24gKz0gYDoke2VsZW1lbnQubGluZX1gXG4gICAgICAgIGlmIChlbGVtZW50LmNvbHVtbikge1xuICAgICAgICAgIGxvY2F0aW9uICs9IGA6JHtlbGVtZW50LmNvbHVtbn1gXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHBhcnRzLnB1c2gobG9jYXRpb24pXG4gICAgfVxuXG4gICAgaWYgKGVsZW1lbnQuaW5uZXJUZXh0Py50cmltKCkpIHtcbiAgICAgIGNvbnN0IHRleHQgPSBlbGVtZW50LmlubmVyVGV4dC50cmltKCkuc3Vic3RyaW5nKDAsIE1BWF9URVhUX0xFTkdUSClcbiAgICAgIGNvbnN0IHN1ZmZpeCA9IGVsZW1lbnQuaW5uZXJUZXh0Lmxlbmd0aCA+IE1BWF9URVhUX0xFTkdUSCA/ICcuLi4nIDogJydcbiAgICAgIHBhcnRzLnB1c2goYOiKgueCueaWh+acrDogXCIke3RleHR9JHtzdWZmaXh9XCJgKVxuICAgIH1cblxuICAgIHJldHVybiBwYXJ0cy5qb2luKCdcXG4nKSArICdcXG4nXG4gIH1cblxuICAvKipcbiAgICog5p6E5bu65LiK5LiL5paH5YmN57yAXG4gICAqIEBwYXJhbSBjb250ZXh0IC0g6aG16Z2i5LiK5LiL5paHXG4gICAqIEByZXR1cm5zIOS4iuS4i+aWh+WJjee8gOWtl+espuS4slxuICAgKi9cbiAgZnVuY3Rpb24gYnVpbGRDb250ZXh0UHJlZml4KGNvbnRleHQ6IFBhZ2VDb250ZXh0RGF0YSk6IHN0cmluZyB7XG4gICAgbGV0IHByZWZpeCA9IGDmiJHnjrDlnKjmraPlnKjmtY/op4jov5nkuKrpobXpnaLvvJoke2NvbnRleHQudXJsfVxcblxcbmBcblxuICAgIGlmIChjb250ZXh0LnNlbGVjdGVkRWxlbWVudHM/Lmxlbmd0aCkge1xuICAgICAgcHJlZml4ICs9IGDluK7miJHmib7liLDku6XkuIvoioLngrnvvIzkuIDlrpropoHnsr7noa7liLDlhbfkvZPnmoToioLngrnvvJpcXG5cXG5gXG4gICAgICBjb250ZXh0LnNlbGVjdGVkRWxlbWVudHMuZm9yRWFjaCgoZWxlbWVudCkgPT4ge1xuICAgICAgICBwcmVmaXggKz0gZm9ybWF0U2VsZWN0ZWRFbGVtZW50KGVsZW1lbnQpICsgXCJcXG5cIlxuICAgICAgfSlcbiAgICB9XG5cbiAgICBwcmVmaXggKz0gYOivt+agueaNruS7peS4iuS/oeaBr++8jOWujOaIkOS7peS4i+S7u+WKoe+8mlxcbmBcblxuICAgIHByZWZpeCArPSBgXFxuYFxuICAgIHJldHVybiBwcmVmaXhcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgXCJleHBlcmltZW50YWwuY2hhdC5tZXNzYWdlcy50cmFuc2Zvcm1cIjogYXN5bmMgKF9pbnB1dCwgb3V0cHV0KSA9PiB7XG4gICAgICBjb25zdCBjb250ZXh0ID0gYXdhaXQgZ2V0UGFnZUNvbnRleHQoKVxuICAgICAgXG4gICAgICBpZiAoIWNvbnRleHQ/LnVybCkgcmV0dXJuXG5cbiAgICAgIGNvbnN0IGxhc3RVc2VyTXNnID0gWy4uLm91dHB1dC5tZXNzYWdlc10ucmV2ZXJzZSgpLmZpbmQobSA9PiBtLmluZm8ucm9sZSA9PT0gXCJ1c2VyXCIpXG4gICAgICBpZiAoIWxhc3RVc2VyTXNnKSByZXR1cm5cblxuICAgICAgY29uc3QgdGV4dFBhcnQgPSBsYXN0VXNlck1zZy5wYXJ0cy5maW5kKHAgPT4gcC50eXBlID09PSBcInRleHRcIilcbiAgICAgIGlmICghdGV4dFBhcnQgfHwgIShcInRleHRcIiBpbiB0ZXh0UGFydCkpIHJldHVyblxuICAgICAgXG4gICAgICBpZiAodGV4dFBhcnQudGV4dC5pbmNsdWRlcyhDT05URVhUX01BUktFUikpIHJldHVyblxuXG4gICAgICBjb25zdCBwcmVmaXggPSBidWlsZENvbnRleHRQcmVmaXgoY29udGV4dClcbiAgICAgIHRleHRQYXJ0LnRleHQgPSBwcmVmaXggKyB0ZXh0UGFydC50ZXh0XG5cbiAgICAgIGlmIChjb250ZXh0LnNlbGVjdGVkRWxlbWVudHM/Lmxlbmd0aCkge1xuICAgICAgICBhd2FpdCBjbGVhclNlbGVjdGVkRWxlbWVudHMoKVxuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBQYWdlQ29udGV4dFBsdWdpblxuIl19
package/dist/utils.d.ts DELETED
@@ -1,42 +0,0 @@
1
- /**
2
- * 等待服务器就绪
3
- * @param url - 服务器 URL
4
- * @param timeout - 超时时间(毫秒),默认 10000
5
- * @returns Promise,服务器就绪时 resolve
6
- * @throws 超时后抛出错误
7
- */
8
- export declare function waitForServer(url: string, timeout?: number): Promise<void>;
9
- /**
10
- * 检查 OpenCode 是否已安装
11
- * @returns 是否已安装
12
- */
13
- export declare function checkOpenCodeInstalled(): Promise<boolean>;
14
- /**
15
- * 检查端口是否可用
16
- * @param port - 端口号
17
- * @param hostname - 主机名,默认 '127.0.0.1'
18
- * @returns 端口是否可用
19
- */
20
- export declare function isPortAvailable(port: number, hostname?: string): Promise<boolean>;
21
- /**
22
- * 查找可用端口
23
- * @param startPort - 起始端口
24
- * @param hostname - 主机名,默认 '127.0.0.1'
25
- * @param maxTries - 最大尝试次数,默认 10
26
- * @returns 可用的端口号
27
- * @throws 找不到可用端口时抛出错误
28
- */
29
- export declare function findAvailablePort(startPort: number, hostname?: string, maxTries?: number): Promise<number>;
30
- /**
31
- * 终止占用指定端口的进程
32
- * @param port - 端口号
33
- * @param hostname - 主机名,默认 '127.0.0.1'
34
- * @returns 是否成功终止进程
35
- */
36
- export declare function killProcessOnPort(port: number, hostname?: string): Promise<boolean>;
37
- /**
38
- * 检查 OpenCode 进程是否在运行
39
- * @param port - 服务端口
40
- * @returns 进程是否在运行
41
- */
42
- export declare function checkOpenCodeProcess(port: number): Promise<boolean>;
package/dist/utils.js DELETED
@@ -1,156 +0,0 @@
1
- import http from 'http';
2
- import { spawn } from 'child_process';
3
- import net from 'net';
4
- import { DEFAULT_HOSTNAME, SERVER_CHECK_INTERVAL, HEALTH_CHECK_TIMEOUT, MAX_PORT_TRIES, } from './constants.js';
5
- /**
6
- * 等待服务器就绪
7
- * @param url - 服务器 URL
8
- * @param timeout - 超时时间(毫秒),默认 10000
9
- * @returns Promise,服务器就绪时 resolve
10
- * @throws 超时后抛出错误
11
- */
12
- export function waitForServer(url, timeout = 10000) {
13
- return new Promise((resolve, reject) => {
14
- const startTime = Date.now();
15
- const check = () => {
16
- const req = http.get(url, (res) => {
17
- if (res.statusCode && res.statusCode < 500) {
18
- resolve();
19
- }
20
- else {
21
- retryOrReject();
22
- }
23
- });
24
- req.on('error', retryOrReject);
25
- };
26
- const retryOrReject = () => {
27
- if (Date.now() - startTime < timeout) {
28
- setTimeout(check, SERVER_CHECK_INTERVAL);
29
- }
30
- else {
31
- reject(new Error(`Server not ready after ${timeout}ms`));
32
- }
33
- };
34
- check();
35
- });
36
- }
37
- /**
38
- * 检查 OpenCode 是否已安装
39
- * @returns 是否已安装
40
- */
41
- export async function checkOpenCodeInstalled() {
42
- return new Promise((resolve) => {
43
- const proc = spawn('opencode', ['--version'], { stdio: 'ignore' });
44
- proc.on('close', (code) => resolve(code === 0));
45
- proc.on('error', () => resolve(false));
46
- });
47
- }
48
- /**
49
- * 检查端口是否可用
50
- * @param port - 端口号
51
- * @param hostname - 主机名,默认 '127.0.0.1'
52
- * @returns 端口是否可用
53
- */
54
- export async function isPortAvailable(port, hostname = DEFAULT_HOSTNAME) {
55
- return new Promise((resolve) => {
56
- const server = net.createServer();
57
- server.once('error', () => resolve(false));
58
- server.once('listening', () => {
59
- server.close();
60
- resolve(true);
61
- });
62
- server.listen(port, hostname);
63
- });
64
- }
65
- /**
66
- * 查找可用端口
67
- * @param startPort - 起始端口
68
- * @param hostname - 主机名,默认 '127.0.0.1'
69
- * @param maxTries - 最大尝试次数,默认 10
70
- * @returns 可用的端口号
71
- * @throws 找不到可用端口时抛出错误
72
- */
73
- export async function findAvailablePort(startPort, hostname = DEFAULT_HOSTNAME, maxTries = MAX_PORT_TRIES) {
74
- for (let port = startPort; port < startPort + maxTries; port++) {
75
- if (await isPortAvailable(port, hostname)) {
76
- return port;
77
- }
78
- }
79
- throw new Error(`No available port found after ${maxTries} tries starting from ${startPort}`);
80
- }
81
- /**
82
- * 终止占用指定端口的进程
83
- * @param port - 端口号
84
- * @param hostname - 主机名,默认 '127.0.0.1'
85
- * @returns 是否成功终止进程
86
- */
87
- export async function killProcessOnPort(port, hostname = DEFAULT_HOSTNAME) {
88
- return new Promise((resolve) => {
89
- if (process.platform === 'win32') {
90
- killProcessOnWindows(port, resolve);
91
- }
92
- else {
93
- killProcessOnUnix(port, resolve);
94
- }
95
- });
96
- }
97
- /**
98
- * 在 Windows 上终止占用端口的进程
99
- */
100
- function killProcessOnWindows(port, resolve) {
101
- const proc = spawn('cmd', ['/c', `netstat -ano | findstr :${port}`], { stdio: 'pipe' });
102
- let output = '';
103
- proc.stdout?.on('data', (data) => {
104
- output += data.toString();
105
- });
106
- proc.on('close', () => {
107
- const match = output.match(/LISTENING\s+(\d+)/);
108
- if (match) {
109
- spawn('taskkill', ['/F', '/PID', match[1]], { stdio: 'ignore' })
110
- .on('close', (code) => resolve(code === 0));
111
- }
112
- else {
113
- resolve(false);
114
- }
115
- });
116
- }
117
- /**
118
- * 在 Unix 系统上终止占用端口的进程
119
- */
120
- function killProcessOnUnix(port, resolve) {
121
- const proc = spawn('lsof', ['-ti', `tcp:${port}`, '-sTCP:LISTEN'], { stdio: 'pipe' });
122
- let output = '';
123
- proc.stdout?.on('data', (data) => {
124
- output += data.toString();
125
- });
126
- proc.on('close', () => {
127
- const pids = output.trim().split('\n').filter(Boolean);
128
- if (pids.length > 0) {
129
- const killProc = spawn('kill', ['-9', ...pids], { stdio: 'ignore' });
130
- killProc.on('close', (code) => resolve(code === 0));
131
- }
132
- else {
133
- resolve(false);
134
- }
135
- });
136
- }
137
- /**
138
- * 检查 OpenCode 进程是否在运行
139
- * @param port - 服务端口
140
- * @returns 进程是否在运行
141
- */
142
- export async function checkOpenCodeProcess(port) {
143
- return new Promise((resolve) => {
144
- const req = http.get({
145
- hostname: DEFAULT_HOSTNAME,
146
- port,
147
- path: '/health',
148
- timeout: HEALTH_CHECK_TIMEOUT,
149
- }, (res) => {
150
- resolve(res.statusCode === 200);
151
- });
152
- req.on('error', () => resolve(false));
153
- req.end();
154
- });
155
- }
156
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvdXRpbHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxJQUFJLE1BQU0sTUFBTSxDQUFBO0FBQ3ZCLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxlQUFlLENBQUE7QUFDckMsT0FBTyxHQUFHLE1BQU0sS0FBSyxDQUFBO0FBQ3JCLE9BQU8sRUFDTCxnQkFBZ0IsRUFDaEIscUJBQXFCLEVBQ3JCLG9CQUFvQixFQUNwQixjQUFjLEdBQ2YsTUFBTSxnQkFBZ0IsQ0FBQTtBQUV2Qjs7Ozs7O0dBTUc7QUFDSCxNQUFNLFVBQVUsYUFBYSxDQUFDLEdBQVcsRUFBRSxPQUFPLEdBQUcsS0FBSztJQUN4RCxPQUFPLElBQUksT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxFQUFFO1FBQ3JDLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQTtRQUU1QixNQUFNLEtBQUssR0FBRyxHQUFTLEVBQUU7WUFDdkIsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxHQUFHLEVBQUUsRUFBRTtnQkFDaEMsSUFBSSxHQUFHLENBQUMsVUFBVSxJQUFJLEdBQUcsQ0FBQyxVQUFVLEdBQUcsR0FBRyxFQUFFLENBQUM7b0JBQzNDLE9BQU8sRUFBRSxDQUFBO2dCQUNYLENBQUM7cUJBQU0sQ0FBQztvQkFDTixhQUFhLEVBQUUsQ0FBQTtnQkFDakIsQ0FBQztZQUNILENBQUMsQ0FBQyxDQUFBO1lBRUYsR0FBRyxDQUFDLEVBQUUsQ0FBQyxPQUFPLEVBQUUsYUFBYSxDQUFDLENBQUE7UUFDaEMsQ0FBQyxDQUFBO1FBRUQsTUFBTSxhQUFhLEdBQUcsR0FBUyxFQUFFO1lBQy9CLElBQUksSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLFNBQVMsR0FBRyxPQUFPLEVBQUUsQ0FBQztnQkFDckMsVUFBVSxDQUFDLEtBQUssRUFB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QyxDQUFBO1FBQ0YsR0FBRyxDQUFDLEVBQUUsQ0FBQyxPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUE7UUFDckMsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFBO0lBQ1gsQ0FBQyxDQUFDLENBQUE7QUFDSixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGh0dHAgZnJvbSAnaHR0cCdcbmltcG9ydCB7IHNwYXduIH0gZnJvbSAnY2hpbGRfcHJvY2VzcydcbmltcG9ydCBuZXQgZnJvbSAnbmV0J1xuaW1wb3J0IHtcbiAgREVGQVVMVF9IT1NUTkFNRSxcbiAgU0VSVkVSX0NIRUNLX0lOVEVSVkFMLFxuICBIRUFMVEhfQ0hFQ0tfVElNRU9VVCxcbiAgTUFYX1BPUlRfVFJJRVMsXG59IGZyb20gJy4vY29uc3RhbnRzLmpzJ1xuXG4vKipcbiAqIOetieW+heacjeWKoeWZqOWwsee7qlxuICogQHBhcmFtIHVybCAtIOacjeWKoeWZqCBVUkxcbiAqIEBwYXJhbSB0aW1lb3V0IC0g6LaF5pe25pe26Ze077yI5q+r56eS77yJ77yM6buY6K6kIDEwMDAwXG4gKiBAcmV0dXJucyBQcm9taXNl77yM5pyN5Yqh5Zmo5bCx57uq5pe2IHJlc29sdmVcbiAqIEB0aHJvd3Mg6LaF5pe25ZCO5oqb5Ye66ZSZ6K+vXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB3YWl0Rm9yU2VydmVyKHVybDogc3RyaW5nLCB0aW1lb3V0ID0gMTAwMDApOiBQcm9taXNlPHZvaWQ+IHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBjb25zdCBzdGFydFRpbWUgPSBEYXRlLm5vdygpXG5cbiAgICBjb25zdCBjaGVjayA9ICgpOiB2b2lkID0+IHtcbiAgICAgIGNvbnN0IHJlcSA9IGh0dHAuZ2V0KHVybCwgKHJlcykgPT4ge1xuICAgICAgICBpZiAocmVzLnN0YXR1c0NvZGUgJiYgcmVzLnN0YXR1c0NvZGUgPCA1MDApIHtcbiAgICAgICAgICByZXNvbHZlKClcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXRyeU9yUmVqZWN0KClcbiAgICAgICAgfVxuICAgICAgfSlcblxuICAgICAgcmVxLm9uKCdlcnJvcicsIHJldHJ5T3JSZWplY3QpXG4gICAgfVxuXG4gICAgY29uc3QgcmV0cnlPclJlamVjdCA9ICgpOiB2b2lkID0+IHtcbiAgICAgIGlmIChEYXRlLm5vdygpIC0gc3RhcnRUaW1lIDwgdGltZW91dCkge1xuICAgICAgICBzZXRUaW1lb3V0KGNoZWNrLCBTRVJWRVJfQ0hFQ0tfSU5URVJWQUwpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZWplY3QobmV3IEVycm9yKGBTZXJ2ZXIgbm90IHJlYWR5IGFmdGVyICR7dGltZW91dH1tc2ApKVxuICAgICAgfVxuICAgIH1cblxuICAgIGNoZWNrKClcbiAgfSlcbn1cblxuLyoqXG4gKiDmo4Dmn6UgT3BlbkNvZGUg5piv5ZCm5bey5a6J6KOFXG4gKiBAcmV0dXJucyDmmK/lkKblt7Llronoo4VcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNoZWNrT3BlbkNvZGVJbnN0YWxsZWQoKTogUHJvbWlzZTxib29sZWFuPiB7XG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgIGNvbnN0IHByb2MgPSBzcGF3bignb3BlbmNvZGUnLCBbJy0tdmVyc2lvbiddLCB7IHN0ZGlvOiAnaWdub3JlJyB9KVxuICAgIHByb2Mub24oJ2Nsb3NlJywgKGNvZGUpID0+IHJlc29sdmUoY29kZSA9PT0gMCkpXG4gICAgcHJvYy5vbignZXJyb3InLCAoKSA9PiByZXNvbHZlKGZhbHNlKSlcbiAgfSlcbn1cblxuLyoqXG4gKiDmo4Dmn6Xnq6/lj6PmmK/lkKblj6/nlKhcbiAqIEBwYXJhbSBwb3J0IC0g56uv5Y+j5Y+3XG4gKiBAcGFyYW0gaG9zdG5hbWUgLSDkuLvmnLrlkI3vvIzpu5jorqQgJzEyNy4wLjAuMSdcbiAqIEByZXR1cm5zIOerr+WPo+aYr+WQpuWPr+eUqFxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gaXNQb3J0QXZhaWxhYmxlKHBvcnQ6IG51bWJlciwgaG9zdG5hbWUgPSBERUZBVUxUX0hPU1ROQU1FKTogUHJvbWlzZTxib29sZWFuPiB7XG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgIGNvbnN0IHNlcnZlciA9IG5ldC5jcmVhdGVTZXJ2ZXIoKVxuICAgIHNlcnZlci5vbmNlKCdlcnJvcicsICgpID0+IHJlc29sdmUoZmFsc2UpKVxuICAgIHNlcnZlci5vbmNlKCdsaXN0ZW5pbmcnLCAoKSA9PiB7XG4gICAgICBzZXJ2ZXIuY2xvc2UoKVxuICAgICAgcmVzb2x2ZSh0cnVlKVxuICAgIH0pXG4gICAgc2VydmVyLmxpc3Rlbihwb3J0LCBob3N0bmFtZSlcbiAgfSlcbn1cblxuLyoqXG4gKiDmn6Xmib7lj6/nlKjnq6/lj6NcbiAqIEBwYXJhbSBzdGFydFBvcnQgLSDotbflp4vnq6/lj6NcbiAqIEBwYXJhbSBob3N0bmFtZSAtIOS4u+acuuWQje+8jOm7mOiupCAnMTI3LjAuMC4xJ1xuICogQHBhcmFtIG1heFRyaWVzIC0g5pyA5aSn5bCd6K+V5qyh5pWw77yM6buY6K6kIDEwXG4gKiBAcmV0dXJucyDlj6/nlKjnmoTnq6/lj6Plj7dcbiAqIEB0aHJvd3Mg5om+5LiN5Yiw5Y+v55So56uv5Y+j5pe25oqb5Ye66ZSZ6K+vXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBmaW5kQXZhaWxhYmxlUG9ydChcbiAgc3RhcnRQb3J0OiBudW1iZXIsXG4gIGhvc3RuYW1lID0gREVGQVVMVF9IT1NUTkFNRSxcbiAgbWF4VHJpZXMgPSBNQVhfUE9SVF9UUklFU1xuKTogUHJvbWlzZTxudW1iZXI+IHtcbiAgZm9yIChsZXQgcG9ydCA9IHN0YXJ0UG9ydDsgcG9ydCA8IHN0YXJ0UG9ydCArIG1heFRyaWVzOyBwb3J0KyspIHtcbiAgICBpZiAoYXdhaXQgaXNQb3J0QXZhaWxhYmxlKHBvcnQsIGhvc3RuYW1lKSkge1xuICAgICAgcmV0dXJuIHBvcnRcbiAgICB9XG4gIH1cbiAgdGhyb3cgbmV3IEVycm9yKGBObyBhdmFpbGFibGUgcG9ydCBmb3VuZCBhZnRlciAke21heFRyaWVzfSB0cmllcyBzdGFydGluZyBmcm9tICR7c3RhcnRQb3J0fWApXG59XG5cbi8qKlxuICog57uI5q2i5Y2g55So5oyH5a6a56uv5Y+j55qE6L+b56iLXG4gKiBAcGFyYW0gcG9ydCAtIOerr+WPo+WPt1xuICogQHBhcmFtIGhvc3RuYW1lIC0g5Li75py65ZCN77yM6buY6K6kICcxMjcuMC4wLjEnXG4gKiBAcmV0dXJucyDmmK/lkKbmiJDlip/nu4jmraLov5vnqItcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGtpbGxQcm9jZXNzT25Qb3J0KHBvcnQ6IG51bWJlciwgaG9zdG5hbWUgPSBERUZBVUxUX0hPU1ROQU1FKTogUHJvbWlzZTxib29sZWFuPiB7XG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgIGlmIChwcm9jZXNzLnBsYXRmb3JtID09PSAnd2luMzInKSB7XG4gICAgICBraWxsUHJvY2Vzc09uV2luZG93cyhwb3J0LCByZXNvbHZlKVxuICAgIH0gZWxzZSB7XG4gICAgICBraWxsUHJvY2Vzc09uVW5peChwb3J0LCByZXNvbHZlKVxuICAgIH1cbiAgfSlcbn1cblxuLyoqXG4gKiDlnKggV2luZG93cyDkuIrnu4jmraLljaDnlKjnq6/lj6PnmoTov5vnqItcbiAqL1xuZnVuY3Rpb24ga2lsbFByb2Nlc3NPbldpbmRvd3MocG9ydDogbnVtYmVyLCByZXNvbHZlOiAodmFsdWU6IGJvb2xlYW4pID0+IHZvaWQpOiB2b2lkIHtcbiAgY29uc3QgcHJvYyA9IHNwYXduKCdjbWQnLCBbJy9jJywgYG5ldHN0YXQgLWFubyB8IGZpbmRzdHIgOiR7cG9ydH1gXSwgeyBzdGRpbzogJ3BpcGUnIH0pXG4gIGxldCBvdXRwdXQgPSAnJ1xuXG4gIHByb2Muc3Rkb3V0Py5vbignZGF0YScsIChkYXRhKSA9PiB7XG4gICAgb3V0cHV0ICs9IGRhdGEudG9TdHJpbmcoKVxuICB9KVxuXG4gIHByb2Mub24oJ2Nsb3NlJywgKCkgPT4ge1xuICAgIGNvbnN0IG1hdGNoID0gb3V0cHV0Lm1hdGNoKC9MSVNURU5JTkdcXHMrKFxcZCspLylcbiAgICBpZiAobWF0Y2gpIHtcbiAgICAgIHNwYXduKCd0YXNra2lsbCcsIFsnL0YnLCAnL1BJRCcsIG1hdGNoWzFdXSwgeyBzdGRpbzogJ2lnbm9yZScgfSlcbiAgICAgICAgLm9uKCdjbG9zZScsIChjb2RlKSA9PiByZXNvbHZlKGNvZGUgPT09IDApKVxuICAgIH0gZWxzZSB7XG4gICAgICByZXNvbHZlKGZhbHNlKVxuICAgIH1cbiAgfSlcbn1cblxuLyoqXG4gKiDlnKggVW5peCDns7vnu5/kuIrnu4jmraLljaDnlKjnq6/lj6PnmoTov5vnqItcbiAqL1xuZnVuY3Rpb24ga2lsbFByb2Nlc3NPblVuaXgocG9ydDogbnVtYmVyLCByZXNvbHZlOiAodmFsdWU6IGJvb2xlYW4pID0+IHZvaWQpOiB2b2lkIHtcbiAgY29uc3QgcHJvYyA9IHNwYXduKCdsc29mJywgWyctdGknLCBgdGNwOiR7cG9ydH1gLCAnLXNUQ1A6TElTVEVOJ10sIHsgc3RkaW86ICdwaXBlJyB9KVxuICBsZXQgb3V0cHV0ID0gJydcblxuICBwcm9jLnN0ZG91dD8ub24oJ2RhdGEnLCAoZGF0YSkgPT4ge1xuICAgIG91dHB1dCArPSBkYXRhLnRvU3RyaW5nKClcbiAgfSlcblxuICBwcm9jLm9uKCdjbG9zZScsICgpID0+IHtcbiAgICBjb25zdCBwaWRzID0gb3V0cHV0LnRyaW0oKS5zcGxpdCgnXFxuJykuZmlsdGVyKEJvb2xlYW4pXG4gICAgaWYgKHBpZHMubGVuZ3RoID4gMCkge1xuICAgICAgY29uc3Qga2lsbFByb2MgPSBzcGF3bigna2lsbCcsIFsnLTknLCAuLi5waWRzXSwgeyBzdGRpbzogJ2lnbm9yZScgfSlcbiAgICAgIGtpbGxQcm9jLm9uKCdjbG9zZScsIChjb2RlKSA9PiByZXNvbHZlKGNvZGUgPT09IDApKVxuICAgIH0gZWxzZSB7XG4gICAgICByZXNvbHZlKGZhbHNlKVxuICAgIH1cbiAgfSlcbn1cblxuLyoqXG4gKiDmo4Dmn6UgT3BlbkNvZGUg6L+b56iL5piv5ZCm5Zyo6L+Q6KGMXG4gKiBAcGFyYW0gcG9ydCAtIOacjeWKoeerr+WPo1xuICogQHJldHVybnMg6L+b56iL5piv5ZCm5Zyo6L+Q6KGMXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjaGVja09wZW5Db2RlUHJvY2Vzcyhwb3J0OiBudW1iZXIpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgY29uc3QgcmVxID0gaHR0cC5nZXQoe1xuICAgICAgaG9zdG5hbWU6IERFRkFVTFRfSE9TVE5BTUUsXG4gICAgICBwb3J0LFxuICAgICAgcGF0aDogJy9oZWFsdGgnLFxuICAgICAgdGltZW91dDogSEVBTFRIX0NIRUNLX1RJTUVPVVQsXG4gICAgfSwgKHJlcykgPT4ge1xuICAgICAgcmVzb2x2ZShyZXMuc3RhdHVzQ29kZSA9PT0gMjAwKVxuICAgIH0pXG4gICAgcmVxLm9uKCdlcnJvcicsICgpID0+IHJlc29sdmUoZmFsc2UpKVxuICAgIHJlcS5lbmQoKVxuICB9KVxufVxuIl19
package/dist/web.d.ts DELETED
@@ -1,18 +0,0 @@
1
- import { ChildProcess } from 'child_process';
2
- import { WebOptions } from './types.js';
3
- /**
4
- * 启动 OpenCode Web 服务
5
- * @param options - Web 服务启动选项
6
- * @returns 子进程实例
7
- * @throws 服务启动超时时抛出错误
8
- * @example
9
- * ```ts
10
- * const proc = await startOpenCodeWeb({
11
- * port: 4097,
12
- * hostname: '127.0.0.1',
13
- * serverUrl: '',
14
- * cwd: process.cwd()
15
- * })
16
- * ```
17
- */
18
- export declare function startOpenCodeWeb(options: WebOptions): Promise<ChildProcess>;
package/dist/web.js DELETED
@@ -1,95 +0,0 @@
1
- import { spawn } from 'child_process';
2
- import { waitForServer } from './utils.js';
3
- import { SERVER_START_TIMEOUT, LOG_PREFIX, } from './constants.js';
4
- import path from 'path';
5
- import fs from 'fs';
6
- /**
7
- * 启动 OpenCode Web 服务
8
- * @param options - Web 服务启动选项
9
- * @returns 子进程实例
10
- * @throws 服务启动超时时抛出错误
11
- * @example
12
- * ```ts
13
- * const proc = await startOpenCodeWeb({
14
- * port: 4097,
15
- * hostname: '127.0.0.1',
16
- * serverUrl: '',
17
- * cwd: process.cwd()
18
- * })
19
- * ```
20
- */
21
- export async function startOpenCodeWeb(options) {
22
- const { port, hostname, cwd, configDir, corsOrigins, contextApiUrl } = options;
23
- const stateDir = createStateDirectory(cwd);
24
- const pluginPath = path.join(stateDir, 'plugins', 'page-context.js');
25
- const env = buildProcessEnv(stateDir, configDir, contextApiUrl, pluginPath);
26
- const args = [
27
- 'serve',
28
- '--port', String(port),
29
- '--hostname', hostname,
30
- ];
31
- if (corsOrigins && corsOrigins.length > 0) {
32
- corsOrigins.forEach(origin => {
33
- args.push('--cors', origin);
34
- });
35
- }
36
- const proc = spawn('opencode', args, {
37
- cwd,
38
- stdio: 'pipe',
39
- env,
40
- });
41
- setupProcessHandlers(proc, port, hostname);
42
- await waitForServer(`http://${hostname}:${port}`, SERVER_START_TIMEOUT);
43
- console.log(`\n\x1b[36m\x1b[1m${LOG_PREFIX}\x1b[0m ✨ OpenCode server started successfully\n`);
44
- return proc;
45
- }
46
- /**
47
- * 创建状态目录
48
- * @param cwd - 工作目录
49
- * @returns 状态目录路径
50
- */
51
- function createStateDirectory(cwd) {
52
- const stateDir = path.join(cwd, 'node_modules', '.cache', 'opencode');
53
- if (!fs.existsSync(stateDir)) {
54
- fs.mkdirSync(stateDir, { recursive: true });
55
- }
56
- return stateDir;
57
- }
58
- /**
59
- * 构建进程环境变量
60
- * @param stateDir - 状态目录路径
61
- * @param configDir - 配置目录路径
62
- * @param contextApiUrl - 上下文 API URL
63
- * @param pluginPath - 插件路径
64
- * @returns 环境变量对象
65
- */
66
- function buildProcessEnv(stateDir, configDir, contextApiUrl, pluginPath) {
67
- const env = {
68
- ...Object.fromEntries(Object.entries(process.env).filter(([, v]) => v !== undefined)),
69
- XDG_STATE_HOME: stateDir,
70
- };
71
- if (configDir) {
72
- env.OPENCODE_CONFIG_DIR = configDir;
73
- }
74
- if (contextApiUrl) {
75
- env.OPENCODE_CONTEXT_API_URL = contextApiUrl;
76
- }
77
- if (pluginPath) {
78
- env.OPENCODE_PLUGINS = pluginPath;
79
- }
80
- return env;
81
- }
82
- /**
83
- * 设置进程事件处理器
84
- * @param proc - 子进程实例
85
- */
86
- function setupProcessHandlers(proc, port, hostname) {
87
- proc.stdout?.on('data', () => {
88
- });
89
- proc.stderr?.on('data', () => {
90
- });
91
- proc.on('error', (err) => {
92
- console.error(`\x1b[31m\x1b[1m${LOG_PREFIX}\x1b[0m ❌ Failed to start OpenCode server:`, err.message);
93
- });
94
- }
95
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2ViLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3dlYi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsS0FBSyxFQUFnQixNQUFNLGVBQWUsQ0FBQTtBQUNuRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sWUFBWSxDQUFBO0FBRTFDLE9BQU8sRUFDTCxvQkFBb0IsRUFDcEIsVUFBVSxHQUNYLE1BQU0sZ0JBQWdCLENBQUE7QUFDdkIsT0FBTyxJQUFJLE1BQU0sTUFBTSxDQUFBO0FBQ3ZCLE9BQU8sRUFBRSxNQUFNLElBQUksQ0FBQTtBQUVuQjs7Ozs7Ozs7Ozs7Ozs7R0FjRztBQUNILE1BQU0sQ0FBQyxLQUFLLFVBQVUsZ0JBQWdCLENBQUMsT0FBbUI7SUFDeEQsTUFBTSxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsR0FBRyxFQUFFLFNBQVMsRUFBRSxXQUFXLEVBQUUsYUFBYSxFQUFFLEdBQUcsT0FBTyxDQUFBO0lBRTlFLE1BQU0sUUFBUSxHQUFHLG9CQUFvQixDQUFDLEdBQUcsQ0FBQyxDQUFBO0lBQzFDLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLFNBQVMsRUFBRSxpQkFBaUIsQ0FBQyxDQUFBO0lBQ3BFLE1BQU0sR0FBRyxHQUFHLGVBQWUsQ0FBQyxRQUFRLEVBQUUsU0FBUyxFQUFFLGFBQWEsRUFBRSxVQUFVLENBQUMsQ0FBQTtJQUUzRSxNQUFNLElBQUksR0FBRztRQUNYLE9BQU87UUFDUCxRQUFRLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQztRQUN0QixZQUFZLEVBQUUsUUFBUTtLQUN2QixDQUFBO0lBRUQsSUFBSSxXQUFXLElBQUksV0FBVyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztRQUMxQyxXQUFXLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxFQUFFO1lBQzNCLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLE1BQU0sQ0FBQyxDQUFBO1FBQzdCLENBQUMsQ0FBQyxDQUFBO0lBQ0osQ0FBQztJQUVELE1BQU0sSUFBSSxHQUFHLEtBQUssQ0FBQyxVQUFVLEVBQUUsSUFBSSxFQUFFO1FBQ25DLEdBQUc7UUFDSCxLQUFLLEVBQUUsTUFBTTtRQUNiLEdBQUc7S0FDSixDQUFDLENBQUE7SUFFRixvQkFBb0IsQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLFFBQVEsQ0FBQyxDQUFBO0lBRTFDLE1BQU0sYUFBYSxDQUFDLFVBQVUsUUFBUSxJQUFJLElBQUksRUFBRSxFQUFFLG9CQUFvQixDQUFDLENBQUE7SUFFdkUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxvQkFBb0IsVUFBVSxrREFBa0QsQ0FBQyxDQUFBO0lBRTdGLE9BQU8sSUFBSSxDQUFBO0FBQ2IsQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxTQUFTLG9CQUFvQixDQUFDLEdBQVc7SUFDdkMsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsY0FBYyxFQUFFLFFBQVEsRUFBRSxVQUFVLENBQUMsQ0FBQTtJQUVyRSxJQUFJLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDO1FBQzdCLEVBQUUsQ0FBQyxTQUFTLENBQUMsUUFBUSxFQUFFLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUE7SUFDN0MsQ0FBQztJQUVELE9BQU8sUUFBUSxDQUFBO0FBQ2pCLENBQUM7QUFFRDs7Ozs7OztHQU9HO0FBQ0gsU0FBUyxlQUFlLENBQUMsUUFBZ0IsRUFBRSxTQUFrQixFQUFFLGFBQXNCLEVBQUUsVUFBbUI7SUFDeEcsTUFBTSxHQUFHLEdBQTJCO1FBQ2xDLEdBQUcsTUFBTSxDQUFDLFdBQVcsQ0FDbkIsTUFBTSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEtBQUssU0FBUyxDQUFDLENBQ3JDO1FBQzNCLGNBQWMsRUFBRSxRQUFRO0tBQ3pCLENBQUE7SUFFRCxJQUFJLFNBQVMsRUFBRSxDQUFDO1FBQ2QsR0FBRyxDQUFDLG1CQUFtQixHQUFHLFNBQVMsQ0FBQTtJQUNyQyxDQUFDO0lBRUQsSUFBSSxhQUFhLEVBQUUsQ0FBQztRQUNsQixHQUFHLENBQUMsd0JBQXdCLEdBQUcsYUFBYSxDQUFBO0lBQzlDLENBQUM7SUFFRCxJQUFJLFVBQVUsRUFBRSxDQUFDO1FBQ2YsR0FBRyxDQUFDLGdCQUFnQixHQUFHLFVBQVUsQ0FBQTtJQUNuQyxDQUFDO0lBRUQsT0FBTyxHQUFHLENBQUE7QUFDWixDQUFDO0FBRUQ7OztHQUdHO0FBQ0gsU0FBUyxvQkFBb0IsQ0FBQyxJQUFrQixFQUFFLElBQVksRUFBRSxRQUFnQjtJQUM5RSxJQUFJLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxNQUFNLEVBQUUsR0FBRyxFQUFFO0lBQzdCLENBQUMsQ0FBQyxDQUFBO0lBRUYsSUFBSSxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsTUFBTSxFQUFFLEdBQUcsRUFBRTtJQUM3QixDQUFDLENBQUMsQ0FBQTtJQUVGLElBQUksQ0FBQyxFQUFFLENBQUMsT0FBTyxFQUFFLENBQUMsR0FBRyxFQUFFLEVBQUU7UUFDdkIsT0FBTyxDQUFDLEtBQUssQ0FBQyxrQkFBa0IsVUFBVSw0Q0FBNEMsRUFBRSxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUE7SUFDdEcsQ0FBQyxDQUFDLENBQUE7QUFDSixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgc3Bhd24sIENoaWxkUHJvY2VzcyB9IGZyb20gJ2NoaWxkX3Byb2Nlc3MnXG5pbXBvcnQgeyB3YWl0Rm9yU2VydmVyIH0gZnJvbSAnLi91dGlscy5qcydcbmltcG9ydCB7IFdlYk9wdGlvbnMgfSBmcm9tICcuL3R5cGVzLmpzJ1xuaW1wb3J0IHtcbiAgU0VSVkVSX1NUQVJUX1RJTUVPVVQsXG4gIExPR19QUkVGSVgsXG59IGZyb20gJy4vY29uc3RhbnRzLmpzJ1xuaW1wb3J0IHBhdGggZnJvbSAncGF0aCdcbmltcG9ydCBmcyBmcm9tICdmcydcblxuLyoqXG4gKiDlkK/liqggT3BlbkNvZGUgV2ViIOacjeWKoVxuICogQHBhcmFtIG9wdGlvbnMgLSBXZWIg5pyN5Yqh5ZCv5Yqo6YCJ6aG5XG4gKiBAcmV0dXJucyDlrZDov5vnqIvlrp7kvotcbiAqIEB0aHJvd3Mg5pyN5Yqh5ZCv5Yqo6LaF5pe25pe25oqb5Ye66ZSZ6K+vXG4gKiBAZXhhbXBsZVxuICogYGBgdHNcbiAqIGNvbnN0IHByb2MgPSBhd2FpdCBzdGFydE9wZW5Db2RlV2ViKHtcbiAqICAgcG9ydDogNDA5NyxcbiAqICAgaG9zdG5hbWU6ICcxMjcuMC4wLjEnLFxuICogICBzZXJ2ZXJVcmw6ICcnLFxuICogICBjd2Q6IHByb2Nlc3MuY3dkKClcbiAqIH0pXG4gKiBgYGBcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHN0YXJ0T3BlbkNvZGVXZWIob3B0aW9uczogV2ViT3B0aW9ucyk6IFByb21pc2U8Q2hpbGRQcm9jZXNzPiB7XG4gIGNvbnN0IHsgcG9ydCwgaG9zdG5hbWUsIGN3ZCwgY29uZmlnRGlyLCBjb3JzT3JpZ2lucywgY29udGV4dEFwaVVybCB9ID0gb3B0aW9uc1xuXG4gIGNvbnN0IHN0YXRlRGlyID0gY3JlYXRlU3RhdGVEaXJlY3RvcnkoY3dkKVxuICBjb25zdCBwbHVnaW5QYXRoID0gcGF0aC5qb2luKHN0YXRlRGlyLCAncGx1Z2lucycsICdwYWdlLWNvbnRleHQuanMnKVxuICBjb25zdCBlbnYgPSBidWlsZFByb2Nlc3NFbnYoc3RhdGVEaXIsIGNvbmZpZ0RpciwgY29udGV4dEFwaVVybCwgcGx1Z2luUGF0aClcblxuICBjb25zdCBhcmdzID0gW1xuICAgICdzZXJ2ZScsXG4gICAgJy0tcG9ydCcsIFN0cmluZyhwb3J0KSxcbiAgICAnLS1ob3N0bmFtZScsIGhvc3RuYW1lLFxuICBdXG5cbiAgaWYgKGNvcnNPcmlnaW5zICYmIGNvcnNPcmlnaW5zLmxlbmd0aCA+IDApIHtcbiAgICBjb3JzT3JpZ2lucy5mb3JFYWNoKG9yaWdpbiA9PiB7XG4gICAgICBhcmdzLnB1c2goJy0tY29ycycsIG9yaWdpbilcbiAgICB9KVxuICB9XG5cbiAgY29uc3QgcHJvYyA9IHNwYXduKCdvcGVuY29kZScsIGFyZ3MsIHtcbiAgICBjd2QsXG4gICAgc3RkaW86ICdwaXBlJyxcbiAgICBlbnYsXG4gIH0pXG5cbiAgc2V0dXBQcm9jZXNzSGFuZGxlcnMocHJvYywgcG9ydCwgaG9zdG5hbWUpXG5cbiAgYXdhaXQgd2FpdEZvclNlcnZlcihgaHR0cDovLyR7aG9zdG5hbWV9OiR7cG9ydH1gLCBTRVJWRVJfU1RBUlRfVElNRU9VVClcblxuICBjb25zb2xlLmxvZyhgXFxuXFx4MWJbMzZtXFx4MWJbMW0ke0xPR19QUkVGSVh9XFx4MWJbMG0g4pyoIE9wZW5Db2RlIHNlcnZlciBzdGFydGVkIHN1Y2Nlc3NmdWxseVxcbmApXG5cbiAgcmV0dXJuIHByb2Ncbn1cblxuLyoqXG4gKiDliJvlu7rnirbmgIHnm67lvZVcbiAqIEBwYXJhbSBjd2QgLSDlt6XkvZznm67lvZVcbiAqIEByZXR1cm5zIOeKtuaAgeebruW9lei3r+W+hFxuICovXG5mdW5jdGlvbiBjcmVhdGVTdGF0ZURpcmVjdG9yeShjd2Q6IHN0cmluZyk6IHN0cmluZyB7XG4gIGNvbnN0IHN0YXRlRGlyID0gcGF0aC5qb2luKGN3ZCwgJ25vZGVfbW9kdWxlcycsICcuY2FjaGUnLCAnb3BlbmNvZGUnKVxuICBcbiAgaWYgKCFmcy5leGlzdHNTeW5jKHN0YXRlRGlyKSkge1xuICAgIGZzLm1rZGlyU3luYyhzdGF0ZURpciwgeyByZWN1cnNpdmU6IHRydWUgfSlcbiAgfVxuICBcbiAgcmV0dXJuIHN0YXRlRGlyXG59XG5cbi8qKlxuICog5p6E5bu66L+b56iL546v5aKD5Y+Y6YePXG4gKiBAcGFyYW0gc3RhdGVEaXIgLSDnirbmgIHnm67lvZXot6/lvoRcbiAqIEBwYXJhbSBjb25maWdEaXIgLSDphY3nva7nm67lvZXot6/lvoRcbiAqIEBwYXJhbSBjb250ZXh0QXBpVXJsIC0g5LiK5LiL5paHIEFQSSBVUkxcbiAqIEBwYXJhbSBwbHVnaW5QYXRoIC0g5o+S5Lu26Lev5b6EXG4gKiBAcmV0dXJucyDnjq/looPlj5jph4/lr7nosaFcbiAqL1xuZnVuY3Rpb24gYnVpbGRQcm9jZXNzRW52KHN0YXRlRGlyOiBzdHJpbmcsIGNvbmZpZ0Rpcj86IHN0cmluZywgY29udGV4dEFwaVVybD86IHN0cmluZywgcGx1Z2luUGF0aD86IHN0cmluZyk6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4ge1xuICBjb25zdCBlbnY6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7XG4gICAgLi4uT2JqZWN0LmZyb21FbnRyaWVzKFxuICAgICAgT2JqZWN0LmVudHJpZXMocHJvY2Vzcy5lbnYpLmZpbHRlcigoWywgdl0pID0+IHYgIT09IHVuZGVmaW5lZClcbiAgICApIGFzIFJlY29yZDxzdHJpbmcsIHN0cmluZz4sXG4gICAgWERHX1NUQVRFX0hPTUU6IHN0YXRlRGlyLFxuICB9XG5cbiAgaWYgKGNvbmZpZ0Rpcikge1xuICAgIGVudi5PUEVOQ09ERV9DT05GSUdfRElSID0gY29uZmlnRGlyXG4gIH1cblxuICBpZiAoY29udGV4dEFwaVVybCkge1xuICAgIGVudi5PUEVOQ09ERV9DT05URVhUX0FQSV9VUkwgPSBjb250ZXh0QXBpVXJsXG4gIH1cblxuICBpZiAocGx1Z2luUGF0aCkge1xuICAgIGVudi5PUEVOQ09ERV9QTFVHSU5TID0gcGx1Z2luUGF0aFxuICB9XG5cbiAgcmV0dXJuIGVudlxufVxuXG4vKipcbiAqIOiuvue9rui/m+eoi+S6i+S7tuWkhOeQhuWZqFxuICogQHBhcmFtIHByb2MgLSDlrZDov5vnqIvlrp7kvotcbiAqL1xuZnVuY3Rpb24gc2V0dXBQcm9jZXNzSGFuZGxlcnMocHJvYzogQ2hpbGRQcm9jZXNzLCBwb3J0OiBudW1iZXIsIGhvc3RuYW1lOiBzdHJpbmcpOiB2b2lkIHtcbiAgcHJvYy5zdGRvdXQ/Lm9uKCdkYXRhJywgKCkgPT4ge1xuICB9KVxuXG4gIHByb2Muc3RkZXJyPy5vbignZGF0YScsICgpID0+IHtcbiAgfSlcblxuICBwcm9jLm9uKCdlcnJvcicsIChlcnIpID0+IHtcbiAgICBjb25zb2xlLmVycm9yKGBcXHgxYlszMW1cXHgxYlsxbSR7TE9HX1BSRUZJWH1cXHgxYlswbSDinYwgRmFpbGVkIHRvIHN0YXJ0IE9wZW5Db2RlIHNlcnZlcjpgLCBlcnIubWVzc2FnZSlcbiAgfSlcbn1cbiJdfQ==
File without changes