feat: 添加工作空间保持存活功能,更新相关依赖和配置
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -4,3 +4,5 @@ node_modules
|
||||
.pnpm-store
|
||||
|
||||
dist
|
||||
|
||||
storage
|
||||
@@ -2,7 +2,6 @@ import { QueryRouterServer as App } from '@kevisual/router'
|
||||
import { useContextKey } from '@kevisual/context'
|
||||
import { useConfig, useKey } from '@kevisual/use-config'
|
||||
import { CNB } from '../src/index.ts';
|
||||
import { nanoid } from 'nanoid';
|
||||
|
||||
export const config = useConfig()
|
||||
export const cnb = useContextKey<CNB>('cnb', () => {
|
||||
@@ -13,9 +12,6 @@ export const cnb = useContextKey<CNB>('cnb', () => {
|
||||
const cookie = useKey('CNB_COOKIE') as string
|
||||
return new CNB({ token: token, cookie: cookie });
|
||||
})
|
||||
export const appId = nanoid();
|
||||
export const app = useContextKey<App>('app', () => {
|
||||
return new App({
|
||||
appId
|
||||
})
|
||||
return new App({})
|
||||
})
|
||||
@@ -1,4 +1,4 @@
|
||||
import { app, appId } from '../app.ts';
|
||||
import { app } from '../app.ts';
|
||||
import './cnb-env/check.ts'
|
||||
import './repo/index.ts'
|
||||
import './workspace/index.ts'
|
||||
@@ -31,7 +31,7 @@ if (!app.hasRoute('auth')) {
|
||||
path: 'auth',
|
||||
}).define(async (ctx) => {
|
||||
// ctx.body = 'Auth Route';
|
||||
if (checkAppId(ctx, appId)) {
|
||||
if (checkAppId(ctx, app.appId)) {
|
||||
return;
|
||||
}
|
||||
}).addTo(app);
|
||||
@@ -42,7 +42,7 @@ if (!app.hasRoute('auth')) {
|
||||
middleware: ['auth'],
|
||||
}).define(async (ctx) => {
|
||||
// ctx.body = 'Admin Auth Route';
|
||||
if (checkAppId(ctx, appId)) {
|
||||
if (checkAppId(ctx, app.appId)) {
|
||||
return;
|
||||
}
|
||||
}).addTo(app);
|
||||
|
||||
@@ -2,6 +2,7 @@ import { createSkill, tool } from '@kevisual/router';
|
||||
import { app, cnb } from '../../app.ts';
|
||||
import z from 'zod';
|
||||
import './skills.ts';
|
||||
import './keep.ts';
|
||||
|
||||
// 启动工作空间
|
||||
app.route({
|
||||
@@ -113,7 +114,7 @@ app.route({
|
||||
args: {
|
||||
pipelineId: tool.schema.string().optional().describe('流水线 ID,优先使用'),
|
||||
sn: tool.schema.string().optional().describe('流水线构建号'),
|
||||
sns: tool.schema.array(z.string()).optional().describe('流水线构建号'),
|
||||
sns: tool.schema.array(z.string()).optional().describe('批量流水线构建号'),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
121
agent/routes/workspace/keep.ts
Normal file
121
agent/routes/workspace/keep.ts
Normal file
@@ -0,0 +1,121 @@
|
||||
import { createSkill, tool } from '@kevisual/router';
|
||||
import { app, cnb } from '../../app.ts';
|
||||
|
||||
import { createKeepAlive } from '../../../src/keep.ts';
|
||||
|
||||
type AliveInfo = {
|
||||
startTime: number;
|
||||
updatedTime?: number;
|
||||
KeepAlive: ReturnType<typeof createKeepAlive>;
|
||||
}
|
||||
|
||||
const keepAliveMap = new Map<string, AliveInfo>();
|
||||
|
||||
// 保持工作空间存活技能
|
||||
app.route({
|
||||
path: 'cnb',
|
||||
key: 'keep-workspace-alive',
|
||||
description: '保持工作空间存活技能,参数wsUrl:工作空间访问URL,cookie:访问工作空间所需的cookie',
|
||||
middleware: ['auth'],
|
||||
metadata: {
|
||||
tags: [],
|
||||
...({
|
||||
args: {
|
||||
wsUrl: tool.schema.string().describe('工作空间的访问URL'),
|
||||
cookie: tool.schema.string().describe('访问工作空间所需的cookie')
|
||||
}
|
||||
})
|
||||
}
|
||||
}).define(async (ctx) => {
|
||||
const wsUrl = ctx.query?.wsUrl as string;
|
||||
const cookie = ctx.query?.cookie as string;
|
||||
if (!wsUrl) {
|
||||
ctx.throw(400, '缺少工作空间访问URL参数');
|
||||
}
|
||||
if (!cookie) {
|
||||
ctx.throw(400, '缺少访问工作空间所需的cookie参数');
|
||||
}
|
||||
|
||||
// 检测是否已在运行
|
||||
const existing = keepAliveMap.get(wsUrl);
|
||||
if (existing) {
|
||||
ctx.body = { message: `工作空间 ${wsUrl} 的保持存活任务已在运行中` };
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(`启动保持工作空间 ${wsUrl} 存活的任务`);
|
||||
const keep = createKeepAlive({
|
||||
wsUrl,
|
||||
cookie,
|
||||
onConnect: () => {
|
||||
console.log(`工作空间 ${wsUrl} 保持存活任务已连接`);
|
||||
},
|
||||
onMessage: (data) => {
|
||||
// 可选:处理收到的消息
|
||||
// console.log(`工作空间 ${wsUrl} 收到消息: ${data}`);
|
||||
const aliveInfo = keepAliveMap.get(wsUrl);
|
||||
if (aliveInfo) {
|
||||
aliveInfo.updatedTime = Date.now();
|
||||
}
|
||||
},
|
||||
debug: true,
|
||||
onExit: (code) => {
|
||||
console.log(`工作空间 ${wsUrl} 保持存活任务已退出,退出码: ${code}`);
|
||||
keepAliveMap.delete(wsUrl);
|
||||
}
|
||||
});
|
||||
|
||||
keepAliveMap.set(wsUrl, { startTime: Date.now(), updatedTime: Date.now(), KeepAlive: keep });
|
||||
|
||||
ctx.body = { message: `已启动保持工作空间 ${wsUrl} 存活的任务` };
|
||||
}).addTo(app);
|
||||
|
||||
// 获取保持工作空间存活任务列表技能
|
||||
app.route({
|
||||
path: 'cnb',
|
||||
key: 'list-keep-alive-tasks',
|
||||
description: '获取保持工作空间存活任务列表技能',
|
||||
middleware: ['auth'],
|
||||
metadata: {
|
||||
tags: [],
|
||||
}
|
||||
}).define(async (ctx) => {
|
||||
const list = Array.from(keepAliveMap.entries()).map(([wsUrl, info]) => ({
|
||||
wsUrl,
|
||||
startTime: info.startTime,
|
||||
updatedTime: info.updatedTime
|
||||
}));
|
||||
ctx.body = { list };
|
||||
}).addTo(app);
|
||||
|
||||
// 停止保持工作空间存活技能
|
||||
app.route({
|
||||
path: 'cnb',
|
||||
key: 'stop-keep-workspace-alive',
|
||||
description: '停止保持工作空间存活技能, 参数wsUrl:工作空间访问URL',
|
||||
middleware: ['auth'],
|
||||
metadata: {
|
||||
tags: [],
|
||||
...({
|
||||
args: {
|
||||
wsUrl: tool.schema.string().describe('工作空间的访问URL'),
|
||||
}
|
||||
})
|
||||
}
|
||||
}).define(async (ctx) => {
|
||||
const wsUrl = ctx.query?.wsUrl as string;
|
||||
if (!wsUrl) {
|
||||
ctx.throw(400, '缺少工作空间访问URL参数');
|
||||
}
|
||||
|
||||
const keepAlive = keepAliveMap.get(wsUrl);
|
||||
if (keepAlive) {
|
||||
const endTime = Date.now();
|
||||
const duration = endTime - keepAlive.startTime;
|
||||
keepAlive?.KeepAlive?.disconnect();
|
||||
keepAliveMap.delete(wsUrl);
|
||||
ctx.body = { message: `已停止保持工作空间 ${wsUrl} 存活的任务,持续时间: ${duration}ms` };
|
||||
} else {
|
||||
ctx.body = { message: `没有找到工作空间 ${wsUrl} 的保持存活任务` };
|
||||
}
|
||||
}).addTo(app);
|
||||
@@ -21,3 +21,4 @@ const buildFn = async (opts: { entry?: string, naming?: string }) => {
|
||||
|
||||
await buildFn({ naming: 'opencode', entry: 'agent/opencode.ts' });
|
||||
await buildFn({ naming: 'keep', entry: 'src/keep.ts' });
|
||||
await buildFn({ naming: 'routes', entry: 'agent/index.ts' });
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@kevisual/cnb",
|
||||
"version": "0.0.10",
|
||||
"version": "0.0.12",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
@@ -30,12 +30,16 @@
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"resolutions": {
|
||||
"zod": "^4.3.6"
|
||||
},
|
||||
"dependencies": {
|
||||
"@kevisual/query": "^0.0.38",
|
||||
"@kevisual/router": "^0.0.63",
|
||||
"@kevisual/router": "^0.0.64",
|
||||
"@kevisual/use-config": "^1.0.28",
|
||||
"es-toolkit": "^1.44.0",
|
||||
"nanoid": "^5.1.6",
|
||||
"unstorage": "^1.17.4",
|
||||
"ws": "npm:@kevisual/ws",
|
||||
"zod": "^4.3.6"
|
||||
},
|
||||
@@ -43,6 +47,7 @@
|
||||
".": "./mod.ts",
|
||||
"./opencode": "./dist/opencode.js",
|
||||
"./keep": "./dist/keep.js",
|
||||
"./routes": "./dist/routes.js",
|
||||
"./src/*": "./src/*",
|
||||
"./agent/*": "./agent/*"
|
||||
}
|
||||
|
||||
238
pnpm-lock.yaml
generated
238
pnpm-lock.yaml
generated
@@ -4,6 +4,9 @@ settings:
|
||||
autoInstallPeers: true
|
||||
excludeLinksFromLockfile: false
|
||||
|
||||
overrides:
|
||||
zod: ^4.3.6
|
||||
|
||||
importers:
|
||||
|
||||
.:
|
||||
@@ -12,8 +15,8 @@ importers:
|
||||
specifier: ^0.0.38
|
||||
version: 0.0.38
|
||||
'@kevisual/router':
|
||||
specifier: ^0.0.63
|
||||
version: 0.0.63(typescript@5.9.3)
|
||||
specifier: ^0.0.64
|
||||
version: 0.0.64(typescript@5.9.3)
|
||||
'@kevisual/use-config':
|
||||
specifier: ^1.0.28
|
||||
version: 1.0.28(dotenv@17.2.3)
|
||||
@@ -23,6 +26,12 @@ importers:
|
||||
nanoid:
|
||||
specifier: ^5.1.6
|
||||
version: 5.1.6
|
||||
unstorage:
|
||||
specifier: ^1.17.4
|
||||
version: 1.17.4
|
||||
ws:
|
||||
specifier: npm:@kevisual/ws
|
||||
version: '@kevisual/ws@8.19.0'
|
||||
zod:
|
||||
specifier: ^4.3.6
|
||||
version: 4.3.6
|
||||
@@ -30,6 +39,9 @@ importers:
|
||||
'@kevisual/ai':
|
||||
specifier: ^0.0.24
|
||||
version: 0.0.24
|
||||
'@kevisual/cnb':
|
||||
specifier: ^0.0.10
|
||||
version: 0.0.10(dotenv@17.2.3)(typescript@5.9.3)
|
||||
'@kevisual/context':
|
||||
specifier: ^0.0.4
|
||||
version: 0.0.4
|
||||
@@ -51,9 +63,6 @@ importers:
|
||||
dotenv:
|
||||
specifier: ^17.2.3
|
||||
version: 17.2.3
|
||||
ws:
|
||||
specifier: npm:@kevisual/ws
|
||||
version: '@kevisual/ws@8.19.0'
|
||||
|
||||
packages:
|
||||
|
||||
@@ -71,6 +80,9 @@ packages:
|
||||
'@kevisual/ai@0.0.24':
|
||||
resolution: {integrity: sha512-7jvZk1/L//VIClK7usuNgN4ZA9Etgbooka1Sj5quE/0UywR+NNnwqXVZ89Y1fBhI1TkhauDsdJBAtcQ7r/vbVw==}
|
||||
|
||||
'@kevisual/cnb@0.0.10':
|
||||
resolution: {integrity: sha512-zwdJOj64FAkbUIGy+3CC+uQMUptWGf1uuQZXy0ZLfBfdFO2BcoHuzvomWhYxF0eexOBsLrz1F9jNWS0heBrp2Q==}
|
||||
|
||||
'@kevisual/context@0.0.4':
|
||||
resolution: {integrity: sha512-HJeLeZQLU+7tCluSfOyvkgKLs0HjCZrdJlZgEgKRSa8XTwZfMAUt6J7qZTbrZAHBlPtX68EPu/PI8JMCeu3WAQ==}
|
||||
|
||||
@@ -93,6 +105,9 @@ packages:
|
||||
'@kevisual/router@0.0.63':
|
||||
resolution: {integrity: sha512-rM/FELiNtTJkjb00sdQ2f8NpWHzfOwrtgQJhsX9Np9KdzAQ5dP6pI5nAHlWvU2QyrC1VH5IibUmsBIeMMV3nWg==}
|
||||
|
||||
'@kevisual/router@0.0.64':
|
||||
resolution: {integrity: sha512-EYz1MZxrltgySUL0Y+/MtZf2FEmqC5U8GmFAqvHNjgtS5FJdHpxRjo6zab4+0wSUlVyCxCpZXFY5vHB/g+nQBw==}
|
||||
|
||||
'@kevisual/types@0.0.12':
|
||||
resolution: {integrity: sha512-zJXH2dosir3jVrQ6QG4i0+iLQeT9gJ3H+cKXs8ReWboxBSYzUZO78XssVeVrFPsJ33iaAqo4q3DWbSS1dWGn7Q==}
|
||||
|
||||
@@ -304,16 +319,36 @@ packages:
|
||||
'@types/ws@8.18.1':
|
||||
resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==}
|
||||
|
||||
anymatch@3.1.3:
|
||||
resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
|
||||
engines: {node: '>= 8'}
|
||||
|
||||
bun-types@1.3.8:
|
||||
resolution: {integrity: sha512-fL99nxdOWvV4LqjmC+8Q9kW3M4QTtTR1eePs94v5ctGqU8OeceWrSUaRw3JYb7tU3FkMIAjkueehrHPPPGKi5Q==}
|
||||
|
||||
chokidar@5.0.0:
|
||||
resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==}
|
||||
engines: {node: '>= 20.19.0'}
|
||||
|
||||
commondir@1.0.1:
|
||||
resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==}
|
||||
|
||||
cookie-es@1.2.2:
|
||||
resolution: {integrity: sha512-+W7VmiVINB+ywl1HGXJXmrqkOhpKrIiVZV6tQuV54ZyQC7MMuBt81Vc336GMLoHBq5hV/F9eXgt5Mnx0Rha5Fg==}
|
||||
|
||||
crossws@0.3.5:
|
||||
resolution: {integrity: sha512-ojKiDvcmByhwa8YYqbQI/hg7MEU0NC03+pSdEq4ZUnZR9xXpwk7E43SMNGkn+JxJGPFtNvQ48+vV2p+P1ml5PA==}
|
||||
|
||||
deepmerge@4.3.1:
|
||||
resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
defu@6.1.4:
|
||||
resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==}
|
||||
|
||||
destr@2.0.5:
|
||||
resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==}
|
||||
|
||||
dotenv@17.2.3:
|
||||
resolution: {integrity: sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==}
|
||||
engines: {node: '>=12'}
|
||||
@@ -344,6 +379,9 @@ packages:
|
||||
function-bind@1.1.2:
|
||||
resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
|
||||
|
||||
h3@1.15.5:
|
||||
resolution: {integrity: sha512-xEyq3rSl+dhGX2Lm0+eFQIAzlDN6Fs0EcC4f7BNUmzaRX/PTzeuM+Tr2lHB8FoXggsQIeXLj8EDVgs5ywxyxmg==}
|
||||
|
||||
hasown@2.0.2:
|
||||
resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
@@ -352,6 +390,9 @@ packages:
|
||||
resolution: {integrity: sha512-l7qMiNee7t82bH3SeyUCt9UF15EVmaBvsppY2zQtrbIhl/yzBTny+YUxsVjSjQ6gaqaeVtZmGocom8TzBlA4Yw==}
|
||||
engines: {node: '>=16.9.0'}
|
||||
|
||||
iron-webcrypto@1.2.1:
|
||||
resolution: {integrity: sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==}
|
||||
|
||||
is-core-module@2.16.1:
|
||||
resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==}
|
||||
engines: {node: '>= 0.4'}
|
||||
@@ -365,6 +406,10 @@ packages:
|
||||
js-tokens@4.0.0:
|
||||
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
|
||||
|
||||
lru-cache@11.2.5:
|
||||
resolution: {integrity: sha512-vFrFJkWtJvJnD5hg+hJvVE8Lh/TcMzKnTgCWmtBipwI5yLX/iX+5UB2tfuyODF5E7k9xEzMdYgGqaSb1c0c5Yw==}
|
||||
engines: {node: 20 || >=22}
|
||||
|
||||
magic-string@0.30.21:
|
||||
resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
|
||||
|
||||
@@ -373,16 +418,40 @@ packages:
|
||||
engines: {node: ^18 || >=20}
|
||||
hasBin: true
|
||||
|
||||
node-fetch-native@1.6.7:
|
||||
resolution: {integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==}
|
||||
|
||||
node-mock-http@1.0.4:
|
||||
resolution: {integrity: sha512-8DY+kFsDkNXy1sJglUfuODx1/opAGJGyrTuFqEoN90oRc2Vk0ZbD4K2qmKXBBEhZQzdKHIVfEJpDU8Ak2NJEvQ==}
|
||||
|
||||
normalize-path@3.0.0:
|
||||
resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
ofetch@1.5.1:
|
||||
resolution: {integrity: sha512-2W4oUZlVaqAPAil6FUg/difl6YhqhUR7x2eZY4bQCko22UXg3hptq9KLQdqFClV+Wu85UX7hNtdGTngi/1BxcA==}
|
||||
|
||||
path-parse@1.0.7:
|
||||
resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
|
||||
|
||||
picocolors@1.1.1:
|
||||
resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
|
||||
|
||||
picomatch@2.3.1:
|
||||
resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
|
||||
engines: {node: '>=8.6'}
|
||||
|
||||
picomatch@4.0.3:
|
||||
resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
radix3@1.1.2:
|
||||
resolution: {integrity: sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==}
|
||||
|
||||
readdirp@5.0.0:
|
||||
resolution: {integrity: sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==}
|
||||
engines: {node: '>= 20.19.0'}
|
||||
|
||||
resolve@1.22.11:
|
||||
resolution: {integrity: sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
@@ -412,11 +481,76 @@ packages:
|
||||
engines: {node: '>=14.17'}
|
||||
hasBin: true
|
||||
|
||||
ufo@1.6.3:
|
||||
resolution: {integrity: sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==}
|
||||
|
||||
uncrypto@0.1.3:
|
||||
resolution: {integrity: sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==}
|
||||
|
||||
undici-types@7.16.0:
|
||||
resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==}
|
||||
|
||||
zod@4.1.8:
|
||||
resolution: {integrity: sha512-5R1P+WwQqmmMIEACyzSvo4JXHY5WiAFHRMg+zBZKgKS+Q1viRa0C1hmUKtHltoIFKtIdki3pRxkmpP74jnNYHQ==}
|
||||
unstorage@1.17.4:
|
||||
resolution: {integrity: sha512-fHK0yNg38tBiJKp/Vgsq4j0JEsCmgqH58HAn707S7zGkArbZsVr/CwINoi+nh3h98BRCwKvx1K3Xg9u3VV83sw==}
|
||||
peerDependencies:
|
||||
'@azure/app-configuration': ^1.8.0
|
||||
'@azure/cosmos': ^4.2.0
|
||||
'@azure/data-tables': ^13.3.0
|
||||
'@azure/identity': ^4.6.0
|
||||
'@azure/keyvault-secrets': ^4.9.0
|
||||
'@azure/storage-blob': ^12.26.0
|
||||
'@capacitor/preferences': ^6 || ^7 || ^8
|
||||
'@deno/kv': '>=0.9.0'
|
||||
'@netlify/blobs': ^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0
|
||||
'@planetscale/database': ^1.19.0
|
||||
'@upstash/redis': ^1.34.3
|
||||
'@vercel/blob': '>=0.27.1'
|
||||
'@vercel/functions': ^2.2.12 || ^3.0.0
|
||||
'@vercel/kv': ^1 || ^2 || ^3
|
||||
aws4fetch: ^1.0.20
|
||||
db0: '>=0.2.1'
|
||||
idb-keyval: ^6.2.1
|
||||
ioredis: ^5.4.2
|
||||
uploadthing: ^7.4.4
|
||||
peerDependenciesMeta:
|
||||
'@azure/app-configuration':
|
||||
optional: true
|
||||
'@azure/cosmos':
|
||||
optional: true
|
||||
'@azure/data-tables':
|
||||
optional: true
|
||||
'@azure/identity':
|
||||
optional: true
|
||||
'@azure/keyvault-secrets':
|
||||
optional: true
|
||||
'@azure/storage-blob':
|
||||
optional: true
|
||||
'@capacitor/preferences':
|
||||
optional: true
|
||||
'@deno/kv':
|
||||
optional: true
|
||||
'@netlify/blobs':
|
||||
optional: true
|
||||
'@planetscale/database':
|
||||
optional: true
|
||||
'@upstash/redis':
|
||||
optional: true
|
||||
'@vercel/blob':
|
||||
optional: true
|
||||
'@vercel/functions':
|
||||
optional: true
|
||||
'@vercel/kv':
|
||||
optional: true
|
||||
aws4fetch:
|
||||
optional: true
|
||||
db0:
|
||||
optional: true
|
||||
idb-keyval:
|
||||
optional: true
|
||||
ioredis:
|
||||
optional: true
|
||||
uploadthing:
|
||||
optional: true
|
||||
|
||||
zod@4.3.6:
|
||||
resolution: {integrity: sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==}
|
||||
@@ -441,6 +575,19 @@ snapshots:
|
||||
'@kevisual/permission': 0.0.3
|
||||
'@kevisual/query': 0.0.38
|
||||
|
||||
'@kevisual/cnb@0.0.10(dotenv@17.2.3)(typescript@5.9.3)':
|
||||
dependencies:
|
||||
'@kevisual/query': 0.0.38
|
||||
'@kevisual/router': 0.0.63(typescript@5.9.3)
|
||||
'@kevisual/use-config': 1.0.28(dotenv@17.2.3)
|
||||
es-toolkit: 1.44.0
|
||||
nanoid: 5.1.6
|
||||
ws: '@kevisual/ws@8.19.0'
|
||||
zod: 4.3.6
|
||||
transitivePeerDependencies:
|
||||
- dotenv
|
||||
- typescript
|
||||
|
||||
'@kevisual/context@0.0.4': {}
|
||||
|
||||
'@kevisual/dts@0.0.3(typescript@5.9.3)':
|
||||
@@ -473,6 +620,13 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- typescript
|
||||
|
||||
'@kevisual/router@0.0.64(typescript@5.9.3)':
|
||||
dependencies:
|
||||
'@kevisual/dts': 0.0.3(typescript@5.9.3)
|
||||
hono: 4.11.7
|
||||
transitivePeerDependencies:
|
||||
- typescript
|
||||
|
||||
'@kevisual/types@0.0.12': {}
|
||||
|
||||
'@kevisual/use-config@1.0.28(dotenv@17.2.3)':
|
||||
@@ -485,7 +639,7 @@ snapshots:
|
||||
'@opencode-ai/plugin@1.1.44':
|
||||
dependencies:
|
||||
'@opencode-ai/sdk': 1.1.44
|
||||
zod: 4.1.8
|
||||
zod: 4.3.6
|
||||
|
||||
'@opencode-ai/sdk@1.1.44': {}
|
||||
|
||||
@@ -619,14 +773,33 @@ snapshots:
|
||||
dependencies:
|
||||
'@types/node': 25.1.0
|
||||
|
||||
anymatch@3.1.3:
|
||||
dependencies:
|
||||
normalize-path: 3.0.0
|
||||
picomatch: 2.3.1
|
||||
|
||||
bun-types@1.3.8:
|
||||
dependencies:
|
||||
'@types/node': 25.1.0
|
||||
|
||||
chokidar@5.0.0:
|
||||
dependencies:
|
||||
readdirp: 5.0.0
|
||||
|
||||
commondir@1.0.1: {}
|
||||
|
||||
cookie-es@1.2.2: {}
|
||||
|
||||
crossws@0.3.5:
|
||||
dependencies:
|
||||
uncrypto: 0.1.3
|
||||
|
||||
deepmerge@4.3.1: {}
|
||||
|
||||
defu@6.1.4: {}
|
||||
|
||||
destr@2.0.5: {}
|
||||
|
||||
dotenv@17.2.3: {}
|
||||
|
||||
es-toolkit@1.44.0: {}
|
||||
@@ -644,12 +817,26 @@ snapshots:
|
||||
|
||||
function-bind@1.1.2: {}
|
||||
|
||||
h3@1.15.5:
|
||||
dependencies:
|
||||
cookie-es: 1.2.2
|
||||
crossws: 0.3.5
|
||||
defu: 6.1.4
|
||||
destr: 2.0.5
|
||||
iron-webcrypto: 1.2.1
|
||||
node-mock-http: 1.0.4
|
||||
radix3: 1.1.2
|
||||
ufo: 1.6.3
|
||||
uncrypto: 0.1.3
|
||||
|
||||
hasown@2.0.2:
|
||||
dependencies:
|
||||
function-bind: 1.1.2
|
||||
|
||||
hono@4.11.7: {}
|
||||
|
||||
iron-webcrypto@1.2.1: {}
|
||||
|
||||
is-core-module@2.16.1:
|
||||
dependencies:
|
||||
hasown: 2.0.2
|
||||
@@ -663,19 +850,39 @@ snapshots:
|
||||
js-tokens@4.0.0:
|
||||
optional: true
|
||||
|
||||
lru-cache@11.2.5: {}
|
||||
|
||||
magic-string@0.30.21:
|
||||
dependencies:
|
||||
'@jridgewell/sourcemap-codec': 1.5.5
|
||||
|
||||
nanoid@5.1.6: {}
|
||||
|
||||
node-fetch-native@1.6.7: {}
|
||||
|
||||
node-mock-http@1.0.4: {}
|
||||
|
||||
normalize-path@3.0.0: {}
|
||||
|
||||
ofetch@1.5.1:
|
||||
dependencies:
|
||||
destr: 2.0.5
|
||||
node-fetch-native: 1.6.7
|
||||
ufo: 1.6.3
|
||||
|
||||
path-parse@1.0.7: {}
|
||||
|
||||
picocolors@1.1.1:
|
||||
optional: true
|
||||
|
||||
picomatch@2.3.1: {}
|
||||
|
||||
picomatch@4.0.3: {}
|
||||
|
||||
radix3@1.1.2: {}
|
||||
|
||||
readdirp@5.0.0: {}
|
||||
|
||||
resolve@1.22.11:
|
||||
dependencies:
|
||||
is-core-module: 2.16.1
|
||||
@@ -727,8 +934,21 @@ snapshots:
|
||||
|
||||
typescript@5.9.3: {}
|
||||
|
||||
ufo@1.6.3: {}
|
||||
|
||||
uncrypto@0.1.3: {}
|
||||
|
||||
undici-types@7.16.0: {}
|
||||
|
||||
zod@4.1.8: {}
|
||||
unstorage@1.17.4:
|
||||
dependencies:
|
||||
anymatch: 3.1.3
|
||||
chokidar: 5.0.0
|
||||
destr: 2.0.5
|
||||
h3: 1.15.5
|
||||
lru-cache: 11.2.5
|
||||
node-fetch-native: 1.6.7
|
||||
ofetch: 1.5.1
|
||||
ufo: 1.6.3
|
||||
|
||||
zod@4.3.6: {}
|
||||
|
||||
@@ -12,6 +12,7 @@ export interface KeepAliveConfig {
|
||||
onDisconnect?: (code: number) => void;
|
||||
onError?: (error: Error) => void;
|
||||
onSign?: (data: { type: string; data: string; signedData: string }) => void;
|
||||
onExit?: (code?: number) => void;
|
||||
debug?: boolean;
|
||||
}
|
||||
|
||||
@@ -43,6 +44,7 @@ export class WSKeepAlive {
|
||||
onDisconnect: config.onDisconnect ?? (() => { }),
|
||||
onError: config.onError ?? (() => { }),
|
||||
onSign: config.onSign ?? (() => { }),
|
||||
onExit: config.onExit ?? (() => { }),
|
||||
debug: config.debug ?? false,
|
||||
};
|
||||
this.url = new URL(this.config.wsUrl);
|
||||
@@ -158,6 +160,7 @@ export class WSKeepAlive {
|
||||
private handleReconnect() {
|
||||
if (this.reconnectAttempts >= this.config.maxReconnectAttempts) {
|
||||
this.log(`Max reconnect attempts (${this.config.maxReconnectAttempts}) reached. Giving up.`);
|
||||
this.config.onExit(1);
|
||||
return;
|
||||
}
|
||||
this.reconnectAttempts++;
|
||||
@@ -174,6 +177,7 @@ export class WSKeepAlive {
|
||||
this.stopPing();
|
||||
if (this.ws) {
|
||||
this.ws.close();
|
||||
this.config.onExit(0);
|
||||
this.ws = null;
|
||||
}
|
||||
}
|
||||
|
||||
13
src/workspace/keep-worker.ts
Normal file
13
src/workspace/keep-worker.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import { createKeepAlive } from '@kevisual/cnb/keep';
|
||||
|
||||
const wsUrl = process.argv[2];
|
||||
const cookie = process.argv[3];
|
||||
|
||||
createKeepAlive({
|
||||
wsUrl,
|
||||
cookie,
|
||||
onConnect: () => console.log('已连接'),
|
||||
debug: true
|
||||
});
|
||||
|
||||
process.on('SIGINT', () => process.exit(0));
|
||||
@@ -3,6 +3,7 @@
|
||||
"compilerOptions": {
|
||||
"module": "NodeNext",
|
||||
"target": "esnext",
|
||||
"rootDir": ".",
|
||||
"baseUrl": ".",
|
||||
"typeRoots": [
|
||||
"./node_modules/@types",
|
||||
@@ -19,6 +20,7 @@
|
||||
},
|
||||
"include": [
|
||||
"src/**/*",
|
||||
"agent/**/*",
|
||||
"mod.ts",
|
||||
"agent/**/*"
|
||||
],
|
||||
}
|
||||
Reference in New Issue
Block a user