c456-cli 0.1.5 → 0.2.0

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.
Files changed (3) hide show
  1. package/README.md +30 -9
  2. package/dist/index.js +283 -90
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -83,26 +83,37 @@ c456 config show
83
83
 
84
84
  ## 常用命令
85
85
 
86
- ### 收录(intake)
86
+ ### 数据管理(5 大类)
87
87
 
88
88
  ```bash
89
- # 按 URL 创建 tool 收录(-B 为站点,-u 为收录目标)
90
- c456 -B https://c456.example.com intake new -k tool -u "https://github.com/owner/repo"
89
+ # 工具
90
+ c456 tool new -u "https://github.com/owner/repo" --auto-resolve-url
91
+
92
+ # 渠道
93
+ c456 channel new -u "https://example.com" --auto-resolve-url
91
94
 
92
95
  # 纯文本信号(可无 URL)
93
- c456 intake new -k signal -t "标题" -b "正文"
96
+ c456 signal new -t "标题" -b "正文"
97
+
98
+ c456 signal show <id>
99
+ c456 signal list -q "关键词" --stage raw
100
+ c456 signal refine <id> --to cleaned --ai
101
+ c456 signal update <id> --refinement-status approved
102
+
103
+ # 打法(M1/M2 仍为独立资源;M3 会逐步合回 Intake)
104
+ c456 playbook new -t "标题" -b "Markdown 正文"
105
+ c456 playbook show <id>
106
+ c456 playbook list -q "关键词"
94
107
 
95
- c456 intake show <id>
96
- c456 intake list -k signal -q "关键词"
97
- c456 intake update <id> -t "新标题"
98
- c456 intake delete <id> --force
108
+ # 讲解
109
+ c456 walkthrough new -t "标题" --cast-file ./demo.cast
110
+ c456 walkthrough list
99
111
  ```
100
112
 
101
113
  ### 资料抓取(fetch)
102
114
 
103
115
  ```bash
104
116
  c456 fetch profile -u "https://..." -p link_product
105
- c456 fetch detect -u "https://..."
106
117
  ```
107
118
 
108
119
  ### 搜索(search)
@@ -112,6 +123,16 @@ c456 search signals -q "关键词"
112
123
  c456 search playbooks -q "关键词"
113
124
  ```
114
125
 
126
+ ### AI 自动识别入口(intake)
127
+
128
+ `intake` 保留为 **AI 识别与录入** 的入口:当你不确定应该落到 signal/tool/channel/playbook 时使用。
129
+
130
+ ```bash
131
+ c456 intake new -t "疑似工具/渠道/信号" -b "一段描述或粘贴内容"
132
+ ```
133
+
134
+ 当 AI 判断不在 `signal/tool/channel/playbook/walkthrough` 五类范围内,会返回 422 并给出错误提示;若识别为 `walkthrough`,会提示改用 `walkthrough` 子命令(因为需要媒体文件/外链)。
135
+
115
136
  ### 打法(playbook)
116
137
 
117
138
  ```bash
package/dist/index.js CHANGED
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/index.js
4
- import { Command as Command7 } from "commander";
4
+ import { Command as Command9 } from "commander";
5
5
 
6
6
  // package.json
