feat: 更新依赖项,添加 OpenCode 支持,重构代理和路由逻辑,新增 AGENTS 文档
This commit is contained in:
1
assistant/.opencode/plugin/agent.ts
Normal file
1
assistant/.opencode/plugin/agent.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from "../../agent/plugin";
|
||||
204
assistant/AGENTS.md
Normal file
204
assistant/AGENTS.md
Normal file
@@ -0,0 +1,204 @@
|
||||
# AGENTS.md
|
||||
|
||||
## 构建、代码检查和测试命令
|
||||
|
||||
### 核心命令
|
||||
|
||||
```bash
|
||||
# 开发
|
||||
bun run dev # 运行主入口 (src/run.ts)
|
||||
bun run dev:server # 启动服务器(热重载)
|
||||
bun run dev:cnb # 使用自定义配置目录启动服务器
|
||||
bun run dev:share # 测试远程应用
|
||||
|
||||
# 构建
|
||||
bun run build # 完整生产构建(先清理 dist)
|
||||
bun run build:lib # 构建库文件
|
||||
bun run postbuild:lib # 生成 TypeScript 类型定义
|
||||
|
||||
# 包管理
|
||||
pnpm install # 安装依赖(使用 pnpm v10.28.0)
|
||||
```
|
||||
|
||||
### 环境要求
|
||||
|
||||
- **Node.js**: >=22.0.0
|
||||
- **运行时**: Bun(开发环境)/ Node.js(生产环境)
|
||||
- **包管理器**: pnpm@10.28.0(强制要求)
|
||||
|
||||
### 环境变量
|
||||
|
||||
- `ASSISTANT_CONFIG_DIR`: 覆盖助手配置文件目录路径
|
||||
- `BUN_PATH`: 覆盖 Bun 可执行文件路径
|
||||
|
||||
---
|
||||
|
||||
## 代码风格规范
|
||||
|
||||
### TypeScript
|
||||
|
||||
- **严格模式**: 通过扩展配置启用(`@kevisual/types/json/backend.json`)
|
||||
- **模块格式**: 仅 ESM(`package.json` 中的 `"type": "module"`)
|
||||
- **目标**: NodeNext 模块解析
|
||||
- **路径别名**: 使用 `@/*` 作为本地导入别名(如 `import { Foo } from '@/module/foo'`)
|
||||
|
||||
### 导入规则
|
||||
|
||||
```typescript
|
||||
// Node.js 内置模块必须使用 node: 协议
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import { execSync } from 'node:child_process';
|
||||
|
||||
// 外部包(不使用路径别名)
|
||||
import chalk from 'chalk';
|
||||
import { program } from 'commander';
|
||||
|
||||
// 本地模块(使用 @ 别名)
|
||||
import { AssistantInit } from '@/services/init/index.ts';
|
||||
|
||||
// 类型导入
|
||||
import type { AssistantConfig } from '@/module/assistant/index.ts';
|
||||
```
|
||||
|
||||
### 命名规范
|
||||
|
||||
| 类型 | 规范 | 示例 |
|
||||
|------|------|------|
|
||||
| 类 | PascalCase | `AssistantInit`, `AssistantApp`, `AssistantQuery` |
|
||||
| 接口 | PascalCase | `ProxyInfo`, `AssistantInitOptions` |
|
||||
| 类型 | PascalCase | `AssistantConfigData` |
|
||||
| 函数 | camelCase | `getBunPath`, `checkFileExists`, `parseHomeArg` |
|
||||
| 变量 | camelCase | `configDir`, `assistantConfig`, `isPortAvailable` |
|
||||
| 私有字段 | `#` 前缀 + camelCase | `#query`, `#config` |
|
||||
| 常量 | UPPER_SNAKE_CASE 或 camelCase | `commonPaths`, `randomId` |
|
||||
| 文件名 | kebab-case | `proxy-page-index.ts`, `query-login.ts` |
|
||||
| 目录名 | kebab-case | `query-login`, `hot-api` |
|
||||
|
||||
### 代码模式
|
||||
|
||||
#### 错误处理
|
||||
|
||||
```typescript
|
||||
// 同步操作包装
|
||||
try {
|
||||
const result = fs.readFileSync(path);
|
||||
return result;
|
||||
} catch (error) {
|
||||
console.error('读取文件错误:', error.message);
|
||||
continue; // 或 return/throw
|
||||
}
|
||||
|
||||
// 异步操作包装
|
||||
try {
|
||||
const result = await someAsyncOperation();
|
||||
return result;
|
||||
} catch (error) {
|
||||
console.error('操作失败:', error.message);
|
||||
process.exit(1); // 或 throw/return undefined
|
||||
}
|
||||
```
|
||||
|
||||
#### 上下文/依赖注入
|
||||
|
||||
使用 `@kevisual/use-config` 进行上下文管理:
|
||||
|
||||
```typescript
|
||||
export const assistantConfig = useContextKey<AssistantInit>('assistantConfig', () => {
|
||||
return new AssistantInit({
|
||||
path: configDir,
|
||||
init: isInit,
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
#### 路由模式
|
||||
|
||||
使用 `@kevisual/router` 的 App 和 SimpleRouter:
|
||||
|
||||
```typescript
|
||||
app.route({
|
||||
path: 'router',
|
||||
key: 'list',
|
||||
description: '获取路由列表',
|
||||
}).define(async (ctx) => {
|
||||
ctx.body = { list };
|
||||
}).addTo(app);
|
||||
```
|
||||
|
||||
### JSDoc 文档
|
||||
|
||||
为公共 API、复杂函数和类型添加文档:
|
||||
|
||||
```typescript
|
||||
/**
|
||||
* 助手初始化类
|
||||
* @class AssistantInit
|
||||
*/
|
||||
export class AssistantInit extends AssistantConfig {}
|
||||
|
||||
/**
|
||||
* @param {string} p - 要解析的路径
|
||||
* @returns {string} 解析后的绝对路径
|
||||
*/
|
||||
export const w = (p: string) => path.join(__dirname, p);
|
||||
```
|
||||
|
||||
### 文件组织
|
||||
|
||||
- **路由**: `src/routes/` 和 `src/routes-simple/`
|
||||
- **模块**: `src/module/`(功能模块)
|
||||
- **服务**: `src/services/`(公共服务)
|
||||
- **命令**: `src/command/`(CLI 命令)
|
||||
- **查询**: `src/query/`(API/查询逻辑)
|
||||
- **入口文件**:
|
||||
- `src/index.ts` - 主 CLI 入口
|
||||
- `src/server.ts` - 服务器入口
|
||||
- `src/run.ts` - 开发运行器
|
||||
- `src/run-server.ts` - 服务器运行器
|
||||
|
||||
### 控制台输出
|
||||
|
||||
使用 `chalk` 实现彩色输出:
|
||||
|
||||
```typescript
|
||||
console.log(chalk.blue('助手路径不存在,正在创建...'));
|
||||
console.log(chalk.yellow('助手路径已存在'), chalk.green(assistantConfig.configDir));
|
||||
console.error(chalk.red('启动服务器错误:'), error.message);
|
||||
```
|
||||
|
||||
### 系统检测
|
||||
|
||||
```typescript
|
||||
const isWindows = process.platform === 'win32';
|
||||
const bunExecutableName = isWindows ? 'bun.exe' : 'bun';
|
||||
```
|
||||
|
||||
### 端口处理
|
||||
|
||||
```typescript
|
||||
import getPort, { portNumbers } from 'get-port';
|
||||
|
||||
const port = await getPort({ port: 51515 });
|
||||
const availablePort = await getPort({ port: portNumbers(51515, 52000) });
|
||||
```
|
||||
|
||||
### 关键依赖
|
||||
|
||||
- `@kevisual/router` - 应用路由
|
||||
- `@kevisual/query` - API 查询
|
||||
- `@kevisual/use-config` - 配置/上下文
|
||||
- `commander` - CLI 参数解析
|
||||
- `chalk` - 终端颜色
|
||||
- `ws` - WebSocket(通过 `@kevisual/ws`)
|
||||
- `pm2` - 进程管理(生产环境)
|
||||
|
||||
### 重要说明
|
||||
|
||||
1. 开发时始终使用 `bun`,但构建输出以 Node.js 为目标
|
||||
2. 打包时外部包必须在 `bun.config.mjs` 的 `external` 数组中声明
|
||||
3. 库构建排除 `pm2`
|
||||
4. 以 `ENVISION_*` 为前缀的环境变量在构建时可用
|
||||
5. 项目在业务逻辑中广泛使用中文注释
|
||||
6. 私有类成员应使用 `#` 前缀语法
|
||||
7. 操作前始终使用 `checkFileExists` 检查文件是否存在
|
||||
33
assistant/agent/call.ts
Normal file
33
assistant/agent/call.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import { createSkill } from '@kevisual/router'
|
||||
import { app } from './index.ts'
|
||||
import { tool } from '@opencode-ai/plugin/tool'
|
||||
|
||||
// "调用 path: router key: list"
|
||||
app.route({
|
||||
path: 'call',
|
||||
key: '',
|
||||
description: '调用',
|
||||
middleware: ['auth'],
|
||||
metadata: {
|
||||
tags: ['opencode'],
|
||||
...createSkill({
|
||||
skill: 'call-app',
|
||||
title: '调用app应用',
|
||||
summary: '调用router的应用, 参数path, key, payload',
|
||||
args: {
|
||||
path: tool.schema.string().describe('应用路径,例如 cnb'),
|
||||
key: tool.schema.string().optional().describe('应用key,例如 list-repos'),
|
||||
payload: tool.schema.object({}).optional().describe('调用参数'),
|
||||
}
|
||||
})
|
||||
},
|
||||
}).define(async (ctx) => {
|
||||
const { path, key = '' } = ctx.query;
|
||||
if (!path) {
|
||||
ctx.throw('路径path不能为空');
|
||||
}
|
||||
const res = await ctx.run({ path, key, payload: ctx.query.payload || {} }, {
|
||||
...ctx
|
||||
});
|
||||
ctx.forward(res);
|
||||
}).addTo(app)
|
||||
3
assistant/agent/index.ts
Normal file
3
assistant/agent/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
import { app } from '../src/main.ts'
|
||||
|
||||
export { app }
|
||||
64
assistant/agent/plugin.ts
Normal file
64
assistant/agent/plugin.ts
Normal file
@@ -0,0 +1,64 @@
|
||||
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<string, any>) {
|
||||
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<string, any>)
|
||||
},
|
||||
'tool.execute.before': async (opts) => {
|
||||
// console.log('CnbPlugin: tool.execute.before', opts.tool);
|
||||
// delete toolSkills['cnb-login-verify']
|
||||
}
|
||||
}
|
||||
}
|
||||
27
assistant/agent/step.ts
Normal file
27
assistant/agent/step.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
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)
|
||||
@@ -10,7 +10,7 @@
|
||||
],
|
||||
"author": "abearxiong <xiongxiao@xiongxiao.me> (https://www.xiongxiao.me)",
|
||||
"license": "MIT",
|
||||
"packageManager": "pnpm@10.28.0",
|
||||
"packageManager": "pnpm@10.28.1",
|
||||
"type": "module",
|
||||
"files": [
|
||||
"dist",
|
||||
@@ -41,15 +41,16 @@
|
||||
}
|
||||
},
|
||||
"devDependencies": {
|
||||
"@kevisual/ai": "^0.0.20",
|
||||
"@kevisual/ai": "^0.0.21",
|
||||
"@kevisual/load": "^0.0.6",
|
||||
"@kevisual/local-app-manager": "^0.1.32",
|
||||
"@kevisual/logger": "^0.0.4",
|
||||
"@kevisual/query": "0.0.35",
|
||||
"@kevisual/query-login": "0.0.7",
|
||||
"@kevisual/router": "^0.0.55",
|
||||
"@kevisual/router": "^0.0.56",
|
||||
"@kevisual/types": "^0.0.11",
|
||||
"@kevisual/use-config": "^1.0.28",
|
||||
"@opencode-ai/plugin": "^1.1.25",
|
||||
"@types/bun": "^1.3.6",
|
||||
"@types/lodash-es": "^4.17.12",
|
||||
"@types/node": "^25.0.9",
|
||||
@@ -80,7 +81,9 @@
|
||||
"@kevisual/ha-api": "^0.0.6",
|
||||
"@kevisual/oss": "^0.0.16",
|
||||
"@kevisual/video-tools": "^0.0.13",
|
||||
"eventemitter3": "^5.0.1",
|
||||
"@opencode-ai/sdk": "^1.1.25",
|
||||
"es-toolkit": "^1.44.0",
|
||||
"eventemitter3": "^5.0.4",
|
||||
"lowdb": "^7.0.1",
|
||||
"lru-cache": "^11.2.4",
|
||||
"pm2": "^6.0.14",
|
||||
|
||||
6
assistant/src/main.ts
Normal file
6
assistant/src/main.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import { app, assistantConfig } from './app.ts';
|
||||
|
||||
import './routes/index.ts';
|
||||
import './routes-simple/index.ts';
|
||||
|
||||
export { app, assistantConfig };
|
||||
@@ -9,8 +9,11 @@ import './user/index.ts';
|
||||
// TODO: 移除
|
||||
// import './hot-api/key-sender/index.ts';
|
||||
|
||||
import './opencode/index.ts';
|
||||
|
||||
import os from 'node:os';
|
||||
import { authCache } from '@/module/cache/auth.ts';
|
||||
import { createSkill } from '@kevisual/router';
|
||||
const getTokenUser = async (token: string) => {
|
||||
const query = assistantConfig.query
|
||||
const res = await query.post({
|
||||
@@ -101,6 +104,9 @@ app
|
||||
description: '获取当前登录用户信息, 第一个登录的用户为管理员用户',
|
||||
})
|
||||
.define(async (ctx) => {
|
||||
if (!ctx.query?.token && ctx.appId === app.appId) {
|
||||
return;
|
||||
}
|
||||
const authResult = await checkAuth(ctx);
|
||||
if (authResult.code !== 200) {
|
||||
ctx.throw(authResult.code, authResult.message);
|
||||
@@ -115,6 +121,9 @@ app
|
||||
})
|
||||
.define(async (ctx) => {
|
||||
console.log('query', ctx.query);
|
||||
if (!ctx.query?.token && ctx.appId === app.appId) {
|
||||
return;
|
||||
}
|
||||
const authResult = await checkAuth(ctx, true);
|
||||
if (authResult.code !== 200) {
|
||||
ctx.throw(authResult.code, authResult.message);
|
||||
@@ -152,6 +161,14 @@ app
|
||||
path: 'client',
|
||||
key: 'system',
|
||||
description: '获取系统信息',
|
||||
metadata: {
|
||||
tags: ['opencode'],
|
||||
...createSkill({
|
||||
skill: 'view-system-info',
|
||||
title: '查看系统信息',
|
||||
summary: '获取服务器操作系统平台、架构和版本信息',
|
||||
})
|
||||
}
|
||||
})
|
||||
.define(async (ctx) => {
|
||||
const { platform, arch, release } = os;
|
||||
|
||||
1
assistant/src/routes/opencode/index.ts
Normal file
1
assistant/src/routes/opencode/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
import './ls.ts'
|
||||
40
assistant/src/routes/opencode/ls.ts
Normal file
40
assistant/src/routes/opencode/ls.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import { useKey } from "@kevisual/use-config";
|
||||
import { app } from '@/app.ts'
|
||||
import { createSkill } from "@kevisual/router";
|
||||
import { opencodeManager } from './module/open.js'
|
||||
|
||||
app.route({
|
||||
path: 'opencode',
|
||||
key: 'create',
|
||||
middleware: ['auth'],
|
||||
description: '创建 OpenCode 客户端',
|
||||
metadata: {
|
||||
tags: ['opencode'],
|
||||
...createSkill({
|
||||
skill: 'create-opencode-client',
|
||||
title: '创建 OpenCode 客户端',
|
||||
summary: '创建 OpenCode 客户端,如果存在则复用',
|
||||
args: {
|
||||
|
||||
}
|
||||
})
|
||||
},
|
||||
}).define(async (ctx) => {
|
||||
const client = await opencodeManager.getClient();
|
||||
ctx.body = { success: true, url: opencodeManager.url, message: 'OpenCode 客户端已就绪' };
|
||||
}).addTo(app);
|
||||
|
||||
// 调用 path: opencode key: ls-projects
|
||||
app.route({
|
||||
path: 'opencode',
|
||||
key: 'ls-projects'
|
||||
}).define(async (ctx) => {
|
||||
const client = await opencodeManager.getClient();
|
||||
const projects = await client.project.list();
|
||||
const currentProject = await client.project.current();
|
||||
ctx.body = {
|
||||
projects,
|
||||
currentProject
|
||||
};
|
||||
}).addTo(app);
|
||||
|
||||
56
assistant/src/routes/opencode/module/open.ts
Normal file
56
assistant/src/routes/opencode/module/open.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
import { createOpencode, OpencodeClient } from "@opencode-ai/sdk";
|
||||
|
||||
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;
|
||||
|
||||
public url: string = '';
|
||||
private constructor() {}
|
||||
|
||||
static getInstance(): OpencodeManager {
|
||||
if (!OpencodeManager.instance) {
|
||||
OpencodeManager.instance = new OpencodeManager();
|
||||
}
|
||||
return OpencodeManager.instance;
|
||||
}
|
||||
|
||||
async getClient(): Promise<OpencodeClient> {
|
||||
// 如果已经有 client,直接返回
|
||||
if (this.client) {
|
||||
return this.client;
|
||||
}
|
||||
|
||||
// 如果正在初始化,等待初始化完成
|
||||
if (this.isInitializing) {
|
||||
await new Promise(resolve => setTimeout(resolve, 100));
|
||||
return this.getClient();
|
||||
}
|
||||
|
||||
// 开始初始化
|
||||
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;
|
||||
} finally {
|
||||
this.isInitializing = false;
|
||||
}
|
||||
}
|
||||
|
||||
close(): void {
|
||||
if (this.server) {
|
||||
this.server.close();
|
||||
this.server = null;
|
||||
}
|
||||
this.client = null;
|
||||
}
|
||||
}
|
||||
|
||||
export const opencodeManager = OpencodeManager.getInstance();
|
||||
@@ -111,6 +111,10 @@ export const proxyRoute = async (req: http.IncomingMessage, res: http.ServerResp
|
||||
logger.debug('handle by router', { url: req.url });
|
||||
return;
|
||||
}
|
||||
if (pathname.startsWith('/router') || pathname.startsWith('/opencode')) {
|
||||
logger.debug('handle by router (opencode/router)', { url: req.url });
|
||||
return;
|
||||
}
|
||||
// client, api, v1, serve 开头的拦截
|
||||
const apiProxy = _assistantConfig?.api?.proxy || [];
|
||||
const defaultApiProxy = createApiProxy(_assistantConfig?.app?.url || 'https://kevisual.cn');
|
||||
|
||||
@@ -14,5 +14,6 @@
|
||||
},
|
||||
"include": [
|
||||
"src/**/*",
|
||||
"agent/**/*"
|
||||
],
|
||||
}
|
||||
@@ -45,9 +45,10 @@
|
||||
"@kevisual/app": "^0.0.2",
|
||||
"@kevisual/context": "^0.0.4",
|
||||
"@kevisual/use-config": "^1.0.28",
|
||||
"@opencode-ai/sdk": "^1.1.25",
|
||||
"@types/busboy": "^1.5.4",
|
||||
"busboy": "^1.6.0",
|
||||
"eventemitter3": "^5.0.1",
|
||||
"eventemitter3": "^5.0.4",
|
||||
"lowdb": "^7.0.1",
|
||||
"lru-cache": "^11.2.4",
|
||||
"micromatch": "^4.0.8",
|
||||
@@ -55,7 +56,6 @@
|
||||
"unstorage": "^1.17.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"pm2": "^6.0.14",
|
||||
"@kevisual/dts": "^0.0.3",
|
||||
"@kevisual/load": "^0.0.6",
|
||||
"@kevisual/logger": "^0.0.4",
|
||||
@@ -75,6 +75,7 @@
|
||||
"form-data": "^4.0.5",
|
||||
"ignore": "^7.0.5",
|
||||
"jsonwebtoken": "^9.0.3",
|
||||
"pm2": "^6.0.14",
|
||||
"tar": "^7.5.3",
|
||||
"zustand": "^5.0.10"
|
||||
},
|
||||
|
||||
90
pnpm-lock.yaml
generated
90
pnpm-lock.yaml
generated
@@ -20,6 +20,9 @@ importers:
|
||||
'@kevisual/use-config':
|
||||
specifier: ^1.0.28
|
||||
version: 1.0.28(dotenv@17.2.3)
|
||||
'@opencode-ai/sdk':
|
||||
specifier: ^1.1.25
|
||||
version: 1.1.25
|
||||
'@types/busboy':
|
||||
specifier: ^1.5.4
|
||||
version: 1.5.4
|
||||
@@ -27,8 +30,8 @@ importers:
|
||||
specifier: ^1.6.0
|
||||
version: 1.6.0
|
||||
eventemitter3:
|
||||
specifier: ^5.0.1
|
||||
version: 5.0.1
|
||||
specifier: ^5.0.4
|
||||
version: 5.0.4
|
||||
lowdb:
|
||||
specifier: ^7.0.1
|
||||
version: 7.0.1
|
||||
@@ -126,9 +129,15 @@ importers:
|
||||
'@kevisual/video-tools':
|
||||
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
|
||||
es-toolkit:
|
||||
specifier: ^1.44.0
|
||||
version: 1.44.0
|
||||
eventemitter3:
|
||||
specifier: ^5.0.1
|
||||
version: 5.0.1
|
||||
specifier: ^5.0.4
|
||||
version: 5.0.4
|
||||
lowdb:
|
||||
specifier: ^7.0.1
|
||||
version: 7.0.1
|
||||
@@ -143,8 +152,8 @@ importers:
|
||||
version: 1.17.4(idb-keyval@6.2.2)
|
||||
devDependencies:
|
||||
'@kevisual/ai':
|
||||
specifier: ^0.0.20
|
||||
version: 0.0.20
|
||||
specifier: ^0.0.21
|
||||
version: 0.0.21
|
||||
'@kevisual/load':
|
||||
specifier: ^0.0.6
|
||||
version: 0.0.6
|
||||
@@ -161,14 +170,17 @@ importers:
|
||||
specifier: 0.0.7
|
||||
version: 0.0.7(@kevisual/query@0.0.35)
|
||||
'@kevisual/router':
|
||||
specifier: ^0.0.55
|
||||
version: 0.0.55
|
||||
specifier: ^0.0.56
|
||||
version: 0.0.56
|
||||
'@kevisual/types':
|
||||
specifier: ^0.0.11
|
||||
version: 0.0.11
|
||||
'@kevisual/use-config':
|
||||
specifier: ^1.0.28
|
||||
version: 1.0.28(dotenv@17.2.3)
|
||||
'@opencode-ai/plugin':
|
||||
specifier: ^1.1.25
|
||||
version: 1.1.25
|
||||
'@types/bun':
|
||||
specifier: ^1.3.6
|
||||
version: 1.3.6
|
||||
@@ -1257,8 +1269,8 @@ packages:
|
||||
'@kevisual/ai@0.0.19':
|
||||
resolution: {integrity: sha512-AFc8m6OcHZNxCb88bvzhvwWTZ4EVYyPupBzPUsLKLpdNBvsqm9TRboKCM2brJj2cqHnm+H+RbAk9AcGJkYhRCA==}
|
||||
|
||||
'@kevisual/ai@0.0.20':
|
||||
resolution: {integrity: sha512-RW4a1T8XbIaonjp4ndt+5YIVeHR9O+pAzZZ1dWeYIlqQXvDuJdHSVukOh4ohgFS0tyEPzCr39seFeb6Y0YNzkw==}
|
||||
'@kevisual/ai@0.0.21':
|
||||
resolution: {integrity: sha512-4YvnEDpgCje3jDZug95pXzmIS4jHHulDjXONXSWLScsSLiqIRZnZQ6K+2IbCnIDAFmGIBYR/xFt0fyJIKJmrDQ==}
|
||||
|
||||
'@kevisual/api@0.0.17':
|
||||
resolution: {integrity: sha512-hW3Q182Lm8wggWfHTEKVTKsmp8MWFINB9l82nEbnwTnd1Lh9DPeQo1hMft7aeL8aGe4vjFCTv4MHixXjmQTzGg==}
|
||||
@@ -1332,8 +1344,8 @@ packages:
|
||||
'@kevisual/router@0.0.51':
|
||||
resolution: {integrity: sha512-i9qYBeS/um78oC912oWJD3iElB+5NTKyTrz1Hzf4DckiUFnjLL81UPwjIh5I2l9+ul0IZ/Pxx+sFSF99fJkzKg==}
|
||||
|
||||
'@kevisual/router@0.0.55':
|
||||
resolution: {integrity: sha512-DVhXbbUCfSWWXsp1id1HBrkGiMZ6nFUBD1/C5E7IpLE5B32w7sv2xjKUt98OriFl0uyuneMEIZuZsAQaKplQ5g==}
|
||||
'@kevisual/router@0.0.56':
|
||||
resolution: {integrity: sha512-3k+wRUNT+kHqoA3r+6+lJRVHvbDMqNW75iWcYrzRFbf9lkEADYXzdIXHrOj/0Dk1EiTuLpK1i1e5dpWNpqlegA==}
|
||||
|
||||
'@kevisual/types@0.0.11':
|
||||
resolution: {integrity: sha512-idNLDTEKVdNXZHFQq8PTN62nflh94kvGtx+v8YDcMxt0Zo+HWVZTFElm+dMQxAs/vn4wo8F2r3VwzWNX/vcqwQ==}
|
||||
@@ -1399,6 +1411,12 @@ 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/sdk@1.1.25':
|
||||
resolution: {integrity: sha512-mWUX489ArEF2ICg3iZsx2VQaGS3Z2j/dwAJDacao9t7dGDzjOIaacPw2weZ10zld7XmT9V9C0PM/A5lDZ52J+w==}
|
||||
|
||||
'@oslojs/encoding@1.1.0':
|
||||
resolution: {integrity: sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ==}
|
||||
|
||||
@@ -3096,8 +3114,8 @@ packages:
|
||||
eventemitter2@6.4.9:
|
||||
resolution: {integrity: sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg==}
|
||||
|
||||
eventemitter3@5.0.1:
|
||||
resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==}
|
||||
eventemitter3@5.0.4:
|
||||
resolution: {integrity: sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==}
|
||||
|
||||
execa@9.6.1:
|
||||
resolution: {integrity: sha512-9Be3ZoN4LmYR90tUoVu2te2BsbzHfhJyfEiAVfz7N5/zv+jduIfLrV2xdQXOHbaD6KgpGdO9PRPM1Y4Q9QkPkA==}
|
||||
@@ -3342,6 +3360,10 @@ packages:
|
||||
resolution: {integrity: sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
|
||||
hono@4.11.4:
|
||||
resolution: {integrity: sha512-U7tt8JsyrxSRKspfhtLET79pU8K+tInj5QZXs1jSugO1Vq5dFj3kmZsRldo29mTBfcjDRVRXrEZ6LS63Cog9ZA==}
|
||||
engines: {node: '>=16.9.0'}
|
||||
|
||||
hookable@5.5.3:
|
||||
resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==}
|
||||
|
||||
@@ -5036,6 +5058,9 @@ packages:
|
||||
zod@3.25.76:
|
||||
resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==}
|
||||
|
||||
zod@4.1.8:
|
||||
resolution: {integrity: sha512-5R1P+WwQqmmMIEACyzSvo4JXHY5WiAFHRMg+zBZKgKS+Q1viRa0C1hmUKtHltoIFKtIdki3pRxkmpP74jnNYHQ==}
|
||||
|
||||
zustand@5.0.10:
|
||||
resolution: {integrity: sha512-U1AiltS1O9hSy3rul+Ub82ut2fqIAefiSuwECWt6jlMVUGejvf+5omLcRBSzqbRagSM3hQZbtzdeRc6QVScXTg==}
|
||||
engines: {node: '>=12.20.0'}
|
||||
@@ -6359,7 +6384,7 @@ snapshots:
|
||||
'@kevisual/permission': 0.0.3
|
||||
'@kevisual/query': 0.0.31
|
||||
|
||||
'@kevisual/ai@0.0.20':
|
||||
'@kevisual/ai@0.0.21':
|
||||
dependencies:
|
||||
'@kevisual/logger': 0.0.4
|
||||
'@kevisual/permission': 0.0.3
|
||||
@@ -6370,7 +6395,7 @@ snapshots:
|
||||
'@kevisual/js-filter': 0.0.3
|
||||
'@kevisual/load': 0.0.6
|
||||
es-toolkit: 1.44.0
|
||||
eventemitter3: 5.0.1
|
||||
eventemitter3: 5.0.4
|
||||
nanoid: 5.1.6
|
||||
|
||||
'@kevisual/app@0.0.1(dotenv@17.2.3)':
|
||||
@@ -6444,7 +6469,7 @@ snapshots:
|
||||
'@kevisual/context': 0.0.4
|
||||
codemirror: 6.0.2
|
||||
dayjs: 1.11.19
|
||||
eventemitter3: 5.0.1
|
||||
eventemitter3: 5.0.4
|
||||
lit-html: 3.3.1
|
||||
nanoid: 5.1.6
|
||||
prettier: 3.7.4
|
||||
@@ -6460,7 +6485,7 @@ snapshots:
|
||||
|
||||
'@kevisual/load@0.0.6':
|
||||
dependencies:
|
||||
eventemitter3: 5.0.1
|
||||
eventemitter3: 5.0.4
|
||||
|
||||
'@kevisual/local-app-manager@0.1.32(supports-color@10.2.2)':
|
||||
dependencies:
|
||||
@@ -6532,7 +6557,9 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@kevisual/router@0.0.55': {}
|
||||
'@kevisual/router@0.0.56':
|
||||
dependencies:
|
||||
hono: 4.11.4
|
||||
|
||||
'@kevisual/types@0.0.11': {}
|
||||
|
||||
@@ -6550,7 +6577,7 @@ snapshots:
|
||||
'@kevisual/video': 0.0.2
|
||||
crypto-js: 4.2.0
|
||||
dayjs: 1.11.19
|
||||
eventemitter3: 5.0.1
|
||||
eventemitter3: 5.0.4
|
||||
nanoid: 5.1.6
|
||||
transitivePeerDependencies:
|
||||
- dotenv
|
||||
@@ -6645,6 +6672,13 @@ snapshots:
|
||||
'@nodelib/fs.scandir': 2.1.5
|
||||
fastq: 1.17.1
|
||||
|
||||
'@opencode-ai/plugin@1.1.25':
|
||||
dependencies:
|
||||
'@opencode-ai/sdk': 1.1.25
|
||||
zod: 4.1.8
|
||||
|
||||
'@opencode-ai/sdk@1.1.25': {}
|
||||
|
||||
'@oslojs/encoding@1.1.0': {}
|
||||
|
||||
'@peculiar/asn1-cms@2.6.0':
|
||||
@@ -6776,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(supports-color@10.2.2))
|
||||
extrareqp2: 1.0.0(debug@4.3.7)
|
||||
ws: 7.5.10
|
||||
transitivePeerDependencies:
|
||||
- bufferutil
|
||||
@@ -8732,7 +8766,7 @@ snapshots:
|
||||
|
||||
eventemitter2@6.4.9: {}
|
||||
|
||||
eventemitter3@5.0.1: {}
|
||||
eventemitter3@5.0.4: {}
|
||||
|
||||
execa@9.6.1:
|
||||
dependencies:
|
||||
@@ -8751,9 +8785,9 @@ snapshots:
|
||||
|
||||
extend@3.0.2: {}
|
||||
|
||||
extrareqp2@1.0.0(debug@4.3.7(supports-color@10.2.2)):
|
||||
extrareqp2@1.0.0(debug@4.3.7):
|
||||
dependencies:
|
||||
follow-redirects: 1.15.9(debug@4.3.7(supports-color@10.2.2))
|
||||
follow-redirects: 1.15.9(debug@4.3.7)
|
||||
transitivePeerDependencies:
|
||||
- debug
|
||||
|
||||
@@ -8807,7 +8841,7 @@ snapshots:
|
||||
|
||||
flattie@1.1.1: {}
|
||||
|
||||
follow-redirects@1.15.9(debug@4.3.7(supports-color@10.2.2)):
|
||||
follow-redirects@1.15.9(debug@4.3.7):
|
||||
optionalDependencies:
|
||||
debug: 4.3.7(supports-color@10.2.2)
|
||||
|
||||
@@ -9093,6 +9127,8 @@ snapshots:
|
||||
|
||||
highlight.js@11.11.1: {}
|
||||
|
||||
hono@4.11.4: {}
|
||||
|
||||
hookable@5.5.3: {}
|
||||
|
||||
html-escaper@3.0.3: {}
|
||||
@@ -9984,7 +10020,7 @@ snapshots:
|
||||
|
||||
p-queue@8.1.1:
|
||||
dependencies:
|
||||
eventemitter3: 5.0.1
|
||||
eventemitter3: 5.0.4
|
||||
p-timeout: 6.1.4
|
||||
|
||||
p-timeout@6.1.4: {}
|
||||
@@ -11115,6 +11151,8 @@ snapshots:
|
||||
|
||||
zod@3.25.76: {}
|
||||
|
||||
zod@4.1.8: {}
|
||||
|
||||
zustand@5.0.10(@types/react@19.2.8)(react@19.2.3):
|
||||
optionalDependencies:
|
||||
'@types/react': 19.2.8
|
||||
|
||||
Reference in New Issue
Block a user