From 89470346be754989ed83a1e0589cb42dd25d7d79 Mon Sep 17 00:00:00 2001 From: abearxiong Date: Tue, 20 Jan 2026 15:39:46 +0800 Subject: [PATCH] udpate --- .cnb.yml | 2 + assistant/.opencode/plugin/agent.ts | 2 +- .../.opencode/skills/kill-opencode/SKILL.md | 35 +++++++ assistant/agent/index.ts | 3 - assistant/agent/plugin.ts | 64 ------------- assistant/agent/step.ts | 27 ------ assistant/bun.config.mjs | 22 +++++ assistant/package.json | 6 +- assistant/src/app.ts | 24 ++--- assistant/src/main.ts | 9 +- .../src/module/assistant/config/index.ts | 3 + .../call.ts => src/routes/call/index.ts} | 7 +- assistant/src/routes/ha-api/ha.ts | 35 +++++++ assistant/src/routes/index.ts | 2 +- assistant/src/routes/opencode/ls.ts | 89 ++++++++++++++++- assistant/src/routes/opencode/module/open.ts | 95 ++++++++++++++++--- assistant/src/services/asr/qwen-asr.ts | 34 +------ assistant/src/services/init/index.ts | 5 + package.json | 7 +- pnpm-lock.yaml | 54 +++++------ 20 files changed, 330 insertions(+), 195 deletions(-) create mode 100644 assistant/.opencode/skills/kill-opencode/SKILL.md delete mode 100644 assistant/agent/index.ts delete mode 100644 assistant/agent/plugin.ts delete mode 100644 assistant/agent/step.ts rename assistant/{agent/call.ts => src/routes/call/index.ts} (83%) diff --git a/.cnb.yml b/.cnb.yml index 77c96db..aa185e7 100644 --- a/.cnb.yml +++ b/.cnb.yml @@ -16,6 +16,8 @@ $: services: - vscode - docker + env: + CNB_BUILD_WORKSPACE: "/root/workspace" imports: !reference [.common_env, imports] # 开发环境启动后会执行的任务 # stages: diff --git a/assistant/.opencode/plugin/agent.ts b/assistant/.opencode/plugin/agent.ts index d0de8bb..65e83d6 100644 --- a/assistant/.opencode/plugin/agent.ts +++ b/assistant/.opencode/plugin/agent.ts @@ -1 +1 @@ -export * from "../../agent/plugin"; \ No newline at end of file +export { AgentPlugin } from "../../src/main.ts"; \ No newline at end of file diff --git a/assistant/.opencode/skills/kill-opencode/SKILL.md b/assistant/.opencode/skills/kill-opencode/SKILL.md new file mode 100644 index 0000000..699835f --- /dev/null +++ b/assistant/.opencode/skills/kill-opencode/SKILL.md @@ -0,0 +1,35 @@ +--- +name: kill-opencode +description: 自动查找并杀死所有opencode相关的进程,确保系统资源释放。 +tags: + - opencode + - process-management + - automation +--- +```bash +#!/bin/bash +# kill_opencode.sh - 自动杀死所有opencode进程 +echo "正在查找opencode进程..." +ps aux | grep opencode | grep -v grep + +if [ $? -eq 0 ]; then + echo "正在杀死所有opencode进程..." + pkill -f opencode + sleep 2 + + # 检查是否还有残留进程 + remaining=$(ps aux | grep opencode | grep -v grep | wc -l) + if [ $remaining -gt 0 ]; then + echo "发现 $remaining 个顽固进程,使用强制杀死模式..." + pkill -9 -f opencode + fi + + echo "opencode进程清理完成!" +else + echo "未找到opencode进程" +fi + +# 验证是否已完全清理 +echo "当前opencode进程状态:" +ps aux | grep opencode | grep -v grep || echo "没有运行中的opencode进程" +``` \ No newline at end of file diff --git a/assistant/agent/index.ts b/assistant/agent/index.ts deleted file mode 100644 index 4e6681a..0000000 --- a/assistant/agent/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { app } from '../src/main.ts' - -export { app } \ No newline at end of file diff --git a/assistant/agent/plugin.ts b/assistant/agent/plugin.ts deleted file mode 100644 index f931300..0000000 --- a/assistant/agent/plugin.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { tool } from "@opencode-ai/plugin/tool" -import { type Plugin } from "@opencode-ai/plugin" -import { app } from './index.ts'; -import { Skill } from "@kevisual/router"; - -import './call.ts'; -import './step.ts'; - -const routes = app.router.routes.filter(r => { - const metadata = r.metadata as Skill - if (metadata && metadata.tags && metadata.tags.includes('opencode')) { - return !!metadata.skill - } - return false -}) - -// opencode run "查看系统信息" -export const AgentPlugin: Plugin = async ({ project, client, $, directory, worktree }) => { - return { - 'tool': { - ...routes.reduce((acc, route) => { - const metadata = route.metadata as Skill - acc[metadata.skill!] = { - name: metadata.title || metadata.skill, - description: metadata.summary || '', - args: metadata.args || {}, - async execute(args: Record) { - console.log(`Executing skill ${metadata.skill} with args:`, args); - await client.app.log({ - body: { - service: 'cnb', - level: 'info', - message: `Executing skill ${metadata.skill} with args: ${JSON.stringify(args)}` - } - }); - const res = await app.run({ - path: route.path, - key: route.key, - payload: args - }, - // @ts-ignore - { appId: app.appId! }); - if (res.code === 200) { - if (res.data?.content) { - return res.data.content; - } - const str = JSON.stringify(res.data || res, null, 2); - if (str.length > 5000) { - return str.slice(0, 5000) + '... (truncated)'; - } - return str; - } - return `Error: ${res?.message || '无法获取结果'}`; - } - } - return acc; - }, {} as Record) - }, - 'tool.execute.before': async (opts) => { - // console.log('CnbPlugin: tool.execute.before', opts.tool); - // delete toolSkills['cnb-login-verify'] - } - } -} diff --git a/assistant/agent/step.ts b/assistant/agent/step.ts deleted file mode 100644 index e7e1a30..0000000 --- a/assistant/agent/step.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { createSkill } from '@kevisual/router' -import { app } from './index.ts' -import { tool } from '@opencode-ai/plugin/tool' - -// "调用 path: test key: step" -app.route({ - path: 'test', - key: 'step', - description: '测试步骤调用', - metadata: { - tags: ['opencode'], - ...createSkill({ - skill: 'test-step', - title: '获取系统信息', - summary: '根据步骤获取系统信息', - args: { - } - }) - }, -}).define(async (ctx) => { - ctx.body = { - context: `执行步骤 -1. 调用 path: client key: system 获取系统信息 -2. 调用 path: client key: time 获取当前时间 -3. 返回结果`, - }; -}).addTo(app) \ No newline at end of file diff --git a/assistant/bun.config.mjs b/assistant/bun.config.mjs index 3632c3a..9c3e4a5 100644 --- a/assistant/bun.config.mjs +++ b/assistant/bun.config.mjs @@ -40,6 +40,28 @@ await Bun.build({ }, external, }); + +await Bun.build({ + target: 'node', + format: 'esm', + entrypoints: [w('./src/main.ts')], + outdir: w('./dist'), + naming: { + entry: 'assistant-opencode.js', + }, + define: { + ENVISION_VERSION: JSON.stringify(pkg.version), + }, + external, +}); + +const dts = 'dts -i src/main.ts -o assistant-opencode.d.ts'; +Bun.spawnSync({ + cmd: ['sh', '-c', dts], + cwd: __dirname, + stdout: 'inherit', + stderr: 'inherit', +}); // const copyDist = ['dist', 'bin']; const copyDist = ['dist']; export const copyFileToEnvision = async () => { diff --git a/assistant/package.json b/assistant/package.json index 595ed2d..d2eede5 100644 --- a/assistant/package.json +++ b/assistant/package.json @@ -47,10 +47,10 @@ "@kevisual/logger": "^0.0.4", "@kevisual/query": "0.0.35", "@kevisual/query-login": "0.0.7", - "@kevisual/router": "^0.0.56", + "@kevisual/router": "^0.0.57", "@kevisual/types": "^0.0.11", "@kevisual/use-config": "^1.0.28", - "@opencode-ai/plugin": "^1.1.25", + "@opencode-ai/plugin": "^1.1.26", "@types/bun": "^1.3.6", "@types/lodash-es": "^4.17.12", "@types/node": "^25.0.9", @@ -81,7 +81,7 @@ "@kevisual/ha-api": "^0.0.6", "@kevisual/oss": "^0.0.16", "@kevisual/video-tools": "^0.0.13", - "@opencode-ai/sdk": "^1.1.25", + "@opencode-ai/sdk": "^1.1.26", "es-toolkit": "^1.44.0", "eventemitter3": "^5.0.4", "lowdb": "^7.0.1", diff --git a/assistant/src/app.ts b/assistant/src/app.ts index eda8228..f016118 100644 --- a/assistant/src/app.ts +++ b/assistant/src/app.ts @@ -2,10 +2,12 @@ import { App } from '@kevisual/router'; import { SimpleRouter } from '@kevisual/router/simple' // import { App } from '@kevisual/router/src/app.ts'; // import { AssistantConfig } from '@/module/assistant/index.ts'; + import { AssistantInit, parseHomeArg } from '@/services/init/index.ts'; import { configDir as HomeConfigDir } from '@/module/assistant/config/index.ts'; import { useContextKey } from '@kevisual/use-config/context'; import { AssistantQuery } from '@/module/assistant/query/index.ts'; + const manualParse = parseHomeArg(HomeConfigDir); const _configDir = manualParse.configDir; export const configDir = AssistantInit.detectConfigDir(_configDir); @@ -14,6 +16,7 @@ export const assistantConfig = useContextKey('assistantConfig', ( return new AssistantInit({ path: configDir, init: isInit, + initWorkspace: manualParse.isOpencode ? false : true, }); }); @@ -28,19 +31,16 @@ export const runtime = useContextKey('runtime', () => { }); export const app: App = useContextKey('app', () => { - const init = isInit; - if (init) { - return new App({ - serverOptions: { - path: '/client/router', - httpType: 'http', - cors: { - origin: '*', - }, - io: true + return new App({ + serverOptions: { + path: '/client/router', + httpType: 'http', + cors: { + origin: '*', }, - }); - } + io: true + }, + }); }); export const simpleRouter = useContextKey('simpleRouter', () => { diff --git a/assistant/src/main.ts b/assistant/src/main.ts index 57e7adf..d10565b 100644 --- a/assistant/src/main.ts +++ b/assistant/src/main.ts @@ -1,6 +1,9 @@ -import { app, assistantConfig } from './app.ts'; - +import { app } from './app.ts'; +import { type Plugin } from "@opencode-ai/plugin" +import { createRouterAgentPluginFn } from '@kevisual/router/opencode'; import './routes/index.ts'; import './routes-simple/index.ts'; -export { app, assistantConfig }; \ No newline at end of file +export const AgentPlugin: Plugin = createRouterAgentPluginFn({ + router: app.router, +}) \ No newline at end of file diff --git a/assistant/src/module/assistant/config/index.ts b/assistant/src/module/assistant/config/index.ts index af6d761..e61fa41 100644 --- a/assistant/src/module/assistant/config/index.ts +++ b/assistant/src/module/assistant/config/index.ts @@ -384,6 +384,7 @@ export function parseArgs(args: string[]) { */ export const parseHomeArg = (homedir?: string) => { const args = process.argv.slice(2); + const execPath = process.execPath; const options = parseArgs(args); let _configDir = undefined; if (options.home && homedir) { @@ -391,7 +392,9 @@ export const parseHomeArg = (homedir?: string) => { } else if (options.root) { _configDir = options.root; } + const isOpencode = execPath.includes('.opencode') || execPath.includes('opencode.exe'); return { + isOpencode, options, configDir: _configDir, }; diff --git a/assistant/agent/call.ts b/assistant/src/routes/call/index.ts similarity index 83% rename from assistant/agent/call.ts rename to assistant/src/routes/call/index.ts index f265207..f92a185 100644 --- a/assistant/agent/call.ts +++ b/assistant/src/routes/call/index.ts @@ -1,8 +1,7 @@ -import { createSkill } from '@kevisual/router' -import { app } from './index.ts' -import { tool } from '@opencode-ai/plugin/tool' -// "调用 path: router key: list" +import { app } from '../../app.ts'; +import { createSkill, tool } from '@kevisual/router'; + app.route({ path: 'call', key: '', diff --git a/assistant/src/routes/ha-api/ha.ts b/assistant/src/routes/ha-api/ha.ts index 8c7ac7c..270ed08 100644 --- a/assistant/src/routes/ha-api/ha.ts +++ b/assistant/src/routes/ha-api/ha.ts @@ -1,2 +1,37 @@ import { LightHA } from "@kevisual/ha-api"; export const lightHA = new LightHA({ token: process.env.HAAS_TOKEN || '', homeassistantURL: process.env.HAAS_URL }); + +export const callText = async (text: string) => { + const command = text?.trim().slice(0, 20); + type ParseCommand = { + type?: '打开' | '关闭', + appName?: string, + command?: string, + } + let obj: ParseCommand = {}; + if (command.startsWith('打开')) { + obj.appName = command.replace('打开', '').trim(); + obj.type = '打开'; + } else if (command.startsWith('关闭')) { + obj.appName = command.replace('关闭', '').trim(); + obj.type = '关闭'; + } + let endTime = Date.now(); + if (obj.type) { + try { + const search = await lightHA.searchLight(obj.appName || ''); + console.log('searchTime', Date.now() - endTime); + if (search.id) { + await lightHA.runService({ entity_id: search.id, service: obj.type === '打开' ? 'turn_on' : 'turn_off' }); + } else if (search.hasMore) { + const [first] = search.result; + await lightHA.runService({ entity_id: first.entity_id, service: obj.type === '打开' ? 'turn_on' : 'turn_off' }); + } else { + console.log('未找到对应设备:', obj.appName); + } + console.log('解析到控制指令', obj); + } catch (e) { + console.error('控制失败', e); + } + } +} \ No newline at end of file diff --git a/assistant/src/routes/index.ts b/assistant/src/routes/index.ts index ac2b2fa..0371702 100644 --- a/assistant/src/routes/index.ts +++ b/assistant/src/routes/index.ts @@ -5,10 +5,10 @@ import './ai/index.ts'; // TODO: // import './light-code/index.ts'; import './user/index.ts'; +import './call/index.ts' // TODO: 移除 // import './hot-api/key-sender/index.ts'; - import './opencode/index.ts'; import os from 'node:os'; diff --git a/assistant/src/routes/opencode/ls.ts b/assistant/src/routes/opencode/ls.ts index 4e1f01c..a402dc4 100644 --- a/assistant/src/routes/opencode/ls.ts +++ b/assistant/src/routes/opencode/ls.ts @@ -1,8 +1,10 @@ -import { useKey } from "@kevisual/use-config"; import { app } from '@/app.ts' -import { createSkill } from "@kevisual/router"; -import { opencodeManager } from './module/open.js' +import { createSkill, tool } from "@kevisual/router"; +import { opencodeManager } from './module/open.ts' +import path from "node:path"; +import { execSync } from "node:child_process"; +// 创建一个opencode 客户端 app.route({ path: 'opencode', key: 'create', @@ -21,9 +23,52 @@ app.route({ }, }).define(async (ctx) => { const client = await opencodeManager.getClient(); - ctx.body = { success: true, url: opencodeManager.url, message: 'OpenCode 客户端已就绪' }; + ctx.body = { content: `${opencodeManager.url} OpenCode 客户端已就绪` }; }).addTo(app); +// 关闭 opencode 客户端 +app.route({ + path: 'opencode', + key: 'close', + middleware: ['auth'], + description: '关闭 OpenCode 客户端', + metadata: { + tags: ['opencode'], + ...createSkill({ + skill: 'close-opencode-client', + title: '关闭 OpenCode 客户端', + summary: '关闭 OpenCode 客户端', + args: { + + } + }) + }, +}).define(async (ctx) => { + await opencodeManager.close(); + ctx.body = { content: 'OpenCode 客户端已关闭' }; +}).addTo(app); + +// 调用 path: opencode key: getUrl +app.route({ + path: 'opencode', + key: 'getUrl', + middleware: ['auth'], + description: '获取 OpenCode 服务 URL', + metadata: { + tags: ['opencode'], + ...createSkill({ + skill: 'get-opencode-url', + title: '获取 OpenCode 服务 URL', + summary: '获取当前 OpenCode 服务的 URL 地址', + args: { + + } + }) + }, +}).define(async (ctx) => { + const url = opencodeManager.getUrl(); + ctx.body = { content: url }; +}).addTo(app); // 调用 path: opencode key: ls-projects app.route({ path: 'opencode', @@ -38,3 +83,39 @@ app.route({ }; }).addTo(app); +// 调用 path: opencode key: runProject 参数 /home/ubuntu/cli/assistant +app.route({ + path: 'opencode', + key: 'runProject', + middleware: ['auth'], + metadata: { + tags: ['opencode'], + ...createSkill({ + skill: 'run-opencode-project', + title: '运行 OpenCode 项目', + summary: '运行一个已有的 OpenCode 项目', + args: { + projectPath: tool.schema.string().optional().describe('OpenCode 项目的路径, 默认为 /workspace') + } + }) + } +}).define(async (ctx) => { + const { projectPath = '/workspace' } = ctx.query; + try { + + // const directory = path.resolve(projectPath); + // const runOpencodeCli = 'opencode run hello'; + // execSync(runOpencodeCli, { cwd: directory, stdio: 'inherit' }); + // ctx.body = { content: `OpenCode 项目已在路径 ${directory} 运行` }; + const client = await opencodeManager.getClient(); + const session = await client.session.create({ + query: { + directory: projectPath + } + }) + console.log('Created session:', session.data.id); + ctx.body = { content: `OpenCode 项目已在路径 ${projectPath} 运行` }; + } catch (error) { + ctx.body = { content: `运行 OpenCode 项目失败, 请手动运行命令初始化: opencode run hello` }; + } +}).addTo(app); diff --git a/assistant/src/routes/opencode/module/open.ts b/assistant/src/routes/opencode/module/open.ts index f81b32c..7ba3721 100644 --- a/assistant/src/routes/opencode/module/open.ts +++ b/assistant/src/routes/opencode/module/open.ts @@ -1,13 +1,21 @@ -import { createOpencode, OpencodeClient } from "@opencode-ai/sdk"; +import { createOpencode, createOpencodeClient, OpencodeClient, } from "@opencode-ai/sdk"; +import { randomInt } from "es-toolkit"; +import getPort from "get-port"; +import os from "node:os"; +import path from "node:path"; +import fs from "node:fs"; +import { execSync } from "node:child_process"; + export class OpencodeManager { private static instance: OpencodeManager | null = null; private client: OpencodeClient | null = null; private server: { url: string; close(): void } | null = null; private isInitializing: boolean = false; + private currentPort: number | null = null; public url: string = ''; - private constructor() {} + private constructor() { } static getInstance(): OpencodeManager { if (!OpencodeManager.instance) { @@ -31,26 +39,89 @@ export class OpencodeManager { // 开始初始化 this.isInitializing = true; try { - const result = await createOpencode({ - hostname: '0.0.0.0', - }); - console.log('OpencodeManager: OpenCode 服务已启动', result.server.url); - this.url = result.server.url; - this.client = result.client; - this.server = result.server; - return this.client; + const port = 5000; + const currentPort = await getPort({ port: port }); + if (port === currentPort) { + const result = await createOpencode({ + hostname: '0.0.0.0', + port: port + }); + this.url = result.server.url; + this.client = result.client; + this.server = result.server; + return this.client; + } else { + this.client = await this.createOpencodeProject({ port }); + this.url = `http://localhost:${port}`; + return this.client; + } } finally { this.isInitializing = false; } } - - close(): void { + async createOpencodeProject({ + directory, + port = 5000 + }: { directory?: string, port?: number }): Promise { + const client = createOpencodeClient({ + baseUrl: `http://localhost:${port}`, + directory + }); + return client; + } + async killPort(port: number): Promise { + try { + // 尝试 使用命令行去关闭 port为5000的服务 + if (os.platform() === 'win32') { + // Windows 平台 + execSync(`netstat -ano | findstr :${port} | findstr LISTENING`).toString().split('\n').forEach(line => { + const parts = line.trim().split(/\s+/); + const pid = parts[parts.length - 1]; + if (pid) { + execSync(`taskkill /PID ${pid} /F`); + console.log(`OpencodeManager: 已关闭占用端口 ${port} 的进程 PID ${pid}`); + } + }); + } else { + // Unix-like 平台 + const result = execSync(`lsof -i :${port} -t`).toString(); + result.split('\n').forEach(pid => { + if (pid) { + execSync(`kill -9 ${pid}`); + console.log(`OpencodeManager: 已关闭占用端口 ${port} 的进程 PID ${pid}`); + } + }); + } + } catch (error) { + console.error('Failed to close OpenCode server:', error); + } + } + async close(): Promise { if (this.server) { this.server.close(); this.server = null; + return } + const port = 5000; + const currentPort = await getPort({ port: port }); + if (port === currentPort) { + this.client = null; + return; + } else { + await this.killPort(port); + } + this.client = null; } + async getUrl(): Promise { + if (this.url) { + return this.url; + } + if (!this.url) { + await this.getClient(); + } + return 'http://localhost:5000'; + } } export const opencodeManager = OpencodeManager.getInstance(); diff --git a/assistant/src/services/asr/qwen-asr.ts b/assistant/src/services/asr/qwen-asr.ts index 314caa4..55f9461 100644 --- a/assistant/src/services/asr/qwen-asr.ts +++ b/assistant/src/services/asr/qwen-asr.ts @@ -1,7 +1,7 @@ import { QwenAsrRelatime } from "@kevisual/video-tools/src/asr/index.ts"; import { Listener, WebSocketListenerFun, WebSocketReq } from "@kevisual/router"; -import { lightHA } from "@/routes/ha-api/ha.ts"; +import { callText } from "@/routes/ha-api/ha.ts"; import { assistantConfig } from "@/app.ts"; const func: WebSocketListenerFun = async (req: WebSocketReq<{ asr: QwenAsrRelatime, msgId: string, startTime?: number, loading?: boolean }>, res) => { @@ -61,37 +61,7 @@ const func: WebSocketListenerFun = async (req: WebSocketReq<{ asr: QwenAsrRelati text, })); if (!text) return; - const command = text?.trim().slice(0, 20); - type ParseCommand = { - type?: '打开' | '关闭', - appName?: string, - command?: string, - } - let obj: ParseCommand = {}; - if (command.startsWith('打开')) { - obj.appName = command.replace('打开', '').trim(); - obj.type = '打开'; - } else if (command.startsWith('关闭')) { - obj.appName = command.replace('关闭', '').trim(); - obj.type = '关闭'; - } - if (obj.type) { - try { - const search = await lightHA.searchLight(obj.appName || ''); - console.log('searchTime', Date.now() - endTime); - if (search.id) { - await lightHA.runService({ entity_id: search.id, service: obj.type === '打开' ? 'turn_on' : 'turn_off' }); - } else if (search.hasMore) { - const [first] = search.result; - await lightHA.runService({ entity_id: first.entity_id, service: obj.type === '打开' ? 'turn_on' : 'turn_off' }); - } else { - console.log('未找到对应设备:', obj.appName); - } - console.log('解析到控制指令', obj); - } catch (e) { - console.error('控制失败', e); - } - } + await callText(text); console.log('toogle light time', Date.now() - endTime); }); asr.start(); diff --git a/assistant/src/services/init/index.ts b/assistant/src/services/init/index.ts index 5a59ae7..0b25a25 100644 --- a/assistant/src/services/init/index.ts +++ b/assistant/src/services/init/index.ts @@ -8,6 +8,7 @@ export { parseHomeArg, parseHelpArg }; export type AssistantInitOptions = { path?: string; init?: boolean; + initWorkspace?: boolean; }; const randomId = () => Math.random().toString(36).substring(2, 8); /** @@ -16,12 +17,14 @@ const randomId = () => Math.random().toString(36).substring(2, 8); */ export class AssistantInit extends AssistantConfig { #query: Query + initWorkspace: boolean = false; constructor(opts?: AssistantInitOptions) { const configDir = opts?.path || process.cwd(); super({ configDir, init: false, }); + this.initWorkspace = opts?.initWorkspace ?? true; if (opts?.init) { this.init(); } @@ -35,8 +38,10 @@ export class AssistantInit extends AssistantConfig { if (!this.checkConfigPath()) { console.log(chalk.blue('助手路径不存在,正在创建...')); super.init(configDir); + if (!this.initWorkspace) { return } } else { super.init(configDir); + if (!this.initWorkspace) { return } const assistantConfig = this; console.log(chalk.yellow('助手路径已存在'), chalk.green(assistantConfig.configDir)); } diff --git a/package.json b/package.json index e0774ba..5c1e956 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,9 @@ "asst": "bin/assistant.js", "asst-server": "bin/assistant-server.js" }, + "exports": { + ".": "./dist/assistant-opencode.js" + }, "files": [ "dist", "bin", @@ -45,7 +48,7 @@ "@kevisual/app": "^0.0.2", "@kevisual/context": "^0.0.4", "@kevisual/use-config": "^1.0.28", - "@opencode-ai/sdk": "^1.1.25", + "@opencode-ai/sdk": "^1.1.26", "@types/busboy": "^1.5.4", "busboy": "^1.6.0", "eventemitter3": "^5.0.4", @@ -76,7 +79,7 @@ "ignore": "^7.0.5", "jsonwebtoken": "^9.0.3", "pm2": "^6.0.14", - "tar": "^7.5.3", + "tar": "^7.5.4", "zustand": "^5.0.10" }, "engines": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8b78d5e..f946d95 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -21,8 +21,8 @@ importers: specifier: ^1.0.28 version: 1.0.28(dotenv@17.2.3) '@opencode-ai/sdk': - specifier: ^1.1.25 - version: 1.1.25 + specifier: ^1.1.26 + version: 1.1.26 '@types/busboy': specifier: ^1.5.4 version: 1.5.4 @@ -109,8 +109,8 @@ importers: specifier: ^6.0.14 version: 6.0.14(supports-color@10.2.2) tar: - specifier: ^7.5.3 - version: 7.5.3 + specifier: ^7.5.4 + version: 7.5.4 zustand: specifier: ^5.0.10 version: 5.0.10(@types/react@19.2.8)(react@19.2.3) @@ -130,8 +130,8 @@ importers: specifier: ^0.0.13 version: 0.0.13(dotenv@17.2.3)(supports-color@10.2.2) '@opencode-ai/sdk': - specifier: ^1.1.25 - version: 1.1.25 + specifier: ^1.1.26 + version: 1.1.26 es-toolkit: specifier: ^1.44.0 version: 1.44.0 @@ -170,8 +170,8 @@ importers: specifier: 0.0.7 version: 0.0.7(@kevisual/query@0.0.35) '@kevisual/router': - specifier: ^0.0.56 - version: 0.0.56 + specifier: ^0.0.57 + version: 0.0.57 '@kevisual/types': specifier: ^0.0.11 version: 0.0.11 @@ -179,8 +179,8 @@ importers: specifier: ^1.0.28 version: 1.0.28(dotenv@17.2.3) '@opencode-ai/plugin': - specifier: ^1.1.25 - version: 1.1.25 + specifier: ^1.1.26 + version: 1.1.26 '@types/bun': specifier: ^1.3.6 version: 1.3.6 @@ -1344,8 +1344,8 @@ packages: '@kevisual/router@0.0.51': resolution: {integrity: sha512-i9qYBeS/um78oC912oWJD3iElB+5NTKyTrz1Hzf4DckiUFnjLL81UPwjIh5I2l9+ul0IZ/Pxx+sFSF99fJkzKg==} - '@kevisual/router@0.0.56': - resolution: {integrity: sha512-3k+wRUNT+kHqoA3r+6+lJRVHvbDMqNW75iWcYrzRFbf9lkEADYXzdIXHrOj/0Dk1EiTuLpK1i1e5dpWNpqlegA==} + '@kevisual/router@0.0.57': + resolution: {integrity: sha512-ZkbzsZD0FEXKBwLfjT4Evki8akHTPWUTZmnz7eGYnfloWDGudRtPJxqSLhzQ1AqfFuSDKJ8XR52Aa4CKdR05lA==} '@kevisual/types@0.0.11': resolution: {integrity: sha512-idNLDTEKVdNXZHFQq8PTN62nflh94kvGtx+v8YDcMxt0Zo+HWVZTFElm+dMQxAs/vn4wo8F2r3VwzWNX/vcqwQ==} @@ -1411,11 +1411,11 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} - '@opencode-ai/plugin@1.1.25': - resolution: {integrity: sha512-oTUWS446H/j7z3pdzo3cOrB5N87XZ/RKdgPD8yHv/rLX92B4YQHjOqggVQ56Q+1VEnN0jxzhoqRylv/0ZEts/Q==} + '@opencode-ai/plugin@1.1.26': + resolution: {integrity: sha512-GnhLZuw9NHDJwY5msUZnFIWiLc0SnoBXWZNfnWF5+hu0fcVLgul8gqB2VK4kUv+KOQlzCVMILYikSSQkMYp7RQ==} - '@opencode-ai/sdk@1.1.25': - resolution: {integrity: sha512-mWUX489ArEF2ICg3iZsx2VQaGS3Z2j/dwAJDacao9t7dGDzjOIaacPw2weZ10zld7XmT9V9C0PM/A5lDZ52J+w==} + '@opencode-ai/sdk@1.1.26': + resolution: {integrity: sha512-5s+yxNJy7DpWwDq0L//F2sqKERz4640DmDLyrRlFXmckx5prnzFl3liEOOTySOL2WaxgVwjYw8OBiT15v2mAgA==} '@oslojs/encoding@1.1.0': resolution: {integrity: sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ==} @@ -4662,8 +4662,8 @@ packages: resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==} engines: {node: '>=6'} - tar@7.5.3: - resolution: {integrity: sha512-ENg5JUHUm2rDD7IvKNFGzyElLXNjachNLp6RaGf4+JOgxXHkqA+gq81ZAMCUmtMtqBsoU62lcp6S27g1LCYGGQ==} + tar@7.5.4: + resolution: {integrity: sha512-AN04xbWGrSTDmVwlI4/GTlIIwMFk/XEv7uL8aa57zuvRy6s4hdBed+lVq2fAZ89XDa7Us3ANXcE3Tvqvja1kTA==} engines: {node: '>=18'} throttle-debounce@5.0.2: @@ -6557,7 +6557,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@kevisual/router@0.0.56': + '@kevisual/router@0.0.57': dependencies: hono: 4.11.4 @@ -6672,12 +6672,12 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.17.1 - '@opencode-ai/plugin@1.1.25': + '@opencode-ai/plugin@1.1.26': dependencies: - '@opencode-ai/sdk': 1.1.25 + '@opencode-ai/sdk': 1.1.26 zod: 4.1.8 - '@opencode-ai/sdk@1.1.25': {} + '@opencode-ai/sdk@1.1.26': {} '@oslojs/encoding@1.1.0': {} @@ -6810,7 +6810,7 @@ snapshots: async: 2.6.4 debug: 4.3.7(supports-color@10.2.2) eventemitter2: 6.4.9 - extrareqp2: 1.0.0(debug@4.3.7) + extrareqp2: 1.0.0(debug@4.3.7(supports-color@10.2.2)) ws: 7.5.10 transitivePeerDependencies: - bufferutil @@ -8785,9 +8785,9 @@ snapshots: extend@3.0.2: {} - extrareqp2@1.0.0(debug@4.3.7): + extrareqp2@1.0.0(debug@4.3.7(supports-color@10.2.2)): dependencies: - follow-redirects: 1.15.9(debug@4.3.7) + follow-redirects: 1.15.9(debug@4.3.7(supports-color@10.2.2)) transitivePeerDependencies: - debug @@ -8841,7 +8841,7 @@ snapshots: flattie@1.1.1: {} - follow-redirects@1.15.9(debug@4.3.7): + follow-redirects@1.15.9(debug@4.3.7(supports-color@10.2.2)): optionalDependencies: debug: 4.3.7(supports-color@10.2.2) @@ -10827,7 +10827,7 @@ snapshots: tapable@2.3.0: {} - tar@7.5.3: + tar@7.5.4: dependencies: '@isaacs/fs-minipass': 4.0.1 chownr: 3.0.0