7
7
  var package_default = {
8
8
  name: "c456-cli",
9
- version: "0.1.5",
9
+ version: "0.2.0",
10
10
  description: "C456 CLI - \u5185\u5BB9\u5F55\u5165\u4E0E\u6574\u7406\u5DE5\u5177",
11
11
  type: "module",
12
12
  bin: {
@@ -270,9 +270,22 @@ function resolveApi(cmd) {
270
270
  return { apiKey, baseUrl, client: new ApiClient(baseUrl, apiKey) };
271
271
  }
272
272
 
273
+ // src/textFile.js
274
+ import { readFileSync as readFileSync2 } from "node:fs";
275
+ function readTextFile(path) {
276
+ try {
277
+ return readFileSync2(path, "utf-8");
278
+ } catch (e) {
279
+ const msg = e instanceof Error ? e.message : String(e);
280
+ console.error(`\u9519\u8BEF\uFF1A\u65E0\u6CD5\u8BFB\u53D6\u6587\u4EF6\uFF1A${path}`);
281
+ console.error(msg);
282
+ process.exit(1);
283
+ }
284
+ }
285
+
273
286
  // src/commands/intake.js
274
- var intake = new Command().name("intake").description("\u6536\u5F55\u7BA1\u7406 - \u521B\u5EFA\u3001\u66F4\u65B0\u3001\u5220\u9664\u5DE5\u5177/\u6E20\u9053/\u4FE1\u53F7");
275
- intake.command("new").description("\u521B\u5EFA\u65B0\u6536\u5F55").option("-u, --url <url>", "\u76EE\u6807 URL\uFF08tool/channel \u65F6\u53EF\u9009\uFF0C\u7528\u4E8E\u81EA\u52A8\u89E3\u6790\u8D44\u6599\uFF09").option("-k, --kind <type>", "\u7C7B\u578B\uFF1Asignal/tool/channel\uFF08\u9ED8\u8BA4 signal\uFF09", "signal").option("-t, --title <title>", "\u6807\u9898\uFF08tool/channel \u5FC5\u586B\uFF09").option("-b, --body <text>", "\u6B63\u6587/\u63CF\u8FF0\uFF08type: markdown_kramdown\uFF1B\u8BED\u6CD5\u89C1 references/content-syntax-kramdown.md\uFF09").option("--profile-data-json <json>", "\u8D44\u6599\u6BB5 JSON\uFF08tool/channel\uFF09").action(async (opts, cmd) => {
287
+ var intake = new Command().name("intake").description("AI \u5F55\u5165\u5165\u53E3 - \u81EA\u52A8\u8BC6\u522B\u7C7B\u578B\u5E76\u521B\u5EFA\uFF08signal/tool/channel/playbook\uFF1Bwalkthrough \u9700\u8D70 walkthrough \u547D\u4EE4\uFF09");
288
+ intake.command("new").description("AI \u81EA\u52A8\u8BC6\u522B\u5E76\u521B\u5EFA\uFF08\u65E7\u7684 kind \u624B\u52A8\u521B\u5EFA\u8BF7\u6539\u7528 signal/tool/channel \u5B50\u547D\u4EE4\uFF09").option("-u, --url <url>", "\u53EF\u9009\uFF1A\u76EE\u6807 URL\uFF08\u6709\u65F6\u6709\u52A9\u4E8E AI \u5224\u65AD\uFF09").option("--hint <type>", "\u53EF\u9009\uFF1A\u63D0\u793A\u7C7B\u578B signal/tool/channel/playbook\uFF08\u4E0D\u4F1A\u5F3A\u5236\uFF09").option("-t, --title <title>", "\u53EF\u9009\uFF1A\u6807\u9898\uFF08AI \u53EF\u80FD\u4F1A\u91CD\u5199\uFF09").option("-b, --body <text>", "\u6B63\u6587/\u63CF\u8FF0\uFF08\u4E0D\u63A8\u8350\u76F4\u63A5\u4F20\uFF1B\u8BF7\u7528 --body-file\uFF09").option("--body-file <path>", "\u6B63\u6587\u6587\u4EF6\u8DEF\u5F84\uFF08type: markdown_kramdown\uFF1B\u5EFA\u8BAE\u5199\u5230\u5F53\u524D\u76EE\u5F55 .tmp/\uFF09").option("--dry-run", "\u53EA\u505A\u8BC6\u522B\u4E0E\u8349\u7A3F\u751F\u6210\uFF0C\u4E0D\u843D\u5E93\uFF08\u82E5\u670D\u52A1\u7AEF\u652F\u6301\uFF09").action(async (opts, cmd) => {
276
289
  const { apiKey, baseUrl, client } = resolveApi(cmd);
277
290
  if (!apiKey) {
278
291
  console.error("\u9519\u8BEF\uFF1A\u672A\u914D\u7F6E API Key");
@@ -280,45 +293,27 @@ intake.command("new").description("\u521B\u5EFA\u65B0\u6536\u5F55").option("-u,
280
293
  process.exit(1);
281
294
  }
282
295
  try {
283
- const body = {
284
- kind: opts.kind,
296
+ if (opts.body && opts.bodyFile) {
297
+ console.error("\u9519\u8BEF\uFF1A--body \u4E0E --body-file \u4E0D\u80FD\u540C\u65F6\u4F7F\u7528");
298
+ process.exit(1);
299
+ }
300
+ const bodyText = opts.bodyFile ? readTextFile(opts.bodyFile) : opts.body || "";
301
+ const payload = {
285
302
  title: opts.title || "",
286
- body: opts.body || ""
303
+ body: bodyText,
304
+ url: opts.url || "",
305
+ hint: opts.hint || "",
306
+ dry_run: Boolean(opts.dryRun)
287
307
  };
288
- if (opts.url) {
289
- body.url = opts.url;
290
- }
291
- if (opts.profileDataJson) {
292
- body.profile_data_json = opts.profileDataJson;
293
- }
294
- const result = await client.post("/intakes", body);
295
- console.log("\u2705 \u6536\u5F55\u521B\u5EFA\u6210\u529F");
296
- console.log(` ID: ${result.data.id}`);
297
- console.log(` \u7C7B\u578B\uFF1A${result.data.kind}`);
298
- console.log(` \u6807\u9898\uFF1A${result.data.title || "(\u65E0)"}`);
308
+ const result = await client.post("/intakes/ai", payload);
309
+ console.log("\u2705 AI \u8BC6\u522B\u6210\u529F");
310
+ if (result.data.kind) console.log(` \u8BC6\u522B\u7C7B\u578B\uFF1A${result.data.kind}`);
311
+ if (result.data.id) console.log(` ID: ${result.data.id}`);
312
+ if (result.data.title) console.log(` \u6807\u9898\uFF1A${result.data.title}`);
299
313
  console.log("\n--- JSON ---");
300
- console.log(
301
- JSON.stringify(
302
- {
303
- id: result.data.id,
304
- kind: result.data.kind,
305
- title: result.data.title || ""
306
- },
307
- null,
308
- 2
309
- )
310
- );
314
+ console.log(JSON.stringify(result.data, null, 2));
311
315
  } catch (err) {
312
316
  console.error(`\u274C \u521B\u5EFA\u5931\u8D25\uFF1A${err.message}`);
313
- const kind = String(opts.kind ?? "signal");
314
- const urlHint = Boolean(opts.url) && kind === "signal" && err instanceof ApiError && err.status === 422;
315
- if (urlHint) {
316
- console.error("");
317
- console.error("\u63D0\u793A\uFF1A\u5F53\u524D\u4E3A signal\uFF08\u9ED8\u8BA4\uFF09\u3002`-u` \u4EC5\u5728 `-k tool` \u6216 `-k channel` \u65F6\u4F1A\u7528\u4E8E\u81EA\u52A8\u89E3\u6790\u8D44\u6599\u3002");
318
- console.error(" \u793A\u4F8B\uFF1A");
319
- console.error(' c456 -B <\u7AD9\u70B9> intake new -k channel -u "<\u9891\u9053\u6216\u4E3B\u9875 URL>"');
320
- console.error(' c456 -B <\u7AD9\u70B9> intake new -k tool -u "<\u5DE5\u5177 / \u4ED3\u5E93 URL>"');
321
- }
322
317
  process.exit(1);
323
318
  }
324
319
  });
@@ -343,7 +338,7 @@ intake.command("show").description("\u67E5\u770B\u6536\u5F55\u8BE6\u60C5").argum
343
338
  process.exit(1);
344
339
  }
345
340
  });
346
- intake.command("update").description("\u66F4\u65B0\u6536\u5F55").argument("<id>", "\u6536\u5F55 ID").option("-t, --title <title>", "\u65B0\u6807\u9898").option("-b, --body <text>", "\u65B0\u6B63\u6587\uFF08type: markdown_kramdown\uFF1B\u8BED\u6CD5\u89C1 references/content-syntax-kramdown.md\uFF09").option("--favorited", "\u6807\u8BB0\u4E3A\u6536\u85CF").option("--unfavorited", "\u53D6\u6D88\u6536\u85CF").action(async (id, opts, cmd) => {
341
+ intake.command("update").description("\u66F4\u65B0\u6536\u5F55").argument("<id>", "\u6536\u5F55 ID").option("-t, --title <title>", "\u65B0\u6807\u9898").option("-b, --body <text>", "\u65B0\u6B63\u6587\uFF08\u4E0D\u63A8\u8350\u76F4\u63A5\u4F20\uFF1B\u8BF7\u7528 --body-file\uFF09").option("--body-file <path>", "\u65B0\u6B63\u6587\u6587\u4EF6\u8DEF\u5F84\uFF08type: markdown_kramdown\uFF1B\u5EFA\u8BAE\u5199\u5230\u5F53\u524D\u76EE\u5F55 .tmp/\uFF09").option("--favorited", "\u6807\u8BB0\u4E3A\u6536\u85CF").option("--unfavorited", "\u53D6\u6D88\u6536\u85CF").action(async (id, opts, cmd) => {
347
342
  const { apiKey, client } = resolveApi(cmd);
348
343
  if (!apiKey) {
349
344
  console.error("\u9519\u8BEF\uFF1A\u672A\u914D\u7F6E API Key");
@@ -351,6 +346,11 @@ intake.command("update").description("\u66F4\u65B0\u6536\u5F55").argument("<id>"
351
346
  }
352
347
  const body = {};
353
348
  if (opts.title) body.title = opts.title;
349
+ if (opts.body && opts.bodyFile) {
350
+ console.error("\u9519\u8BEF\uFF1A--body \u4E0E --body-file \u4E0D\u80FD\u540C\u65F6\u4F7F\u7528");
351
+ process.exit(1);
352
+ }
353
+ if (opts.bodyFile) body.body = readTextFile(opts.bodyFile);
354
354
  if (opts.body) body.body = opts.body;
355
355
  if (opts.favorited) body.favorited = true;
356
356
  if (opts.unfavorited) body.favorited = false;
@@ -420,9 +420,196 @@ intake.command("list").description("\u5217\u51FA\u6536\u5F55\uFF08\u5206\u9875\u
420
420
  });
421
421
  var intake_default = intake;
422
422
 
423
- // src/commands/fetch.js
423
+ // src/commands/signal.js
424
+ import { Command as Command3 } from "commander";
425
+
426
+ // src/commands/_intake_kind_helpers.js
424
427
  import { Command as Command2 } from "commander";
425
- var fetchProfile = new Command2().name("fetch").description("\u8D44\u6599\u6293\u53D6 - \u4ECE URL \u81EA\u52A8\u89E3\u6790\u5E73\u53F0\u8D44\u6599");
428
+ function requireApiKey(apiKey) {
429
+ if (!apiKey) {
430
+ console.error("\u9519\u8BEF\uFF1A\u672A\u914D\u7F6E API Key");
431
+ console.error("\u4F7F\u7528 c456 config set-key <token> \u914D\u7F6E\uFF0C\u6216\u8BBE\u7F6E C456_API_KEY \u73AF\u5883\u53D8\u91CF");
432
+ process.exit(1);
433
+ }
434
+ }
435
+ function buildKindCommand(kind, label) {
436
+ const cmd = new Command2().name(kind).description(`${label} \u7BA1\u7406 - \u521B\u5EFA\u3001\u66F4\u65B0\u3001\u5220\u9664\u3001\u5217\u8868`);
437
+ cmd.command("new").description(`\u521B\u5EFA\u65B0${label}`).option("-u, --url <url>", "\u76EE\u6807 URL\uFF08tool/channel \u65F6\u53EF\u9009\uFF1B\u914D\u5408 --auto-resolve-url \u53EF\u81EA\u52A8\u89E3\u6790\u8D44\u6599\uFF09").option("-t, --title <title>", "\u6807\u9898\uFF08tool/channel \u5FC5\u586B\uFF1Bsignal \u53EF\u9009\uFF09").option("-b, --body <text>", "\u6B63\u6587/\u63CF\u8FF0\uFF08\u4E0D\u63A8\u8350\u76F4\u63A5\u4F20\uFF1B\u8BF7\u7528 --body-file\uFF09").option("--body-file <path>", "\u6B63\u6587\u6587\u4EF6\u8DEF\u5F84\uFF08type: markdown_kramdown\uFF1B\u5EFA\u8BAE\u5199\u5230\u5F53\u524D\u76EE\u5F55 .tmp/\uFF09").option("--profile-data-json <json>", "\u8D44\u6599\u6BB5 JSON\uFF08tool/channel\uFF09").option("--auto-resolve-url", "\u81EA\u52A8\u89E3\u6790 URL \u5E76\u586B\u5145\u8D44\u6599\u6BB5 profile_data\uFF08\u4EC5 tool/channel\uFF1B\u4F1A\u53D1\u8D77\u7F51\u7EDC\u8BF7\u6C42\uFF09").action(async (opts, cmd2) => {
438
+ const { apiKey, client } = resolveApi(cmd2);
439
+ requireApiKey(apiKey);
440
+ if (opts.body && opts.bodyFile) {
441
+ console.error("\u9519\u8BEF\uFF1A--body \u4E0E --body-file \u4E0D\u80FD\u540C\u65F6\u4F7F\u7528");
442
+ process.exit(1);
443
+ }
444
+ const bodyText = opts.bodyFile ? readTextFile(opts.bodyFile) : opts.body || "";
445
+ const body = {
446
+ kind,
447
+ title: opts.title || "",
448
+ body: bodyText
449
+ };
450
+ if (opts.url) body.url = opts.url;
451
+ if (opts.profileDataJson) body.profile_data_json = opts.profileDataJson;
452
+ if (opts.autoResolveUrl) {
453
+ if (!opts.url) {
454
+ console.error("\u9519\u8BEF\uFF1A\u4F7F\u7528 --auto-resolve-url \u65F6\u5FC5\u987B\u540C\u65F6\u63D0\u4F9B -u/--url");
455
+ process.exit(1);
456
+ }
457
+ if (kind !== "tool" && kind !== "channel") {
458
+ console.error("\u9519\u8BEF\uFF1A--auto-resolve-url \u4EC5\u9002\u7528\u4E8E tool \u6216 channel");
459
+ process.exit(1);
460
+ }
461
+ body.auto_resolve_url = true;
462
+ }
463
+ try {
464
+ const result = await client.post("/intakes", body);
465
+ console.log(`\u2705 ${label}\u521B\u5EFA\u6210\u529F`);
466
+ console.log(` ID: ${result.data.id}`);
467
+ console.log(` \u7C7B\u578B\uFF1A${result.data.kind}`);
468
+ console.log(` \u6807\u9898\uFF1A${result.data.title || "(\u65E0)"}`);
469
+ } catch (err) {
470
+ console.error(`\u274C \u521B\u5EFA\u5931\u8D25\uFF1A${err.message}`);
471
+ process.exit(1);
472
+ }
473
+ });
474
+ cmd.command("show").description(`\u67E5\u770B${label}\u8BE6\u60C5`).argument("<id>", `${label} ID`).action(async (id, opts, cmd2) => {
475
+ const { apiKey, client } = resolveApi(cmd2);
476
+ requireApiKey(apiKey);
477
+ try {
478
+ const result = await client.get(`/intakes/${id}`);
479
+ const data = result.data;
480
+ console.log(`ID: ${data.id}`);
481
+ console.log(`\u7C7B\u578B\uFF1A${data.kind}`);
482
+ console.log(`\u6807\u9898\uFF1A${data.title || "(\u65E0)"}`);
483
+ if (data.stage) console.log(`\u6F0F\u6597\uFF1A${data.stage} / ${data.refinementStatus || ""}`.trim());
484
+ if (data.derivedFromId) console.log(`\u4E0A\u6E38\uFF1AIntake #${data.derivedFromId}`);
485
+ console.log(`\u6B63\u6587\uFF1A${data.body || "(\u65E0)"}`);
486
+ } catch (err) {
487
+ console.error(`\u274C \u67E5\u8BE2\u5931\u8D25\uFF1A${err.message}`);
488
+ process.exit(1);
489
+ }
490
+ });
491
+ cmd.command("update").description(`\u66F4\u65B0${label}`).argument("<id>", `${label} ID`).option("-t, --title <title>", "\u65B0\u6807\u9898").option("-b, --body <text>", "\u65B0\u6B63\u6587\uFF08\u4E0D\u63A8\u8350\u76F4\u63A5\u4F20\uFF1B\u8BF7\u7528 --body-file\uFF09").option("--body-file <path>", "\u65B0\u6B63\u6587\u6587\u4EF6\u8DEF\u5F84\uFF08type: markdown_kramdown\uFF1B\u5EFA\u8BAE\u5199\u5230\u5F53\u524D\u76EE\u5F55 .tmp/\uFF09").option("--favorited", "\u6807\u8BB0\u4E3A\u6536\u85CF").option("--unfavorited", "\u53D6\u6D88\u6536\u85CF").option("--refinement-status <status>", "\u6F0F\u6597\u5904\u7406\u72B6\u6001\uFF08signal\uFF09\uFF1Aapproved/ai_drafting/ai_drafted/rejected/dropped").action(async (id, opts, cmd2) => {
492
+ const { apiKey, client } = resolveApi(cmd2);
493
+ requireApiKey(apiKey);
494
+ const body = {};
495
+ if (opts.title) body.title = opts.title;
496
+ if (opts.body && opts.bodyFile) {
497
+ console.error("\u9519\u8BEF\uFF1A--body \u4E0E --body-file \u4E0D\u80FD\u540C\u65F6\u4F7F\u7528");
498
+ process.exit(1);
499
+ }
500
+ if (opts.bodyFile) body.body = readTextFile(opts.bodyFile);
501
+ if (opts.body) body.body = opts.body;
502
+ if (opts.favorited) body.favorited = true;
503
+ if (opts.unfavorited) body.favorited = false;
504
+ if (opts.refinementStatus) body.refinement_status = opts.refinementStatus;
505
+ try {
506
+ await client.patch(`/intakes/${id}`, body);
507
+ console.log(`\u2705 ${label}\u66F4\u65B0\u6210\u529F`);
508
+ } catch (err) {
509
+ console.error(`\u274C \u66F4\u65B0\u5931\u8D25\uFF1A${err.message}`);
510
+ process.exit(1);
511
+ }
512
+ });
513
+ cmd.command("delete").description(`\u5220\u9664${label}`).argument("<id>", `${label} ID`).option("-f, --force", "\u5F3A\u5236\u5220\u9664\uFF08\u65E0\u9700\u786E\u8BA4\uFF09").action(async (id, opts, cmd2) => {
514
+ const { apiKey, client } = resolveApi(cmd2);
515
+ requireApiKey(apiKey);
516
+ if (!opts.force) {
517
+ const readline = await import("node:readline");
518
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
519
+ const answer = await new Promise((resolve) => {
520
+ rl.question("\u786E\u8BA4\u5220\u9664\uFF1F(y/N): ", (ans) => {
521
+ rl.close();
522
+ resolve(ans.toLowerCase());
523
+ });
524
+ });
525
+ if (answer !== "y" && answer !== "yes") {
526
+ console.log("\u5DF2\u53D6\u6D88");
527
+ return;
528
+ }
529
+ }
530
+ try {
531
+ await client.delete(`/intakes/${id}`);
532
+ console.log(`\u2705 ${label}\u5DF2\u5220\u9664`);
533
+ } catch (err) {
534
+ console.error(`\u274C \u5220\u9664\u5931\u8D25\uFF1A${err.message}`);
535
+ process.exit(1);
536
+ }
537
+ });
538
+ cmd.command("list").description(`\u5217\u51FA${label}\uFF08\u5206\u9875\uFF09`).option("-q, --query <text>", "\u641C\u7D22\u5173\u952E\u8BCD").option("-p, --page <num>", "\u9875\u7801\uFF081-10000\uFF09", "1").option("-n, --per-page <num>", "\u6BCF\u9875\u6570\u91CF\uFF081-100\uFF0C\u9ED8\u8BA4 20\uFF09", "20").option("--stage <stage>", "\uFF08signal\uFF09\u6F0F\u6597\u9636\u6BB5\uFF1Araw/cleaned/curated/playbook").option("--refinement-status <status>", "\uFF08signal\uFF09\u5904\u7406\u72B6\u6001\uFF1Aapproved/ai_drafting/ai_drafted/rejected/dropped").option("--include-dropped", "\uFF08signal\uFF09\u5305\u542B dropped\uFF08\u9ED8\u8BA4\u9690\u85CF\uFF09").option("--derived-from-id <id>", "\uFF08signal\uFF09\u53EA\u770B\u76F4\u63A5\u5B50\u9879").option("--tree-root-id <id>", "\uFF08signal\uFF09\u67E5\u770B\u67D0\u68F5\u6D3E\u751F\u6811\uFF08\u542B\u6839\uFF09").action(async (opts, cmd2) => {
539
+ const { apiKey, client } = resolveApi(cmd2);
540
+ requireApiKey(apiKey);
541
+ const params = {
542
+ kind,
543
+ q: opts.query,
544
+ page: opts.page,
545
+ per_page: opts.perPage
546
+ };
547
+ if (kind === "signal") {
548
+ if (opts.stage) params.stage = opts.stage;
549
+ if (opts.refinementStatus) params.refinement_status = opts.refinementStatus;
550
+ if (opts.includeDropped) params.include_dropped = 1;
551
+ if (opts.derivedFromId) params.derived_from_id = opts.derivedFromId;
552
+ if (opts.treeRootId) params.tree_root_id = opts.treeRootId;
553
+ }
554
+ try {
555
+ const result = await client.get("/intakes", params);
556
+ const { data, meta } = result;
557
+ const perPage = metaPerPage(meta);
558
+ const totalPages = Math.max(1, Math.ceil(meta.total / perPage));
559
+ console.log(`\u5171 ${meta.total} \u6761${label}\uFF08\u7B2C ${meta.page}/${totalPages} \u9875\uFF09
560
+ `);
561
+ data.forEach((item) => {
562
+ const stage = item.stage ? ` ${item.stage}/${item.refinementStatus || ""}` : "";
563
+ console.log(`\u2022 [${item.id}] ${item.kind}${stage}`);
564
+ console.log(` ${item.title || item.listSummary || "(\u65E0\u6807\u9898)"}`);
565
+ });
566
+ } catch (err) {
567
+ console.error(`\u274C \u67E5\u8BE2\u5931\u8D25\uFF1A${err.message}`);
568
+ const urlHint = Boolean(opts.url) && kind === "signal" && err instanceof ApiError && err.status === 422;
569
+ if (urlHint) {
570
+ console.error("");
571
+ console.error("\u63D0\u793A\uFF1A\u82E5\u8981\u89E3\u6790 URL \u7684\u8D44\u6599\u6BB5\uFF0C\u8BF7\u4F7F\u7528 tool/channel \u547D\u4EE4\u5E76\u663E\u5F0F\u5F00\u542F --auto-resolve-url\u3002");
572
+ }
573
+ process.exit(1);
574
+ }
575
+ });
576
+ return cmd;
577
+ }
578
+
579
+ // src/commands/signal.js
580
+ var signalCmd = buildKindCommand("signal", "\u4FE1\u53F7");
581
+ signalCmd.command("refine").description("\u6D3E\u751F\u4E0B\u4E00\u7EA7\uFF08raw\u2192cleaned / cleaned\u2192curated / curated\u2192playbook\uFF09").argument("<id>", "\u4FE1\u53F7 Intake ID").requiredOption("--to <stage>", "\u76EE\u6807\u9636\u6BB5\uFF1Acleaned/curated/playbook").option("--ai", "\u4F7F\u7528 AI \u8D77\u8349\uFF08mode=ai\uFF09").option("--manual", "\u624B\u52A8\u6D3E\u751F\uFF08\u9ED8\u8BA4\uFF09").action(async (id, opts, cmd) => {
582
+ const { apiKey, client } = resolveApi(cmd);
583
+ if (!apiKey) {
584
+ console.error("\u9519\u8BEF\uFF1A\u672A\u914D\u7F6E API Key");
585
+ process.exit(1);
586
+ }
587
+ const mode = opts.ai ? "ai" : "";
588
+ const result = await client.post(`/intakes/${id}/refinements`, { target_stage: opts.to, mode });
589
+ console.log("\u2705 \u5DF2\u6D3E\u751F");
590
+ console.log(` \u5B50\u9879 ID: ${result.data.id}`);
591
+ console.log(` stage: ${result.data.stage} / ${result.data.refinementStatus}`);
592
+ });
593
+ signalCmd.command("redraft").description("\u5BF9\u5931\u8D25\u7684 AI \u8D77\u8349\u91CD\u8BD5\uFF08rejected\u2192ai_drafting\uFF0C\u5E76\u5165\u961F Job\uFF09").argument("<id>", "\u5B50\u4FE1\u53F7 Intake ID\uFF08refinement_status=rejected\uFF09").action(async (id, opts, cmd) => {
594
+ const { apiKey, client } = resolveApi(cmd);
595
+ if (!apiKey) {
596
+ console.error("\u9519\u8BEF\uFF1A\u672A\u914D\u7F6E API Key");
597
+ process.exit(1);
598
+ }
599
+ await client.patch(`/intakes/${id}`, { refinement_status: "ai_drafting" });
600
+ console.log("\u2705 \u5DF2\u63D0\u4EA4\u91CD\u8BD5\u8D77\u8349");
601
+ });
602
+ var signal_default = signalCmd;
603
+
604
+ // src/commands/tool.js
605
+ var tool_default = buildKindCommand("tool", "\u5DE5\u5177");
606
+
607
+ // src/commands/channel.js
608
+ var channel_default = buildKindCommand("channel", "\u6E20\u9053");
609
+
610
+ // src/commands/fetch.js
611
+ import { Command as Command4 } from "commander";
612
+ var fetchProfile = new Command4().name("fetch").description("\u8D44\u6599\u6293\u53D6 - \u4ECE URL \u81EA\u52A8\u89E3\u6790\u5E73\u53F0\u8D44\u6599");
426
613
  fetchProfile.command("profile").description("\u6293\u53D6\u6307\u5B9A URL \u7684\u8D44\u6599\u6BB5\u6570\u636E").requiredOption("-u, --url <url>", "\u76EE\u6807 URL").requiredOption(
427
614
  "-p, --profile-id <type>",
428
615
  [
@@ -453,34 +640,11 @@ fetchProfile.command("profile").description("\u6293\u53D6\u6307\u5B9A URL \u7684
453
640
  process.exit(1);
454
641
  }
455
642
  });
456
- fetchProfile.command("detect").description("\u521B\u5EFA tool \u6536\u5F55\u5E76\u5C1D\u8BD5\u81EA\u52A8\u89E3\u6790\u8D44\u6599\uFF08\u4E0D\u662F profile_id \u81EA\u52A8\u63A8\u65AD\uFF1B\u793E\u4EA4\u8D26\u53F7\u8BF7\u7528 fetch profile -p social_account\uFF09").requiredOption("-u, --url <url>", "\u76EE\u6807 URL").action(async (opts, cmd) => {
457
- const { apiKey, client } = resolveApi(cmd);
458
- if (!apiKey) {
459
- console.error("\u9519\u8BEF\uFF1A\u672A\u914D\u7F6E API Key");
460
- process.exit(1);
461
- }
462
- try {
463
- const result = await client.post("/intakes", {
464
- kind: "tool",
465
- url: opts.url
466
- });
467
- console.log("\u2705 \u81EA\u52A8\u68C0\u6D4B\u5E76\u6536\u5F55\u6210\u529F");
468
- console.log(`ID: ${result.data.id}`);
469
- console.log(`\u7C7B\u578B\uFF1A${result.data.kind}`);
470
- if (result.data.profileData) {
471
- console.log("\n\u89E3\u6790\u7684\u8D44\u6599\u6BB5\uFF1A");
472
- console.log(JSON.stringify(result.data.profileData, null, 2));
473
- }
474
- } catch (err) {
475
- console.error(`\u274C \u68C0\u6D4B\u5931\u8D25\uFF1A${err.message}`);
476
- process.exit(1);
477
- }
478
- });
479
643
  var fetch_default = fetchProfile;
480
644
 
481
645
  // src/commands/search.js
482
- import { Command as Command3 } from "commander";
483
- var searchCmd = new Command3().name("search").description("\u641C\u7D22 - \u67E5\u627E\u53EF\u5173\u8054\u7684\u6536\u5F55\u6216\u6253\u6CD5");
646
+ import { Command as Command5 } from "commander";
647
+ var searchCmd = new Command5().name("search").description("\u641C\u7D22 - \u67E5\u627E\u53EF\u5173\u8054\u7684\u6536\u5F55\u6216\u6253\u6CD5");
484
648
  searchCmd.command("signals").description("\u641C\u7D22\u6536\u5F55\uFF08\u7528\u4E8E\u4FE1\u53F7\u5173\u8054\uFF09").option("-q, --query <text>", "\u641C\u7D22\u5173\u952E\u8BCD", "").option("-k, --kind <type>", "\u7C7B\u578B\u8FC7\u6EE4\uFF1Asignal/tool/channel").option("-l, --limit <num>", "\u7ED3\u679C\u6570\u91CF\u9650\u5236", "20").action(async (opts, cmd) => {
485
649
  const { apiKey, client } = resolveApi(cmd);
486
650
  if (!apiKey) {
@@ -549,9 +713,9 @@ searchCmd.command("playbooks").description("\u641C\u7D22\u6253\u6CD5\uFF08\u7528
549
713
  var search_default = searchCmd;
550
714
 
551
715
  // src/commands/playbook.js
552
- import { Command as Command4 } from "commander";
553
- var playbookCmd = new Command4().name("playbook").description("\u6253\u6CD5\u7BA1\u7406 - \u521B\u5EFA\u3001\u66F4\u65B0\u3001\u5220\u9664\u6253\u6CD5");
554
- playbookCmd.command("new").description("\u521B\u5EFA\u65B0\u6253\u6CD5").requiredOption("-t, --title <title>", "\u6253\u6CD5\u6807\u9898").option("-b, --body <text>", "\u6253\u6CD5\u6B63\u6587\uFF08type: markdown_kramdown\uFF1B\u8BED\u6CD5\u89C1 references/content-syntax-kramdown.md\uFF09").option("--ref-intake <id>", "\u5F15\u7528\u6536\u5F55 ID\uFF08\u53EF\u591A\u6B21\u6307\u5B9A\uFF09").option("--ref-playbook <id>", "\u5F15\u7528\u6253\u6CD5 ID\uFF08\u53EF\u591A\u6B21\u6307\u5B9A\uFF09").action(async (opts, cmd) => {
716
+ import { Command as Command6 } from "commander";
717
+ var playbookCmd = new Command6().name("playbook").description("\u6253\u6CD5\u7BA1\u7406 - \u521B\u5EFA\u3001\u66F4\u65B0\u3001\u5220\u9664\u6253\u6CD5");
718
+ playbookCmd.command("new").description("\u521B\u5EFA\u65B0\u6253\u6CD5").requiredOption("-t, --title <title>", "\u6253\u6CD5\u6807\u9898").option("-b, --body <text>", "\u6253\u6CD5\u6B63\u6587\uFF08\u4E0D\u63A8\u8350\u76F4\u63A5\u4F20\uFF1B\u8BF7\u7528 --body-file\uFF09").option("--body-file <path>", "\u6253\u6CD5\u6B63\u6587\u6587\u4EF6\u8DEF\u5F84\uFF08type: markdown_kramdown\uFF1B\u5EFA\u8BAE\u5199\u5230\u5F53\u524D\u76EE\u5F55 .tmp/\uFF09").option("--ref-intake <id>", "\u5F15\u7528\u6536\u5F55 ID\uFF08\u53EF\u591A\u6B21\u6307\u5B9A\uFF09").option("--ref-playbook <id>", "\u5F15\u7528\u6253\u6CD5 ID\uFF08\u53EF\u591A\u6B21\u6307\u5B9A\uFF09").action(async (opts, cmd) => {
555
719
  const { apiKey, client } = resolveApi(cmd);
556
720
  if (!apiKey) {
557
721
  console.error("\u9519\u8BEF\uFF1A\u672A\u914D\u7F6E API Key");
@@ -571,9 +735,14 @@ playbookCmd.command("new").description("\u521B\u5EFA\u65B0\u6253\u6CD5").require
571
735
  });
572
736
  }
573
737
  try {
738
+ if (opts.body && opts.bodyFile) {
739
+ console.error("\u9519\u8BEF\uFF1A--body \u4E0E --body-file \u4E0D\u80FD\u540C\u65F6\u4F7F\u7528");
740
+ process.exit(1);
741
+ }
742
+ const bodyText = opts.bodyFile ? readTextFile(opts.bodyFile) : opts.body || "";
574
743
  const body = {
575
744
  title: opts.title,
576
- body: opts.body || ""
745
+ body: bodyText
577
746
  };
578
747
  if (referenceTargets.length > 0) {
579
748
  body.reference_targets = referenceTargets;
@@ -617,7 +786,7 @@ ${data.body || "(\u65E0)"}`);
617
786
  process.exit(1);
618
787
  }
619
788
  });
620
- playbookCmd.command("update").description("\u66F4\u65B0\u6253\u6CD5").argument("<id>", "\u6253\u6CD5 ID").option("-t, --title <title>", "\u65B0\u6807\u9898").option("-b, --body <text>", "\u65B0\u6B63\u6587\uFF08type: markdown_kramdown\uFF1B\u8BED\u6CD5\u89C1 references/content-syntax-kramdown.md\uFF09").action(async (id, opts, cmd) => {
789
+ playbookCmd.command("update").description("\u66F4\u65B0\u6253\u6CD5").argument("<id>", "\u6253\u6CD5 ID").option("-t, --title <title>", "\u65B0\u6807\u9898").option("-b, --body <text>", "\u65B0\u6B63\u6587\uFF08\u4E0D\u63A8\u8350\u76F4\u63A5\u4F20\uFF1B\u8BF7\u7528 --body-file\uFF09").option("--body-file <path>", "\u65B0\u6B63\u6587\u6587\u4EF6\u8DEF\u5F84\uFF08type: markdown_kramdown\uFF1B\u5EFA\u8BAE\u5199\u5230\u5F53\u524D\u76EE\u5F55 .tmp/\uFF09").action(async (id, opts, cmd) => {
621
790
  const { apiKey, client } = resolveApi(cmd);
622
791
  if (!apiKey) {
623
792
  console.error("\u9519\u8BEF\uFF1A\u672A\u914D\u7F6E API Key");
@@ -625,6 +794,11 @@ playbookCmd.command("update").description("\u66F4\u65B0\u6253\u6CD5").argument("
625
794
  }
626
795
  const body = {};
627
796
  if (opts.title) body.title = opts.title;
797
+ if (opts.body && opts.bodyFile) {
798
+ console.error("\u9519\u8BEF\uFF1A--body \u4E0E --body-file \u4E0D\u80FD\u540C\u65F6\u4F7F\u7528");
799
+ process.exit(1);
800
+ }
801
+ if (opts.bodyFile) body.body = readTextFile(opts.bodyFile);
628
802
  if (opts.body) body.body = opts.body;
629
803
  try {
630
804
  await client.patch(`/playbooks/${id}`, body);
@@ -693,9 +867,9 @@ playbookCmd.command("list").description("\u5217\u51FA\u6253\u6CD5\uFF08\u5206\u9
693
867
  var playbook_default = playbookCmd;
694
868
 
695
869
  // src/commands/walkthrough.js
696
- import { Command as Command5 } from "commander";
697
- var walkthroughCmd = new Command5().name("walkthrough").description("\u8BB2\u89E3\uFF08Walkthrough\uFF09\u7BA1\u7406 - \u521B\u5EFA\u3001\u66F4\u65B0\u3001\u5220\u9664\u8BB2\u89E3");
698
- function requireApiKey(apiKey) {
870
+ import { Command as Command7 } from "commander";
871
+ var walkthroughCmd = new Command7().name("walkthrough").description("\u8BB2\u89E3\uFF08Walkthrough\uFF09\u7BA1\u7406 - \u521B\u5EFA\u3001\u66F4\u65B0\u3001\u5220\u9664\u8BB2\u89E3");
872
+ function requireApiKey2(apiKey) {
699
873
  if (!apiKey) {
700
874
  console.error("\u9519\u8BEF\uFF1A\u672A\u914D\u7F6E API Key");
701
875
  process.exit(1);
@@ -720,15 +894,23 @@ function buildWalkthroughFields(opts) {
720
894
  if (opts.publicationStatus !== void 0) w.publication_status = opts.publicationStatus;
721
895
  return w;
722
896
  }
723
- walkthroughCmd.command("new").description("\u521B\u5EFA\u65B0\u8BB2\u89E3").requiredOption("-t, --title <title>", "\u6807\u9898").option("-s, --summary <text>", "\u6458\u8981").option("-b, --body <text>", "\u6B63\u6587\uFF08type: markdown_kramdown\uFF1B\u8BED\u6CD5\u89C1 references/content-syntax-kramdown.md\uFF09").option("--source-kind <kind>", "\u6765\u6E90\uFF1Aupload/external_url\uFF08\u9ED8\u8BA4 upload\uFF09", "upload").option("--external-url <url>", "asciinema.org \u94FE\u63A5\uFF08source-kind=external_url \u65F6\u5FC5\u586B\uFF09").option("--cast-file <path>", ".cast \u6587\u4EF6\u8DEF\u5F84\uFF08source-kind=upload \u65F6\u5FC5\u586B\uFF09").option("--poster-at <seconds>", "\u5C01\u9762\u9884\u89C8\u79D2\u6570\uFF08>=0 \u7684\u6574\u6570\uFF09").action(async (opts, cmd) => {
897
+ walkthroughCmd.command("new").description("\u521B\u5EFA\u65B0\u8BB2\u89E3").requiredOption("-t, --title <title>", "\u6807\u9898").option("-s, --summary <text>", "\u6458\u8981\uFF08\u4E0D\u63A8\u8350\u76F4\u63A5\u4F20\uFF1B\u8BF7\u7528 --summary-file\uFF09").option("--summary-file <path>", "\u6458\u8981\u6587\u4EF6\u8DEF\u5F84\uFF08\u5EFA\u8BAE\u5199\u5230\u5F53\u524D\u76EE\u5F55 .tmp/\uFF09").option("-b, --body <text>", "\u6B63\u6587\uFF08\u4E0D\u63A8\u8350\u76F4\u63A5\u4F20\uFF1B\u8BF7\u7528 --body-file\uFF09").option("--body-file <path>", "\u6B63\u6587\u6587\u4EF6\u8DEF\u5F84\uFF08type: markdown_kramdown\uFF1B\u5EFA\u8BAE\u5199\u5230\u5F53\u524D\u76EE\u5F55 .tmp/\uFF09").option("--source-kind <kind>", "\u6765\u6E90\uFF1Aupload/external_url\uFF08\u9ED8\u8BA4 upload\uFF09", "upload").option("--external-url <url>", "asciinema.org \u94FE\u63A5\uFF08source-kind=external_url \u65F6\u5FC5\u586B\uFF09").option("--cast-file <path>", ".cast \u6587\u4EF6\u8DEF\u5F84\uFF08source-kind=upload \u65F6\u5FC5\u586B\uFF09").option("--poster-at <seconds>", "\u5C01\u9762\u9884\u89C8\u79D2\u6570\uFF08>=0 \u7684\u6574\u6570\uFF09").action(async (opts, cmd) => {
724
898
  const { apiKey, client } = resolveApi(cmd);
725
- requireApiKey(apiKey);
899
+ requireApiKey2(apiKey);
726
900
  const sourceKind = ensureSourceKind(opts.sourceKind);
727
901
  const posterAt = opts.posterAt !== void 0 ? Number.parseInt(String(opts.posterAt), 10) : void 0;
902
+ if (opts.body && opts.bodyFile) {
903
+ console.error("\u9519\u8BEF\uFF1A--body \u4E0E --body-file \u4E0D\u80FD\u540C\u65F6\u4F7F\u7528");
904
+ process.exit(1);
905
+ }
906
+ if (opts.summary && opts.summaryFile) {
907
+ console.error("\u9519\u8BEF\uFF1A--summary \u4E0E --summary-file \u4E0D\u80FD\u540C\u65F6\u4F7F\u7528");
908
+ process.exit(1);
909
+ }
728
910
  const w = {
729
911
  title: opts.title,
730
- summary: opts.summary || "",
731
- body: opts.body || "",
912
+ summary: opts.summaryFile ? readTextFile(opts.summaryFile) : opts.summary || "",
913
+ body: opts.bodyFile ? readTextFile(opts.bodyFile) : opts.body || "",
732
914
  source_kind: sourceKind,
733
915
  external_url: opts.externalUrl || "",
734
916
  poster_preview_at_seconds: Number.isFinite(posterAt) ? posterAt : void 0
@@ -768,7 +950,7 @@ walkthroughCmd.command("new").description("\u521B\u5EFA\u65B0\u8BB2\u89E3").requ
768
950
  });
769
951
  walkthroughCmd.command("list").description("\u5217\u51FA\u8BB2\u89E3\uFF08\u5206\u9875\uFF09").option("-q, --query <text>", "\u641C\u7D22\u5173\u952E\u8BCD").option("-p, --page <num>", "\u9875\u7801\uFF081-10000\uFF09", "1").option("-n, --per-page <num>", "\u6BCF\u9875\u6570\u91CF\uFF081-100\uFF0C\u9ED8\u8BA4 20\uFF09", "20").action(async (opts, cmd) => {
770
952
  const { apiKey, client } = resolveApi(cmd);
771
- requireApiKey(apiKey);
953
+ requireApiKey2(apiKey);
772
954
  const result = await client.get("/walkthroughs", {
773
955
  q: opts.query,
774
956
  page: opts.page,
@@ -787,7 +969,7 @@ walkthroughCmd.command("list").description("\u5217\u51FA\u8BB2\u89E3\uFF08\u5206
787
969
  });
788
970
  walkthroughCmd.command("show").description("\u67E5\u770B\u8BB2\u89E3\u8BE6\u60C5").argument("<id>", "\u8BB2\u89E3 ID").action(async (id, opts, cmd) => {
789
971
  const { apiKey, client } = resolveApi(cmd);
790
- requireApiKey(apiKey);
972
+ requireApiKey2(apiKey);
791
973
  const result = await client.get(`/walkthroughs/${id}`);
792
974
  const w = result.data;
793
975
  console.log(`ID: ${w.id}`);
@@ -799,14 +981,22 @@ ${w.body || "(\u65E0)"}`);
799
981
  console.log(`\u6765\u6E90\uFF1A${w.sourceKind}`);
800
982
  if (w.src) console.log(`\u5A92\u4F53\uFF1A${w.src}`);
801
983
  });
802
- walkthroughCmd.command("update").description("\u66F4\u65B0\u8BB2\u89E3").argument("<id>", "\u8BB2\u89E3 ID").option("-t, --title <title>", "\u65B0\u6807\u9898").option("-s, --summary <text>", "\u65B0\u6458\u8981").option("-b, --body <text>", "\u65B0\u6B63\u6587\uFF08type: markdown_kramdown\uFF1B\u8BED\u6CD5\u89C1 references/content-syntax-kramdown.md\uFF09").option("--publication-status <status>", "\u53D1\u5E03\u72B6\u6001\uFF1Apending_review/private").option("--source-kind <kind>", "\u6765\u6E90\uFF1Aupload/external_url").option("--external-url <url>", "asciinema.org \u94FE\u63A5\uFF08source-kind=external_url\uFF09").option("--cast-file <path>", ".cast \u6587\u4EF6\u8DEF\u5F84\uFF08\u4E0A\u4F20\u66FF\u6362\uFF09").option("--poster-at <seconds>", "\u5C01\u9762\u9884\u89C8\u79D2\u6570\uFF08>=0 \u7684\u6574\u6570\uFF09").action(async (id, opts, cmd) => {
984
+ walkthroughCmd.command("update").description("\u66F4\u65B0\u8BB2\u89E3").argument("<id>", "\u8BB2\u89E3 ID").option("-t, --title <title>", "\u65B0\u6807\u9898").option("-s, --summary <text>", "\u65B0\u6458\u8981\uFF08\u4E0D\u63A8\u8350\u76F4\u63A5\u4F20\uFF1B\u8BF7\u7528 --summary-file\uFF09").option("--summary-file <path>", "\u65B0\u6458\u8981\u6587\u4EF6\u8DEF\u5F84\uFF08\u5EFA\u8BAE\u5199\u5230\u5F53\u524D\u76EE\u5F55 .tmp/\uFF09").option("-b, --body <text>", "\u65B0\u6B63\u6587\uFF08\u4E0D\u63A8\u8350\u76F4\u63A5\u4F20\uFF1B\u8BF7\u7528 --body-file\uFF09").option("--body-file <path>", "\u65B0\u6B63\u6587\u6587\u4EF6\u8DEF\u5F84\uFF08type: markdown_kramdown\uFF1B\u5EFA\u8BAE\u5199\u5230\u5F53\u524D\u76EE\u5F55 .tmp/\uFF09").option("--publication-status <status>", "\u53D1\u5E03\u72B6\u6001\uFF1Apending_review/private").option("--source-kind <kind>", "\u6765\u6E90\uFF1Aupload/external_url").option("--external-url <url>", "asciinema.org \u94FE\u63A5\uFF08source-kind=external_url\uFF09").option("--cast-file <path>", ".cast \u6587\u4EF6\u8DEF\u5F84\uFF08\u4E0A\u4F20\u66FF\u6362\uFF09").option("--poster-at <seconds>", "\u5C01\u9762\u9884\u89C8\u79D2\u6570\uFF08>=0 \u7684\u6574\u6570\uFF09").action(async (id, opts, cmd) => {
803
985
  const { apiKey, client } = resolveApi(cmd);
804
- requireApiKey(apiKey);
986
+ requireApiKey2(apiKey);
805
987
  const posterAt = opts.posterAt !== void 0 ? Number.parseInt(String(opts.posterAt), 10) : void 0;
988
+ if (opts.body && opts.bodyFile) {
989
+ console.error("\u9519\u8BEF\uFF1A--body \u4E0E --body-file \u4E0D\u80FD\u540C\u65F6\u4F7F\u7528");
990
+ process.exit(1);
991
+ }
992
+ if (opts.summary && opts.summaryFile) {
993
+ console.error("\u9519\u8BEF\uFF1A--summary \u4E0E --summary-file \u4E0D\u80FD\u540C\u65F6\u4F7F\u7528");
994
+ process.exit(1);
995
+ }
806
996
  const w = buildWalkthroughFields({
807
997
  title: opts.title,
808
- summary: opts.summary,
809
- body: opts.body,
998
+ summary: opts.summaryFile ? readTextFile(opts.summaryFile) : opts.summary,
999
+ body: opts.bodyFile ? readTextFile(opts.bodyFile) : opts.body,
810
1000
  sourceKind: opts.sourceKind ? ensureSourceKind(opts.sourceKind) : void 0,
811
1001
  externalUrl: opts.externalUrl,
812
1002
  posterAt: Number.isFinite(posterAt) ? posterAt : void 0,
@@ -833,7 +1023,7 @@ walkthroughCmd.command("update").description("\u66F4\u65B0\u8BB2\u89E3").argumen
833
1023
  });
834
1024
  walkthroughCmd.command("delete").description("\u5220\u9664\u8BB2\u89E3").argument("<id>", "\u8BB2\u89E3 ID").option("-f, --force", "\u5F3A\u5236\u5220\u9664\uFF08\u65E0\u9700\u786E\u8BA4\uFF09").action(async (id, opts, cmd) => {
835
1025
  const { apiKey, client } = resolveApi(cmd);
836
- requireApiKey(apiKey);
1026
+ requireApiKey2(apiKey);
837
1027
  if (!opts.force) {
838
1028
  const readline = await import("node:readline");
839
1029
  const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
@@ -854,8 +1044,8 @@ walkthroughCmd.command("delete").description("\u5220\u9664\u8BB2\u89E3").argumen
854
1044
  var walkthrough_default = walkthroughCmd;
855
1045
 
856
1046
  // src/commands/config.js
857
- import { Command as Command6 } from "commander";
858
- var configCmd = new Command6().name("config").description("\u914D\u7F6E\u7BA1\u7406 - \u8BBE\u7F6E API Key \u548C\u7CFB\u7EDF\u5730\u5740");
1047
+ import { Command as Command8 } from "commander";
1048
+ var configCmd = new Command8().name("config").description("\u914D\u7F6E\u7BA1\u7406 - \u8BBE\u7F6E API Key \u548C\u7CFB\u7EDF\u5730\u5740");
859
1049
  configCmd.command("set-key").description("\u8BBE\u7F6E API Key").argument("<token>", "API Key \u4EE4\u724C").action((token, cmd) => {
860
1050
  const config = loadConfig();
861
1051
  config.apiKey = token;
@@ -951,18 +1141,21 @@ ${body}
951
1141
  }
952
1142
 
953
1143
  // src/index.js
954
- var program = new Command7();
1144
+ var program = new Command9();
955
1145
  program.name("c456").description("C456 CLI - \u5FEB\u901F\u5185\u5BB9\u5F55\u5165\u4E0E\u6574\u7406\u5DE5\u5177").version(package_default.version);
956
1146
  program.addHelpText("before", () => getHelpBanner());
957
1147
  program.option(
958
1148
  "-B, --base-url <url>",
959
1149
  "C456 \u7AD9\u70B9\u6839\u5730\u5740\uFF1B\u672A\u4F20\u5219\u4F7F\u7528 C456_URL \u73AF\u5883\u53D8\u91CF\u6216 ~/.config/c456/config.json \u7684 baseUrl\uFF0C\u9ED8\u8BA4 https://c456.com"
960
1150
  );
961
- program.addCommand(intake_default);
1151
+ program.addCommand(signal_default);
1152
+ program.addCommand(tool_default);
1153
+ program.addCommand(channel_default);
962
1154
  program.addCommand(fetch_default);
963
1155
  program.addCommand(search_default);
964
1156
  program.addCommand(playbook_default);
965
1157
  program.addCommand(walkthrough_default);
1158
+ program.addCommand(intake_default);
966
1159
  program.addCommand(config_default);
967
1160
  program.on("--help", () => {
968
1161
  console.log("\n\u793A\u4F8B:");
@@ -970,7 +1163,7 @@ program.on("--help", () => {
970
1163
  console.log(" c456 config set-key your-api-token");
971
1164
  console.log("");
972
1165
  console.log(" # \u81EA\u6258\u7BA1\u7AD9\u70B9 + \u6309 URL \u6536\u5F55\u5DE5\u5177\uFF08-B=\u7AD9\u70B9\uFF0C-u=\u76EE\u6807 URL\uFF09");
973
- console.log(' c456 -B https://c456.example.com intake new -k tool -u "https://github.com/owner/repo"');
1166
+ console.log(' c456 -B https://c456.example.com tool new -u "https://github.com/owner/repo" --auto-resolve-url');
974
1167
  console.log("");
975
1168
  console.log(" # \u641C\u7D22\u6536\u5F55");
976
1169
  console.log(' c456 search signals -q "AI agent"');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "c456-cli",
3
- "version": "0.1.5",
3
+ "version": "0.2.0",
4
4
  "description": "C456 CLI - 内容录入与整理工具",
5
5
  "type": "module",
6
6
  "bin": {