@kevisual/cnb 0.0.52 → 0.0.54

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/dist/cli.js CHANGED
@@ -4432,7 +4432,7 @@ var require_commander = __commonJS((exports) => {
4432
4432
  exports.InvalidOptionArgumentError = InvalidArgumentError3;
4433
4433
  });
4434
4434
 
4435
- // ../../node_modules/.pnpm/@kevisual+router@0.1.3/node_modules/@kevisual/router/dist/router.js
4435
+ // ../../node_modules/.pnpm/@kevisual+router@0.1.6/node_modules/@kevisual/router/dist/router.js
4436
4436
  import { createRequire as createRequire2 } from "node:module";
4437
4437
  import { webcrypto as crypto } from "node:crypto";
4438
4438
  import url2 from "node:url";
@@ -21947,7 +21947,7 @@ class QueryRouter {
21947
21947
  console.error("=====debug====:", e);
21948
21948
  console.error("=====debug====:[path:key]:", `${route.path}-${route.key}`);
21949
21949
  }
21950
- if (e instanceof CustomError) {
21950
+ if (e instanceof CustomError || e?.code) {
21951
21951
  ctx.code = e.code;
21952
21952
  ctx.message = e.message;
21953
21953
  } else {
@@ -22210,6 +22210,39 @@ class QueryRouterServer extends QueryRouter {
22210
22210
  const { path, key, id } = api2;
22211
22211
  return this.run({ path, key, id, payload }, ctx);
22212
22212
  }
22213
+ async createAuth(fun) {
22214
+ this.route({
22215
+ path: "auth",
22216
+ key: "auth",
22217
+ id: "auth",
22218
+ description: "token验证"
22219
+ }).define(async (ctx) => {
22220
+ if (fun) {
22221
+ await fun(ctx, "auth");
22222
+ }
22223
+ }).addTo(this, { overwrite: false });
22224
+ this.route({
22225
+ path: "auth-admin",
22226
+ key: "auth-admin",
22227
+ id: "auth-admin",
22228
+ description: "admin token验证",
22229
+ middleware: ["auth"]
22230
+ }).define(async (ctx) => {
22231
+ if (fun) {
22232
+ await fun(ctx, "auth-admin");
22233
+ }
22234
+ }).addTo(this, { overwrite: false });
22235
+ this.route({
22236
+ path: "auth-can",
22237
+ key: "auth-can",
22238
+ id: "auth-can",
22239
+ description: "权限验证"
22240
+ }).define(async (ctx) => {
22241
+ if (fun) {
22242
+ await fun(ctx, "auth-can");
22243
+ }
22244
+ }).addTo(this, { overwrite: false });
22245
+ }
22213
22246
  }
22214
22247
  var isNode2 = typeof process !== "undefined" && process.versions != null && process.versions.node != null;
22215
22248
  var isBrowser2 = typeof window !== "undefined" && typeof document !== "undefined" && typeof document.createElement === "function";
@@ -25020,6 +25053,22 @@ class Issue extends CNBCore {
25020
25053
  }
25021
25054
  }
25022
25055
 
25056
+ // src/mission/modules/resources.ts
25057
+ var queryResources = async (cnb, opts) => {
25058
+ const url3 = `${cnb.hackURL}/${opts?.repo || "kevisual/projects"}/-/mission-resource/resources`;
25059
+ return cnb.post({
25060
+ url: url3,
25061
+ data: {
25062
+ selectors: opts?.selectors,
25063
+ slugName: opts?.repo
25064
+ },
25065
+ headers: {
25066
+ Accept: "application/vnd.cnb.web+json"
25067
+ },
25068
+ useCookie: true
25069
+ });
25070
+ };
25071
+
25023
25072
  // src/mission/index.ts
25024
25073
  class Mission extends CNBCore {
25025
25074
  constructor(options) {
@@ -25082,6 +25131,9 @@ class Mission extends CNBCore {
25082
25131
  params: { visibility }
25083
25132
  });
25084
25133
  }
25134
+ queryResources(repo, selectors) {
25135
+ return queryResources(this, { repo, selectors });
25136
+ }
25085
25137
  }
25086
25138
 
25087
25139
  // src/ai/index.ts
@@ -25101,6 +25153,78 @@ class AiBase extends CNBCore {
25101
25153
  }
25102
25154
  }
25103
25155
 
