@kevisual/router 0.0.61 → 0.0.63

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,7 +2,7 @@ import { EventEmitter } from 'eventemitter3';
2
2
  import * as http from 'node:http';
3
3
  import { IncomingMessage, ServerResponse } from 'node:http';
4
4
  import { IncomingMessage as IncomingMessage$1, ServerResponse as ServerResponse$1 } from 'http';
5
- import { Plugin } from '@opencode-ai/plugin';
5
+ import { PluginInput, Hooks, Plugin } from '@opencode-ai/plugin';
6
6
 
7
7
  type RouterContextT = {
8
8
  code?: number;
@@ -296,8 +296,7 @@ declare class QueryRouter {
296
296
  createRouteList(force?: boolean, filter?: (route: Route) => boolean): void;
297
297
  /**
298
298
  * 等待程序运行, 获取到message的数据,就执行
299
- * params 是预设参数,默认path为main
300
- *
299
+ * params 是预设参数
301
300
  * emitter = process
302
301
  * -- .exit
303
302
  * -- .on
@@ -673,6 +672,8 @@ declare const addCallFn: (app: App) => void;
673
672
  declare const createRouterAgentPluginFn: (opts?: {
674
673
  router?: App | QueryRouterServer;
675
674
  query?: string;
675
+ hooks?: (plugin: PluginInput) => Promise<Hooks>;
676
676
  }) => Plugin;
677
+ declare const usePluginInput: () => PluginInput;
677
678
 
678
- export { addCallFn, createRouterAgentPluginFn };
679
+ export { addCallFn, createRouterAgentPluginFn, usePluginInput };
package/dist/opencode.js CHANGED
@@ -2770,7 +2770,7 @@ class Doc {
2770
2770
  const version = {
2771
2771
  major: 4,
2772
2772
  minor: 3,
2773
- patch: 5,
2773
+ patch: 6,
2774
2774
  };
2775
2775
 
2776
2776
  const $ZodType = /*@__PURE__*/ $constructor("$ZodType", (inst, def) => {
@@ -4132,11 +4132,9 @@ const $ZodRecord = /*@__PURE__*/ $constructor("$ZodRecord", (inst, def) => {
4132
4132
  if (keyResult instanceof Promise) {
4133
4133
  throw new Error("Async schemas not supported in object keys currently");
4134
4134
  }
4135
- // Numeric string fallback: if key failed with "expected number", retry with Number(key)
4136
- const checkNumericKey = typeof key === "string" &&
4137
- number$2.test(key) &&
4138
- keyResult.issues.length &&
4139
- keyResult.issues.some((iss) => iss.code === "invalid_type" && iss.expected === "number");
4135
+ // Numeric string fallback: if key is a numeric string and failed, retry with Number(key)
4136
+ // This handles z.number(), z.literal([1, 2, 3]), and unions containing numeric literals
4137
+ const checkNumericKey = typeof key === "string" && number$2.test(key) && keyResult.issues.length;
4140
4138
  if (checkNumericKey) {
4141
4139
  const retryResult = def.keyType._zod.run({ value: Number(key), issues: [] }, ctx);
4142
4140
  if (retryResult instanceof Promise) {
@@ -11789,7 +11787,7 @@ function finalize(ctx, schema) {
11789
11787
  }
11790
11788
  }
11791
11789
  // When ref was extracted to $defs, remove properties that match the definition
11792
- if (refSchema.$ref) {
11790
+ if (refSchema.$ref && refSeen.def) {
11793
11791
  for (const key in schema) {
11794
11792
  if (key === "$ref" || key === "allOf")
11795
11793
  continue;
@@ -15684,8 +15682,11 @@ const createRouterAgentPluginFn = (opts) => {
15684
15682
  return false;
15685
15683
  });
15686
15684
  // opencode run "查看系统信息"
15687
- const AgentPlugin = async ({ project, client, $, directory, worktree }) => {
15685
+ const AgentPlugin = async (pluginInput) => {
15686
+ useContextKey('plugin-input', () => pluginInput, true);
15687
+ const hooks = opts?.hooks ? await opts.hooks(pluginInput) : {};
15688
15688
  return {
15689
+ ...hooks,
15689
15690
  'tool': {
15690
15691
  ...routes.reduce((acc, route) => {
15691
15692
  const metadata = route.metadata;
@@ -15717,15 +15718,19 @@ const createRouterAgentPluginFn = (opts) => {
15717
15718
  }
15718
15719
  };
15719
15720
  return acc;
15720
- }, {})
15721
+ }, {}),
15722
+ ...hooks?.tool
15721
15723
  },
15722
- 'tool.execute.before': async (opts) => {
15723
- // console.log('CnbPlugin: tool.execute.before', opts.tool);
15724
- // delete toolSkills['cnb-login-verify']
15725
- }
15724
+ // 'tool.execute.before': async (opts) => {
15725
+ // // console.log('CnbPlugin: tool.execute.before', opts.tool);
15726
+ // // delete toolSkills['cnb-login-verify']
15727
+ // },
15726
15728
  };
15727
15729
  };
15728
15730
  return AgentPlugin;
15729
15731
  };
15732
+ const usePluginInput = () => {
15733
+ return useContextKey('plugin-input');
15734
+ };
15730
15735
 
15731
- export { addCallFn, createRouterAgentPluginFn };
15736
+ export { addCallFn, createRouterAgentPluginFn, usePluginInput };
@@ -308,8 +308,7 @@ declare class QueryRouter {
308
308
  createRouteList(force?: boolean, filter?: (route: Route) => boolean): void;
309
309
  /**
310
310
  * 等待程序运行, 获取到message的数据,就执行
311
- * params 是预设参数,默认path为main
312
- *
311
+ * params 是预设参数
313
312
  * emitter = process
314
313
  * -- .exit
315
314
  * -- .on
@@ -517,9 +517,17 @@ const listenProcess = async ({ app, mockProcess, params, timeout = 10 * 60 * 60
517
517
  /**
518
518
  * 如果不提供path,默认是main
519
519
  */
520
- const { path = 'main', payload = {}, ...rest } = await getParams();
520
+ const { payload = {}, ...rest } = await getParams();
521
+ const msg = { ...params, ...rest, payload: { ...params?.payload, ...payload } };
522
+ /**
523
+ * 如果没有提供path和id,默认取第一个路由, 而且路由path不是router的
524
+ */
525
+ if (!msg.path && !msg.id) {
526
+ const route = app.routes.find(r => r.path !== 'router');
527
+ msg.id = route?.id;
528
+ }
521
529
  // 执行主要逻辑
522
- const result = await app.run({ path, ...params, ...rest, payload: { ...params?.payload, ...payload } });
530
+ const result = await app.run(msg);
523
531
  // 发送结果回主进程
524
532
  const response = {
525
533
  success: true,
@@ -2410,7 +2418,7 @@ class Doc {
2410
2418
  const version = {
2411
2419
  major: 4,
2412
2420
  minor: 3,
2413
- patch: 5,
2421
+ patch: 6,
2414
2422
  };
2415
2423
 
2416
2424
  const $ZodType = /*@__PURE__*/ $constructor("$ZodType", (inst, def) => {
@@ -3772,11 +3780,9 @@ const $ZodRecord = /*@__PURE__*/ $constructor("$ZodRecord", (inst, def) => {
3772
3780
  if (keyResult instanceof Promise) {
3773
3781
  throw new Error("Async schemas not supported in object keys currently");
3774
3782
  }
3775
- // Numeric string fallback: if key failed with "expected number", retry with Number(key)
3776
- const checkNumericKey = typeof key === "string" &&
3777
- number$2.test(key) &&
3778
- keyResult.issues.length &&
3779
- keyResult.issues.some((iss) => iss.code === "invalid_type" && iss.expected === "number");
3783
+ // Numeric string fallback: if key is a numeric string and failed, retry with Number(key)
3784
+ // This handles z.number(), z.literal([1, 2, 3]), and unions containing numeric literals
3785
+ const checkNumericKey = typeof key === "string" && number$2.test(key) && keyResult.issues.length;
3780
3786
  if (checkNumericKey) {
3781
3787
  const retryResult = def.keyType._zod.run({ value: Number(key), issues: [] }, ctx);
3782
3788
  if (retryResult instanceof Promise) {
@@ -11429,7 +11435,7 @@ function finalize(ctx, schema) {
11429
11435
  }
11430
11436
  }
11431
11437
  // When ref was extracted to $defs, remove properties that match the definition
11432
- if (refSchema.$ref) {
11438
+ if (refSchema.$ref && refSeen.def) {
11433
11439
  for (const key in schema) {
11434
11440
  if (key === "$ref" || key === "allOf")
11435
11441
  continue;
@@ -15420,8 +15426,7 @@ class QueryRouter {
15420
15426
  }
15421
15427
  /**
15422
15428
  * 等待程序运行, 获取到message的数据,就执行
15423
- * params 是预设参数,默认path为main
15424
- *
15429
+ * params 是预设参数
15425
15430
  * emitter = process
15426
15431
  * -- .exit
15427
15432
  * -- .on
package/dist/router.d.ts CHANGED
@@ -314,8 +314,7 @@ declare class QueryRouter {
314
314
  createRouteList(force?: boolean, filter?: (route: Route) => boolean): void;
315
315
  /**
316
316
  * 等待程序运行, 获取到message的数据,就执行
317
- * params 是预设参数,默认path为main
318
- *
317
+ * params 是预设参数
319
318
  * emitter = process
320
319
  * -- .exit
321
320
  * -- .on
package/dist/router.js CHANGED
@@ -541,9 +541,17 @@ const listenProcess = async ({ app, mockProcess, params, timeout = 10 * 60 * 60
541
541
  /**
542
542
  * 如果不提供path,默认是main
543
543
  */
544
- const { path = 'main', payload = {}, ...rest } = await getParams();
544
+ const { payload = {}, ...rest } = await getParams();
545
+ const msg = { ...params, ...rest, payload: { ...params?.payload, ...payload } };
546
+ /**
547
+ * 如果没有提供path和id,默认取第一个路由, 而且路由path不是router的
548
+ */
549
+ if (!msg.path && !msg.id) {
550
+ const route = app.routes.find(r => r.path !== 'router');
551
+ msg.id = route?.id;
552
+ }
545
553
  // 执行主要逻辑
546
- const result = await app.run({ path, ...params, ...rest, payload: { ...params?.payload, ...payload } });
554
+ const result = await app.run(msg);
547
555
  // 发送结果回主进程
548
556
  const response = {
549
557
  success: true,
@@ -2434,7 +2442,7 @@ class Doc {
2434
2442
  const version = {
2435
2443
  major: 4,
2436
2444
  minor: 3,
2437
- patch: 5,
2445
+ patch: 6,
2438
2446
  };
2439
2447
 
2440
2448
  const $ZodType = /*@__PURE__*/ $constructor("$ZodType", (inst, def) => {
@@ -3796,11 +3804,9 @@ const $ZodRecord = /*@__PURE__*/ $constructor("$ZodRecord", (inst, def) => {
3796
3804
  if (keyResult instanceof Promise) {
3797
3805
  throw new Error("Async schemas not supported in object keys currently");
3798
3806
  }
3799
- // Numeric string fallback: if key failed with "expected number", retry with Number(key)
3800
- const checkNumericKey = typeof key === "string" &&
3801
- number$2.test(key) &&
3802
- keyResult.issues.length &&
3803
- keyResult.issues.some((iss) => iss.code === "invalid_type" && iss.expected === "number");
3807
+ // Numeric string fallback: if key is a numeric string and failed, retry with Number(key)
3808
+ // This handles z.number(), z.literal([1, 2, 3]), and unions containing numeric literals
3809
+ const checkNumericKey = typeof key === "string" && number$2.test(key) && keyResult.issues.length;
3804
3810
  if (checkNumericKey) {
3805
3811
  const retryResult = def.keyType._zod.run({ value: Number(key), issues: [] }, ctx);
3806
3812
  if (retryResult instanceof Promise) {
@@ -11453,7 +11459,7 @@ function finalize(ctx, schema) {
11453
11459
  }
11454
11460
  }
11455
11461
  // When ref was extracted to $defs, remove properties that match the definition
11456
- if (refSchema.$ref) {
11462
+ if (refSchema.$ref && refSeen.def) {
11457
11463
  for (const key in schema) {
11458
11464
  if (key === "$ref" || key === "allOf")
11459
11465
  continue;
@@ -15444,8 +15450,7 @@ class QueryRouter {
15444
15450
  }
15445
15451
  /**
15446
15452
  * 等待程序运行, 获取到message的数据,就执行
15447
- * params 是预设参数,默认path为main
15448
- *
15453
+ * params 是预设参数
15449
15454
  * emitter = process
15450
15455
  * -- .exit
15451
15456
  * -- .on
package/package.json CHANGED
@@ -1,14 +1,13 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package",
3
3
  "name": "@kevisual/router",
4
- "version": "0.0.61",
4
+ "version": "0.0.63",
5
5
  "description": "",
6
6
  "type": "module",
7
7
  "main": "./dist/router.js",
8
8
  "types": "./dist/router.d.ts",
9
9
  "scripts": {
10
10
  "build": "npm run clean && rollup -c",
11
- "postbuild": "bun run bun.config.ts",
12
11
  "watch": "rollup -c -w",
13
12
  "clean": "rm -rf dist"
14
13
  },
@@ -22,20 +21,20 @@
22
21
  "keywords": [],
23
22
  "author": "abearxiong",
24
23
  "license": "MIT",
25
- "packageManager": "pnpm@10.28.1",
24
+ "packageManager": "pnpm@10.28.2",
26
25
  "devDependencies": {
27
26
  "@kevisual/context": "^0.0.4",
28
27
  "@kevisual/js-filter": "^0.0.5",
29
28
  "@kevisual/local-proxy": "^0.0.8",
30
- "@kevisual/query": "^0.0.35",
29
+ "@kevisual/query": "^0.0.38",
31
30
  "@kevisual/use-config": "^1.0.28",
32
- "@opencode-ai/plugin": "^1.1.27",
31
+ "@opencode-ai/plugin": "^1.1.36",
33
32
  "@rollup/plugin-alias": "^6.0.0",
34
33
  "@rollup/plugin-commonjs": "29.0.0",
35
34
  "@rollup/plugin-node-resolve": "^16.0.3",
36
35
  "@rollup/plugin-typescript": "^12.3.0",
37
36
  "@types/bun": "^1.3.6",
38
- "@types/node": "^25.0.9",
37
+ "@types/node": "^25.0.10",
39
38
  "@types/send": "^1.2.1",
40
39
  "@types/ws": "^8.18.1",
41
40
  "@types/xml2js": "^0.4.14",
@@ -43,7 +42,7 @@
43
42
  "fast-glob": "^3.3.3",
44
43
  "nanoid": "^5.1.6",
45
44
  "path-to-regexp": "^8.3.0",
46
- "rollup": "^4.55.2",
45
+ "rollup": "^4.57.0",
47
46
  "rollup-plugin-dts": "^6.3.0",
48
47
  "send": "^1.2.1",
49
48
  "ts-loader": "^9.5.4",
@@ -53,14 +52,15 @@
53
52
  "typescript": "^5.9.3",
54
53
  "ws": "npm:@kevisual/ws",
55
54
  "xml2js": "^0.6.2",
56
- "zod": "^4.3.5"
55
+ "zod": "^4.3.6"
57
56
  },
58
57
  "repository": {
59
58
  "type": "git",
60
59
  "url": "git+https://github.com/abearxiong/kevisual-router.git"
61
60
  },
62
61
  "dependencies": {
63
- "hono": "^4.11.4"
62
+ "@kevisual/dts": "^0.0.3",
63
+ "hono": "^4.11.7"
64
64
  },
65
65
  "publishConfig": {
66
66
  "access": "public"
package/src/opencode.ts CHANGED
@@ -1,9 +1,10 @@
1
1
  import { useContextKey } from '@kevisual/context'
2
2
  import { createSkill, type QueryRouterServer, tool, type QueryRouter, type Skill } from './route.ts'
3
3
  import { type App } from './app.ts'
4
- import { type Plugin } from "@opencode-ai/plugin"
4
+ import { PluginInput, type Plugin, Hooks } from "@opencode-ai/plugin"
5
5
 
6
6
  import { filter } from '@kevisual/js-filter';
7
+
7
8
  export const addCallFn = (app: App) => {
8
9
  app.route({
9
10
  path: 'call',
@@ -34,10 +35,12 @@ export const addCallFn = (app: App) => {
34
35
  ctx.forward(res);
35
36
  }).addTo(app)
36
37
  }
38
+
37
39
  export const createRouterAgentPluginFn = (opts?: {
38
40
  router?: App | QueryRouterServer,
39
41
  //** 过滤比如,WHERE metadata.tags includes 'opencode' */
40
- query?: string
42
+ query?: string,
43
+ hooks?: (plugin: PluginInput) => Promise<Hooks>
41
44
  }) => {
42
45
  let router = opts?.router
43
46
  if (!router) {
@@ -60,10 +63,14 @@ export const createRouterAgentPluginFn = (opts?: {
60
63
  return !!metadata.skill
61
64
  }
62
65
  return false
63
- })
66
+ });
67
+
64
68
  // opencode run "查看系统信息"
65
- const AgentPlugin: Plugin = async ({ project, client, $, directory, worktree }) => {
69
+ const AgentPlugin: Plugin = async (pluginInput) => {
70
+ useContextKey<PluginInput>('plugin-input', () => pluginInput, true)
71
+ const hooks = opts?.hooks ? await opts.hooks(pluginInput) : {}
66
72
  return {
73
+ ...hooks,
67
74
  'tool': {
68
75
  ...routes.reduce((acc, route) => {
69
76
  const metadata = route.metadata as Skill
@@ -96,13 +103,18 @@ export const createRouterAgentPluginFn = (opts?: {
96
103
  }
97
104
  }
98
105
  return acc;
99
- }, {} as Record<string, any>)
106
+ }, {} as Record<string, any>),
107
+ ...hooks?.tool
100
108
  },
101
- 'tool.execute.before': async (opts) => {
102
- // console.log('CnbPlugin: tool.execute.before', opts.tool);
103
- // delete toolSkills['cnb-login-verify']
104
- }
109
+ // 'tool.execute.before': async (opts) => {
110
+ // // console.log('CnbPlugin: tool.execute.before', opts.tool);
111
+ // // delete toolSkills['cnb-login-verify']
112
+ // },
105
113
  }
106
114
  }
107
115
  return AgentPlugin
108
116
  }
117
+
118
+ export const usePluginInput = (): PluginInput => {
119
+ return useContextKey<PluginInput>('plugin-input')
120
+ }
package/src/route.ts CHANGED
@@ -614,8 +614,7 @@ export class QueryRouter {
614
614
  }
615
615
  /**
616
616
  * 等待程序运行, 获取到message的数据,就执行
617
- * params 是预设参数,默认path为main
618
- *
617
+ * params 是预设参数
619
618
  * emitter = process
620
619
  * -- .exit
621
620
  * -- .on
package/src/test/mini.ts CHANGED
@@ -3,7 +3,9 @@ import { Mini } from "../route.ts";
3
3
  const app = new Mini();
4
4
 
5
5
  app.route({
6
- path: 'main'
6
+ path: 'main',
7
+ id: 'abc',
8
+ description: '这是一个测试的 main 路由'
7
9
  }).define(async (ctx) => {
8
10
  ctx.body = {
9
11
  a: '123'
@@ -49,8 +49,11 @@ export const runCode = async (tsPath: string, params: RunCodeParams = {}): Promi
49
49
  });
50
50
  }
51
51
  import path from 'node:path'
52
- const res =await runCode(path.join(process.cwd(), './src/test/mini.ts'), {
52
+ const res = await runCode(path.join(process.cwd(), './src/test/mini.ts'), {
53
53
  // path: 'main'
54
+ // id: 'abc'
55
+ path: 'router',
56
+ key: 'list'
54
57
  })
55
58
 
56
- console.log('res', res)
59
+ console.log('res', res.data.data.list)
@@ -71,12 +71,19 @@ export const listenProcess = async ({ app, mockProcess, params, timeout = 10 * 6
71
71
  * 如果不提供path,默认是main
72
72
  */
73
73
  const {
74
- path = 'main',
75
74
  payload = {},
76
75
  ...rest
77
76
  } = await getParams()
77
+ const msg = { ...params, ...rest, payload: { ...params?.payload, ...payload } }
78
+ /**
79
+ * 如果没有提供path和id,默认取第一个路由, 而且路由path不是router的
80
+ */
81
+ if (!msg.path && !msg.id) {
82
+ const route = app.routes.find(r => r.path !== 'router')
83
+ msg.id = route?.id
84
+ }
78
85
  // 执行主要逻辑
79
- const result = await app.run({ path, ...params, ...rest, payload: { ...params?.payload, ...payload } })
86
+ const result = await app.run(msg)
80
87
  // 发送结果回主进程
81
88
  const response = {
82
89
  success: true,
package/dist/app.d.ts DELETED
@@ -1,5 +0,0 @@
1
- import * as _opencode_ai_plugin from '@opencode-ai/plugin';
2
-
3
- declare const routerAgentPlugin: _opencode_ai_plugin.Plugin;
4
-
5
- export { routerAgentPlugin };