@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.
- package/dist/index.js +76 -10
- 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
|
|
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:
|
|
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\
|
|
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
|
|
3767
|
-
|
|
3768
|
-
|
|
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.
|
|
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.
|
|
31
|
-
"@siming-org/server": "0.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",
|