Refactor client routes and add IP fetching functionality
- Moved client route definitions to separate files for better organization. - Added new route to fetch client IP addresses, supporting both IPv4 and IPv6. - Implemented system information retrieval in the client routes. - Updated package dependencies to their latest versions. - Adjusted call route to prevent overwriting existing routes.
This commit is contained in:
@@ -44,16 +44,16 @@
|
||||
"devDependencies": {
|
||||
"@inquirer/prompts": "^8.2.0",
|
||||
"@kevisual/ai": "^0.0.24",
|
||||
"@kevisual/api": "^0.0.42",
|
||||
"@kevisual/api": "^0.0.44",
|
||||
"@kevisual/load": "^0.0.6",
|
||||
"@kevisual/local-app-manager": "^0.1.32",
|
||||
"@kevisual/logger": "^0.0.4",
|
||||
"@kevisual/query": "0.0.39",
|
||||
"@kevisual/query-login": "0.0.7",
|
||||
"@kevisual/router": "^0.0.67",
|
||||
"@kevisual/router": "^0.0.70",
|
||||
"@kevisual/types": "^0.0.12",
|
||||
"@kevisual/use-config": "^1.0.30",
|
||||
"@opencode-ai/plugin": "^1.1.48",
|
||||
"@opencode-ai/plugin": "^1.1.49",
|
||||
"@types/bun": "^1.3.8",
|
||||
"@types/node": "^25.2.0",
|
||||
"@types/send": "^1.2.1",
|
||||
@@ -77,11 +77,11 @@
|
||||
"access": "public"
|
||||
},
|
||||
"dependencies": {
|
||||
"@aws-sdk/client-s3": "^3.980.0",
|
||||
"@aws-sdk/client-s3": "^3.981.0",
|
||||
"@kevisual/js-filter": "^0.0.5",
|
||||
"@kevisual/oss": "^0.0.19",
|
||||
"@kevisual/video-tools": "^0.0.13",
|
||||
"@opencode-ai/sdk": "^1.1.48",
|
||||
"@opencode-ai/sdk": "^1.1.49",
|
||||
"es-toolkit": "^1.44.0",
|
||||
"eventemitter3": "^5.0.4",
|
||||
"lowdb": "^7.0.1",
|
||||
|
||||
@@ -60,8 +60,9 @@ app.route({
|
||||
description: '获取路由列表',
|
||||
}).define(async (ctx) => {
|
||||
const list = ctx.app.getList((item) => {
|
||||
if (item?.path?.includes('auth') || item?.id?.includes('auth')) return false;
|
||||
if (item?.path?.includes?.('auth') || item?.id?.includes?.('auth')) return false;
|
||||
return true;
|
||||
})
|
||||
console.log('路由列表:', list.length);
|
||||
ctx.body = { list }
|
||||
}).addTo(app);
|
||||
@@ -12,6 +12,7 @@ import { initApi } from '@kevisual/api/proxy'
|
||||
import { Query } from '@kevisual/query';
|
||||
import { initLightCode } from '@/module/light-code/index.ts';
|
||||
import { ModuleResolver } from './assistant-app-resolve.ts';
|
||||
import z from 'zod';
|
||||
export class AssistantApp extends Manager {
|
||||
config: AssistantConfig;
|
||||
pagesPath: string;
|
||||
@@ -149,7 +150,9 @@ export class AssistantApp extends Manager {
|
||||
routerProxy.push({
|
||||
type: 'lightcode',
|
||||
lightcode: {
|
||||
check: true,
|
||||
id: 'main',
|
||||
sync: 'remote',
|
||||
rootPath: path.join(this.config.configPath.appsDir, 'light-code', 'code'),
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -162,9 +165,22 @@ export class AssistantApp extends Manager {
|
||||
continue;
|
||||
}
|
||||
if (proxyInfo.type === 'lightcode') {
|
||||
const schema = z.object({
|
||||
rootPath: z.string().describe('light-code 代码存放路径'),
|
||||
sync: z.enum(['remote', 'local', 'both']).describe('同步方式,remote: 仅从远程拉取,local: 仅上传本地代码,both: 双向同步').default('remote'),
|
||||
});
|
||||
const parseRes = schema.safeParse(proxyInfo.lightcode);
|
||||
if (!parseRes.success) {
|
||||
console.warn('lightcode 配置错误', parseRes.error);
|
||||
continue;
|
||||
}
|
||||
const lightcodeConfig = parseRes.data;
|
||||
|
||||
initLightCode({
|
||||
router: this.mainApp,
|
||||
config: this.config
|
||||
config: this.config,
|
||||
sync: lightcodeConfig.sync,
|
||||
rootPath: lightcodeConfig.rootPath,
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -48,10 +48,8 @@ export type ProxyInfo = {
|
||||
},
|
||||
lightcode?: {
|
||||
id?: string;
|
||||
/**
|
||||
* 是否检测远程服务更新
|
||||
*/
|
||||
check?: boolean;
|
||||
sync?: 'remote' | 'local' | 'both';
|
||||
rootPath?: string;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import { App, QueryRouterServer } from '@kevisual/router';
|
||||
import { AssistantInit } from '../../services/init/index.ts';
|
||||
import path from 'node:path';
|
||||
import fs, { write } from 'node:fs';
|
||||
import os from 'node:os';
|
||||
import fs from 'node:fs';
|
||||
import glob from 'fast-glob';
|
||||
import { runCode } from './run.ts';
|
||||
const codeDemoId = '0e700dc8-90dd-41b7-91dd-336ea51de3d2'
|
||||
@@ -35,44 +34,47 @@ const writeCodeDemo = async (appDir: string) => {
|
||||
}
|
||||
// writeCodeDemo(path.join(os.homedir(), 'kevisual', 'assistant-app', 'apps'));
|
||||
|
||||
type opts = {
|
||||
type Opts = {
|
||||
router: QueryRouterServer | App
|
||||
config: AssistantConfig | AssistantInit
|
||||
sync?: boolean
|
||||
sync?: 'remote' | 'local' | 'both'
|
||||
rootPath?: string
|
||||
}
|
||||
type LightCodeFile = {
|
||||
id?: string, code?: string, hash?: string, filepath: string
|
||||
}
|
||||
export const initLightCode = async (opts: opts) => {
|
||||
export const initLightCode = async (opts: Opts) => {
|
||||
// 注册 light-code 路由
|
||||
console.log('初始化 light-code 路由');
|
||||
const config = opts.config as AssistantInit;
|
||||
const app = opts.router;
|
||||
const token = config.getConfig()?.token || '';
|
||||
const query = config.query;
|
||||
const sync = opts.sync ?? true;
|
||||
const sync = opts.sync ?? 'remote';
|
||||
if (!config || !app) {
|
||||
console.error('initLightCode 缺少必要参数, config 或 app');
|
||||
return;
|
||||
}
|
||||
const appDir = config.configPath.appsDir;
|
||||
const lightcodeDir = path.join(appDir, 'light-code', 'code');
|
||||
const lightcodeDir = opts.rootPath;
|
||||
if (!fs.existsSync(lightcodeDir)) {
|
||||
fs.mkdirSync(lightcodeDir, { recursive: true });
|
||||
}
|
||||
let diffList: LightCodeFile[] = [];
|
||||
|
||||
const codeFiles = glob.sync(['**/*.ts', '**/*.js'], {
|
||||
cwd: lightcodeDir,
|
||||
const findGlob = (opts: { cwd: string }) => {
|
||||
return glob.sync(['**/*.ts', '**/*.js'], {
|
||||
cwd: opts.cwd,
|
||||
onlyFiles: true,
|
||||
}).map(file => {
|
||||
return {
|
||||
filepath: path.join(lightcodeDir, file),
|
||||
filepath: path.join(opts.cwd, file),
|
||||
// hash: getHash(path.join(lightcodeDir, file))
|
||||
}
|
||||
});
|
||||
}
|
||||
const codeFiles = findGlob({ cwd: lightcodeDir });
|
||||
|
||||
if (sync) {
|
||||
if (sync === 'remote' || sync === 'both') {
|
||||
const queryRes = await query.post({
|
||||
path: 'light-code',
|
||||
key: 'list',
|
||||
@@ -100,13 +102,6 @@ export const initLightCode = async (opts: opts) => {
|
||||
fs.writeFileSync(item.filepath, item.code, 'utf-8');
|
||||
// console.log(`新增 light-code 文件: ${item.filepath}`);
|
||||
}
|
||||
|
||||
// 执行删除
|
||||
for (const filepath of toDelete) {
|
||||
fs.unlinkSync(filepath.filepath);
|
||||
// console.log(`删除 light-code 文件: ${filepath.filepath}`);
|
||||
}
|
||||
|
||||
// 执行更新
|
||||
for (const item of toUpdate) {
|
||||
fs.writeFileSync(item.filepath, item.code, 'utf-8');
|
||||
@@ -117,23 +112,38 @@ export const initLightCode = async (opts: opts) => {
|
||||
// filepath: d.filepath,
|
||||
// hash: d.hash
|
||||
// }));
|
||||
|
||||
if (sync === 'remote') {
|
||||
// 执行删除
|
||||
for (const filepath of toDelete) {
|
||||
// console.log(`删除 light-code 文件: ${filepath.filepath}`);
|
||||
const parentDir = path.dirname(filepath.filepath);
|
||||
// console.log('parentDir', parentDir, lightcodeDir);
|
||||
if (parentDir === lightcodeDir) {
|
||||
fs.unlinkSync(filepath.filepath);
|
||||
}
|
||||
}
|
||||
}
|
||||
diffList = findGlob({ cwd: lightcodeDir });
|
||||
} else {
|
||||
console.error('light-code 同步失败', queryRes.message);
|
||||
diffList = codeFiles;
|
||||
}
|
||||
} else {
|
||||
} else if (sync === 'local') {
|
||||
diffList = codeFiles;
|
||||
}
|
||||
|
||||
|
||||
for (const file of diffList) {
|
||||
const tsPath = file.filepath;
|
||||
const runRes = await runCode(tsPath, { path: 'router', key: 'list' }, { timeout: 10000 });
|
||||
const runRes = await runCode(tsPath, { message: { path: 'router', key: 'list' } }, { timeout: 10000 });
|
||||
// console.log('light-code 运行结果', file.filepath, runRes);
|
||||
if (runRes.success) {
|
||||
const res = runRes.data;
|
||||
if (res.code === 200) {
|
||||
const list = res.data?.list || [];
|
||||
for (const routerItem of list) {
|
||||
// console.log('注册 light-code 路由项:', routerItem.id, routerItem.path);
|
||||
if (routerItem.path?.includes('auth') || routerItem.path?.includes('router') || routerItem.path?.includes('call')) {
|
||||
continue;
|
||||
}
|
||||
@@ -144,6 +154,10 @@ export const initLightCode = async (opts: opts) => {
|
||||
} else {
|
||||
metadata.tags = ['light-code'];
|
||||
}
|
||||
metadata.source = 'light-code';
|
||||
metadata['light-code'] = {
|
||||
id: file.id
|
||||
}
|
||||
app.route({
|
||||
id: routerItem.id,
|
||||
path: `${routerItem.id}__${routerItem.path}`,
|
||||
@@ -153,8 +167,13 @@ export const initLightCode = async (opts: opts) => {
|
||||
middleware: ['auth'],
|
||||
}).define(async (ctx) => {
|
||||
const tokenUser = ctx.state?.tokenUser || {};
|
||||
const query = { ...ctx.query, tokenUser }
|
||||
const runRes2 = await runCode(tsPath, query, { timeout: 30000 });
|
||||
const query = { ...ctx.query }
|
||||
const runRes2 = await runCode(tsPath, {
|
||||
message: query,
|
||||
context: {
|
||||
state: { tokenUser, user: tokenUser },
|
||||
}
|
||||
}, { timeout: 30000 });
|
||||
if (runRes2.success) {
|
||||
const res2 = runRes2.data;
|
||||
if (res2.code === 200) {
|
||||
@@ -166,11 +185,9 @@ export const initLightCode = async (opts: opts) => {
|
||||
ctx.throw(runRes2.error || 'Lightcode 路由执行失败');
|
||||
}
|
||||
}).addTo(app, {
|
||||
override: false,
|
||||
// @ts-ignore
|
||||
overwrite: false
|
||||
});// 不允许覆盖已存在的路由
|
||||
|
||||
// console.log(`light-code 路由注册成功: [${routerItem.path}] ${routerItem.id} 来自文件: ${file.filepath}`);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -179,3 +196,18 @@ export const initLightCode = async (opts: opts) => {
|
||||
}
|
||||
console.log(`light-code 路由注册成功`, `注册${diffList.length}个路由`);
|
||||
}
|
||||
|
||||
export const clearLightCodeRoutes = (opts: Pick<Opts, 'router'>) => {
|
||||
const app = opts.router;
|
||||
if (!app) {
|
||||
console.error('clearLightCodeRoutes 缺少必要参数, app');
|
||||
return;
|
||||
}
|
||||
const routes = app.getList();
|
||||
for (const route of routes) {
|
||||
if (route.metadata?.source === 'light-code') {
|
||||
// console.log(`删除 light-code 路由: ${route.path} ${route.id}`);
|
||||
app.removeById(route.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import { fork } from 'node:child_process'
|
||||
import fs from 'fs';
|
||||
|
||||
import fs from 'node:fs';
|
||||
import { ListenProcessParams, ListenProcessResponse } from '@kevisual/router';
|
||||
export const fileExists = (path: string): boolean => {
|
||||
try {
|
||||
fs.accessSync(path, fs.constants.F_OK);
|
||||
@@ -10,30 +10,12 @@ export const fileExists = (path: string): boolean => {
|
||||
}
|
||||
}
|
||||
|
||||
export type RunCodeParams = {
|
||||
path?: string;
|
||||
key?: string;
|
||||
payload?: string;
|
||||
[key: string]: any
|
||||
}
|
||||
export type RunCodeParams = ListenProcessParams
|
||||
type RunCodeOptions = {
|
||||
timeout?: number; // 超时时间,单位毫秒
|
||||
[key: string]: any
|
||||
}
|
||||
type RunCode = {
|
||||
// 调用进程的功能
|
||||
success?: boolean
|
||||
data?: {
|
||||
// 调用router的结果
|
||||
code?: number
|
||||
data?: any
|
||||
message?: string
|
||||
[key: string]: any
|
||||
};
|
||||
error?: any
|
||||
timestamp?: string
|
||||
output?: string
|
||||
}
|
||||
type RunCode = ListenProcessResponse & { output?: string }
|
||||
export const runCode = async (tsPath: string, params: RunCodeParams = {}, opts?: RunCodeOptions): Promise<RunCode> => {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (fileExists(tsPath) === false) {
|
||||
@@ -81,7 +63,7 @@ export const runCode = async (tsPath: string, params: RunCodeParams = {}, opts?:
|
||||
silent: true, // 启用 stdio 重定向
|
||||
env: {
|
||||
...process.env,
|
||||
BUN_CHILD_PROCESS: 'true' // 标记为子进程
|
||||
KEVISUAL_CHILD_PROCESS: 'true' // 标记为子进程
|
||||
}
|
||||
})
|
||||
// 监听来自子进程的消息
|
||||
@@ -150,6 +132,7 @@ export const runCode = async (tsPath: string, params: RunCodeParams = {}, opts?:
|
||||
// 向子进程发送消息
|
||||
|
||||
} catch (error) {
|
||||
console.error('启动子进程失败:', error)
|
||||
resolveOnce({
|
||||
success: false,
|
||||
error: `启动子进程失败: ${error instanceof Error ? error.message : '未知错误'}`
|
||||
|
||||
@@ -1,17 +1,21 @@
|
||||
import { WSSManager } from './wss.ts';
|
||||
import { App, Route } from '@kevisual/router'
|
||||
import { WebSocketReq } from '@kevisual/router'
|
||||
import { WebSocketReq, ListenProcessParams } from '@kevisual/router'
|
||||
import { EventEmitter } from 'eventemitter3';
|
||||
import { customAlphabet } from 'nanoid';
|
||||
|
||||
const letter = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||
const customId = customAlphabet(letter, 16);
|
||||
/**
|
||||
* 实时注册的代码模块
|
||||
*
|
||||
* 别人通过 WebSocket 连接到此模块,发送路由列表和请求数据
|
||||
*/
|
||||
export class LiveCode {
|
||||
wssManager: WSSManager;
|
||||
app: App;
|
||||
emitter: EventEmitter;
|
||||
constructor(app: App) {
|
||||
this.wssManager = new WSSManager({ heartbeatInterval: 5000 });
|
||||
this.wssManager = new WSSManager({ heartbeatInterval: 6 * 5000 });
|
||||
this.app = app;
|
||||
this.emitter = new EventEmitter();
|
||||
console.log('[LiveCode] 模块已初始化');
|
||||
@@ -46,9 +50,9 @@ export class LiveCode {
|
||||
return this.wssManager.getConnection(id)
|
||||
}
|
||||
async init(id: string): Promise<{ code: number, message?: string, data?: any }> {
|
||||
return this.sendData({ path: 'router', key: 'list', }, id);
|
||||
return this.sendData({ message: { path: 'router', key: 'list', } }, id);
|
||||
}
|
||||
sendData(data: any, id: string): Promise<{ code: number, message?: string, data?: any }> {
|
||||
sendData(data: ListenProcessParams, id: string): Promise<{ code: number, message?: string, data?: any }> {
|
||||
const reqId = customId()
|
||||
const wss = this.getWss(id);
|
||||
if (!wss) {
|
||||
@@ -102,6 +106,7 @@ export class LiveCode {
|
||||
description: route.description,
|
||||
metadata: {
|
||||
...route.metadata,
|
||||
source: 'livecode',
|
||||
liveCodeId: wid
|
||||
},
|
||||
middleware: ['auth'],
|
||||
@@ -109,9 +114,15 @@ export class LiveCode {
|
||||
const { token, cookie, ...rest } = ctx.query;
|
||||
const tokenUser = ctx.state.tokernUser;
|
||||
const res = await this.sendData({
|
||||
message: {
|
||||
id: route.id,
|
||||
tokenUser,
|
||||
payload: rest,
|
||||
},
|
||||
context: {
|
||||
state: {
|
||||
tokenUser
|
||||
}
|
||||
}
|
||||
}, wid);
|
||||
// console.log('路由响应数据:', res);
|
||||
ctx.forward(res)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { nanoid } from "nanoid";
|
||||
import { WebSocketReq } from '@kevisual/router'
|
||||
import { logger } from "../logger.ts";
|
||||
type ConnectionInfo = {
|
||||
id: string;
|
||||
wsReq: WebSocketReq;
|
||||
@@ -59,7 +60,7 @@ export class WSSManager {
|
||||
const ws = connection.wsReq.ws;
|
||||
ws.send(JSON.stringify({ type: 'heartbeat', timestamp: new Date().toISOString() }));
|
||||
connection.lastHeartbeat = new Date();
|
||||
console.log(`[LiveCode] 发送心跳给连接 ${connection.id}`);
|
||||
logger.debug(`[LiveCode] 发送心跳给连接 ${connection.id}`);
|
||||
}, this.heartbeatInterval);
|
||||
}
|
||||
|
||||
|
||||
@@ -29,4 +29,6 @@ app.route({
|
||||
...ctx
|
||||
});
|
||||
ctx.forward(res);
|
||||
}).addTo(app)
|
||||
}).addTo(app, {
|
||||
overwrite: false
|
||||
})
|
||||
@@ -1,84 +1,2 @@
|
||||
|
||||
import { app, assistantConfig } from '../../app.ts';
|
||||
import { createSkill } from '@kevisual/router';
|
||||
import os from 'node:os';
|
||||
import { runCommand } from '@/services/app/index.ts';
|
||||
app
|
||||
.route({
|
||||
path: 'client',
|
||||
key: 'version',
|
||||
description: '获取客户端版本号',
|
||||
})
|
||||
.define(async (ctx) => {
|
||||
ctx.body = 'v1.0.0';
|
||||
})
|
||||
.addTo(app);
|
||||
|
||||
app
|
||||
.route({
|
||||
path: 'client',
|
||||
key: 'time',
|
||||
description: '获取当前时间',
|
||||
})
|
||||
.define(async (ctx) => {
|
||||
ctx.body = {
|
||||
time: new Date().getTime(),
|
||||
date: new Date().toLocaleDateString(),
|
||||
};
|
||||
})
|
||||
.addTo(app);
|
||||
|
||||
// 调用 path: client key: system
|
||||
app
|
||||
.route({
|
||||
path: 'client',
|
||||
key: 'system',
|
||||
description: '获取系统信息',
|
||||
metadata: {
|
||||
tags: ['opencode'],
|
||||
...createSkill({
|
||||
skill: 'view-system-info',
|
||||
title: '查看系统信息',
|
||||
summary: '获取服务器操作系统平台、架构和版本信息',
|
||||
})
|
||||
}
|
||||
})
|
||||
.define(async (ctx) => {
|
||||
const { platform, arch, release } = os;
|
||||
ctx.body = {
|
||||
platform: platform(),
|
||||
arch: arch(),
|
||||
release: release(),
|
||||
};
|
||||
})
|
||||
.addTo(app);
|
||||
|
||||
|
||||
app.route({
|
||||
path: 'client',
|
||||
key: 'restart',
|
||||
description: '重启客户端',
|
||||
middleware: ['admin-auth'],
|
||||
metadata: {
|
||||
tags: ['opencode'],
|
||||
...createSkill({
|
||||
skill: 'restart-client',
|
||||
title: '重启客户端',
|
||||
summary: '重启当前运行的客户端应用程序',
|
||||
})
|
||||
}
|
||||
}).define(async (ctx) => {
|
||||
const cmd = 'pm2 restart assistant-server --update-env';
|
||||
try {
|
||||
runCommand(cmd, []);
|
||||
ctx.body = {
|
||||
message: '客户端重启命令已执行',
|
||||
};
|
||||
} catch (error) {
|
||||
ctx.status = 500;
|
||||
ctx.body = {
|
||||
message: '重启客户端失败',
|
||||
error: error.message,
|
||||
};
|
||||
}
|
||||
}).addTo(app);
|
||||
import './ip.ts';
|
||||
import './system.ts'
|
||||
72
assistant/src/routes/client/ip.ts
Normal file
72
assistant/src/routes/client/ip.ts
Normal file
@@ -0,0 +1,72 @@
|
||||
|
||||
import { app } from '../../app.ts';
|
||||
import { createSkill } from '@kevisual/router';
|
||||
import os from 'node:os';
|
||||
|
||||
const baseURLv4 = 'https://4.ipw.cn/';
|
||||
const baseURLv6 = 'https://6.ipw.cn/';
|
||||
|
||||
export const isIpv6 = (ip: string): boolean => {
|
||||
return ip.includes(':');
|
||||
}
|
||||
|
||||
export const isIpv4 = (ip: string): boolean => {
|
||||
return ip.split('.').length === 4;
|
||||
}
|
||||
export const fetchIP = async (url: string): Promise<string> => {
|
||||
const response = await fetch(url);
|
||||
if (!response.ok) {
|
||||
throw new Error(`Failed to fetch IP from ${url}: ${response.statusText}`);
|
||||
}
|
||||
const ip = (await response.text()).trim();
|
||||
return ip;
|
||||
}
|
||||
|
||||
app.route({
|
||||
path: 'client',
|
||||
key: 'ip',
|
||||
description: '获取客户端 IP 地址',
|
||||
metadata: {
|
||||
tags: ['opencode'],
|
||||
...createSkill({
|
||||
skill: 'view-client-ip',
|
||||
title: '查看客户端 IP 地址',
|
||||
summary: '获取当前客户端的 IP 地址信息',
|
||||
})
|
||||
}
|
||||
})
|
||||
.define(async (ctx) => {
|
||||
const networkInterfaces = os.networkInterfaces();
|
||||
const ipAddresses: { type: string, address: string }[] = [];
|
||||
for (const interfaceDetails of Object.values(networkInterfaces)) {
|
||||
if (interfaceDetails) {
|
||||
for (const detail of interfaceDetails) {
|
||||
if (detail.family === 'IPv4' && !detail.internal) {
|
||||
ipAddresses.push({
|
||||
type: 'IPv4-local',
|
||||
address: detail.address,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
const res = await fetchIP(baseURLv6);
|
||||
if (isIpv6(res)) {
|
||||
ipAddresses.push({
|
||||
type: 'IPv6',
|
||||
address: res,
|
||||
});
|
||||
}
|
||||
const res4 = await fetchIP(baseURLv4);
|
||||
if (isIpv4(res4)) {
|
||||
ipAddresses.push({
|
||||
type: 'IPv4',
|
||||
address: res4,
|
||||
});
|
||||
}
|
||||
|
||||
ctx.body = {
|
||||
ipAddresses,
|
||||
};
|
||||
})
|
||||
.addTo(app);
|
||||
85
assistant/src/routes/client/system.ts
Normal file
85
assistant/src/routes/client/system.ts
Normal file
@@ -0,0 +1,85 @@
|
||||
|
||||
import { app, assistantConfig } from '../../app.ts';
|
||||
import { createSkill } from '@kevisual/router';
|
||||
import os from 'node:os';
|
||||
import { runCommand } from '@/services/app/index.ts';
|
||||
|
||||
app
|
||||
.route({
|
||||
path: 'client',
|
||||
key: 'version',
|
||||
description: '获取客户端版本号',
|
||||
})
|
||||
.define(async (ctx) => {
|
||||
ctx.body = 'v1.0.0';
|
||||
})
|
||||
.addTo(app);
|
||||
|
||||
app
|
||||
.route({
|
||||
path: 'client',
|
||||
key: 'time',
|
||||
description: '获取当前时间',
|
||||
})
|
||||
.define(async (ctx) => {
|
||||
ctx.body = {
|
||||
time: new Date().getTime(),
|
||||
date: new Date().toLocaleDateString(),
|
||||
};
|
||||
})
|
||||
.addTo(app);
|
||||
|
||||
// 调用 path: client key: system
|
||||
app
|
||||
.route({
|
||||
path: 'client',
|
||||
key: 'system',
|
||||
description: '获取系统信息',
|
||||
metadata: {
|
||||
tags: ['opencode'],
|
||||
...createSkill({
|
||||
skill: 'view-system-info',
|
||||
title: '查看系统信息',
|
||||
summary: '获取服务器操作系统平台、架构和版本信息',
|
||||
})
|
||||
}
|
||||
})
|
||||
.define(async (ctx) => {
|
||||
const { platform, arch, release } = os;
|
||||
ctx.body = {
|
||||
platform: platform(),
|
||||
arch: arch(),
|
||||
release: release(),
|
||||
};
|
||||
})
|
||||
.addTo(app);
|
||||
|
||||
|
||||
app.route({
|
||||
path: 'client',
|
||||
key: 'restart',
|
||||
description: '重启客户端',
|
||||
middleware: ['admin-auth'],
|
||||
metadata: {
|
||||
tags: ['opencode'],
|
||||
...createSkill({
|
||||
skill: 'restart-client',
|
||||
title: '重启客户端',
|
||||
summary: '重启当前运行的客户端应用程序',
|
||||
})
|
||||
}
|
||||
}).define(async (ctx) => {
|
||||
const cmd = 'pm2 restart assistant-server --update-env';
|
||||
try {
|
||||
runCommand(cmd, []);
|
||||
ctx.body = {
|
||||
message: '客户端重启命令已执行',
|
||||
};
|
||||
} catch (error) {
|
||||
ctx.status = 500;
|
||||
ctx.body = {
|
||||
message: '重启客户端失败',
|
||||
error: error.message,
|
||||
};
|
||||
}
|
||||
}).addTo(app);
|
||||
@@ -1,5 +1,6 @@
|
||||
import { app, assistantConfig } from '../app.ts';
|
||||
import './config/index.ts';
|
||||
import './client/index.ts';
|
||||
import './shop-install/index.ts';
|
||||
import './ai/index.ts';
|
||||
import './user/index.ts';
|
||||
@@ -7,7 +8,7 @@ import './call/index.ts'
|
||||
|
||||
import './opencode/index.ts';
|
||||
import './remote/index.ts';
|
||||
import './kevisual/index.ts'
|
||||
// import './kevisual/index.ts'
|
||||
|
||||
import { authCache } from '@/module/cache/auth.ts';
|
||||
|
||||
|
||||
0
assistant/src/routes/light-code/index.ts
Normal file
0
assistant/src/routes/light-code/index.ts
Normal file
5
assistant/src/routes/light-code/reload.ts
Normal file
5
assistant/src/routes/light-code/reload.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
// TODO: 重载 light-code
|
||||
import { initLightCode } from "@/module/light-code/index.ts";
|
||||
|
||||
// 下载最新代码,覆盖本地文件
|
||||
// 重新启动 light-code 相关服务
|
||||
2
assistant/src/routes/manager/index.ts
Normal file
2
assistant/src/routes/manager/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
import { AssistantApp } from '../../module/assistant/local-app-manager/assistant-app.ts';
|
||||
// AssistantApp
|
||||
@@ -1,9 +1,6 @@
|
||||
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";
|
||||
|
||||
const DEFAULT_PORT = 5000;
|
||||
|
||||
@@ -12,15 +12,15 @@
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@aws-sdk/client-s3": "^3.978.0",
|
||||
"@kevisual/oss": "^0.0.16",
|
||||
"@kevisual/query": "^0.0.38",
|
||||
"@aws-sdk/client-s3": "^3.981.0",
|
||||
"@kevisual/oss": "^0.0.19",
|
||||
"@kevisual/query": "^0.0.39",
|
||||
"eventemitter3": "^5.0.4",
|
||||
"@kevisual/router": "^0.0.64",
|
||||
"@kevisual/use-config": "^1.0.28",
|
||||
"@kevisual/router": "^0.0.70",
|
||||
"@kevisual/use-config": "^1.0.30",
|
||||
"ioredis": "^5.9.2",
|
||||
"minio": "^8.0.6",
|
||||
"pg": "^8.17.2",
|
||||
"pg": "^8.18.0",
|
||||
"pm2": "^6.0.14",
|
||||
"sequelize": "^6.37.7",
|
||||
"crypto-js": "^4.2.0",
|
||||
@@ -35,6 +35,6 @@
|
||||
"@kevisual/types": "^0.0.12",
|
||||
"@types/bun": "^1.3.8",
|
||||
"@types/crypto-js": "^4.2.2",
|
||||
"@types/node": "^25.1.0"
|
||||
"@types/node": "^25.2.0"
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
import { App } from '@kevisual/router'
|
||||
import { App, ListenProcessResponse } from '@kevisual/router'
|
||||
import { WebSocket } from 'ws'
|
||||
import { ReconnectingWebSocket, handleCallApp } from '@kevisual/router/ws'
|
||||
import net from 'net';
|
||||
@@ -23,7 +23,7 @@ app.createRouteList();
|
||||
await new Promise((resolve) => setTimeout(resolve, 1000));
|
||||
|
||||
// 创建支持断开重连的 WebSocket 客户端
|
||||
const ws = new ReconnectingWebSocket('ws://localhost:51516/livecode/ws?id=test-live-app', {
|
||||
const ws = new ReconnectingWebSocket('ws://localhost:51515/livecode/ws?id=test-live-app', {
|
||||
maxRetries: Infinity, // 无限重试
|
||||
retryDelay: 1000, // 初始重试延迟 1 秒
|
||||
maxDelay: 30000, // 最大延迟 30 秒
|
||||
@@ -33,7 +33,7 @@ ws.onMessage(async (message) => {
|
||||
console.log('收到消息:', message);
|
||||
if (message.type === 'router' && message.id) {
|
||||
console.log('收到路由响应:', message);
|
||||
const data = message?.data;
|
||||
const data = message?.data as ListenProcessResponse;
|
||||
if (!data) {
|
||||
ws.send({
|
||||
type: 'router',
|
||||
@@ -42,7 +42,17 @@ ws.onMessage(async (message) => {
|
||||
});
|
||||
return;
|
||||
}
|
||||
const res = await app.run(message.data);
|
||||
const msg = data.message;
|
||||
if (!msg) {
|
||||
ws.send({
|
||||
type: 'router',
|
||||
id: message.id,
|
||||
data: { code: 500, message: 'No {message} received' }
|
||||
});
|
||||
return;
|
||||
}
|
||||
const context = data.context || {};
|
||||
const res = await app.run(msg, context);
|
||||
console.log('路由处理结果:', res);
|
||||
ws.send({
|
||||
type: 'router',
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@kevisual/cli",
|
||||
"version": "0.1.0",
|
||||
"version": "0.1.1",
|
||||
"description": "envision 命令行工具",
|
||||
"type": "module",
|
||||
"basename": "/root/cli",
|
||||
@@ -49,7 +49,7 @@
|
||||
"@kevisual/auth": "^2.0.3",
|
||||
"@kevisual/context": "^0.0.4",
|
||||
"@kevisual/use-config": "^1.0.30",
|
||||
"@opencode-ai/sdk": "^1.1.48",
|
||||
"@opencode-ai/sdk": "^1.1.49",
|
||||
"@types/busboy": "^1.5.4",
|
||||
"busboy": "^1.6.0",
|
||||
"eventemitter3": "^5.0.4",
|
||||
@@ -62,7 +62,7 @@
|
||||
"unstorage": "^1.17.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@kevisual/api": "^0.0.42",
|
||||
"@kevisual/api": "^0.0.44",
|
||||
"@kevisual/dts": "^0.0.3",
|
||||
"@kevisual/load": "^0.0.6",
|
||||
"@kevisual/logger": "^0.0.4",
|
||||
|
||||
125
pnpm-lock.yaml
generated
125
pnpm-lock.yaml
generated
@@ -24,8 +24,8 @@ importers:
|
||||
specifier: ^1.0.30
|
||||
version: 1.0.30(dotenv@17.2.3)
|
||||
'@opencode-ai/sdk':
|
||||
specifier: ^1.1.48
|
||||
version: 1.1.48
|
||||
specifier: ^1.1.49
|
||||
version: 1.1.49
|
||||
'@types/busboy':
|
||||
specifier: ^1.5.4
|
||||
version: 1.5.4
|
||||
@@ -58,8 +58,8 @@ importers:
|
||||
version: 1.17.4(idb-keyval@6.2.2)
|
||||
devDependencies:
|
||||
'@kevisual/api':
|
||||
specifier: ^0.0.42
|
||||
version: 0.0.42
|
||||
specifier: ^0.0.44
|
||||
version: 0.0.44
|
||||
'@kevisual/dts':
|
||||
specifier: ^0.0.3
|
||||
version: 0.0.3(typescript@5.8.2)
|
||||
@@ -127,8 +127,8 @@ importers:
|
||||
assistant:
|
||||
dependencies:
|
||||
'@aws-sdk/client-s3':
|
||||
specifier: ^3.980.0
|
||||
version: 3.980.0
|
||||
specifier: ^3.981.0
|
||||
version: 3.981.0
|
||||
'@kevisual/js-filter':
|
||||
specifier: ^0.0.5
|
||||
version: 0.0.5
|
||||
@@ -139,8 +139,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.48
|
||||
version: 1.1.48
|
||||
specifier: ^1.1.49
|
||||
version: 1.1.49
|
||||
es-toolkit:
|
||||
specifier: ^1.44.0
|
||||
version: 1.44.0
|
||||
@@ -170,8 +170,8 @@ importers:
|
||||
specifier: ^0.0.24
|
||||
version: 0.0.24
|
||||
'@kevisual/api':
|
||||
specifier: ^0.0.42
|
||||
version: 0.0.42
|
||||
specifier: ^0.0.44
|
||||
version: 0.0.44
|
||||
'@kevisual/load':
|
||||
specifier: ^0.0.6
|
||||
version: 0.0.6
|
||||
@@ -188,8 +188,8 @@ importers:
|
||||
specifier: 0.0.7
|
||||
version: 0.0.7(@kevisual/query@0.0.39)
|
||||
'@kevisual/router':
|
||||
specifier: ^0.0.67
|
||||
version: 0.0.67
|
||||
specifier: ^0.0.70
|
||||
version: 0.0.70
|
||||
'@kevisual/types':
|
||||
specifier: ^0.0.12
|
||||
version: 0.0.12
|
||||
@@ -197,8 +197,8 @@ importers:
|
||||
specifier: ^1.0.30
|
||||
version: 1.0.30(dotenv@17.2.3)
|
||||
'@opencode-ai/plugin':
|
||||
specifier: ^1.1.48
|
||||
version: 1.1.48
|
||||
specifier: ^1.1.49
|
||||
version: 1.1.49
|
||||
'@types/bun':
|
||||
specifier: ^1.3.8
|
||||
version: 1.3.8
|
||||
@@ -465,8 +465,8 @@ packages:
|
||||
'@aws-crypto/util@5.2.0':
|
||||
resolution: {integrity: sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==}
|
||||
|
||||
'@aws-sdk/client-s3@3.980.0':
|
||||
resolution: {integrity: sha512-ch8QqKehyn1WOYbd8LyDbWjv84Z9OEj9qUxz8q3IOCU3ftAVkVR0wAuN96a1xCHnpOJcQZo3rOB08RlyKdkGxQ==}
|
||||
'@aws-sdk/client-s3@3.981.0':
|
||||
resolution: {integrity: sha512-zX3Xqm7V30J1D2II7WBL23SyqIIMD0wMzpiE+VosBxH6fAeXgrjIwSudCypNgnE1EK9OZoZMT3mJtkbUqUDdaA==}
|
||||
engines: {node: '>=20.0.0'}
|
||||
|
||||
'@aws-sdk/client-sso@3.980.0':
|
||||
@@ -561,8 +561,8 @@ packages:
|
||||
resolution: {integrity: sha512-v4J8qYAWfOMcZ4MJUyatntOicTzEMaU7j3OpkRCGGFSL2NgXQ5VbxauIyORA+pxdKZ0qQG2tCQjQjZDlXEC3Ow==}
|
||||
engines: {node: '>=20.0.0'}
|
||||
|
||||
'@aws-sdk/signature-v4-multi-region@3.980.0':
|
||||
resolution: {integrity: sha512-tO2jBj+ZIVM0nEgi1SyxWtaYGpuAJdsrugmWcI3/U2MPWCYsrvKasUo0026NvJJao38wyUq9B8XTG8Xu53j/VA==}
|
||||
'@aws-sdk/signature-v4-multi-region@3.981.0':
|
||||
resolution: {integrity: sha512-T/+h9df0DALAXXP+YfZ8bgmH6cEN7HAg6BqHe3t38GhHgQ1HULXwK5XMhiLWiHpytDdhLqiVH41SRgW8ynBl6Q==}
|
||||
engines: {node: '>=20.0.0'}
|
||||
|
||||
'@aws-sdk/token-providers@3.980.0':
|
||||
@@ -581,6 +581,10 @@ packages:
|
||||
resolution: {integrity: sha512-AjKBNEc+rjOZQE1HwcD9aCELqg1GmUj1rtICKuY8cgwB73xJ4U/kNyqKKpN2k9emGqlfDY2D8itIp/vDc6OKpw==}
|
||||
engines: {node: '>=20.0.0'}
|
||||
|
||||
'@aws-sdk/util-endpoints@3.981.0':
|
||||
resolution: {integrity: sha512-a8nXh/H3/4j+sxhZk+N3acSDlgwTVSZbX9i55dx41gI1H+geuonuRG+Shv3GZsCb46vzc08RK2qC78ypO8uRlg==}
|
||||
engines: {node: '>=20.0.0'}
|
||||
|
||||
'@aws-sdk/util-locate-window@3.965.2':
|
||||
resolution: {integrity: sha512-qKgO7wAYsXzhwCHhdbaKFyxd83Fgs8/1Ka+jjSPrv2Ll7mB55Wbwlo0kkfMLh993/yEc8aoDIAc1Fz9h4Spi4Q==}
|
||||
engines: {node: '>=20.0.0'}
|
||||
@@ -1011,105 +1015,89 @@ packages:
|
||||
resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-libvips-linux-arm@1.2.4':
|
||||
resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-libvips-linux-ppc64@1.2.4':
|
||||
resolution: {integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-libvips-linux-riscv64@1.2.4':
|
||||
resolution: {integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-libvips-linux-s390x@1.2.4':
|
||||
resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-libvips-linux-x64@1.2.4':
|
||||
resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-libvips-linuxmusl-arm64@1.2.4':
|
||||
resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@img/sharp-libvips-linuxmusl-x64@1.2.4':
|
||||
resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@img/sharp-linux-arm64@0.34.5':
|
||||
resolution: {integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-linux-arm@0.34.5':
|
||||
resolution: {integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-linux-ppc64@0.34.5':
|
||||
resolution: {integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-linux-riscv64@0.34.5':
|
||||
resolution: {integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-linux-s390x@0.34.5':
|
||||
resolution: {integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-linux-x64@0.34.5':
|
||||
resolution: {integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-linuxmusl-arm64@0.34.5':
|
||||
resolution: {integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@img/sharp-linuxmusl-x64@0.34.5':
|
||||
resolution: {integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@img/sharp-wasm32@0.34.5':
|
||||
resolution: {integrity: sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==}
|
||||
@@ -1300,8 +1288,8 @@ packages:
|
||||
'@kevisual/api@0.0.28':
|
||||
resolution: {integrity: sha512-WQluRlu2qGM1qktIhPLODie8x382a6jEMfFOcay/rnkCgXK0BRpnqOKwlX7IMLdMqka7GY/BD69kSMnK1Exf5g==}
|
||||
|
||||
'@kevisual/api@0.0.42':
|
||||
resolution: {integrity: sha512-Bn5G+ZzGEPoJdvd5U3xWHGY0oidQj23gt1YAWvTqjm0frDJfJ4Q2WT9Xjb1ZdJ/YBcfaNe9yEoMCpFNdUls/mw==}
|
||||
'@kevisual/api@0.0.44':
|
||||
resolution: {integrity: sha512-KA2b17pxW1pTPWa4zsTSRTiGTmwdkIesV1ig51MyISUllita5VPqZ6UYYDJQTHuPzYcIkuodQ9iWTEZNM9AkFw==}
|
||||
|
||||
'@kevisual/app@0.0.1':
|
||||
resolution: {integrity: sha512-PEx8P3l0iNSqrz9Ib9kVCYfqNMX6/LfNu+cEafmY6ECP1cV5Vmv+TH2fuasMosKjtbH2fAdDi97sbd29tdEK+g==}
|
||||
@@ -1372,8 +1360,8 @@ packages:
|
||||
'@kevisual/router@0.0.51':
|
||||
resolution: {integrity: sha512-i9qYBeS/um78oC912oWJD3iElB+5NTKyTrz1Hzf4DckiUFnjLL81UPwjIh5I2l9+ul0IZ/Pxx+sFSF99fJkzKg==}
|
||||
|
||||
'@kevisual/router@0.0.67':
|
||||
resolution: {integrity: sha512-SKQDc9RUSUqpcVA4Y05rl525zmHcyl4JlHdFyBhatNRMBQdKCVd8rBAojnyz4gNmUU9bY+gxM87f30dHsQkRAw==}
|
||||
'@kevisual/router@0.0.70':
|
||||
resolution: {integrity: sha512-vXlIj9jRufhcIfeuPWemjSI+dxdzSmIBq5eRxQzqEfAJ7k+mBPhoI4KxH8vHnwyL30bqm8EdODL/p6Wg8uBw3g==}
|
||||
|
||||
'@kevisual/types@0.0.12':
|
||||
resolution: {integrity: sha512-zJXH2dosir3jVrQ6QG4i0+iLQeT9gJ3H+cKXs8ReWboxBSYzUZO78XssVeVrFPsJ33iaAqo4q3DWbSS1dWGn7Q==}
|
||||
@@ -1439,11 +1427,11 @@ packages:
|
||||
resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
|
||||
engines: {node: '>= 8'}
|
||||
|
||||
'@opencode-ai/plugin@1.1.48':
|
||||
resolution: {integrity: sha512-KkaSMevXmz7tOwYDMJeWiXE5N8LmRP18qWI5Xhv3+c+FdGPL+l1hQrjSgyv3k7Co7qpCyW3kAUESBB7BzIOl2w==}
|
||||
'@opencode-ai/plugin@1.1.49':
|
||||
resolution: {integrity: sha512-+FEE730fLJtoHCta5MXixOIzI9Cjos700QDNnAx6mA8YjFzO+kABnyqLQrCgZ9wUPJgiKH9bnHxT7AdRjWsNPw==}
|
||||
|
||||
'@opencode-ai/sdk@1.1.48':
|
||||
resolution: {integrity: sha512-j5/79X45fUPWVD2Ffm/qvwLclDCdPeV+TYMDrm9to0p4pmzhmeKevCsyiRdLg0o0HE3AFRUnOo2rdO9NetN79A==}
|
||||
'@opencode-ai/sdk@1.1.49':
|
||||
resolution: {integrity: sha512-F5ZkgiqOiV+z3U4zeBLvrmNZv5MwNFMTWM+HWhChD+/UEswIebQKk9UMz9lPX4fswexIJdFPwFI/TBdNyZfKMg==}
|
||||
|
||||
'@oslojs/encoding@1.1.0':
|
||||
resolution: {integrity: sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ==}
|
||||
@@ -1894,67 +1882,56 @@ packages:
|
||||
resolution: {integrity: sha512-gTJ/JnnjCMc15uwB10TTATBEhK9meBIY+gXP4s0sHD1zHOaIh4Dmy1X9wup18IiY9tTNk5gJc4yx9ctj/fjrIw==}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-arm-musleabihf@4.43.0':
|
||||
resolution: {integrity: sha512-ZJ3gZynL1LDSIvRfz0qXtTNs56n5DI2Mq+WACWZ7yGHFUEirHBRt7fyIk0NsCKhmRhn7WAcjgSkSVVxKlPNFFw==}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rollup/rollup-linux-arm64-gnu@4.43.0':
|
||||
resolution: {integrity: sha512-8FnkipasmOOSSlfucGYEu58U8cxEdhziKjPD2FIa0ONVMxvl/hmONtX/7y4vGjdUhjcTHlKlDhw3H9t98fPvyA==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-arm64-musl@4.43.0':
|
||||
resolution: {integrity: sha512-KPPyAdlcIZ6S9C3S2cndXDkV0Bb1OSMsX0Eelr2Bay4EsF9yi9u9uzc9RniK3mcUGCLhWY9oLr6er80P5DE6XA==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rollup/rollup-linux-loongarch64-gnu@4.43.0':
|
||||
resolution: {integrity: sha512-HPGDIH0/ZzAZjvtlXj6g+KDQ9ZMHfSP553za7o2Odegb/BEfwJcR0Sw0RLNpQ9nC6Gy8s+3mSS9xjZ0n3rhcYg==}
|
||||
cpu: [loong64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-powerpc64le-gnu@4.43.0':
|
||||
resolution: {integrity: sha512-gEmwbOws4U4GLAJDhhtSPWPXUzDfMRedT3hFMyRAvM9Mrnj+dJIFIeL7otsv2WF3D7GrV0GIewW0y28dOYWkmw==}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-riscv64-gnu@4.43.0':
|
||||
resolution: {integrity: sha512-XXKvo2e+wFtXZF/9xoWohHg+MuRnvO29TI5Hqe9xwN5uN8NKUYy7tXUG3EZAlfchufNCTHNGjEx7uN78KsBo0g==}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-riscv64-musl@4.43.0':
|
||||
resolution: {integrity: sha512-ruf3hPWhjw6uDFsOAzmbNIvlXFXlBQ4nk57Sec8E8rUxs/AI4HD6xmiiasOOx/3QxS2f5eQMKTAwk7KHwpzr/Q==}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rollup/rollup-linux-s390x-gnu@4.43.0':
|
||||
resolution: {integrity: sha512-QmNIAqDiEMEvFV15rsSnjoSmO0+eJLoKRD9EAa9rrYNwO/XRCtOGM3A5A0X+wmG+XRrw9Fxdsw+LnyYiZWWcVw==}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-x64-gnu@4.43.0':
|
||||
resolution: {integrity: sha512-jAHr/S0iiBtFyzjhOkAics/2SrXE092qyqEg96e90L3t9Op8OTzS6+IX0Fy5wCt2+KqeHAkti+eitV0wvblEoQ==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-x64-musl@4.43.0':
|
||||
resolution: {integrity: sha512-3yATWgdeXyuHtBhrLt98w+5fKurdqvs8B53LaoKD7P7H7FKOONLsBVMNl9ghPQZQuYcceV5CDyPfyfGpMWD9mQ==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rollup/rollup-win32-arm64-msvc@4.43.0':
|
||||
resolution: {integrity: sha512-wVzXp2qDSCOpcBCT5WRWLmpJRIzv23valvcTwMHEobkjippNf+C3ys/+wf07poPkeNix0paTNemB2XrHr2TnGw==}
|
||||
@@ -2253,28 +2230,24 @@ packages:
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@tailwindcss/oxide-linux-arm64-musl@4.1.18':
|
||||
resolution: {integrity: sha512-1px92582HkPQlaaCkdRcio71p8bc8i/ap5807tPRDK/uw953cauQBT8c5tVGkOwrHMfc2Yh6UuxaH4vtTjGvHg==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@tailwindcss/oxide-linux-x64-gnu@4.1.18':
|
||||
resolution: {integrity: sha512-v3gyT0ivkfBLoZGF9LyHmts0Isc8jHZyVcbzio6Wpzifg/+5ZJpDiRiUhDLkcr7f/r38SWNe7ucxmGW3j3Kb/g==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@tailwindcss/oxide-linux-x64-musl@4.1.18':
|
||||
resolution: {integrity: sha512-bhJ2y2OQNlcRwwgOAGMY0xTFStt4/wyU6pvI6LSuZpRgKQwxTec0/3Scu91O8ir7qCR3AuepQKLU/kX99FouqQ==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@tailwindcss/oxide-wasm32-wasi@4.1.18':
|
||||
resolution: {integrity: sha512-LffYTvPjODiP6PT16oNeUQJzNVyJl1cjIebq/rWWBF+3eDst5JGEFSc5cWxyRCJ0Mxl+KyIkqRxk1XPEs9x8TA==}
|
||||
@@ -2398,9 +2371,6 @@ packages:
|
||||
'@types/send@1.2.1':
|
||||
resolution: {integrity: sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==}
|
||||
|
||||
'@types/spark-md5@3.0.5':
|
||||
resolution: {integrity: sha512-lWf05dnD42DLVKQJZrDHtWFidcLrHuip01CtnC2/S6AMhX4t9ZlEUj4iuRlAnts0PQk7KESOqKxeGE/b6sIPGg==}
|
||||
|
||||
'@types/trusted-types@2.0.7':
|
||||
resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==}
|
||||
|
||||
@@ -3651,28 +3621,24 @@ packages:
|
||||
engines: {node: '>= 12.0.0'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
lightningcss-linux-arm64-musl@1.30.2:
|
||||
resolution: {integrity: sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==}
|
||||
engines: {node: '>= 12.0.0'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
lightningcss-linux-x64-gnu@1.30.2:
|
||||
resolution: {integrity: sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==}
|
||||
engines: {node: '>= 12.0.0'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
lightningcss-linux-x64-musl@1.30.2:
|
||||
resolution: {integrity: sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==}
|
||||
engines: {node: '>= 12.0.0'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
lightningcss-win32-arm64-msvc@1.30.2:
|
||||
resolution: {integrity: sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==}
|
||||
@@ -5339,7 +5305,7 @@ snapshots:
|
||||
'@smithy/util-utf8': 2.3.0
|
||||
tslib: 2.8.1
|
||||
|
||||
'@aws-sdk/client-s3@3.980.0':
|
||||
'@aws-sdk/client-s3@3.981.0':
|
||||
dependencies:
|
||||
'@aws-crypto/sha1-browser': 5.2.0
|
||||
'@aws-crypto/sha256-browser': 5.2.0
|
||||
@@ -5357,9 +5323,9 @@ snapshots:
|
||||
'@aws-sdk/middleware-ssec': 3.972.3
|
||||
'@aws-sdk/middleware-user-agent': 3.972.5
|
||||
'@aws-sdk/region-config-resolver': 3.972.3
|
||||
'@aws-sdk/signature-v4-multi-region': 3.980.0
|
||||
'@aws-sdk/signature-v4-multi-region': 3.981.0
|
||||
'@aws-sdk/types': 3.973.1
|
||||
'@aws-sdk/util-endpoints': 3.980.0
|
||||
'@aws-sdk/util-endpoints': 3.981.0
|
||||
'@aws-sdk/util-user-agent-browser': 3.972.3
|
||||
'@aws-sdk/util-user-agent-node': 3.972.3
|
||||
'@smithy/config-resolver': 4.4.6
|
||||
@@ -5712,7 +5678,7 @@ snapshots:
|
||||
'@smithy/types': 4.12.0
|
||||
tslib: 2.8.1
|
||||
|
||||
'@aws-sdk/signature-v4-multi-region@3.980.0':
|
||||
'@aws-sdk/signature-v4-multi-region@3.981.0':
|
||||
dependencies:
|
||||
'@aws-sdk/middleware-sdk-s3': 3.972.5
|
||||
'@aws-sdk/types': 3.973.1
|
||||
@@ -5750,6 +5716,14 @@ snapshots:
|
||||
'@smithy/util-endpoints': 3.2.8
|
||||
tslib: 2.8.1
|
||||
|
||||
'@aws-sdk/util-endpoints@3.981.0':
|
||||
dependencies:
|
||||
'@aws-sdk/types': 3.973.1
|
||||
'@smithy/types': 4.12.0
|
||||
'@smithy/url-parser': 4.2.8
|
||||
'@smithy/util-endpoints': 3.2.8
|
||||
tslib: 2.8.1
|
||||
|
||||
'@aws-sdk/util-locate-window@3.965.2':
|
||||
dependencies:
|
||||
tslib: 2.8.1
|
||||
@@ -6440,11 +6414,10 @@ snapshots:
|
||||
fuse.js: 7.1.0
|
||||
nanoid: 5.1.6
|
||||
|
||||
'@kevisual/api@0.0.42':
|
||||
'@kevisual/api@0.0.44':
|
||||
dependencies:
|
||||
'@kevisual/js-filter': 0.0.5
|
||||
'@kevisual/load': 0.0.6
|
||||
'@types/spark-md5': 3.0.5
|
||||
es-toolkit: 1.44.0
|
||||
eventemitter3: 5.0.4
|
||||
fuse.js: 7.1.0
|
||||
@@ -6611,7 +6584,9 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@kevisual/router@0.0.67': {}
|
||||
'@kevisual/router@0.0.70':
|
||||
dependencies:
|
||||
es-toolkit: 1.44.0
|
||||
|
||||
'@kevisual/types@0.0.12': {}
|
||||
|
||||
@@ -6724,12 +6699,12 @@ snapshots:
|
||||
'@nodelib/fs.scandir': 2.1.5
|
||||
fastq: 1.17.1
|
||||
|
||||
'@opencode-ai/plugin@1.1.48':
|
||||
'@opencode-ai/plugin@1.1.49':
|
||||
dependencies:
|
||||
'@opencode-ai/sdk': 1.1.48
|
||||
'@opencode-ai/sdk': 1.1.49
|
||||
zod: 4.1.8
|
||||
|
||||
'@opencode-ai/sdk@1.1.48': {}
|
||||
'@opencode-ai/sdk@1.1.49': {}
|
||||
|
||||
'@oslojs/encoding@1.1.0': {}
|
||||
|
||||
@@ -7892,8 +7867,6 @@ snapshots:
|
||||
dependencies:
|
||||
'@types/node': 25.2.0
|
||||
|
||||
'@types/spark-md5@3.0.5': {}
|
||||
|
||||
'@types/trusted-types@2.0.7': {}
|
||||
|
||||
'@types/unist@2.0.11': {}
|
||||
|
||||
Reference in New Issue
Block a user