@siming-org/cli 0.8.8 → 0.8.10

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 (2) hide show
  1. package/dist/index.js +76 -10
  2. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -1458,10 +1458,27 @@ var defaultGitRunner = async (args, cwd) => {
1458
1458
  return { ok: false, stdout: e.stdout ?? "", stderr: e.stderr ?? e.message ?? String(err2) };
1459
1459
  }
1460
1460
  };
1461
+ var KNOWN_BRANCH_PREFIXES = ["refs/remotes/origin/", "refs/heads/", "refs/remotes/", "origin/"];
1462
+ function normalizeBaseBranch(raw) {
1463
+ let name = raw.trim();
1464
+ let stripped = true;
1465
+ while (stripped) {
1466
+ stripped = false;
1467
+ for (const prefix of KNOWN_BRANCH_PREFIXES) {
1468
+ if (name.startsWith(prefix)) {
1469
+ name = name.slice(prefix.length);
1470
+ stripped = true;
1471
+ break;
1472
+ }
1473
+ }
1474
+ }
1475
+ return name.length > 0 ? name : null;
1476
+ }
1461
1477
  async function resolveCheckContextWithRunner(base, vcs, cwd, scan) {
1462
1478
  const result = scan !== void 0 ? scan(cwd) : scanWorkspaceRepos(cwd);
1463
1479
  const alignRecord = base.nodeRecords["ALIGN"];
1464
- const baseBranch = (alignRecord?.baseBranch !== void 0 && alignRecord.baseBranch !== "" ? alignRecord.baseBranch : void 0) ?? vcs.baseBranch ?? null;
1480
+ const normalizeSource = (value) => value !== void 0 && value !== "" ? normalizeBaseBranch(value) : null;
1481
+ const baseBranch = normalizeSource(alignRecord?.baseBranch) ?? normalizeSource(vcs.baseBranch) ?? null;
1465
1482
  return {
1466
1483
  ...base,
1467
1484
  repos: result.repos,
@@ -2648,12 +2665,16 @@ function mcpContent(result) {
2648
2665
  }
2649
2666
  function requireError(action, fields, args) {
2650
2667
  const missingFields = fields.filter((f) => args[f] === void 0);
2668
+ const stripped = missingFields.filter((f) => strippedFieldsOf(args).includes(f));
2669
+ const rest = missingFields.filter((f) => !stripped.includes(f));
2670
+ const strippedHint = stripped.length > 0 ? `\u5B57\u6BB5 ${stripped.join(", ")} \u5DF2\u63D0\u4F9B\u4F46\u672A\u5217\u5165 fieldMask \u88AB\u5FFD\u7565\uFF1A\u5C06 ${stripped.join(", ")} \u52A0\u5165 fieldMask \u540E\u91CD\u8BD5` : "";
2671
+ const passHint = rest.length > 0 ? `pass ${rest.map((f) => `${f}=<value>`).join(" ")} for action=${action}` : "";
2651
2672
  return mcpContent({
2652
2673
  success: false,
2653
2674
  error: {
2654
2675
  message: `action=${action} requires ${missingFields.join(", ")}`,
2655
2676
  httpStatus: 0,
2656
- hint: `pass ${missingFields.map((f) => `${f}=<value>`).join(" ")} for action=${action}`
2677
+ hint: [strippedHint, passHint].filter((s) => s !== "").join("\uFF1B")
2657
2678
  }
2658
2679
  });
2659
2680
  }
@@ -2663,6 +2684,10 @@ function localError(message, hint) {
2663
2684
  error: { message, httpStatus: 0, ...hint !== void 0 ? { hint } : {} }
2664
2685
  });
2665
2686
  }