25156
+ // src/labels/repo-label.ts
25157
+ class RepoLabel extends CNBCore {
25158
+ constructor(options) {
25159
+ super(options);
25160
+ }
25161
+ list(repo, params) {
25162
+ const url3 = `/${repo}/-/labels`;
25163
+ return this.get({
25164
+ url: url3,
25165
+ params,
25166
+ headers: {
25167
+ Accept: "application/vnd.cnb.api+json"
25168
+ }
25169
+ });
25170
+ }
25171
+ create(repo, data) {
25172
+ const url3 = `/${repo}/-/labels`;
25173
+ return this.post({
25174
+ url: url3,
25175
+ data
25176
+ });
25177
+ }
25178
+ update(repo, name, data) {
25179
+ const url3 = `/${repo}/-/labels/${encodeURIComponent(name)}`;
25180
+ return this.patch({
25181
+ url: url3,
25182
+ data
25183
+ });
25184
+ }
25185
+ remove(repo, name) {
25186
+ const url3 = `/${repo}/-/labels/${encodeURIComponent(name)}`;
25187
+ return this.delete({ url: url3 });
25188
+ }
25189
+ }
25190
+
25191
+ class IssueLabel extends CNBCore {
25192
+ constructor(options) {
25193
+ super(options);
25194
+ }
25195
+ list(repo, number4, params) {
25196
+ const url3 = `/${repo}/-/issues/${number4}/labels`;
25197
+ return this.get({
25198
+ url: url3,
25199
+ params,
25200
+ headers: {
25201
+ Accept: "application/vnd.cnb.api+json"
25202
+ }
25203
+ });
25204
+ }
25205
+ set(repo, number4, data) {
25206
+ const url3 = `/${repo}/-/issues/${number4}/labels`;
25207
+ return this.put({
25208
+ url: url3,
25209
+ data
25210
+ });
25211
+ }
25212
+ add(repo, number4, data) {
25213
+ const url3 = `/${repo}/-/issues/${number4}/labels`;
25214
+ return this.post({
25215
+ url: url3,
25216
+ data
25217
+ });
25218
+ }
25219
+ clear(repo, number4) {
25220
+ const url3 = `/${repo}/-/issues/${number4}/labels`;
25221
+ return this.delete({ url: url3 });
25222
+ }
25223
+ remove(repo, number4, name) {
25224
+ const url3 = `/${repo}/-/issues/${number4}/labels/${encodeURIComponent(name)}`;
25225
+ return this.delete({ url: url3 });
25226
+ }
25227
+ }
25104
25228
  // src/index.ts
