@siming-org/cli 0.8.11 → 0.8.13

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 +65 -14
  2. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -629,6 +629,21 @@ var SimingHttpClient = class {
629
629
  }
630
630
  }
631
631
  };
632
+ function firstZod4Issue(raw) {
633
+ let parsed;
634
+ try {
635
+ parsed = JSON.parse(raw);
636
+ } catch {
637
+ return null;
638
+ }
639
+ if (!Array.isArray(parsed) || parsed.length === 0) return null;
640
+ const issue = parsed[0] ?? {};
641
+ if (typeof issue.message !== "string") return null;
642
+ if (Array.isArray(issue.path) && issue.path.length > 0) {
643
+ return `${issue.message}\uFF08at ${issue.path.map(String).join(".")}\uFF09`;
644
+ }
645
+ return issue.message;
646
+ }
632
647
  function extractError(res, body) {
633
648
  let bizCode;
634
649
  let message = `HTTP ${res.status}`;
@@ -639,7 +654,12 @@ function extractError(res, body) {
639
654
  } else if (b.error && typeof b.error === "object") {
640
655
  const e = b.error;
641
656
  const first = e.issues?.[0]?.message;
642
- if (typeof first === "string") message = first;
657
+ if (typeof first === "string") {
658
+ message = first;
659
+ } else if (typeof e.message === "string") {
660
+ const zod4 = firstZod4Issue(e.message);
661
+ if (zod4 !== null) message = zod4;
662
+ }
643
663
  }
644
664
  if (typeof b.message === "string") message = b.message;
645
665
  }