2687
+ var FIELD_MASK_STRIPPED = /* @__PURE__ */ new WeakMap();
2688
+ function strippedFieldsOf(args) {
2689
+ return FIELD_MASK_STRIPPED.get(args) ?? [];
2690
+ }
2666
2691
  var FIELD_MASK_ENUM_FIELDS = /* @__PURE__ */ new Set([
2667
2692
  "type",
2668
2693
  "view",
@@ -2729,6 +2754,14 @@ function applyFieldMask(rawArgs, specs) {
2729
2754
  const masked = { action: rawArgs.action, fieldMask: [...rawArgs.fieldMask] };
2730
2755
  for (const field of spec.required) masked[field] = source[field];
2731
2756
  for (const field of rawArgs.fieldMask) masked[field] = source[field];
2757
+ const stripped = [];
2758
+ for (const field of Object.keys(source)) {
2759
+ if (field === "action" || field === "fieldMask") continue;
2760
+ if (source[field] === void 0) continue;
2761
+ if (spec.required.includes(field) || rawArgs.fieldMask.includes(field)) continue;
2762
+ stripped.push(field);
2763
+ }
2764
+ FIELD_MASK_STRIPPED.set(masked, stripped);
2732
2765
  return { success: true, args: masked };
2733
2766
  }
2734
2767
  var TASK_FIELD_SPECS = {
@@ -2778,7 +2811,7 @@ function createMcpServer() {
2778
2811
  const client = createClient(void 0, "mcp");
2779
2812
  server.tool(
2780
2813
  "siming_task",
2781
- 'task \u8D44\u6E90\u57DF\u805A\u5408\u5DE5\u5177\uFF08\u4EFB\u52A1\u5168\u64CD\u4F5C\u7ECF\u672C\u5DE5\u5177 + action \u53C2\u6570\uFF09\u3002action \u5FC5\u586B\uFF1B\u8C03\u7528\u65B9\u5E94\u5728 fieldMask \u4E2D\u5217\u51FA\u672C\u6B21\u771F\u5B9E\u63D0\u4F9B\u7684\u53EF\u9009\u5B57\u6BB5\uFF0Cmask \u5916\u7531\u5BBF\u4E3B\u81EA\u52A8\u586B\u5145\u7684\u7A7A\u4E32\u3001\u7A7A\u6570\u7EC4\u3001false\u30010 \u5747\u5FFD\u7565\uFF0Cmask \u5185\u7A7A\u6570\u7EC4/false \u8868\u793A\u663E\u5F0F\u6E05\u7A7A\u6216\u5173\u95ED\uFF1B\u5404 action \u56FA\u5B9A\u5FC5\u586B\u5B57\u6BB5\u65E0\u9700\u5199\u5165 mask\u3002\u5176\u4F59\u53C2\u6570\u5168\u53EF\u9009\u3001\u6309 action \u8FD0\u884C\u65F6\u6821\u9A8C\u5FC5\u586B\uFF08\u7F3A\u5931\u8FD4\u56DE\u5931\u8D25\u4E09\u8981\u7D20\uFF1A\u5BF9\u8C61+\u6839\u56E0+\u4FEE\u590D\u6307\u5F15\uFF09\u3002projectId \u4E3A key|id \u53CC\u5F62\u6001\uFF0C\u901A\u9053\u5C42\u81EA\u52A8\u5F52\u4E00\u4E3A 24-hex id\uFF1B\u663E\u5F0F\u6307\u5B9A\u89E3\u6790\u5931\u8D25\u62A5\u9519\u4E0D\u515C\u5E95\uFF1B\u7F3A\u7701\u8BED\u4E49\u6309 action\uFF1Acreate \u843D\u9ED8\u8BA4\u9879\u76EE\u94FE\uFF08\u5DE5\u4F5C\u533A defaultProject \u5931\u6548\u62A5\u9519\uFF0C\u65E0\u914D\u7F6E\u4E0D\u4F20\u7531 server \u6309\u6A21\u677F\u5F52\u5C5E\u515C\u5E95\uFF09\uFF0Cquery \u4E0D\u8FC7\u6EE4\uFF08\u5168\u5C40\u67E5\u8BE2\uFF09\u3002\u5199\u64CD\u4F5C\uFF08create/doc-*/record-*/archnote-add/pause/resume/cancel\uFF09\u54CD\u5E94\u4E3A\u8F7B\u91CF\u56DE\u6267\uFF1A{taskId, updated(\u89E6\u53CA\u5B57\u6BB5\u8DEF\u5F84), entry(\u65B0\u6761\u76EE id+kind\uFF0C\u4F9B\u540E\u7EED patch \u5B9A\u4F4D), echo(\u5199\u5165\u5185\u5BB9\u56DE\u663E), updatedAt, task(\u4EFB\u52A1\u8FDB\u5EA6\u6458\u8981 progress: {completed,total})}\u2014\u2014\u4E0D\u8FD4\u56DE\u5B8C\u6574\u4EFB\u52A1\u5B9E\u4F53\u3002action \u6E05\u5355\uFF08\u62EC\u53F7\u5185\u4E3A\u8BE5 action \u5FC5\u586B\u53C2\u6570\uFF09\uFF1Acreate(templateId,taskTitle,track\uFF1Btrack \u652F\u6301\u7EC4\u5408\u8F68\u9053\u2014\u2014\u6570\u7EC4\u5F62\u6001\uFF08\u5982 ["backend","godot"]\uFF0C\u6210\u5458=\u6CE8\u518C\u8868 active \u5355\u8F68\uFF09\u6216\u5355\u503C string\uFF1Ball \u4E3A\u4EFB\u52A1\u7EA7\u901A\u914D\uFF08\u6FC0\u6D3B\u521B\u5EFA\u65F6\u70B9\u5168\u90E8\u542F\u7528\u5355\u8F68\uFF0C\u5355\u503C\u4F7F\u7528\uFF09\uFF1B\u53EF\u9009 type=feature|bugfix|ui-tweak|research\u3001skipNodes\u3001projectId\uFF1BtemplateId \u652F\u6301 code|id \u53CC\u5F62\u6001\u2014\u2014code \u4E3A\u6A21\u677F\u4E1A\u52A1\u6807\u8BC6\uFF08\u9879\u76EE\u5185\u552F\u4E00\u3001kebab-case \u5FC5\u542B\u8FDE\u5B57\u7B26\uFF0C\u5982 full-workflow\uFF09\uFF0C\u63A8\u8350\u5F15\u7528\u5F62\u6001\uFF0C\u5BFB\u5740\u987B\u914D projectId \u6307\u5B9A\u9879\u76EE\u57DF\uFF1B24-hex \u6570\u636E\u5E93 id \u76F4\u67E5\u517C\u5BB9\uFF1Bcode \u5F62\u6001\u4E0D\u5B58\u5728\u65F6\u9519\u8BEF\u542B candidates \u76F8\u8FD1\u5019\u9009\u6E05\u5355\uFF08id/code/name \u22645 \u6761\uFF09\uFF1B\u54CD\u5E94 {task, firstNode}\u2014\u2014firstNode \u5373\u9996\u8282\u70B9\u5B8C\u6574\u8D44\u6599\u5305\uFF0C\u514D\u8C03 context)\uFF1Bquery(taskId \u8FD4\u56DE\u5355\u4EFB\u52A1\u8BE6\u60C5\uFF0C\u7F3A\u7701\u8FD4\u56DE\u5217\u8868\uFF0C\u53EF\u9009 status/track/projectId/page/limit)\uFF1Bcontext(taskId\uFF1B\u53EF\u9009 view=basic|full\u2014\u2014basic \u7F3A\u7701\u4E0D\u643A\u5E26 artifact \u5168\u6587\u5FEB\u7167\uFF0Cfull \u65AD\u70B9\u7EED\u8DD1\u9700\u5386\u53F2\u4EA7\u7269\u5168\u6587\u65F6\u7528\u3002\u26A0 \u514D\u91CD\u8BFB\uFF1Aadvance/approve \u6D41\u8F6C\u54CD\u5E94\u5DF2\u542B\u4E0B\u4E00\u8282\u70B9\u5B8C\u6574\u8D44\u6599\u5305\uFF0C\u540C\u4F1A\u8BDD\u5185\u6D41\u8F6C\u540E\u76F4\u63A5\u5F00\u5DE5\u3001\u65E0\u9700\u518D\u8C03 context\uFF1B\u4EC5\u65B0\u4F1A\u8BDD/\u65AD\u70B9\u7EED\u8DD1\u8C03\u7528)\uFF1Bnode(taskId,view=prompt|skills\uFF1BnodeId \u7F3A\u7701\u7528\u5F53\u524D\u8282\u70B9\uFF1B\u26A0 view \u503C\u968F action \u4E0D\u540C\uFF1Anode\u2192prompt|skills\uFF0Ccontext\u2192basic|full\uFF0C\u9519\u914D\u62A5\u9519)\uFF1Badvance(taskId\uFF1Bnote \u5199 history\u3001summary \u5199 nodeRecords\uFF0C\u4E24\u4F4D\u72EC\u7ACB\uFF1B\u26A0 T202610130004 \u7EC8\u6001\u6536\u5C3E\uFF1A\u4EFB\u52A1\u5904\u4E8E\u7EC8\u8282\u70B9\u65F6 advance \u5FC5\u5E26 finalize=true \u4F5C\u6536\u5C3E\u786E\u8BA4\uFF08\u7F3A\u7701\u88AB\u62D2\u5E76\u8FD4\u56DE\u63D0\u793A\uFF09\uFF0C\u4E2D\u95F4\u8282\u70B9\u5FFD\u7565\u8BE5\u53C2\u6570\uFF1B\u54CD\u5E94\u5DF2\u542B\u4E0B\u4E00\u8282\u70B9\u8D44\u6599\u5305\uFF0C\u540C\u4F1A\u8BDD\u514D\u91CD\u8BFB context\u3002\u26A0 T202609230001 \u8282\u70B9\u95E8\u7981\uFF1A\u914D\u7F6E\u4E86 toolChecks/aiChecks \u7684\u8282\u70B9\u63A8\u8FDB\u524D\u81EA\u52A8\u6267\u884C\u68C0\u67E5\u2014\u2014fail \u4F1A\u88AB\u6253\u56DE\u5E76\u8FD4\u56DE\u9010\u9879\u4FEE\u590D\u6307\u5F15\uFF08\u7ED3\u679C\u5DF2\u5199 history checks_rejected\uFF09\uFF0C\u6309\u6307\u5F15\u4FEE\u590D\u6216\u83B7\u7528\u6237\u8C41\u514D\u7559\u75D5\u540E\u91CD\u63A8\uFF1B\u975E\u4EBA\u5DE5\u5BA1\u6279\u8282\u70B9\u7981\u6B62\u56E0\u95E8\u7981\u4E2D\u65AD\u4EFB\u52A1\uFF08\u6253\u56DE\u4FE1\u606F\u5373\u7EE7\u7EED\u4F9D\u636E\uFF09\u3002force+forceReason \u6210\u5BF9\u63D0\u4F9B\u65F6\u53EF\u8D8A\u8FC7 fail \u5F3A\u5236\u63A8\u8FDB\u2014\u2014\u4EC5\u51ED\u7528\u6237\u660E\u793A\u6307\u4EE4\uFF0CAI \u7981\u6B62\u81EA\u51B3\uFF0C\u7406\u7531\u539F\u6587\u843D history \u5BA1\u8BA1)\uFF1Bcheck(taskId\uFF1B\u95E8\u7981\u53EA\u8BFB\u9884\u68C0\u2014\u2014\u9010\u9879\u62A5\u544A\u4E0D\u5199\u4EFB\u4F55\u72B6\u6001\uFF0Cadvance \u524D\u81EA\u67E5\u7528)\uFF1Bapprove(taskId,decision=approved|rejected\uFF1B\u53EF\u9009 comment\uFF1B\u54CD\u5E94\u5DF2\u542B\u4E0B\u4E00\u8282\u70B9\u8D44\u6599\u5305\uFF0C\u540C\u4F1A\u8BDD\u514D\u91CD\u8BFB context)\uFF1Bpause(taskId\uFF1B\u53EF\u9009 reason)\uFF1Bresume(taskId\uFF1B\u53EF\u9009 resumeNote)\uFF1Bcancel(taskId\uFF1B\u53EF\u9009 reason 1-500 \u5B57\u7B26\uFF1B\u26A0 \u7EC8\u6001\u4E0D\u53EF\u9006\u2014\u2014active/paused \u53EF\u53D6\u6D88\uFF0Ccompleted/cancelled \u62D2\u7EDD\u5E76\u8FD4\u56DE TASK_TERMINATED\uFF1B\u53D6\u6D88\u540E\u7ECF\u672C\u5DE5\u5177\u7684\u6D41\u8F6C\u4E0E\u8BB0\u5F55\u5199\u64CD\u4F5C\u88AB\u62D2)\uFF1Bhistory(taskId)\uFF1Binstance(taskId\u2014\u2014\u67E5\u770B\u4EFB\u52A1 DAG \u5B9E\u4F8B\u5FEB\u7167\uFF1A\u521B\u5EFA\u4EFB\u52A1\u65F6\u51BB\u7ED3\u7684\u6A21\u677F\u5B9E\u4F8B\uFF0C\u6A21\u677F\u540E\u7EED\u53D8\u66F4\u4E0D\u56DE\u6EAF)\u3002\u8BB0\u5F55\u5199\u5165\uFF1Arecord-set(taskId,node\uFF1Bsummary \u4E0E\u516D\u4E2A\u7ED3\u6784\u5316\u5B57\u6BB5\uFF08baseBranch/verifiedCommit/fixesApplied/testReport/deferredIssues/evidenceFiles\uFF09\u81F3\u5C11\u5176\u4E00\u2014\u2014\u7ED3\u6784\u5316\u5B57\u6BB5\u6309\u8282\u70B9 prompt\u300C\u7ED3\u6784\u5316\u5B57\u6BB5\u5199\u5165\u8981\u6C42\u300D\u9010\u5B57\u6BB5\u843D\u5E93\uFF0CPATCH \u8BED\u4E49=\u4EC5\u66F4\u65B0\u63D0\u4F9B\u5B57\u6BB5)\uFF1Brecord-check-add(taskId,node,item\uFF1B\u53EF\u9009 passed \u7F3A\u7701 true\u3001refId=aiChecks \u81EA\u68C0\u7559\u75D5\u951A\uFF08\u5BA1\u8BA1\u8BA4 refId===aiCheck.id \u4E14 passed=true\uFF0C\u7F3A\u7559\u75D5\u7684\u5B8C\u6210\u5224\u5B9A\u5BA1\u8BA1 fail\uFF09\u3001source=self|tool \u672C\u7248\u5DE5\u5177\u7F3A\u7701\u4E0D\u5199\uFF1B\u6279\u91CF checkItems \u5143\u7D20\u540C\u6784\uFF1B\u56DE\u6267 entry.id \u4F9B record-check-patch \u5B9A\u4F4D)\uFF1Brecord-check-patch(taskId,node,checkId\uFF1B\u53EF\u9009 passed/item/refId/source\uFF0C\u4EC5\u66F4\u65B0\u63D0\u4F9B\u5B57\u6BB5)\uFF1Brecord-artifact-add(taskId,node,artifactType=prd|tech|code|test|doc|other\uFF1Bpath \u7EAF\u5F15\u7528 / file \u8BFB\u672C\u673A\u6587\u4EF6 / content \u76F4\u4F20\u5168\u6587\u2014\u2014file \u4E0E content\u3001file \u4E0E path \u4E92\u65A5\uFF0Ccontent \u53EF\u4E0E path \u6210\u5BF9\u6216\u5355\u72EC\uFF0C\u5355\u72EC\u65F6\u767B\u8BB0\u503C\u5408\u6210 mcp-inline/<type>\uFF1B\u53EF\u9009 note)\uFF1Brecord-confirm(taskId,node,quote\u2014\u2014\u6682\u505C\u70B9\u7528\u6237\u786E\u8BA4\u539F\u6587\u9010\u5B57)\uFF1Brecord-decision-add(taskId,node,topic,decisionText)\uFF1Brecord-review-set(taskId,node,verdict=pass|fail,rounds,critical)\u3002\u9700\u6C42\u6587\u6863\uFF1Adoc-set(taskId\uFF1Bwhat/why/trackNote \u81F3\u5C11\u4F20\u4E00)\uFF1Bdoc-acceptance-add(taskId,text)\uFF1Bdoc-non-goal-add(taskId,text)\u3002\u7D20\u6750\uFF1Aarchnote-add(taskId,text)\u3002\u6279\u91CF\u5F62\u6001\uFF08\u63A8\u8350\uFF0C\u516D\u7C7B\u540C\u6784\uFF09\uFF1Arecord-check-add \u4F20 checkItems=[{item,passed?}]\u3001record-artifact-add \u4F20 artifactEntries=[{artifactType,path?/file?/content?,note?}]\u3001record-decision-add \u4F20 decisionEntries=[{topic,decisionText}]\u3001doc-acceptance-add/doc-non-goal-add/archnote-add \u4F20 textItems=[string]\u2014\u2014\u6279\u91CF\u53C2\u6570\u4E0E\u5355\u6761\u53C2\u6570\u4E8C\u9009\u4E00\uFF0C\u4E00\u6B21\u8C03\u7528\u5199\u591A\u6761\uFF08\u4E0A\u9650 50 \u6761/\u6279\uFF0Cartifact \u5168\u6587\u5FEB\u7167\u603B\u91CF \u22642M \u5B57\u7B26/\u6279\uFF09\uFF1B\u90E8\u5206\u5931\u8D25\u4FDD\u7559\u6210\u529F\u6761\u76EE\u5E76\u9010\u6761\u62A5\u544A\uFF08failures[].index=\u539F\u59CB\u63D0\u4EA4\u5E8F\uFF0C\u53EA\u91CD\u8BD5\u5931\u8D25\u9879\uFF09\uFF0Capplied=0 \u6574\u4F53\u62A5\u5931\u8D25\u3002',
2814
+ 'task \u8D44\u6E90\u57DF\u805A\u5408\u5DE5\u5177\uFF08\u4EFB\u52A1\u5168\u64CD\u4F5C\u7ECF\u672C\u5DE5\u5177 + action \u53C2\u6570\uFF09\u3002action \u5FC5\u586B\uFF1B\u8C03\u7528\u65B9\u5E94\u5728 fieldMask \u4E2D\u5217\u51FA\u672C\u6B21\u771F\u5B9E\u63D0\u4F9B\u7684\u53EF\u9009\u5B57\u6BB5\uFF0Cmask \u5916\u7531\u5BBF\u4E3B\u81EA\u52A8\u586B\u5145\u7684\u7A7A\u4E32\u3001\u7A7A\u6570\u7EC4\u3001false\u30010 \u5747\u5FFD\u7565\uFF0Cmask \u5185\u7A7A\u6570\u7EC4/false \u8868\u793A\u663E\u5F0F\u6E05\u7A7A\u6216\u5173\u95ED\uFF1B\u9664 taskId/node \u7B49\u8BE5 action \u56FA\u6709\u5FC5\u586B\u53C2\u6570\u5916\uFF0C\u672C\u6B21\u771F\u5B9E\u63D0\u4F9B\u7684\u5176\u4F59\u53C2\u6570\u2014\u2014\u542B\u5F62\u6001\u4E8C\u9009\u4E00\u7684\u5355\u6761\u5B57\u6BB5\uFF08\u4E0B\u6587\u4EE5 \u203B \u6807\u6CE8\uFF09\u4E0E\u6279\u91CF\u6570\u7EC4\u53C2\u6570\u2014\u2014\u90FD\u5FC5\u987B\u5217\u5165 fieldMask\uFF0C\u5426\u5219\u4F1A\u88AB\u9759\u9ED8\u5FFD\u7565\u3002\u5176\u4F59\u53C2\u6570\u5168\u53EF\u9009\u3001\u6309 action \u8FD0\u884C\u65F6\u6821\u9A8C\u5FC5\u586B\uFF08\u7F3A\u5931\u8FD4\u56DE\u5931\u8D25\u4E09\u8981\u7D20\uFF1A\u5BF9\u8C61+\u6839\u56E0+\u4FEE\u590D\u6307\u5F15\uFF09\u3002projectId \u4E3A key|id \u53CC\u5F62\u6001\uFF0C\u901A\u9053\u5C42\u81EA\u52A8\u5F52\u4E00\u4E3A 24-hex id\uFF1B\u663E\u5F0F\u6307\u5B9A\u89E3\u6790\u5931\u8D25\u62A5\u9519\u4E0D\u515C\u5E95\uFF1B\u7F3A\u7701\u8BED\u4E49\u6309 action\uFF1Acreate \u843D\u9ED8\u8BA4\u9879\u76EE\u94FE\uFF08\u5DE5\u4F5C\u533A defaultProject \u5931\u6548\u62A5\u9519\uFF0C\u65E0\u914D\u7F6E\u4E0D\u4F20\u7531 server \u6309\u6A21\u677F\u5F52\u5C5E\u515C\u5E95\uFF09\uFF0Cquery \u4E0D\u8FC7\u6EE4\uFF08\u5168\u5C40\u67E5\u8BE2\uFF09\u3002\u5199\u64CD\u4F5C\uFF08create/doc-*/record-*/archnote-add/pause/resume/cancel\uFF09\u54CD\u5E94\u4E3A\u8F7B\u91CF\u56DE\u6267\uFF1A{taskId, updated(\u89E6\u53CA\u5B57\u6BB5\u8DEF\u5F84), entry(\u65B0\u6761\u76EE id+kind\uFF0C\u4F9B\u540E\u7EED patch \u5B9A\u4F4D), echo(\u5199\u5165\u5185\u5BB9\u56DE\u663E), updatedAt, task(\u4EFB\u52A1\u8FDB\u5EA6\u6458\u8981 progress: {completed,total})}\u2014\u2014\u4E0D\u8FD4\u56DE\u5B8C\u6574\u4EFB\u52A1\u5B9E\u4F53\u3002action \u6E05\u5355\uFF08\u62EC\u53F7\u5185\u4E3A\u8BE5 action \u5FC5\u586B\u53C2\u6570\uFF09\uFF1Acreate(templateId,taskTitle,track\uFF1Btrack \u652F\u6301\u7EC4\u5408\u8F68\u9053\u2014\u2014\u6570\u7EC4\u5F62\u6001\uFF08\u5982 ["backend","godot"]\uFF0C\u6210\u5458=\u6CE8\u518C\u8868 active \u5355\u8F68\uFF09\u6216\u5355\u503C string\uFF1Ball \u4E3A\u4EFB\u52A1\u7EA7\u901A\u914D\uFF08\u6FC0\u6D3B\u521B\u5EFA\u65F6\u70B9\u5168\u90E8\u542F\u7528\u5355\u8F68\uFF0C\u5355\u503C\u4F7F\u7528\uFF09\uFF1B\u53EF\u9009 type=feature|bugfix|ui-tweak|research\u3001skipNodes\u3001projectId\uFF1BtemplateId \u652F\u6301 code|id \u53CC\u5F62\u6001\u2014\u2014code \u4E3A\u6A21\u677F\u4E1A\u52A1\u6807\u8BC6\uFF08\u9879\u76EE\u5185\u552F\u4E00\u3001kebab-case \u5FC5\u542B\u8FDE\u5B57\u7B26\uFF0C\u5982 full-workflow\uFF09\uFF0C\u63A8\u8350\u5F15\u7528\u5F62\u6001\uFF0C\u5BFB\u5740\u987B\u914D projectId \u6307\u5B9A\u9879\u76EE\u57DF\uFF1B24-hex \u6570\u636E\u5E93 id \u76F4\u67E5\u517C\u5BB9\uFF1Bcode \u5F62\u6001\u4E0D\u5B58\u5728\u65F6\u9519\u8BEF\u542B candidates \u76F8\u8FD1\u5019\u9009\u6E05\u5355\uFF08id/code/name \u22645 \u6761\uFF09\uFF1B\u54CD\u5E94 {task, firstNode}\u2014\u2014firstNode \u5373\u9996\u8282\u70B9\u5B8C\u6574\u8D44\u6599\u5305\uFF0C\u514D\u8C03 context)\uFF1Bquery(taskId \u8FD4\u56DE\u5355\u4EFB\u52A1\u8BE6\u60C5\uFF0C\u7F3A\u7701\u8FD4\u56DE\u5217\u8868\uFF0C\u53EF\u9009 status/track/projectId/page/limit)\uFF1Bcontext(taskId\uFF1B\u53EF\u9009 view=basic|full\u2014\u2014basic \u7F3A\u7701\u4E0D\u643A\u5E26 artifact \u5168\u6587\u5FEB\u7167\uFF0Cfull \u65AD\u70B9\u7EED\u8DD1\u9700\u5386\u53F2\u4EA7\u7269\u5168\u6587\u65F6\u7528\u3002\u26A0 \u514D\u91CD\u8BFB\uFF1Aadvance/approve \u6D41\u8F6C\u54CD\u5E94\u5DF2\u542B\u4E0B\u4E00\u8282\u70B9\u5B8C\u6574\u8D44\u6599\u5305\uFF0C\u540C\u4F1A\u8BDD\u5185\u6D41\u8F6C\u540E\u76F4\u63A5\u5F00\u5DE5\u3001\u65E0\u9700\u518D\u8C03 context\uFF1B\u4EC5\u65B0\u4F1A\u8BDD/\u65AD\u70B9\u7EED\u8DD1\u8C03\u7528)\uFF1Bnode(taskId,view=prompt|skills\uFF1BnodeId \u7F3A\u7701\u7528\u5F53\u524D\u8282\u70B9\uFF1B\u26A0 view \u503C\u968F action \u4E0D\u540C\uFF1Anode\u2192prompt|skills\uFF0Ccontext\u2192basic|full\uFF0C\u9519\u914D\u62A5\u9519)\uFF1Badvance(taskId\uFF1Bnote \u5199 history\u3001summary \u5199 nodeRecords\uFF0C\u4E24\u4F4D\u72EC\u7ACB\uFF1B\u26A0 T202610130004 \u7EC8\u6001\u6536\u5C3E\uFF1A\u4EFB\u52A1\u5904\u4E8E\u7EC8\u8282\u70B9\u65F6 advance \u5FC5\u5E26 finalize=true \u4F5C\u6536\u5C3E\u786E\u8BA4\uFF08\u7F3A\u7701\u88AB\u62D2\u5E76\u8FD4\u56DE\u63D0\u793A\uFF09\uFF0C\u4E2D\u95F4\u8282\u70B9\u5FFD\u7565\u8BE5\u53C2\u6570\uFF1B\u54CD\u5E94\u5DF2\u542B\u4E0B\u4E00\u8282\u70B9\u8D44\u6599\u5305\uFF0C\u540C\u4F1A\u8BDD\u514D\u91CD\u8BFB context\u3002\u26A0 T202609230001 \u8282\u70B9\u95E8\u7981\uFF1A\u914D\u7F6E\u4E86 toolChecks/aiChecks \u7684\u8282\u70B9\u63A8\u8FDB\u524D\u81EA\u52A8\u6267\u884C\u68C0\u67E5\u2014\u2014fail \u4F1A\u88AB\u6253\u56DE\u5E76\u8FD4\u56DE\u9010\u9879\u4FEE\u590D\u6307\u5F15\uFF08\u7ED3\u679C\u5DF2\u5199 history checks_rejected\uFF09\uFF0C\u6309\u6307\u5F15\u4FEE\u590D\u6216\u83B7\u7528\u6237\u8C41\u514D\u7559\u75D5\u540E\u91CD\u63A8\uFF1B\u975E\u4EBA\u5DE5\u5BA1\u6279\u8282\u70B9\u7981\u6B62\u56E0\u95E8\u7981\u4E2D\u65AD\u4EFB\u52A1\uFF08\u6253\u56DE\u4FE1\u606F\u5373\u7EE7\u7EED\u4F9D\u636E\uFF09\u3002force+forceReason \u6210\u5BF9\u63D0\u4F9B\u65F6\u53EF\u8D8A\u8FC7 fail \u5F3A\u5236\u63A8\u8FDB\u2014\u2014\u4EC5\u51ED\u7528\u6237\u660E\u793A\u6307\u4EE4\uFF0CAI \u7981\u6B62\u81EA\u51B3\uFF0C\u7406\u7531\u539F\u6587\u843D history \u5BA1\u8BA1)\uFF1Bcheck(taskId\uFF1B\u95E8\u7981\u53EA\u8BFB\u9884\u68C0\u2014\u2014\u9010\u9879\u62A5\u544A\u4E0D\u5199\u4EFB\u4F55\u72B6\u6001\uFF0Cadvance \u524D\u81EA\u67E5\u7528)\uFF1Bapprove(taskId,decision=approved|rejected\uFF1B\u53EF\u9009 comment\uFF1B\u54CD\u5E94\u5DF2\u542B\u4E0B\u4E00\u8282\u70B9\u8D44\u6599\u5305\uFF0C\u540C\u4F1A\u8BDD\u514D\u91CD\u8BFB context)\uFF1Bpause(taskId\uFF1B\u53EF\u9009 reason)\uFF1Bresume(taskId\uFF1B\u53EF\u9009 resumeNote)\uFF1Bcancel(taskId\uFF1B\u53EF\u9009 reason 1-500 \u5B57\u7B26\uFF1B\u26A0 \u7EC8\u6001\u4E0D\u53EF\u9006\u2014\u2014active/paused \u53EF\u53D6\u6D88\uFF0Ccompleted/cancelled \u62D2\u7EDD\u5E76\u8FD4\u56DE TASK_TERMINATED\uFF1B\u53D6\u6D88\u540E\u7ECF\u672C\u5DE5\u5177\u7684\u6D41\u8F6C\u4E0E\u8BB0\u5F55\u5199\u64CD\u4F5C\u88AB\u62D2)\uFF1Bhistory(taskId)\uFF1Binstance(taskId\u2014\u2014\u67E5\u770B\u4EFB\u52A1 DAG \u5B9E\u4F8B\u5FEB\u7167\uFF1A\u521B\u5EFA\u4EFB\u52A1\u65F6\u51BB\u7ED3\u7684\u6A21\u677F\u5B9E\u4F8B\uFF0C\u6A21\u677F\u540E\u7EED\u53D8\u66F4\u4E0D\u56DE\u6EAF)\u3002\u8BB0\u5F55\u5199\u5165\uFF1Arecord-set(taskId,node\uFF1Bsummary \u4E0E\u516D\u4E2A\u7ED3\u6784\u5316\u5B57\u6BB5\uFF08baseBranch/verifiedCommit/fixesApplied/testReport/deferredIssues/evidenceFiles\uFF09\u81F3\u5C11\u5176\u4E00\u203B\u2014\u2014\u7ED3\u6784\u5316\u5B57\u6BB5\u6309\u8282\u70B9 prompt\u300C\u7ED3\u6784\u5316\u5B57\u6BB5\u5199\u5165\u8981\u6C42\u300D\u9010\u5B57\u6BB5\u843D\u5E93\uFF0CPATCH \u8BED\u4E49=\u4EC5\u66F4\u65B0\u63D0\u4F9B\u5B57\u6BB5)\uFF1Brecord-check-add(taskId,node,item\u203B\uFF1B\u53EF\u9009 passed \u7F3A\u7701 true\u3001refId=aiChecks \u81EA\u68C0\u7559\u75D5\u951A\uFF08\u5BA1\u8BA1\u8BA4 refId===aiCheck.id \u4E14 passed=true\uFF0C\u7F3A\u7559\u75D5\u7684\u5B8C\u6210\u5224\u5B9A\u5BA1\u8BA1 fail\uFF09\u3001source=self|tool \u672C\u7248\u5DE5\u5177\u7F3A\u7701\u4E0D\u5199\uFF1B\u6279\u91CF checkItems \u5143\u7D20\u540C\u6784\uFF1B\u56DE\u6267 entry.id \u4F9B record-check-patch \u5B9A\u4F4D)\uFF1Brecord-check-patch(taskId,node,checkId\uFF1B\u53EF\u9009 passed/item/refId/source\uFF08\u5747\u203B\uFF09\uFF0C\u4EC5\u66F4\u65B0\u63D0\u4F9B\u5B57\u6BB5)\uFF1Brecord-artifact-add(taskId,node,artifactType=prd|tech|code|test|doc|other\u203B\uFF1Bpath / file / content \u4E09\u9009\u4E00\u203B\u2014\u2014path \u7EAF\u5F15\u7528 / file \u8BFB\u672C\u673A\u6587\u4EF6 / content \u76F4\u4F20\u5168\u6587\u2014\u2014file \u4E0E content\u3001file \u4E0E path \u4E92\u65A5\uFF0Ccontent \u53EF\u4E0E path \u6210\u5BF9\u6216\u5355\u72EC\uFF0C\u5355\u72EC\u65F6\u767B\u8BB0\u503C\u5408\u6210 mcp-inline/<type>\uFF1B\u53EF\u9009 note)\uFF1Brecord-confirm(taskId,node,quote\u2014\u2014\u6682\u505C\u70B9\u7528\u6237\u786E\u8BA4\u539F\u6587\u9010\u5B57)\uFF1Brecord-decision-add(taskId,node,topic\u203B,decisionText\u203B)\uFF1Brecord-review-set(taskId,node,verdict=pass|fail,rounds,critical)\u3002\u9700\u6C42\u6587\u6863\uFF1Adoc-set(taskId\uFF1Bwhat/why/trackNote \u81F3\u5C11\u4F20\u4E00\u203B)\uFF1Bdoc-acceptance-add(taskId,text\u203B)\uFF1Bdoc-non-goal-add(taskId,text\u203B)\u3002\u7D20\u6750\uFF1Aarchnote-add(taskId,text\u203B)\u3002\u6279\u91CF\u5F62\u6001\uFF08\u63A8\u8350\uFF0C\u516D\u7C7B\u540C\u6784\uFF09\uFF1Arecord-check-add \u4F20 checkItems=[{item,passed?}]\u3001record-artifact-add \u4F20 artifactEntries=[{artifactType,path?/file?/content?,note?}]\u3001record-decision-add \u4F20 decisionEntries=[{topic,decisionText}]\u3001doc-acceptance-add/doc-non-goal-add/archnote-add \u4F20 textItems=[string]\u2014\u2014\u6279\u91CF\u53C2\u6570\u4E0E\u5355\u6761\u53C2\u6570\u4E8C\u9009\u4E00\uFF08\u6279\u91CF\u53C2\u6570\u540C\u6837\u203B\uFF09\uFF0C\u4E00\u6B21\u8C03\u7528\u5199\u591A\u6761\uFF08\u4E0A\u9650 50 \u6761/\u6279\uFF0Cartifact \u5168\u6587\u5FEB\u7167\u603B\u91CF \u22642M \u5B57\u7B26/\u6279\uFF09\uFF1B\u90E8\u5206\u5931\u8D25\u4FDD\u7559\u6210\u529F\u6761\u76EE\u5E76\u9010\u6761\u62A5\u544A\uFF08failures[].index=\u539F\u59CB\u63D0\u4EA4\u5E8F\uFF0C\u53EA\u91CD\u8BD5\u5931\u8D25\u9879\uFF09\uFF0Capplied=0 \u6574\u4F53\u62A5\u5931\u8D25\u3002',
2782
2815
  taskArgs,
2783
2816
  async (rawArgs) => {
2784
2817
  const masked = applyFieldMask(rawArgs, TASK_FIELD_SPECS);
@@ -2936,9 +2969,10 @@ function createMcpServer() {
2936
2969
  ...args.evidenceFiles !== void 0 ? { evidenceFiles: args.evidenceFiles } : {}
2937
2970
  };
2938
2971
  if (Object.keys(fields).length === 0) {
2972
+ const stripped = strippedFieldsOf(args);
2939
2973
  return localError(
2940
2974
  "record-set \u9700\u8981\u81F3\u5C11\u4E00\u4E2A\u5B57\u6BB5\uFF08summary \u6216\u7ED3\u6784\u5316\u5B57\u6BB5\uFF09",
2941
- "\u7ED3\u6784\u5316\u5B57\u6BB5\u6309\u8282\u70B9 prompt\u300C\u7ED3\u6784\u5316\u5B57\u6BB5\u5199\u5165\u8981\u6C42\u300D\u9010\u5B57\u6BB5\u843D\u5E93\uFF1AbaseBranch/verifiedCommit/fixesApplied/testReport/deferredIssues/evidenceFiles"
2975
+ stripped.length > 0 ? `\u5B57\u6BB5 ${stripped.join(", ")} \u5DF2\u63D0\u4F9B\u4F46\u672A\u5217\u5165 fieldMask \u88AB\u5FFD\u7565\uFF1A\u5C06\u5176\u52A0\u5165 fieldMask \u540E\u91CD\u8BD5\uFF1B\u7ED3\u6784\u5316\u5B57\u6BB5\u6309\u8282\u70B9 prompt\u300C\u7ED3\u6784\u5316\u5B57\u6BB5\u5199\u5165\u8981\u6C42\u300D\u9010\u5B57\u6BB5\u843D\u5E93\uFF1AbaseBranch/verifiedCommit/fixesApplied/testReport/deferredIssues/evidenceFiles` : "\u7ED3\u6784\u5316\u5B57\u6BB5\u6309\u8282\u70B9 prompt\u300C\u7ED3\u6784\u5316\u5B57\u6BB5\u5199\u5165\u8981\u6C42\u300D\u9010\u5B57\u6BB5\u843D\u5E93\uFF1AbaseBranch/verifiedCommit/fixesApplied/testReport/deferredIssues/evidenceFiles"
2942
2976
  );
2943
2977
  }
2944
2978
  return mcpContent(await handleRecordSummarySet(client, taskId, node, fields));
@@ -3015,9 +3049,10 @@ function createMcpServer() {
3015
3049
  }
3016
3050
  const { path, file, content, note } = args;
3017
3051
  if (!path && !file && !content) {
3052
+ const stripped = strippedFieldsOf(args).filter((f) => f === "path" || f === "file" || f === "content");
3018
3053
  return localError(
3019
3054
  "record-artifact-add \u9700\u8981 path\uFF08\u7EAF\u5F15\u7528\uFF09/ file\uFF08\u8BFB\u672C\u673A\u6587\u4EF6\uFF09/ content\uFF08\u76F4\u4F20\u5168\u6587\uFF09\u4E4B\u4E00",
3020
- "\u8BBE\u8BA1\u6587\u6863\u7C7B\u4EA7\u7269\u7528 content \u6216 file\uFF1A\u7EED\u8DD1\u4F1A\u8BDD\u51ED context \u5373\u53EF\u53D6\u56DE\u5168\u6587"
3055
+ stripped.length > 0 ? `\u5B57\u6BB5 ${stripped.join(", ")} \u5DF2\u63D0\u4F9B\u4F46\u672A\u5217\u5165 fieldMask \u88AB\u5FFD\u7565\uFF1A\u5C06\u5176\u52A0\u5165 fieldMask \u540E\u91CD\u8BD5\uFF1B\u8BBE\u8BA1\u6587\u6863\u7C7B\u4EA7\u7269\u7528 content \u6216 file\uFF1A\u7EED\u8DD1\u4F1A\u8BDD\u51ED context \u5373\u53EF\u53D6\u56DE\u5168\u6587` : "\u8BBE\u8BA1\u6587\u6863\u7C7B\u4EA7\u7269\u7528 content \u6216 file\uFF1A\u7EED\u8DD1\u4F1A\u8BDD\u51ED context \u5373\u53EF\u53D6\u56DE\u5168\u6587"
3021
3056
  );
3022
3057
  }
3023
3058
  if (file && content) {
@@ -3098,9 +3133,10 @@ function createMcpServer() {
3098
3133
  const { taskId } = args;
3099
3134
  if (taskId === void 0) return requireError("doc-set", ["taskId"], args);
3100
3135
  if (args.what === void 0 && args.why === void 0 && args.trackNote === void 0) {
3136
+ const stripped = strippedFieldsOf(args).filter((f) => f === "what" || f === "why" || f === "trackNote");
3101
3137
  return localError(
3102
3138
  "action=doc-set \u9700\u8981 what / why / trackNote \u4E4B\u4E00\uFF08\u7A7A\u66F4\u65B0\u65E0\u610F\u4E49\uFF09",
3103
- '\u793A\u4F8B\uFF1A{"taskId":"T1","action":"doc-set","what":"\u76EE\u6807","why":"\u52A8\u673A"}'
3139
+ stripped.length > 0 ? `\u5B57\u6BB5 ${stripped.join(", ")} \u5DF2\u63D0\u4F9B\u4F46\u672A\u5217\u5165 fieldMask \u88AB\u5FFD\u7565\uFF1A\u5C06\u5176\u52A0\u5165 fieldMask \u540E\u91CD\u8BD5\uFF1B\u793A\u4F8B\uFF1A{"taskId":"T1","action":"doc-set","what":"\u76EE\u6807","why":"\u52A8\u673A"}` : '\u793A\u4F8B\uFF1A{"taskId":"T1","action":"doc-set","what":"\u76EE\u6807","why":"\u52A8\u673A"}'
3104
3140
  );
3105
3141
  }
3106
3142
  return mcpContent(
@@ -3742,7 +3778,7 @@ function createTaskCommand() {
3742
3778
  renderResult(opts.format, result, { fields: result.success ? nodeFields(result.data) : [] });
3743
3779
  });
3744
3780
  const record = task.command("record").description("Node execution records \u2014 summary/checks/artifacts/confirmations/decisions/review (draft-writable, small-step append)");
3745
- withCommonOpts(record.command("set <taskId>"), "fancy").description("Set node record fields \u2014 --summary and/or structured fields (T202609230001: baseBranch/testReport/... ; at least one required)").requiredOption("--node <nid>", "node id (see `task context`)").option("--summary <text>", "node summary text").option("--base-branch <branch>", "align \u57FA\u7840\u5206\u652F\uFF08test-integrate \u7B49\u8282\u70B9\u7ED3\u6784\u5316\u5199\u5165\uFF09").option("--verified-commit <sha>", "\u9A8C\u8BC1\u901A\u8FC7\u5BF9\u5E94\u7684\u63D0\u4EA4\u53F7\uFF08verifiedCommit\uFF09").option("--fixes-applied <n>", "fixesApplied \u4FEE\u590D\u6B21\u6570\uFF08\u975E\u8D1F\u6574\u6570\uFF1BB4 \u6761\u4EF6\u95E8\u7981\uFF1A>0 \u987B\u8BC4\u5BA1 verdict=pass\uFF09").option("--test-report <json>", `testReport JSON\uFF1A'{"command":"pnpm test","passed":10,"failed":0,"skipped":0}'`).option("--deferred-issues <list>", "\u5EF6\u540E\u95EE\u9898 id \u5217\u8868\uFF08\u9017\u53F7\u5206\u9694\uFF09").option("--evidence-files <list>", "\u8BC1\u636E\u6587\u4EF6\u8DEF\u5F84\u5217\u8868\uFF08\u9017\u53F7\u5206\u9694\uFF09").action(
3781
+ withCommonOpts(record.command("set <taskId>"), "fancy").description("Set node record fields \u2014 --summary and/or structured fields (T202609230001: baseBranch/testReport/... ; at least one required)").requiredOption("--node <nid>", "node id (see `task context`)").option("--summary <text>", "node summary text").option("--base-branch <branch>", "align \u57FA\u7840\u5206\u652F\uFF08test-integrate \u7B49\u8282\u70B9\u7ED3\u6784\u5316\u5199\u5165\uFF09").option("--verified-commit <sha>", "\u9A8C\u8BC1\u901A\u8FC7\u5BF9\u5E94\u7684\u63D0\u4EA4\u53F7\uFF08verifiedCommit\uFF09").option("--fixes-applied <n>", "fixesApplied \u4FEE\u590D\u6B21\u6570\uFF08\u975E\u8D1F\u6574\u6570\uFF1BB4 \u6761\u4EF6\u95E8\u7981\uFF1A>0 \u987B\u8BC4\u5BA1 verdict=pass\uFF09").option("--test-report <json>", `testReport JSON\uFF1A'{"command":"pnpm test","passed":10,"failed":0,"skipped":0}'`).option("--deferred-issues <list>", "\u5EF6\u540E\u95EE\u9898 id \u5217\u8868\uFF08\u9017\u53F7\u5206\u9694\u6216 JSON \u5B57\u7B26\u4E32\u6570\u7EC4\uFF09").option("--evidence-files <list>", "\u8BC1\u636E\u6587\u4EF6\u8DEF\u5F84\u5217\u8868\uFF08\u9017\u53F7\u5206\u9694\u6216 JSON \u5B57\u7B26\u4E32\u6570\u7EC4\uFF09").action(
3746
3782
  async (taskId, opts) => {
3747
3783
  const client = createClient(opts.url);
3748
3784
  let fixesApplied;
@@ -3763,9 +3799,39 @@ function createTaskCommand() {
3763
3799
  return;
3764
3800
  }
3765
3801
  }
3766
- const splitList = (raw) => raw === void 0 ? void 0 : raw.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
3767
- const deferredIssues = splitList(opts.deferredIssues);
3768
- const evidenceFiles = splitList(opts.evidenceFiles);
3802
+ const parseListField = (label, raw) => {
3803
+ const trimmed = raw.trim();
3804
+ if (trimmed.startsWith("[") && trimmed.endsWith("]")) {
3805
+ try {
3806
+ const parsed = JSON.parse(trimmed);
3807
+ if (Array.isArray(parsed) && parsed.every((item) => typeof item === "string")) {
3808
+ return { ok: true, value: parsed.filter((s) => s.trim().length > 0) };
3809
+ }
3810
+ return { ok: false, message: `${label} JSON \u6570\u7EC4\u5143\u7D20\u987B\u5168\u4E3A\u5B57\u7B26\u4E32\uFF08\u6536\u5230 ${raw}\uFF09` };
3811
+ } catch {
3812
+ return { ok: false, message: `${label} JSON \u6570\u7EC4\u89E3\u6790\u5931\u8D25\uFF08\u6536\u5230 ${raw}\uFF09` };
3813
+ }
3814
+ }
3815
+ return { ok: true, value: raw.split(",").map((s) => s.trim()).filter((s) => s.length > 0) };
3816
+ };
3817
+ let deferredIssues;
3818
+ if (opts.deferredIssues !== void 0) {
3819
+ const parsed = parseListField("--deferred-issues", opts.deferredIssues);
3820
+ if (!parsed.ok) {
3821
+ renderResult(opts.format, fail({ message: parsed.message, httpStatus: 0 }));
3822
+ return;
3823
+ }
3824
+ deferredIssues = parsed.value;
3825
+ }
3826
+ let evidenceFiles;
3827
+ if (opts.evidenceFiles !== void 0) {
3828
+ const parsed = parseListField("--evidence-files", opts.evidenceFiles);
3829
+ if (!parsed.ok) {
3830
+ renderResult(opts.format, fail({ message: parsed.message, httpStatus: 0 }));
3831
+ return;
3832
+ }
3833
+ evidenceFiles = parsed.value;
3834
+ }
3769
3835
  const fields = {
3770
3836
  ...opts.summary !== void 0 ? { summary: opts.summary } : {},
3771
3837
  ...opts.baseBranch !== void 0 ? { baseBranch: opts.baseBranch } : {},
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@siming-org/cli",
3
- "version": "0.8.8",
3
+ "version": "0.8.10",
4
4
  "license": "MIT",
5
5
  "author": "Wuchao",
6
6
  "engines": {
@@ -27,8 +27,8 @@
27
27
  "picocolors": "^1.1.1",
28
28
  "yaml": "^2.6.0",
29
29
  "zod": "^4.4.3",
30
- "@siming-org/core": "0.8.8",
31
- "@siming-org/server": "0.8.8"
30
+ "@siming-org/core": "0.8.10",
31
+ "@siming-org/server": "0.8.10"
32
32
  },
33
33
  "devDependencies": {
34
34
  "tsup": "^8.3.5",