@kevisual/router 0.1.2 → 0.1.4

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.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package",
3
3
  "name": "@kevisual/router",
4
- "version": "0.1.2",
4
+ "version": "0.1.4",
5
5
  "description": "",
6
6
  "type": "module",
7
7
  "main": "./dist/router.js",
@@ -30,7 +30,7 @@
30
30
  "@kevisual/query": "^0.0.53",
31
31
  "@kevisual/remote-app": "^0.0.7",
32
32
  "@kevisual/use-config": "^1.0.30",
33
- "@opencode-ai/plugin": "^1.2.26",
33
+ "@opencode-ai/plugin": "^1.2.27",
34
34
  "@types/bun": "^1.3.10",
35
35
  "@types/crypto-js": "^4.2.2",
36
36
  "@types/node": "^25.5.0",
@@ -43,7 +43,7 @@
43
43
  "eventemitter3": "^5.0.4",
44
44
  "fast-glob": "^3.3.3",
45
45
  "hono": "^4.12.8",
46
- "nanoid": "^5.1.6",
46
+ "nanoid": "^5.1.7",
47
47
  "path-to-regexp": "^8.3.0",
48
48
  "send": "^1.2.1",
49
49
  "typescript": "^5.9.3",
package/src/commander.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { Command, program } from 'commander';
2
- import { App, QueryRouterServer } from './app.ts';
2
+ import { App } from './app.ts';
3
3
  import { RemoteApp } from '@kevisual/remote-app'
4
+ import z from 'zod';
4
5
  export const groupByPath = (routes: App['routes']) => {
5
6
  return routes.reduce((acc, route) => {
6
7
  const path = route.path || 'default';
@@ -124,9 +125,10 @@ export const parse = async (opts: {
124
125
  token?: string,
125
126
  username?: string,
126
127
  id?: string,
127
- }
128
+ },
129
+ exitOnEnd?: boolean,
128
130
  }) => {
129
- const { description, parse = true, version } = opts;
131
+ const { description, parse = true, version, exitOnEnd = true } = opts;
130
132
  const app = opts.app as App;
131
133
  const _program = opts.program || program;
132
134
  _program.description(description || 'Router 命令行工具');
@@ -134,25 +136,8 @@ export const parse = async (opts: {
134
136
  _program.version(version);
135
137
  }
136
138
  app.createRouteList();
137
- app.route({
138
- path: 'cli',
139
- key: 'list'
140
- }).define(async () => {
141
- const routes = app.routes.map(route => {
142
- return {
143
- path: route.path,
144
- key: route.key,
145
- description: route?.metadata?.summary || route.description || '',
146
- };
147
- });
148
- // 输出为表格格式
149
- const table = routes.map(route => {
150
- return `${route.path} ${route.key} - ${route.description}`;
151
- }).join('\n');
152
-
153
- console.log(table);
154
- }).addTo(app, { overwrite: false })
155
139
 
140
+ createCliList(app);
156
141
  createCommand({ app: app as App, program: _program });
157
142
 
158
143
  if (opts.remote) {
@@ -167,9 +152,104 @@ export const parse = async (opts: {
167
152
  remoteApp.listenProxy();
168
153
  console.log('已连接到远程应用,正在监听命令...');
169
154
  }
170
- return
155
+ return;
171
156
  }
172
157
  if (parse) {
173
- _program.parse(process.argv);
158
+ await _program.parseAsync(process.argv);
159
+ if (exitOnEnd) {
160
+ process.exit(0);
161
+ }
174
162
  }
163
+ }
164
+
165
+ const createCliList = (app: App) => {
166
+ app.route({
167
+ path: 'cli',
168
+ key: 'list',
169
+ description: '列出所有可用的命令',
170
+ metadata: {
171
+ summary: '列出所有可用的命令',
172
+ args: {
173
+ q: z.string().optional().describe('查询关键词,支持模糊匹配命令'),
174
+ path: z.string().optional().describe('按路径前缀过滤,如 user、admin'),
175
+ tags: z.string().optional().describe('按标签过滤,多个标签用逗号分隔'),
176
+ sort: z.enum(['key', 'path', 'name']).optional().describe('排序方式'),
177
+ limit: z.number().optional().describe('限制返回数量'),
178
+ offset: z.number().optional().describe('偏移量,用于分页'),
179
+ format: z.enum(['table', 'simple', 'json']).optional().describe('输出格式'),
180
+ }
181
+ }
182
+ }).define(async (ctx) => {
183
+ const { q, path: pathFilter, tags, sort, limit, offset, format } = ctx.query as any;
184
+ let routes = app.routes.map(route => {
185
+ return {
186
+ path: route.path,
187
+ key: route.key,
188
+ description: route?.metadata?.summary || route.description || '',
189
+ tags: route?.metadata?.tags || [],
190
+ };
191
+ });
192
+
193
+ // 路径过滤
194
+ if (pathFilter) {
195
+ routes = routes.filter(route => route.path.startsWith(pathFilter));
196
+ }
197
+
198
+ // 标签过滤
199
+ if (tags) {
200
+ const tagList = tags.split(',').map((t: string) => t.trim().toLowerCase()).filter(Boolean);
201
+ if (tagList.length > 0) {
202
+ routes = routes.filter(route => {
203
+ const routeTags = Array.isArray(route.tags) ? route.tags.map((t: unknown) => String(t).toLowerCase()) : [];
204
+ return tagList.some((tag: string) => routeTags.includes(tag));
205
+ });
206
+ }
207
+ }
208
+
209
+ // 关键词过滤
210
+ if (q) {
211
+ const keyword = q.toLowerCase();
212
+ routes = routes.filter(route => {
213
+ return route.path.toLowerCase().includes(keyword) ||
214
+ route.key.toLowerCase().includes(keyword) ||
215
+ route.description.toLowerCase().includes(keyword);
216
+ });
217
+ }
218
+
219
+ // 排序
220
+ if (sort) {
221
+ routes.sort((a, b) => {
222
+ if (sort === 'path') return a.path.localeCompare(b.path);
223
+ if (sort === 'key') return a.key.localeCompare(b.key);
224
+ return a.key.localeCompare(b.key); // name 默认为 key
225
+ });
226
+ }
227
+
228
+ // 分页
229
+ const total = routes.length;
230
+ const start = offset || 0;
231
+ const end = limit ? start + limit : undefined;
232
+ routes = routes.slice(start, end);
233
+
234
+ // 输出
235
+ const outputFormat = format || 'table';
236
+ if (outputFormat === 'json') {
237
+ console.log(JSON.stringify({ total, offset: start, limit, routes }, null, 2));
238
+ return;
239
+ }
240
+
241
+ if (outputFormat === 'simple') {
242
+ routes.forEach(route => {
243
+ console.log(`${route.path} ${route.key}`);
244
+ });
245
+ return;
246
+ }
247
+
248
+ // table 格式
249
+ const table = routes.map(route => {
250
+ return `${route.path} ${route.key} - ${route.description}`;
251
+ }).join('\n');
252
+
253
+ console.log(table);
254
+ }).addTo(app, { overwrite: false })
175
255
  }
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 };