@@ -759,6 +779,10 @@ import {
759
779
  var NA_PHRASES = ["\u4E0D\u9002\u7528", "N/A", "not applicable", "n-a"];
760
780
  var MIN_AI_CHECK_ITEM_LENGTH = 15;
761
781
  var VAGUE_AI_CHECK_BLACKLIST = ["\u5DF2\u5B8C\u6210", "\u901A\u8FC7", "\u5B8C\u6210", "done", "ok", "pass"];
782
+ var VAGUE_PHRASE_STRIP = /[\s\p{P}\p{S}]+/gu;
783
+ function normalizeVaguePhrase(text) {
784
+ return text.normalize("NFKC").replace(VAGUE_PHRASE_STRIP, "").toLowerCase();
785
+ }
762
786
 
763
787
  // src/client/checks/git-checks.ts
764
788
  async function perRepoCheck(ctx, type, judge) {
@@ -976,7 +1000,13 @@ async function checkTestReport(ctx) {
976
1000
  return fail3(type, "\u672C\u8282\u70B9\u8BB0\u5F55\u672A\u5199 testReport\uFF08\u7ED3\u6784\u5316\u5B57\u6BB5\u7F3A\u5931\uFF09", "record-set \u5199 testReport {command,passed,failed,skipped}\uFF08\u771F\u5B9E\u6267\u884C\u7684\u6D4B\u8BD5\u547D\u4EE4\u4E0E\u7ED3\u679C\u8BA1\u6570\uFF09");
977
1001
  }
978
1002
  if (report.failed > 0) {
979
- return fail3(type, `\u6D4B\u8BD5\u5B58\u5728\u5931\u8D25\uFF1Afailed=${report.failed}\uFF08${report.command}\uFF09`, "\u4FEE\u590D\u5931\u8D25\u7528\u4F8B\u6216\u7ECF\u7528\u6237\u6388\u6743\u540E\u8D70\u8C41\u514D\u901A\u9053\uFF0C\u7981\u6B62\u5E26\u5931\u8D25\u63A8\u8FDB");
1003
+ const topics = (ctx.record?.decisions ?? []).filter((d) => d.decision.trim() !== "").map((d) => d.topic);
1004
+ const diagnosis = topics.length > 0 ? `\uFF1B\u672C\u8282\u70B9\u5DF2\u6709 decisions\uFF08topic\uFF1A${topics.join("\u3001")}\uFF09\u2014\u2014\u5931\u8D25\u7528\u4F8B\u4E0D\u8BBE decision \u8C41\u514D\uFF0C\u4EE5\u4E0A\u7559\u75D5\u4E0D\u6539\u53D8\u672C\u5224\u5B9A` : "";
1005
+ return fail3(
1006
+ type,
1007
+ `\u6D4B\u8BD5\u5B58\u5728\u5931\u8D25\uFF1Afailed=${report.failed}\uFF08${report.command}\uFF09${diagnosis}`,
1008
+ "\u4FEE\u590D\u5931\u8D25\u7528\u4F8B\u81F3\u5168\u7EFF\u540E\u91CD\u63A8\uFF08\u7981\u6B62\u5E26\u5931\u8D25\u63A8\u8FDB\uFF1B\u5931\u8D25\u7528\u4F8B\u65E0 decision \u8C41\u514D\u8DEF\u5F84\uFF09"
1009
+ );
980
1010
  }
981
1011
  if (report.skipped > 0) {
982
1012
  const waiver = decisionByTopic(ctx.record, "skip-authorized");
@@ -1337,14 +1367,15 @@ function auditAiChecks(aiChecks, record) {
1337
1367
  });
1338
1368
  continue;
1339
1369
  }
1340
- if (VAGUE_AI_CHECK_BLACKLIST.some((w) => lowered.includes(w))) {
1370
+ const normalizedItem = normalizeVaguePhrase(check.item);
1371
+ if (VAGUE_AI_CHECK_BLACKLIST.some((w) => normalizedItem === normalizeVaguePhrase(w))) {
1341
1372
  results.push({
1342
1373
  id: check.id,
1343
1374
  item: check.item,
1344
1375
  status: "fail",
1345
1376
  // T202610130004 C3(I202610120001):模糊语分支仅在无 refId 留痕时触发,record-check-patch 无可修补目标(按 entry id 寻址)——
1346
1377
  // 指引指向 add 带 refId 重记;补 item 原文让被打回方定位是哪条自检项被判模糊
1347
- detail: `item\u300C${check.item}\u300D\u4E3A\u6A21\u7CCA\u5B8C\u6210\u8BED\uFF08\u547D\u4E2D\u9ED1\u540D\u5355\u300C${VAGUE_AI_CHECK_BLACKLIST.join("/")}\u300D\uFF09\u3002\u4FEE\u590D\uFF1A\u6539\u5199\u4E3A\u53EF\u6838\u5BF9\u7684\u5177\u4F53\u4E8B\u5B9E\u540E record-check-add \u5E26 refId=${check.id}\uFF08CLI --ref-id\uFF09+ passed=true \u91CD\u8BB0`
1378
+ detail: `item\u300C${check.item}\u300D\u4E3A\u6A21\u7CCA\u5B8C\u6210\u8BED\uFF08\u547D\u4E2D\u9ED1\u540D\u5355\u300C${VAGUE_AI_CHECK_BLACKLIST.join("/")}\u300D\u6574\u53E5\u7B49\u4EF7\u5F62\u6001\uFF09\u3002\u4FEE\u590D\uFF1Arecord-check-add \u5E26 refId=${check.id}\uFF08CLI --ref-id\uFF09+ \u53EF\u6838\u5BF9\u7684\u5177\u4F53\u4E8B\u5B9E + passed=true \u7559\u75D5`
1348
1379
  });
1349
1380
  continue;
1350
1381
  }
@@ -1573,7 +1604,7 @@ function buildGateFailMessage(report, reportWritten = true) {
1573
1604
  return {
1574
1605
  message: `\u8282\u70B9\u95E8\u7981\u672A\u901A\u8FC7\uFF08${fails.length} \u9879 fail\uFF0C${passed} \u9879\u901A\u8FC7/\u4E0D\u9002\u7528\uFF09\uFF0Cadvance \u5DF2\u62E6\u622A\uFF1A
1575
1606
  ${fails.map((f, i) => `${i + 1}. ${f}`).join("\n")}`,
1576
- hint: reportWritten ? "\u9010\u9879\u5B8C\u6210\u4FEE\u590D\u6216\u7528\u6237\u660E\u793A\u8C41\u514D\uFF08\u7ECF record-decision-add \u7559\u75D5\uFF09\u540E\u91CD\u65B0\u63A8\u8FDB\uFF1B\u95E8\u7981\u7ED3\u679C\u5DF2\u5199\u5165\u4EFB\u52A1 history\uFF08checks_rejected\uFF09" : "\u9010\u9879\u5B8C\u6210\u4FEE\u590D\u6216\u7528\u6237\u660E\u793A\u8C41\u514D\uFF08\u7ECF record-decision-add \u7559\u75D5\uFF09\u540E\u91CD\u65B0\u63A8\u8FDB\u3002\u6CE8\u610F\uFF1A\u672C\u6B21\u95E8\u7981\u7ED3\u679C\u7559\u75D5\u5931\u8D25\uFF0Chistory \u7F3A\u5931\u8BE5\u6B21\u8BB0\u5F55\uFF08\u4FEE\u590D\u540E\u91CD\u63A8\u65F6\u4F1A\u91CD\u65B0\u7559\u75D5\uFF09"
1607
+ hint: reportWritten ? "\u9010\u9879\u6309\u8BE5\u68C0\u67E5\u7684\u4FEE\u590D\u6307\u5F15\u5904\u7406\uFF1B\u8C41\u514D\u4EC5\u5BF9\u6307\u5F15\u4E2D\u58F0\u660E\u7684\u8C41\u514D\u8DEF\u5F84\u6709\u6548\uFF08\u7ECF\u7528\u6237\u660E\u793A\u6388\u6743\u540E\u6309\u6307\u5F15\u7559\u75D5\uFF09\u540E\u91CD\u65B0\u63A8\u8FDB\uFF1B\u95E8\u7981\u7ED3\u679C\u5DF2\u5199\u5165\u4EFB\u52A1 history\uFF08checks_rejected\uFF09" : "\u9010\u9879\u6309\u8BE5\u68C0\u67E5\u7684\u4FEE\u590D\u6307\u5F15\u5904\u7406\uFF1B\u8C41\u514D\u4EC5\u5BF9\u6307\u5F15\u4E2D\u58F0\u660E\u7684\u8C41\u514D\u8DEF\u5F84\u6709\u6548\uFF08\u7ECF\u7528\u6237\u660E\u793A\u6388\u6743\u540E\u6309\u6307\u5F15\u7559\u75D5\uFF09\u540E\u91CD\u65B0\u63A8\u8FDB\u3002\u6CE8\u610F\uFF1A\u672C\u6B21\u95E8\u7981\u7ED3\u679C\u7559\u75D5\u5931\u8D25\uFF0Chistory \u7F3A\u5931\u8BE5\u6B21\u8BB0\u5F55\uFF08\u4FEE\u590D\u540E\u91CD\u63A8\u65F6\u4F1A\u91CD\u65B0\u7559\u75D5\uFF09"
1577
1608
  };
1578
1609
  }
1579
1610
  function naCategory(detail) {
@@ -2582,7 +2613,8 @@ var taskArgs = {
2582
2613
  verifiedCommit: z3.string().optional(),
2583
2614
  fixesApplied: z3.number().int().nonnegative().optional(),
2584
2615
  testReport: z3.object({
2585
- command: z3.string(),
2616
+ // 与 core TestReportSchema 对齐(T202610190002 ⑤):min/max 同步对齐,超限在 MCP 层即报字段级错误
2617
+ command: z3.string().min(1).max(200),
2586
2618
  passed: z3.number().int().nonnegative(),
2587
2619
  failed: z3.number().int().nonnegative(),
2588
2620
  // 与 core TestReportSchema 对齐:skipped 必填(缺省语义由调用方显式补 0,禁 optional 漂移)
@@ -2663,18 +2695,19 @@ function mcpContent(result) {
2663
2695
  const text = payload === void 0 ? "null" : JSON.stringify(payload);
2664
2696
  return result.success ? { content: [{ type: "text", text }] } : { content: [{ type: "text", text }], isError: true };
2665
2697
  }
2666
- function requireError(action, fields, args) {
2698
+ function requireError(action, fields, args, structureHint) {
2667
2699
  const missingFields = fields.filter((f) => args[f] === void 0);
2668
2700
  const stripped = missingFields.filter((f) => strippedFieldsOf(args).includes(f));
2669
2701
  const rest = missingFields.filter((f) => !stripped.includes(f));
2670
2702
  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
2703
  const passHint = rest.length > 0 ? `pass ${rest.map((f) => `${f}=<value>`).join(" ")} for action=${action}` : "";
2704
+ const structurePart = structureHint !== void 0 && structureHint !== "" ? `\u53C2\u6570\u7ED3\u6784\uFF1A${structureHint}` : "";
2672
2705
  return mcpContent({
2673
2706
  success: false,
2674
2707
  error: {
2675
2708
  message: `action=${action} requires ${missingFields.join(", ")}`,
2676
2709
  httpStatus: 0,
2677
- hint: [strippedHint, passHint].filter((s) => s !== "").join("\uFF1B")
2710
+ hint: [strippedHint, passHint, structurePart].filter((s) => s !== "").join("\uFF1B")
2678
2711
  }
2679
2712
  });
2680
2713
  }
@@ -2811,7 +2844,7 @@ function createMcpServer() {
2811
2844
  const client = createClient(void 0, "mcp");
2812
2845
  server.tool(
2813
2846
  "siming_task",
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',
2847
+ '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\u9010\u9879\u6309\u6307\u5F15\u4FEE\u590D\u540E\u91CD\u63A8\uFF1B\u8C41\u514D\u4EC5\u5BF9\u4FEE\u590D\u6307\u5F15\u4E2D\u660E\u793A\u7684\u8C41\u514D\u8DEF\u5F84\u6709\u6548\uFF08\u6309\u6307\u5F15\u7559\u75D5\uFF09\uFF0C\u65E0\u8C41\u514D\u8DEF\u5F84\u7684\u68C0\u67E5\u9879\u53EA\u80FD\u4FEE\u590D\uFF08\u5982\u6D4B\u8BD5\u5931\u8D25\uFF09\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\u2014testReport \u5F62\u5982 {"command":"pnpm vitest run","passed":106,"failed":0,"skipped":0}\uFF08\u56DB\u952E\u5FC5\u586B\u3001\u8BA1\u6570\u4E3A\u975E\u8D1F\u6574\u6570\u3001command 1-200 \u5B57\u7B26\uFF09\uFF1B\u5176\u4F59\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\u2014\u2014\u53C2\u6570\u5E73\u94FA\u4E0D\u5D4C\u5957\uFF1A{taskId,node,item,passed?,refId?,source?}\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\uFF08\u767B\u8BB0\u503C\u5373\u8BE5\u8DEF\u5F84\uFF09/ 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\u2014\u2014\u4E94\u53C2\u5747\u5FC5\u586B\u3001\u65E0\u7F3A\u7701\uFF1Arounds>=1\u3001critical>=0)\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',
2815
2848
  taskArgs,
2816
2849
  async (rawArgs) => {
2817
2850
  const masked = applyFieldMask(rawArgs, TASK_FIELD_SPECS);
@@ -2972,7 +3005,7 @@ function createMcpServer() {
2972
3005
  const stripped = strippedFieldsOf(args);
2973
3006
  return localError(
2974
3007
  "record-set \u9700\u8981\u81F3\u5C11\u4E00\u4E2A\u5B57\u6BB5\uFF08summary \u6216\u7ED3\u6784\u5316\u5B57\u6BB5\uFF09",
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"
3008
+ 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\uFF1BtestReport \u7ED3\u6784 {"command":"pnpm vitest run","passed":106,"failed":0,"skipped":0}\uFF08\u56DB\u952E\u5FC5\u586B\u3001\u8BA1\u6570\u4E3A\u975E\u8D1F\u6574\u6570\u3001command 1-200 \u5B57\u7B26\uFF09` : '\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\uFF1BtestReport \u7ED3\u6784 {"command":"pnpm vitest run","passed":106,"failed":0,"skipped":0}\uFF08\u56DB\u952E\u5FC5\u586B\u3001\u8BA1\u6570\u4E3A\u975E\u8D1F\u6574\u6570\u3001command 1-200 \u5B57\u7B26\uFF09'
2976
3009
  );
2977
3010
  }
2978
3011
  return mcpContent(await handleRecordSummarySet(client, taskId, node, fields));
@@ -2993,7 +3026,12 @@ function createMcpServer() {
2993
3026
  }
2994
3027
  const { item } = args;
2995
3028
  if (taskId === void 0 || node === void 0 || item === void 0) {
2996
- return requireError("record-check-add", ["taskId", "node", "item"], args);
3029
+ return requireError(
3030
+ "record-check-add",
3031
+ ["taskId", "node", "item"],
3032
+ args,
3033
+ "{taskId, node, item, passed?, refId?, source?} \u5E73\u94FA\u5355\u6761\uFF08passed \u7F3A\u7701 true\uFF1BrefId=\u5BF9\u5E94 aiCheck.id \u7684\u81EA\u68C0\u951A\uFF09\u6216\u6279\u91CF {taskId, node, checkItems:[{item, passed?, refId?, source?}]}\uFF08\u4E0A\u9650 50\uFF09"
3034
+ );
2997
3035
  }
2998
3036
  return mcpContent(
2999
3037
  await handleRecordCheckAdd(client, taskId, node, item, args.passed ?? true, {
@@ -3045,7 +3083,12 @@ function createMcpServer() {
3045
3083
  }
3046
3084
  const { taskId: singleTaskId, node: singleNode, artifactType } = args;
3047
3085
  if (singleTaskId === void 0 || singleNode === void 0 || artifactType === void 0) {
3048
- return requireError("record-artifact-add", ["taskId", "node", "artifactType"], args);
3086
+ return requireError(
3087
+ "record-artifact-add",
3088
+ ["taskId", "node", "artifactType"],
3089
+ args,
3090
+ "{taskId, node, artifactType, note?} + \u8F7D\u8377\u4E09\u9009\u4E00\uFF1Apath=\u7EAF\u5F15\u7528\u4E0D\u8BFB\u6587\u4EF6 / file=\u8BFB\u672C\u673A\u6587\u4EF6\uFF08\u767B\u8BB0\u503C\u5373\u8BE5\u8DEF\u5F84\uFF09/ content=\u76F4\u4F20\u5168\u6587\uFF1B\u6279\u91CF\u5F62\u6001 {taskId, node, artifactEntries:[\u2026]}"
3091
+ );
3049
3092
  }
3050
3093
  const { path, file, content, note } = args;
3051
3094
  if (!path && !file && !content) {
@@ -3059,7 +3102,10 @@ function createMcpServer() {
3059
3102
  return localError("file \u4E0E content \u4E92\u65A5\uFF0C\u4E8C\u9009\u4E00", "file \u8BFB\u672C\u673A\u6587\u4EF6\uFF1Bcontent \u76F4\u63A5\u643A\u5E26\u5168\u6587");
3060
3103
  }
3061
3104
  if (file && path) {
3062
- return localError("file \u4E0E path \u4E92\u65A5", "file \u6A21\u5F0F\u767B\u8BB0\u503C\u5C31\u662F\u8BE5\u6587\u4EF6\u8DEF\u5F84");
3105
+ return localError(
3106
+ "file \u4E0E path \u4E92\u65A5\uFF0C\u4E8C\u9009\u4E00",
3107
+ "file=\u8BFB\u53D6\u8BE5\u672C\u673A\u6587\u4EF6\u5185\u5BB9\u4F5C\u5168\u6587\u5FEB\u7167\uFF08\u767B\u8BB0\u503C\u5373\u8BE5\u8DEF\u5F84\uFF09\uFF1Bpath=\u7EAF\u5F15\u7528\u4E0D\u8BFB\u6587\u4EF6\uFF1B\u9700\u8981\u5168\u6587\u5FEB\u7167\u7528 file\uFF0C\u53EA\u7559\u8DEF\u5F84\u7D22\u5F15\u7528 path"
3108
+ );
3063
3109
  }
3064
3110
  let registeredPath = path;
3065
3111
  let fullText = content;
@@ -3117,7 +3163,12 @@ function createMcpServer() {
3117
3163
  case "record-review-set": {
3118
3164
  const { taskId, node, verdict, rounds, critical } = args;
3119
3165
  if (taskId === void 0 || node === void 0 || verdict === void 0 || rounds === void 0 || critical === void 0) {
3120
- return requireError("record-review-set", ["taskId", "node", "verdict", "rounds", "critical"], args);
3166
+ return requireError(
3167
+ "record-review-set",
3168
+ ["taskId", "node", "verdict", "rounds", "critical"],
3169
+ args,
3170
+ '{taskId, node, verdict:"pass"|"fail", rounds>=1, critical>=0}\uFF08\u4E94\u53C2\u5747\u5FC5\u586B\uFF0C\u65E0\u7F3A\u7701\uFF1Bverdict \u7559\u7A7A\u4F1A\u88AB\u5224\u5B9A\u4E3A\u672A\u901A\u8FC7\uFF09'
3171
+ );
3121
3172
  }
3122
3173
  if (rounds < 1 || critical < 0) {
3123
3174
  return localError(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@siming-org/cli",
3
- "version": "0.8.11",
3
+ "version": "0.8.13",
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/server": "0.8.11",
31
- "@siming-org/core": "0.8.11"
30
+ "@siming-org/core": "0.8.13",
31
+ "@siming-org/server": "0.8.13"
32
32
  },
33
33
  "devDependencies": {
34
34
  "tsup": "^8.3.5",