25105
25229
  class CNB extends CNBCore {
25106
25230
  workspace;
@@ -25111,6 +25235,7 @@ class CNB extends CNBCore {
25111
25235
  issue;
25112
25236
  mission;
25113
25237
  ai;
25238
+ labels;
25114
25239
  constructor(options) {
25115
25240
  super({ ...options, token: options.token, cookie: options.cookie, cnb: options.cnb });
25116
25241
  this.init(options);
@@ -25129,6 +25254,10 @@ class CNB extends CNBCore {
25129
25254
  this.issue = new Issue(options);
25130
25255
  this.mission = new Mission(options);
25131
25256
  this.ai = new AiBase(options);
25257
+ this.labels = {
25258
+ repoLabel: new RepoLabel(options),
25259
+ issueLabel: new IssueLabel(options)
25260
+ };
25132
25261
  }
25133
25262
  setToken(token) {
25134
25263
  this.token = token;
@@ -25138,6 +25267,8 @@ class CNB extends CNBCore {
25138
25267
  this.build.token = token;
25139
25268
  this.issue.token = token;
25140
25269
  this.mission.token = token;
25270
+ this.labels.repoLabel.token = token;
25271
+ this.labels.issueLabel.token = token;
25141
25272
  }
25142
25273
  setCookie(cookie) {
25143
25274
  this.cookie = cookie;
@@ -25147,8 +25278,15 @@ class CNB extends CNBCore {
25147
25278
  this.build.cookie = cookie;
25148
25279
  this.issue.cookie = cookie;
25149
25280
  this.mission.cookie = cookie;
25281
+ this.labels.repoLabel.cookie = cookie;
25282
+ this.labels.issueLabel.cookie = cookie;
25150
25283
  }
25284
+ getCNBVersion = getCNBVersion;
25151
25285
  }
25286
+ var getCNBVersion = () => {
25287
+ const url3 = "https://cnb.cool/api/version";
25288
+ return fetch(url3).then((res) => res.json());
25289
+ };
25152
25290
 
25153
25291
  // ../../node_modules/.pnpm/@ai-sdk+provider@3.0.8/node_modules/@ai-sdk/provider/dist/index.mjs
25154
25292
  var marker = "vercel.ai.error";
@@ -46858,6 +46996,169 @@ app.route({
46858
46996
  const res = await cnb.repo.updateRepoInfo(name15, { description, license, site, topics });
46859
46997
  ctx.forward(res);
46860
46998
  }).addTo(app);
46999
+ app.route({
47000
+ path: "cnb",
47001
+ key: "update-repo-visibility",
47002
+ description: "更新代码仓库的可见性, 参数name, visibility",
47003
+ middleware: ["auth"],
47004
+ metadata: {
47005
+ args: {
47006
+ name: tool.schema.string().describe("代码仓库名称"),
47007
+ visibility: tool.schema.string().describe("代码仓库可见性, public 或 private 或 protected")
47008
+ }
47009
+ }
47010
+ }).define(async (ctx) => {
47011
+ const cnb = await cnbManager.getContext(ctx);
47012
+ const name15 = ctx.query?.name;
47013
+ const visibility = ctx.query?.visibility;
47014
+ if (!name15) {
47015
+ ctx.throw(400, "缺少参数 name");
47016
+ }
47017
+ if (!visibility) {
47018
+ ctx.throw(400, "缺少参数 visibility");
47019
+ }
47020
+ const res = await cnb.post({
47021
+ url: `/${name15}/-/settings/set_visibility`,
47022
+ data: { visibility }
47023
+ });
47024
+ ctx.forward(res);
47025
+ }).addTo(app);
47026
+
47027
+ // agent/routes/repo/repo-label.ts
47028
+ app.route({
47029
+ path: "cnb",
47030
+ key: "list-repo-labels",
47031
+ description: "查询仓库的标签列表",
47032
+ middleware: ["auth"],
47033
+ metadata: {
47034
+ tags: ["opencode"],
47035
+ ...createSkill({
47036
+ skill: "list-repo-labels",
47037
+ title: "查询仓库标签列表",
47038
+ summary: "查询仓库的标签列表",
47039
+ args: {
47040
+ repo: tool.schema.string().describe("仓库路径, 如 my-user/my-repo"),
47041
+ page: tool.schema.number().optional().describe("分页页码,默认 1"),
47042
+ pageSize: tool.schema.number().optional().describe("分页每页大小,默认 30"),
47043
+ keyword: tool.schema.string().optional().describe("标签搜索关键词")
47044
+ }
47045
+ })
47046
+ }
47047
+ }).define(async (ctx) => {
47048
+ const cnb = await cnbManager.getContext(ctx);
47049
+ const repo2 = ctx.query?.repo;
47050
+ const page = ctx.query?.page;
47051
+ const pageSize = ctx.query?.pageSize;
47052
+ const keyword = ctx.query?.keyword;
47053
+ if (!repo2) {
47054
+ ctx.throw(400, "缺少参数 repo");
47055
+ }
47056
+ const res = await cnb.labels.repoLabel.list(repo2, {
47057
+ page,
47058
+ page_size: pageSize,
47059
+ keyword
47060
+ });
47061
+ ctx.forward(res);
47062
+ }).addTo(app);
47063
+ app.route({
47064
+ path: "cnb",
47065
+ key: "create-repo-label",
47066
+ description: "创建仓库标签",
47067
+ middleware: ["auth"],
47068
+ metadata: {
47069
+ tags: ["opencode"],
47070
+ ...createSkill({
47071
+ skill: "create-repo-label",
47072
+ title: "创建仓库标签",
47073
+ summary: "创建一个仓库标签",
47074
+ args: {
47075
+ repo: tool.schema.string().describe("仓库路径, 如 my-user/my-repo"),
47076
+ name: tool.schema.string().describe("标签名称"),
47077
+ color: tool.schema.string().describe("标签颜色,十六进制颜色码,不含 # 前缀"),
47078
+ description: tool.schema.string().optional().describe("标签描述")
47079
+ }
47080
+ })
47081
+ }
47082
+ }).define(async (ctx) => {
47083
+ const cnb = await cnbManager.getContext(ctx);
47084
+ const repo2 = ctx.query?.repo;
47085
+ const name15 = ctx.query?.name;
47086
+ const color = ctx.query?.color;
47087
+ const description = ctx.query?.description;
47088
+ if (!repo2 || !name15 || !color) {
47089
+ ctx.throw(400, "缺少参数 repo, name 或 color");
47090
+ }
47091
+ const res = await cnb.labels.repoLabel.create(repo2, {
47092
+ name: name15,
47093
+ color,
47094
+ description
47095
+ });
47096
+ ctx.forward(res);
47097
+ }).addTo(app);
47098
+ app.route({
47099
+ path: "cnb",
47100
+ key: "update-repo-label",
47101
+ description: "更新仓库标签",
47102
+ middleware: ["auth"],
47103
+ metadata: {
47104
+ tags: ["opencode"],
47105
+ ...createSkill({
47106
+ skill: "update-repo-label",
47107
+ title: "更新仓库标签",
47108
+ summary: "更新仓库标签信息",
47109
+ args: {
47110
+ repo: tool.schema.string().describe("仓库路径, 如 my-user/my-repo"),
47111
+ name: tool.schema.string().describe("标签名称"),
47112
+ color: tool.schema.string().optional().describe("标签颜色,十六进制颜色码,不含 # 前缀"),
47113
+ description: tool.schema.string().optional().describe("标签描述"),
47114
+ newName: tool.schema.string().optional().describe("新标签名称")
47115
+ }
47116
+ })
47117
+ }
47118
+ }).define(async (ctx) => {
47119
+ const cnb = await cnbManager.getContext(ctx);
47120
+ const repo2 = ctx.query?.repo;
47121
+ const name15 = ctx.query?.name;
47122
+ const color = ctx.query?.color;
47123
+ const description = ctx.query?.description;
47124
+ const newName = ctx.query?.newName;
47125
+ if (!repo2 || !name15) {
47126
+ ctx.throw(400, "缺少参数 repo 或 name");
47127
+ }
47128
+ const res = await cnb.labels.repoLabel.update(repo2, name15, {
47129
+ color,
47130
+ description,
47131
+ new_name: newName
47132
+ });
47133
+ ctx.forward(res);
47134
+ }).addTo(app);
47135
+ app.route({
47136
+ path: "cnb",
47137
+ key: "delete-repo-label",
47138
+ description: "删除仓库标签",
47139
+ middleware: ["auth"],
47140
+ metadata: {
47141
+ tags: ["opencode"],
47142
+ ...createSkill({
47143
+ skill: "delete-repo-label",
47144
+ title: "删除仓库标签",
47145
+ summary: "删除指定的仓库标签",
47146
+ args: {
47147
+ repo: tool.schema.string().describe("仓库路径, 如 my-user/my-repo"),
47148
+ name: tool.schema.string().describe("标签名称")
47149
+ }
47150
+ })
47151
+ }
47152
+ }).define(async (ctx) => {
47153
+ const cnb = await cnbManager.getContext(ctx);
47154
+ const repo2 = ctx.query?.repo;
47155
+ const name15 = ctx.query?.name;
47156
+ if (!repo2 || !name15) {
47157
+ ctx.throw(400, "缺少参数 repo 或 name");
47158
+ }
47159
+ const res = await cnb.labels.repoLabel.remove(repo2, name15);
47160
+ ctx.forward(res);
47161
+ }).addTo(app);
46861
47162
 
46862
47163
  // agent/routes/workspace/skills.ts
46863
47164
  app.route({
@@ -47948,7 +48249,7 @@ app.route({
47948
48249
  let repo2 = ctx.query?.repo || useKey("CNB_REPO_SLUG_LOWERCASE");
47949
48250
  const state = ctx.query?.state;
47950
48251
  const keyword = ctx.query?.keyword;
47951
- const labels = ctx.query?.labels;
48252
+ const labels2 = ctx.query?.labels;
47952
48253
  const page = ctx.query?.page ? Number(ctx.query.page) : undefined;
47953
48254
  const page_size = ctx.query?.page_size ? Number(ctx.query.page_size) : undefined;
47954
48255
  const order_by = ctx.query?.order_by;
@@ -47960,8 +48261,8 @@ app.route({
47960
48261
  params.state = state;
47961
48262
  if (keyword)
47962
48263
  params.keyword = keyword;
47963
- if (labels)
47964
- params.labels = labels;
48264
+ if (labels2)
48265
+ params.labels = labels2;
47965
48266
  if (page)
47966
48267
  params.page = page;
47967
48268
  if (page_size)
@@ -48030,7 +48331,7 @@ app.route({
48030
48331
  const title = ctx.query?.title;
48031
48332
  const body = ctx.query?.body;
48032
48333
  const assignees = ctx.query?.assignees;
48033
- const labels = ctx.query?.labels;
48334
+ const labels2 = ctx.query?.labels;
48034
48335
  const priority = ctx.query?.priority;
48035
48336
  if (!repo2 || !title) {
48036
48337
  ctx.throw(400, "缺少参数 repo 或 title");
@@ -48039,7 +48340,7 @@ app.route({
48039
48340
  title,
48040
48341
  body,
48041
48342
  assignees,
48042
- labels,
48343
+ labels: labels2,
48043
48344
  priority
48044
48345
  });
48045
48346
  ctx.forward(res);
@@ -48296,7 +48597,7 @@ var getLiveMdContent = (opts) => {
48296
48597
  2. Opencode web访问说明
48297
48598
  Opencode打开web地址,需要在浏览器输入用户名和密码,用户名固定为root,密码为CNB_TOKEN的值. 纯连接打开包含账号密码,第一次点击后,需要把账号密码清理掉才能访问,opencode的bug导致的。
48298
48599
  `;
48299
- const labels = [
48600
+ const labels2 = [
48300
48601
  {
48301
48602
  key: "vscodeWebUrl",
48302
48603
  title: "VSCode Web 地址",
@@ -48353,11 +48654,11 @@ Opencode打开web地址,需要在浏览器输入用户名和密码,用户名
48353
48654
  }
48354
48655
  ];
48355
48656
  const osInfoList = createOSInfo(more);
48356
- labels.push(...osInfoList);
48357
- return labels;
48657
+ labels2.push(...osInfoList);
48658
+ return labels2;
48358
48659
  };
48359
48660
  var createOSInfo = (more = false) => {
48360
- const labels = [];
48661
+ const labels2 = [];
48361
48662
  const startTimer = useKey("CNB_BUILD_START_TIME") || "";
48362
48663
  const cpus = os2.cpus();
48363
48664
  let totalIdle = 0;
@@ -48417,7 +48718,7 @@ var createOSInfo = (more = false) => {
48417
48718
  } catch (e) {
48418
48719
  diskUsage = "获取失败";
48419
48720
  }
48420
- labels.push({
48721
+ labels2.push({
48421
48722
  key: "cpuUsage",
48422
48723
  title: "CPU 使用率",
48423
48724
  value: `${cpuUsage}%`,
@@ -48459,7 +48760,7 @@ var createOSInfo = (more = false) => {
48459
48760
  const buildUptime = Date.now() - buildStartTimestamp;
48460
48761
  const buildUptimeStr = formatUptime(Math.floor(buildUptime / 1000));
48461
48762
  const maxRunTime = useKey("CNB_PIPELINE_MAX_RUN_TIME") || 0;
48462
- labels.push({
48763
+ labels2.push({
48463
48764
  key: "buildStartTime",
48464
48765
  title: "构建启动时间",
48465
48766
  value: buildStartTime,
@@ -48478,13 +48779,13 @@ var createOSInfo = (more = false) => {
48478
48779
  timeTo4 = today4am.add(1, "day").valueOf() - now.valueOf();
48479
48780
  }
48480
48781
  const timeTo4Str = `[距离晚上4点重启时间: ${formatUptime(Math.floor(timeTo4 / 1000))}]`;
48481
- labels.push({
48782
+ labels2.push({
48482
48783
  key: "buildMaxRunTime",
48483
48784
  title: "最大运行时间",
48484
48785
  value: formatUptime(Math.floor(maxRunTime / 1000)),
48485
48786
  description: "构建最大运行时间(限制时间)"
48486
48787
  });
48487
- labels.unshift({
48788
+ labels2.unshift({
48488
48789
  key: "remainingTime",
48489
48790
  title: "剩余时间",
48490
48791
  value: maxRunTime - buildUptime,
@@ -48494,7 +48795,7 @@ var createOSInfo = (more = false) => {
48494
48795
  }
48495
48796
  if (more) {
48496
48797
  const loadavg = os2.loadavg();
48497
- labels.push({
48798
+ labels2.push({
48498
48799
  key: "hostname",
48499
48800
  title: "主机名",
48500
48801
  value: os2.hostname(),
@@ -48531,7 +48832,7 @@ var createOSInfo = (more = false) => {
48531
48832
  description: "系统负载 (15分钟)"
48532
48833
  });
48533
48834
  }
48534
- return labels;
48835
+ return labels2;
48535
48836
  };
48536
48837
 
48537
48838
  // agent/routes/cnb-board/cnb-dev-env.ts
@@ -48568,7 +48869,7 @@ app.route({
48568
48869
  if (notCNBCheck(ctx))
48569
48870
  return;
48570
48871
  const repoNameFromSlug = repoSlug.split("/").pop() || "";
48571
- const labels = [
48872
+ const labels2 = [
48572
48873
  {
48573
48874
  title: "CNB_REPO_SLUG",
48574
48875
  value: repoSlug,
@@ -48602,7 +48903,7 @@ app.route({
48602
48903
  ];
48603
48904
  ctx.body = {
48604
48905
  title: "CNB_BOARD_LIVE_REPO_INFO",
48605
- list: labels
48906
+ list: labels2
48606
48907
  };
48607
48908
  }).addTo(app);
48608
48909
  app.route({
@@ -48613,7 +48914,7 @@ app.route({
48613
48914
  }).define(async (ctx) => {
48614
48915
  if (notCNBCheck(ctx))
48615
48916
  return;
48616
- const labels = [
48917
+ const labels2 = [
48617
48918
  {
48618
48919
  title: "CNB_BUILD_ID",
48619
48920
  value: useKey("CNB_BUILD_ID") || "",
@@ -48747,7 +49048,7 @@ app.route({
48747
49048
  ];
48748
49049
  ctx.body = {
48749
49050
  title: "CNB_BOARD_LIVE_BUILD_INFO",
48750
- list: labels
49051
+ list: labels2
48751
49052
  };
48752
49053
  }).addTo(app);
48753
49054
  app.route({
@@ -48756,7 +49057,7 @@ app.route({
48756
49057
  description: "获取cnb-board live的PR信息",
48757
49058
  middleware: ["auth-admin"]
48758
49059
  }).define(async (ctx) => {
48759
- const labels = [
49060
+ const labels2 = [
48760
49061
  {
48761
49062
  title: "CNB_PULL_REQUEST",
48762
49063
  value: useKey("CNB_PULL_REQUEST") || "",
@@ -48845,7 +49146,7 @@ app.route({
48845
49146
  ];
48846
49147
  ctx.body = {
48847
49148
  title: "CNB_BOARD_LIVE_PULL_INFO",
48848
- list: labels
49149
+ list: labels2
48849
49150
  };
48850
49151
  }).addTo(app);
48851
49152
  app.route({
@@ -48856,7 +49157,7 @@ app.route({
48856
49157
  }).define(async (ctx) => {
48857
49158
  if (notCNBCheck(ctx))
48858
49159
  return;
48859
- const labels = [
49160
+ const labels2 = [
48860
49161
  {
48861
49162
  title: "CNB_NPC_SLUG",
48862
49163
  value: useKey("CNB_NPC_SLUG") || "",
@@ -48890,7 +49191,7 @@ app.route({
48890
49191
  ];
48891
49192
  ctx.body = {
48892
49193
  title: "CNB_BOARD_LIVE_NPC_INFO",
48893
- list: labels
49194
+ list: labels2
48894
49195
  };
48895
49196
  }).addTo(app);
48896
49197
  app.route({
@@ -48901,7 +49202,7 @@ app.route({
48901
49202
  }).define(async (ctx) => {
48902
49203
  if (notCNBCheck(ctx))
48903
49204
  return;
48904
- const labels = [
49205
+ const labels2 = [
48905
49206
  {
48906
49207
  title: "CNB_COMMENT_ID",
48907
49208
  value: useKey("CNB_COMMENT_ID") || "",
@@ -48935,7 +49236,7 @@ app.route({
48935
49236
  ];
48936
49237
  ctx.body = {
48937
49238
  title: "CNB_BOARD_LIVE_COMMENT_INFO",
48938
- list: labels
49239
+ list: labels2
48939
49240
  };
48940
49241
  }).addTo(app);
48941
49242
 
@@ -55074,6 +55375,44 @@ app.route({
55074
55375
  ctx.body = result;
55075
55376
  }).addTo(app);
55076
55377
 
55378
+ // agent/routes/missions/list.ts
55379
+ app.route({
55380
+ path: "cnb",
55381
+ key: "missions-list",
55382
+ description: "查询missions列表",
55383
+ metadata: {
55384
+ args: {
55385
+ repo: zod_default.string().optional().describe("missions所在的仓库,例如 kevisual/projects"),
55386
+ selector: zod_default.array(zod_default.any()).optional().describe('查询条件,例如 [{field: "resource_type", operator: "contains", value: ["issues"]},…]')
55387
+ }
55388
+ }
55389
+ }).define(async (ctx) => {
55390
+ const cnb = await cnbManager.getContext(ctx);
55391
+ const repo2 = ctx.query?.repo || "kevisual/projects";
55392
+ const res = await cnb.mission.queryResources(repo2, ctx.query?.selector || [
55393
+ {
55394
+ field: "resource_type",
55395
+ operator: "contains",
55396
+ value: [
55397
+ "issues"
55398
+ ]
55399
+ },
55400
+ {
55401
+ field: "state",
55402
+ operator: "not_equals",
55403
+ value: [
55404
+ "closed"
55405
+ ]
55406
+ },
55407
+ {
55408
+ field: "label",
55409
+ operator: "contains",
55410
+ value: ["AICoding"]
55411
+ }
55412
+ ]);
55413
+ ctx.forward(res);
55414
+ }).addTo(app);
55415
+
55077
55416
  // agent/routes/index.ts
55078
55417
  var checkAppId = (ctx, appId) => {
55079
55418
  const _appId = ctx?.app?.appId;
@@ -55125,7 +55464,7 @@ var {
55125
55464
  Help
55126
55465
  } = import__3.default;
55127
55466
 
55128
- // ../../node_modules/.pnpm/@kevisual+remote-app@0.0.7/node_modules/@kevisual/remote-app/dist/app.js
55467
+ // ../../node_modules/.pnpm/@kevisual+remote-app@0.0.6/node_modules/@kevisual/remote-app/dist/app.js
55129
55468
  var __create4 = Object.create;
55130
55469
  var __getProtoOf4 = Object.getPrototypeOf;
55131
55470
  var __defProp5 = Object.defineProperty;
@@ -55340,12 +55679,10 @@ class RemoteApp {
55340
55679
  reconnectAttempts = 0;
55341
55680
  reconnectTimer = null;
55342
55681
  isManuallyClosed = false;
55343
- isInitializing = false;
55344
- initId = 0;
55345
55682
  constructor(opts) {
55346
55683
  this.mainApp = opts?.app;
55347
55684
  const token2 = opts.token;
55348
- const url4 = opts.url || "https://kevisual.cn/ws/proxy";
55685
+ const url4 = opts.url;
55349
55686
  const id = opts.id;
55350
55687
  const username = opts.username;
55351
55688
  this.username = username;
@@ -55411,17 +55748,10 @@ class RemoteApp {
55411
55748
  return wsURL;
55412
55749
  }
55413
55750
  async init() {
55414
- if (this.isInitializing) {
55415
- return;
55416
- }
55417
- this.isInitializing = true;
55418
- const currentInitId = ++this.initId;
55419
55751
  if (!this.url) {
55420
- this.isInitializing = false;
55421
55752
  throw new Error("No url provided for remote app");
55422
55753
  }
55423
55754
  if (!this.id) {
55424
- this.isInitializing = false;
55425
55755
  throw new Error("No id provided for remote app");
55426
55756
  }
55427
55757
  this.isError = false;
@@ -55431,20 +55761,11 @@ class RemoteApp {
55431
55761
  const ws = new WebSocket(this.getWsURL(this.url));
55432
55762
  const that = this;
55433
55763
  ws.onopen = function() {
55434
- if (currentInitId !== that.initId) {
55435
- ws.close();
55436
- return;
55437
- }
55438
55764
  that.isConnected = true;
55439
- that.isInitializing = false;
55440
55765
  that.onOpen();
55441
55766
  console.log("[remote-app] WebSocket connection opened");
55442
55767
  };
55443
55768
  ws.onclose = function() {
55444
- if (currentInitId !== that.initId) {
55445
- return;
55446
- }
55447
- that.isInitializing = false;
55448
55769
  that.isConnected = false;
55449
55770
  that.onClose();
55450
55771
  };
@@ -55452,10 +55773,6 @@ class RemoteApp {
55452
55773
  that.onMessage(event.data);
55453
55774
  };
55454
55775
  ws.onerror = function(error49) {
55455
- if (currentInitId !== that.initId) {
55456
- return;
55457
- }
55458
- that.isInitializing = false;
55459
55776
  that.onError(error49);
55460
55777
  };
55461
55778
  this.ws = ws;
@@ -55609,7 +55926,7 @@ class RemoteApp {
55609
55926
  }
55610
55927
  }
55611
55928
 
55612
- // ../../node_modules/.pnpm/@kevisual+router@0.1.3/node_modules/@kevisual/router/src/commander.ts
55929
+ // ../../node_modules/.pnpm/@kevisual+router@0.1.6/node_modules/@kevisual/router/src/commander.ts
55613
55930
  var groupByPath = (routes) => {
55614
55931
  return routes.reduce((acc, route) => {
55615
55932
  const path3 = route.path || "default";
@@ -55729,23 +56046,7 @@ var parse8 = async (opts) => {
55729
56046
  _program.version(version3);
55730
56047
  }
55731
56048
  app3.createRouteList();
55732
- app3.route({
55733
- path: "cli",
55734
- key: "list"
55735
- }).define(async () => {
55736
- const routes = app3.routes.map((route) => {
55737
- return {
55738
- path: route.path,
55739
- key: route.key,
55740
- description: route?.metadata?.summary || route.description || ""
55741
- };
55742
- });
55743
- const table = routes.map((route) => {
55744
- return `${route.path} ${route.key} - ${route.description}`;
55745
- }).join(`
55746
- `);
55747
- console.log(table);
55748
- }).addTo(app3, { overwrite: false });
56049
+ createCliList(app3);
55749
56050
  createCommand2({ app: app3, program: _program });
55750
56051
  if (opts.remote) {
55751
56052
  const { token: token2, username, id } = opts.remote;
@@ -55768,6 +56069,82 @@ var parse8 = async (opts) => {
55768
56069
  }
55769
56070
  }
55770
56071
  };
56072
+ var createCliList = (app3) => {
56073
+ app3.route({
56074
+ path: "cli",
56075
+ key: "list",
56076
+ description: "列出所有可用的命令",
56077
+ metadata: {
56078
+ summary: "列出所有可用的命令",
56079
+ args: {
56080
+ q: zod_default.string().optional().describe("查询关键词,支持模糊匹配命令"),
56081
+ path: zod_default.string().optional().describe("按路径前缀过滤,如 user、admin"),
56082
+ tags: zod_default.string().optional().describe("按标签过滤,多个标签用逗号分隔"),
56083
+ sort: zod_default.enum(["key", "path", "name"]).optional().describe("排序方式"),
56084
+ limit: zod_default.number().optional().describe("限制返回数量"),
56085
+ offset: zod_default.number().optional().describe("偏移量,用于分页"),
56086
+ format: zod_default.enum(["table", "simple", "json"]).optional().describe("输出格式")
56087
+ }
56088
+ }
56089
+ }).define(async (ctx) => {
56090
+ const { q, path: pathFilter, tags, sort, limit, offset, format } = ctx.query;
56091
+ let routes = app3.routes.map((route) => {
56092
+ return {
56093
+ path: route.path,
56094
+ key: route.key,
56095
+ description: route?.metadata?.summary || route.description || "",
56096
+ tags: route?.metadata?.tags || []
56097
+ };
56098
+ });
56099
+ if (pathFilter) {
56100
+ routes = routes.filter((route) => route.path.startsWith(pathFilter));
56101
+ }
56102
+ if (tags) {
56103
+ const tagList = tags.split(",").map((t) => t.trim().toLowerCase()).filter(Boolean);
56104
+ if (tagList.length > 0) {
56105
+ routes = routes.filter((route) => {
56106
+ const routeTags = Array.isArray(route.tags) ? route.tags.map((t) => String(t).toLowerCase()) : [];
56107
+ return tagList.some((tag) => routeTags.includes(tag));
56108
+ });
56109
+ }
56110
+ }
56111
+ if (q) {
56112
+ const keyword = q.toLowerCase();
56113
+ routes = routes.filter((route) => {
56114
+ return route.path.toLowerCase().includes(keyword) || route.key.toLowerCase().includes(keyword) || route.description.toLowerCase().includes(keyword);
56115
+ });
56116
+ }
56117
+ if (sort) {
56118
+ routes.sort((a, b) => {
56119
+ if (sort === "path")
56120
+ return a.path.localeCompare(b.path);
56121
+ if (sort === "key")
56122
+ return a.key.localeCompare(b.key);
56123
+ return a.key.localeCompare(b.key);
56124
+ });
56125
+ }
56126
+ const total = routes.length;
56127
+ const start = offset || 0;
56128
+ const end = limit ? start + limit : undefined;
56129
+ routes = routes.slice(start, end);
56130
+ const outputFormat = format || "table";
56131
+ if (outputFormat === "json") {
56132
+ console.log(JSON.stringify({ total, offset: start, limit, routes }, null, 2));
56133
+ return;
56134
+ }
56135
+ if (outputFormat === "simple") {
56136
+ routes.forEach((route) => {
56137
+ console.log(`${route.path} ${route.key}`);
56138
+ });
56139
+ return;
56140
+ }
56141
+ const table = routes.map((route) => {
56142
+ return `${route.path} ${route.key} - ${route.description}`;
56143
+ }).join(`
56144
+ `);
56145
+ console.log(table);
56146
+ }).addTo(app3, { overwrite: false });
56147
+ };
55771
56148
 
55772
56149
  // agent/cli.ts
55773
56150
  await parse8({ app, description: "CNB控制台命令行工具", parse: true });