@siming-org/cli 0.7.3 → 0.7.4
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 +408 -235
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -1307,17 +1307,24 @@ async function handleUpdateProject(client, id, patch) {
|
|
|
1307
1307
|
return client.putJson(`/api/projects/${encodeURIComponent(id)}`, patch);
|
|
1308
1308
|
}
|
|
1309
1309
|
var OBJECT_ID_HEX = /^[a-f0-9]{24}$/;
|
|
1310
|
-
|
|
1310
|
+
function formatCandidateHint(projects, input) {
|
|
1311
|
+
const q = input.toLowerCase();
|
|
1312
|
+
const hits = projects.filter((p) => p.key.toLowerCase().includes(q) || p.name.toLowerCase().includes(q)).slice(0, 5).map((p) => `${p.key} (${p.name})`);
|
|
1313
|
+
if (hits.length === 0) return void 0;
|
|
1314
|
+
return `\u76F8\u8FD1\u9879\u76EE\uFF1A${hits.join("\u3001")}\uFF1B\u68C0\u67E5\u62FC\u5199\uFF0C\u6216 siming project list \u67E5\u770B\u5168\u90E8\u9879\u76EE`;
|
|
1315
|
+
}
|
|
1316
|
+
async function resolveProjectId(client, input, opts) {
|
|
1311
1317
|
if (OBJECT_ID_HEX.test(input)) return { success: true, data: input };
|
|
1312
1318
|
const list = await handleListProjects(client);
|
|
1313
1319
|
if (!list.success) return list;
|
|
1314
1320
|
const hit = list.data.find((p) => p.key === input);
|
|
1315
1321
|
if (!hit) {
|
|
1322
|
+
const candidateHint = opts?.withCandidates === true ? formatCandidateHint(list.data, input) : void 0;
|
|
1316
1323
|
const error = {
|
|
1317
1324
|
message: `project "${input}" not found`,
|
|
1318
1325
|
httpStatus: 404,
|
|
1319
1326
|
bizCode: "PROJECT_NOT_FOUND",
|
|
1320
|
-
hint: `check \`siming project list\` for available keys; pass --project <key|id>`
|
|
1327
|
+
hint: candidateHint ?? `check \`siming project list\` for available keys; pass --project <key|id>`
|
|
1321
1328
|
};
|
|
1322
1329
|
return fail(error);
|
|
1323
1330
|
}
|
|
@@ -1331,6 +1338,74 @@ async function resolveProjectId(client, input) {
|
|
|
1331
1338
|
}
|
|
1332
1339
|
return { success: true, data: hit.id };
|
|
1333
1340
|
}
|
|
1341
|
+
async function findProjectDetailByKey(client, key) {
|
|
1342
|
+
const list = await handleListProjects(client);
|
|
1343
|
+
if (!list.success) return list;
|
|
1344
|
+
const hit = list.data.find((p) => p.key === key);
|
|
1345
|
+
if (hit === void 0) {
|
|
1346
|
+
return fail({
|
|
1347
|
+
message: `workspace defaultProject "${key}" not found (removed or renamed)`,
|
|
1348
|
+
httpStatus: 0,
|
|
1349
|
+
bizCode: "DEFAULT_PROJECT_INVALID",
|
|
1350
|
+
hint: DEFAULT_PROJECT_HINT
|
|
1351
|
+
});
|
|
1352
|
+
}
|
|
1353
|
+
if (hit.id === void 0) {
|
|
1354
|
+
return fail({
|
|
1355
|
+
message: `workspace defaultProject "${key}" has no id`,
|
|
1356
|
+
httpStatus: 500,
|
|
1357
|
+
hint: "server returned a project without id; check `siming project list`"
|
|
1358
|
+
});
|
|
1359
|
+
}
|
|
1360
|
+
return ok2({ id: hit.id, status: hit.status });
|
|
1361
|
+
}
|
|
1362
|
+
var MCP_PROJECT_HINT = "MCP \u8C03\u7528\u8BF7\u4F20 projectId \u5B57\u6BB5\uFF08\u9879\u76EE key \u6216 24-hex id \u53CC\u5F62\u6001\uFF0C\u81EA\u52A8\u5F52\u4E00\uFF09\uFF1B\u53EF\u7528 `siming project list` \u67E5\u8BE2\u53EF\u7528\u9879\u76EE";
|
|
1363
|
+
var DEFAULT_PROJECT_HINT = "siming config unset defaultProject \u540E\u91CD\u8BD5\uFF0C\u6216 siming config set defaultProject <key|id> \u91CD\u8BBE\uFF1Bsiming project list \u67E5\u770B\u53EF\u7528\u9879\u76EE";
|
|
1364
|
+
var PROJECT_REQUIRED_HINT = "\u663E\u5F0F\u4F20 --project <key|id>\uFF0C\u6216 siming config set defaultProject <key|id> \u914D\u7F6E\u9ED8\u8BA4\u9879\u76EE\uFF1Bsiming project list \u67E5\u770B\u53EF\u7528\u9879\u76EE";
|
|
1365
|
+
async function resolveScopedProject(client, explicit, tail, opts) {
|
|
1366
|
+
const value = explicit !== void 0 && explicit.trim().length > 0 ? explicit.trim() : void 0;
|
|
1367
|
+
if (value !== void 0) {
|
|
1368
|
+
const r = await resolveProjectId(client, value, { withCandidates: true });
|
|
1369
|
+
if (!r.success) {
|
|
1370
|
+
return fail(
|
|
1371
|
+
opts?.channel === "mcp" && r.error.bizCode === "PROJECT_NOT_FOUND" ? { ...r.error, hint: MCP_PROJECT_HINT } : r.error
|
|
1372
|
+
);
|
|
1373
|
+
}
|
|
1374
|
+
return ok2({ projectId: r.data, source: "explicit" });
|
|
1375
|
+
}
|
|
1376
|
+
if (tail === "explicit-only") {
|
|
1377
|
+
return ok2({ source: "explicit" });
|
|
1378
|
+
}
|
|
1379
|
+
const wsDefault = readWorkspaceConfig()?.defaultProject;
|
|
1380
|
+
if (wsDefault !== void 0) {
|
|
1381
|
+
const detail = await findProjectDetailByKey(client, wsDefault);
|
|
1382
|
+
if (!detail.success) return detail;
|
|
1383
|
+
if (detail.data.status !== "active") {
|
|
1384
|
+
return fail({
|
|
1385
|
+
message: `workspace defaultProject "${wsDefault}" is archived`,
|
|
1386
|
+
httpStatus: 0,
|
|
1387
|
+
bizCode: "DEFAULT_PROJECT_INVALID",
|
|
1388
|
+
hint: DEFAULT_PROJECT_HINT
|
|
1389
|
+
});
|
|
1390
|
+
}
|
|
1391
|
+
return ok2({ projectId: detail.data.id, source: "workspace-default" });
|
|
1392
|
+
}
|
|
1393
|
+
if (tail === "ws-default") {
|
|
1394
|
+
return ok2({ source: "delegated" });
|
|
1395
|
+
}
|
|
1396
|
+
const list = await handleListProjects(client);
|
|
1397
|
+
if (!list.success) return list;
|
|
1398
|
+
const instanceDefault = list.data.find((p) => p.key === "default");
|
|
1399
|
+
if (instanceDefault === void 0 || instanceDefault.id === void 0) {
|
|
1400
|
+
return fail({
|
|
1401
|
+
message: `${opts?.commandLabel ?? "this command"} needs a project: no --project given, no workspace defaultProject, and no key=default project on server`,
|
|
1402
|
+
httpStatus: 0,
|
|
1403
|
+
bizCode: "PROJECT_REQUIRED",
|
|
1404
|
+
hint: PROJECT_REQUIRED_HINT
|
|
1405
|
+
});
|
|
1406
|
+
}
|
|
1407
|
+
return ok2({ projectId: instanceDefault.id, source: "instance-default" });
|
|
1408
|
+
}
|
|
1334
1409
|
async function resolveProjectKey(client, input) {
|
|
1335
1410
|
const list = await handleListProjects(client);
|
|
1336
1411
|
if (!list.success) return list;
|
|
@@ -1463,7 +1538,7 @@ var issueArgs = {
|
|
|
1463
1538
|
// create
|
|
1464
1539
|
title: z3.string().optional(),
|
|
1465
1540
|
description: z3.string().optional(),
|
|
1466
|
-
// 公共:create 缺省按工作区 defaultProject
|
|
1541
|
+
// 公共:create 缺省按工作区 defaultProject(key|id 双形态通道层归一,失效报错)/ query 过滤(空/未传不过滤)
|
|
1467
1542
|
projectId: z3.string().optional(),
|
|
1468
1543
|
// query:view 缺省 open(有效未跟进完);与 REST 词汇统一(status/taskId 指定时切对应过滤)
|
|
1469
1544
|
view: hostNeutralEnum(z3.enum(["open", "all"])).optional(),
|
|
@@ -1608,7 +1683,7 @@ function createMcpServer() {
|
|
|
1608
1683
|
const client = createClient(void 0, "mcp");
|
|
1609
1684
|
server.tool(
|
|
1610
1685
|
"siming_task",
|
|
1611
|
-
"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\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\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\u54CD\u5E94\u5DF2\u542B\u4E0B\u4E00\u8282\u70B9\u8D44\u6599\u5305\uFF0C\u540C\u4F1A\u8BDD\u514D\u91CD\u8BFB context)\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,summary)\uFF1Brecord-check-add(taskId,node,item\uFF1B\u53EF\u9009 passed \u7F3A\u7701 true\uFF1B\u56DE\u6267 entry.id \u4F9B record-check-patch \u5B9A\u4F4D)\uFF1Brecord-check-patch(taskId,node,checkId\uFF1B\u53EF\u9009 passed)\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",
|
|
1686
|
+
"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\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\u54CD\u5E94\u5DF2\u542B\u4E0B\u4E00\u8282\u70B9\u8D44\u6599\u5305\uFF0C\u540C\u4F1A\u8BDD\u514D\u91CD\u8BFB context)\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,summary)\uFF1Brecord-check-add(taskId,node,item\uFF1B\u53EF\u9009 passed \u7F3A\u7701 true\uFF1B\u56DE\u6267 entry.id \u4F9B record-check-patch \u5B9A\u4F4D)\uFF1Brecord-check-patch(taskId,node,checkId\uFF1B\u53EF\u9009 passed)\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",
|
|
1612
1687
|
taskArgs,
|
|
1613
1688
|
async (rawArgs) => {
|
|
1614
1689
|
const masked = applyFieldMask(rawArgs, TASK_FIELD_SPECS);
|
|
@@ -1620,13 +1695,15 @@ function createMcpServer() {
|
|
|
1620
1695
|
if (templateId === void 0 || taskTitle === void 0 || track === void 0) {
|
|
1621
1696
|
return requireError("create", ["templateId", "taskTitle", "track"], args);
|
|
1622
1697
|
}
|
|
1698
|
+
const projectR = await resolveScopedProject(client, args.projectId, "ws-default", { channel: "mcp" });
|
|
1699
|
+
if (!projectR.success) return mcpContent(projectR);
|
|
1623
1700
|
const input = {
|
|
1624
1701
|
title: taskTitle,
|
|
1625
1702
|
track,
|
|
1626
1703
|
dagTemplateId: templateId,
|
|
1627
1704
|
...args.type !== void 0 ? { type: args.type } : {},
|
|
1628
1705
|
...args.skipNodes !== void 0 ? { skipNodes: args.skipNodes } : {},
|
|
1629
|
-
...
|
|
1706
|
+
...projectR.data.projectId !== void 0 ? { projectId: projectR.data.projectId } : {}
|
|
1630
1707
|
};
|
|
1631
1708
|
return mcpContent(await handleCreateTask(client, input));
|
|
1632
1709
|
}
|
|
@@ -1640,11 +1717,17 @@ function createMcpServer() {
|
|
|
1640
1717
|
if (args.taskId) {
|
|
1641
1718
|
return mcpContent(await handleQueryState(client, args.taskId));
|
|
1642
1719
|
}
|
|
1720
|
+
let queryProjectId;
|
|
1721
|
+
if (args.projectId !== void 0 && args.projectId.trim().length > 0) {
|
|
1722
|
+
const pr = await resolveScopedProject(client, args.projectId, "explicit-only", { channel: "mcp" });
|
|
1723
|
+
if (!pr.success) return mcpContent(pr);
|
|
1724
|
+
queryProjectId = pr.data.projectId;
|
|
1725
|
+
}
|
|
1643
1726
|
return mcpContent(
|
|
1644
1727
|
await handleListTasks(client, {
|
|
1645
1728
|
...args.status !== void 0 ? { status: args.status } : {},
|
|
1646
1729
|
...args.track !== void 0 ? { track: args.track } : {},
|
|
1647
|
-
...
|
|
1730
|
+
...queryProjectId !== void 0 ? { projectId: queryProjectId } : {},
|
|
1648
1731
|
...args.page !== void 0 ? { page: args.page } : {},
|
|
1649
1732
|
...args.limit !== void 0 ? { limit: args.limit } : {}
|
|
1650
1733
|
})
|
|
@@ -1942,26 +2025,38 @@ function createMcpServer() {
|
|
|
1942
2025
|
);
|
|
1943
2026
|
server.tool(
|
|
1944
2027
|
"siming_template",
|
|
1945
|
-
"DAG \u6A21\u677F\u53EA\u8BFB\u67E5\u8BE2\uFF08\u4EFB\u52A1\u521B\u5EFA\u524D\u9009\u6A21\u677F/\u6838\u5BF9\u6A21\u677F\u7ED3\u6784\u7528\uFF1B\u672C\u5DE5\u5177\u65E0\u5199\u64CD\u4F5C\uFF09\u3002action\uFF1Alist=\u6A21\u677F\u5217\u8868\uFF08\u6982\u8981\u6295\u5F71\uFF0C\u542B id/code/name/version/isDefault/projectId/nodeCount/nodes \u6982\u8981/pausePoints/description\uFF0C\u4E0D\u542B\u8282\u70B9 prompt \u5168\u6587\uFF1B\u53EF\u9009 projectId \u8FC7\u6EE4\u9879\u76EE\u57DF\uFF1B\u8FD4\u56DE code \u4E3A\u540E\u7EED\u5F15\u7528\u6A21\u677F\u7684\u63A8\u8350\u5F62\u6001\uFF09\uFF1Bshow=\u6A21\u677F\u8BE6\u60C5\uFF08\u542B\u5168\u90E8\u8282\u70B9 prompt\uFF1BtemplateId \u652F\u6301 code|id \u53CC\u5F62\u6001\u2014\u2014code \u4E3A\u4E1A\u52A1\u6807\u8BC6\uFF08\u9879\u76EE\u5185\u552F\u4E00\u3001\u521B\u5EFA\u540E\u4E0D\u53EF\u53D8\u3001kebab-case \u5FC5\u542B\u8FDE\u5B57\u7B26\u4E14\u975E\u7EAF 24-hex \u5F62\u6001\uFF0C\u5982 full-workflow\uFF09\uFF0Ccode \u5F62\u6001\u5BFB\u5740\u987B\u914D projectId \u6307\u5B9A\u9879\u76EE\u57DF\uFF1B24 \u4F4D\u6570\u636E\u5E93 id \u76F4\u67E5\u517C\u5BB9\uFF0C\u65E0\u9700 projectId\uFF09\u3002\u6A21\u677F\u4E0D\u5B58\u5728\u65F6\u9519\u8BEF\u4FE1\u606F\u542B candidates \u5019\u9009\u6E05\u5355\uFF08\u9879\u76EE\u5185\u76F8\u8FD1\u6A21\u677F\u7684 id/code/name\uFF0C\u6309\u76F8\u5173\u5EA6\u6392\u5E8F\u4E0A\u9650 5 \u6761\uFF09\u2014\u2014\u8F6C\u5F55\u9519\u8BEF\u53EF\u636E\u6E05\u5355\u5F53\u573A\u7EA0\u6B63\u3002\u505C\u7528\u6A21\u677F\uFF08Web \u7BA1\u7406\u53F0\u542F\u505C\uFF09\uFF1Alist \u9ED8\u8BA4\u4E0D\u542B\u505C\u7528\u6A21\u677F\uFF1Bshow \u6309 code|id \u4ECD\u53EF\u8BFB\uFF1B\u7528\u505C\u7528\u6A21\u677F\u521B\u5EFA\u4EFB\u52A1\u88AB\u62D2\uFF08409 TEMPLATE_DISABLED\uFF09\u2014\u2014\u9700\u5728 Web \u7BA1\u7406\u53F0\u91CD\u65B0\u542F\u7528\u540E\u518D\u5EFA\u4EFB\u52A1\u3002\u6A21\u677F\u5199\u5165\u4E0E\u6F14\u8FDB\u4E0D\u5728 MCP\uFF1A\u5BFC\u5165\uFF08\u542B\u540C\u540D\u66F4\u65B0/\u9884\u89C8/\u5B8C\u6574\u4F9D\u8D56\u95ED\u5305 bundle\uFF09\u7528 CLI `siming dag template import`\uFF0C\u6A21\u677F\u5347\u7EA7\u9884\u68C0/\u6267\u884C\u7528 CLI `siming dag template upgrade plan/apply`\uFF08bash \u6267\u884C\uFF0C--help \u67E5\u7528\u6CD5\uFF09\u3002",
|
|
2028
|
+
"DAG \u6A21\u677F\u53EA\u8BFB\u67E5\u8BE2\uFF08\u4EFB\u52A1\u521B\u5EFA\u524D\u9009\u6A21\u677F/\u6838\u5BF9\u6A21\u677F\u7ED3\u6784\u7528\uFF1B\u672C\u5DE5\u5177\u65E0\u5199\u64CD\u4F5C\uFF09\u3002action\uFF1Alist=\u6A21\u677F\u5217\u8868\uFF08\u6982\u8981\u6295\u5F71\uFF0C\u542B id/code/name/version/isDefault/projectId/nodeCount/nodes \u6982\u8981/pausePoints/description\uFF0C\u4E0D\u542B\u8282\u70B9 prompt \u5168\u6587\uFF1B\u53EF\u9009 projectId \u8FC7\u6EE4\u9879\u76EE\u57DF\u2014\u2014key|id \u53CC\u5F62\u6001\uFF0C\u901A\u9053\u5C42\u81EA\u52A8\u5F52\u4E00\uFF0C\u7A7A/\u672A\u4F20\u4E0D\u8FC7\u6EE4\uFF1B\u8FD4\u56DE code \u4E3A\u540E\u7EED\u5F15\u7528\u6A21\u677F\u7684\u63A8\u8350\u5F62\u6001\uFF09\uFF1Bshow=\u6A21\u677F\u8BE6\u60C5\uFF08\u542B\u5168\u90E8\u8282\u70B9 prompt\uFF1BtemplateId \u652F\u6301 code|id \u53CC\u5F62\u6001\u2014\u2014code \u4E3A\u4E1A\u52A1\u6807\u8BC6\uFF08\u9879\u76EE\u5185\u552F\u4E00\u3001\u521B\u5EFA\u540E\u4E0D\u53EF\u53D8\u3001kebab-case \u5FC5\u542B\u8FDE\u5B57\u7B26\u4E14\u975E\u7EAF 24-hex \u5F62\u6001\uFF0C\u5982 full-workflow\uFF09\uFF0Ccode \u5F62\u6001\u5BFB\u5740\u987B\u914D projectId \u6307\u5B9A\u9879\u76EE\u57DF\u2014\u2014key|id \u53CC\u5F62\u6001\u81EA\u52A8\u5F52\u4E00\uFF0C\u7F3A\u7701\u6309\u5DE5\u4F5C\u533A defaultProject\uFF08\u5931\u6548\u62A5\u9519\uFF09\uFF0C\u65E0\u914D\u7F6E\u4E0D\u4F20\u7531 server \u63D0\u793A\u8865\u57DF\uFF1B24 \u4F4D\u6570\u636E\u5E93 id \u76F4\u67E5\u517C\u5BB9\uFF0C\u65E0\u9700 projectId\uFF09\u3002\u6A21\u677F\u4E0D\u5B58\u5728\u65F6\u9519\u8BEF\u4FE1\u606F\u542B candidates \u5019\u9009\u6E05\u5355\uFF08\u9879\u76EE\u5185\u76F8\u8FD1\u6A21\u677F\u7684 id/code/name\uFF0C\u6309\u76F8\u5173\u5EA6\u6392\u5E8F\u4E0A\u9650 5 \u6761\uFF09\u2014\u2014\u8F6C\u5F55\u9519\u8BEF\u53EF\u636E\u6E05\u5355\u5F53\u573A\u7EA0\u6B63\u3002\u505C\u7528\u6A21\u677F\uFF08Web \u7BA1\u7406\u53F0\u542F\u505C\uFF09\uFF1Alist \u9ED8\u8BA4\u4E0D\u542B\u505C\u7528\u6A21\u677F\uFF1Bshow \u6309 code|id \u4ECD\u53EF\u8BFB\uFF1B\u7528\u505C\u7528\u6A21\u677F\u521B\u5EFA\u4EFB\u52A1\u88AB\u62D2\uFF08409 TEMPLATE_DISABLED\uFF09\u2014\u2014\u9700\u5728 Web \u7BA1\u7406\u53F0\u91CD\u65B0\u542F\u7528\u540E\u518D\u5EFA\u4EFB\u52A1\u3002\u6A21\u677F\u5199\u5165\u4E0E\u6F14\u8FDB\u4E0D\u5728 MCP\uFF1A\u5BFC\u5165\uFF08\u542B\u540C\u540D\u66F4\u65B0/\u9884\u89C8/\u5B8C\u6574\u4F9D\u8D56\u95ED\u5305 bundle\uFF09\u7528 CLI `siming dag template import`\uFF0C\u6A21\u677F\u5347\u7EA7\u9884\u68C0/\u6267\u884C\u7528 CLI `siming dag template upgrade plan/apply`\uFF08bash \u6267\u884C\uFF0C--help \u67E5\u7528\u6CD5\uFF09\u3002",
|
|
1946
2029
|
templateArgs,
|
|
1947
2030
|
async (args) => {
|
|
1948
2031
|
switch (args.action) {
|
|
1949
2032
|
case "list": {
|
|
1950
|
-
|
|
2033
|
+
let listProjectId;
|
|
2034
|
+
if (args.projectId !== void 0 && args.projectId.trim().length > 0) {
|
|
2035
|
+
const pr = await resolveScopedProject(client, args.projectId, "explicit-only", { channel: "mcp" });
|
|
2036
|
+
if (!pr.success) return mcpContent(pr);
|
|
2037
|
+
listProjectId = pr.data.projectId;
|
|
2038
|
+
}
|
|
2039
|
+
const result = await handleListTemplates(client, listProjectId);
|
|
1951
2040
|
if (!result.success) return mcpContent(result);
|
|
1952
2041
|
return mcpContent(ok2(result.data.map(toTemplateSummary)));
|
|
1953
2042
|
}
|
|
1954
2043
|
case "show": {
|
|
1955
|
-
const { templateId
|
|
2044
|
+
const { templateId } = args;
|
|
1956
2045
|
if (templateId === void 0) return requireError("show", ["templateId"], args);
|
|
1957
|
-
|
|
2046
|
+
let showProjectId;
|
|
2047
|
+
if (!/^[a-f0-9]{24}$/.test(templateId)) {
|
|
2048
|
+
const pr = await resolveScopedProject(client, args.projectId, "ws-default", { channel: "mcp" });
|
|
2049
|
+
if (!pr.success) return mcpContent(pr);
|
|
2050
|
+
showProjectId = pr.data.projectId;
|
|
2051
|
+
}
|
|
2052
|
+
return mcpContent(await handleGetTemplate(client, templateId, showProjectId));
|
|
1958
2053
|
}
|
|
1959
2054
|
}
|
|
1960
2055
|
}
|
|
1961
2056
|
);
|
|
1962
2057
|
server.tool(
|
|
1963
2058
|
"siming_issue",
|
|
1964
|
-
`\u95EE\u9898\u6C60\u5DE5\u5177\uFF08T202609150002\uFF09\uFF1A\u5C0F\u95EE\u9898\u4F4E\u6210\u672C\u5165\u6C60\uFF0C\u6C89\u6DC0\u540E\u7EDF\u4E00\u6574\u7406\u8F6C\u4EFB\u52A1\uFF08\u8F6C\u4EFB\u52A1/\u6574\u7406\u91CD\u4EA4\u4E92\u8D70 CLI siming issue convert \u6216 Web\uFF0C\u4E0D\u5728\u672C\u5DE5\u5177\u9762\uFF09\u3002action\uFF1Acreate(title \u5FC5\u586B 1-200 \u5B57\uFF1B\u53EF\u9009 description\u3001projectId\u2014\u2014key|id \u53CC\u5F62\u6001\uFF0C\u901A\u9053\u5C42\u81EA\u52A8\u5F52\u4E00\u4E3A 24-hex id\uFF08hex \u96F6\u7F51\u7EDC\u5F00\u9500\u76F4\u901A\uFF09\uFF1B\u663E\u5F0F\u6307\u5B9A\u89E3\u6790\u5931\u8D25\u62A5\u9519\u4E0D\u515C\u5E95\uFF1B\u7F3A\u7701\u94FE\uFF1A\u672A\u4F20\u6216\u7A7A\u4E32\u65F6\u6309\u5DE5\u4F5C\u533A defaultProject \u89E3\u6790\uFF0C\u65E0\u914D\u7F6E\
|
|
2059
|
+
`\u95EE\u9898\u6C60\u5DE5\u5177\uFF08T202609150002\uFF09\uFF1A\u5C0F\u95EE\u9898\u4F4E\u6210\u672C\u5165\u6C60\uFF0C\u6C89\u6DC0\u540E\u7EDF\u4E00\u6574\u7406\u8F6C\u4EFB\u52A1\uFF08\u8F6C\u4EFB\u52A1/\u6574\u7406\u91CD\u4EA4\u4E92\u8D70 CLI siming issue convert \u6216 Web\uFF0C\u4E0D\u5728\u672C\u5DE5\u5177\u9762\uFF09\u3002action\uFF1Acreate(title \u5FC5\u586B 1-200 \u5B57\uFF1B\u53EF\u9009 description\u3001projectId\u2014\u2014key|id \u53CC\u5F62\u6001\uFF0C\u901A\u9053\u5C42\u81EA\u52A8\u5F52\u4E00\u4E3A 24-hex id\uFF08hex \u96F6\u7F51\u7EDC\u5F00\u9500\u76F4\u901A\uFF09\uFF1B\u663E\u5F0F\u6307\u5B9A\u89E3\u6790\u5931\u8D25\u62A5\u9519\u4E0D\u515C\u5E95\uFF1B\u7F3A\u7701\u94FE\uFF1A\u672A\u4F20\u6216\u7A7A\u4E32\u65F6\u6309\u5DE5\u4F5C\u533A defaultProject \u89E3\u6790\uFF08\u5931\u6548\u62A5\u9519\uFF09\uFF0C\u65E0\u914D\u7F6E\u65F6\u4E0D\u4F20 projectId \u7531 server \u6309 key=default \u515C\u5E95\uFF1B\u5F55\u5165\u540E source=mcp)\uFF1Bquery(\u53EF\u9009 view=open|all\u2014\u2014\u7F3A\u7701 open=\u6709\u6548\u672A\u8DDF\u8FDB\u5B8C\uFF0Call=\u5168\u91CF\uFF1Bstatus \u8FC7\u6EE4\u2014\u2014\u663E\u5F0F\u6307\u5B9A\u65F6\u4F18\u5148\u4E8E view\uFF0C\u53EF\u67E5\u5DF2\u53D6\u6D88/\u5DF2\u5B8C\u7ED3\uFF1BtaskId=\u4EFB\u52A1\u53CD\u67E5\uFF1BprojectId\u2014\u2014key|id \u53CC\u5F62\u6001\uFF0C\u901A\u9053\u5C42\u81EA\u52A8\u5F52\u4E00\uFF0C\u7A7A/\u672A\u4F20\u4E0D\u8FC7\u6EE4\uFF08\u663E\u5F0F\u89E3\u6790\u5931\u8D25\u62A5\u9519\uFF09\uFF1Bpage\u22651/limit 1-500\uFF1B\u54CD\u5E94 items \u542B progress {done,cancelled,total})\u3002\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\uFF1B\u5404 action \u56FA\u5B9A\u5FC5\u586B\u5B57\u6BB5\u65E0\u9700\u5199\u5165 mask\u3002`,
|
|
1965
2060
|
issueArgs,
|
|
1966
2061
|
async (rawArgs) => {
|
|
1967
2062
|
const masked = applyFieldMask(rawArgs, ISSUE_FIELD_SPECS);
|
|
@@ -1973,27 +2068,9 @@ function createMcpServer() {
|
|
|
1973
2068
|
if (title === void 0) {
|
|
1974
2069
|
return requireError("create", ["title"], args);
|
|
1975
2070
|
}
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
const resolved = await resolveProjectId(client, explicitProject);
|
|
1980
|
-
if (!resolved.success) {
|
|
1981
|
-
return mcpContent({
|
|
1982
|
-
...resolved,
|
|
1983
|
-
error: {
|
|
1984
|
-
...resolved.error,
|
|
1985
|
-
hint: "MCP \u8C03\u7528\u8BF7\u4F20 projectId \u5B57\u6BB5\uFF08\u9879\u76EE key \u6216 24-hex id \u53CC\u5F62\u6001\uFF0C\u81EA\u52A8\u5F52\u4E00\uFF09\uFF1B\u53EF\u7528 `siming project list` \u67E5\u8BE2\u53EF\u7528\u9879\u76EE"
|
|
1986
|
-
}
|
|
1987
|
-
});
|
|
1988
|
-
}
|
|
1989
|
-
projectId = resolved.data;
|
|
1990
|
-
} else {
|
|
1991
|
-
const wsDefaultProject = readWorkspaceConfig()?.defaultProject;
|
|
1992
|
-
if (wsDefaultProject) {
|
|
1993
|
-
const resolved = await resolveProjectId(client, wsDefaultProject);
|
|
1994
|
-
if (resolved.success) projectId = resolved.data;
|
|
1995
|
-
}
|
|
1996
|
-
}
|
|
2071
|
+
const projectR = await resolveScopedProject(client, args.projectId, "ws-default", { channel: "mcp" });
|
|
2072
|
+
if (!projectR.success) return mcpContent(projectR);
|
|
2073
|
+
const projectId = projectR.data.projectId;
|
|
1997
2074
|
return mcpContent(
|
|
1998
2075
|
await handleCreateIssue(client, {
|
|
1999
2076
|
title,
|
|
@@ -2009,12 +2086,18 @@ function createMcpServer() {
|
|
|
2009
2086
|
if (args.limit !== void 0 && (args.limit < 1 || args.limit > 500)) {
|
|
2010
2087
|
return localError("action=query \u7684 limit \u5FC5\u987B\u4E3A 1-500 \u7684\u6574\u6570");
|
|
2011
2088
|
}
|
|
2089
|
+
let issueQueryProjectId;
|
|
2090
|
+
if (args.projectId !== void 0 && args.projectId.trim().length > 0) {
|
|
2091
|
+
const pr = await resolveScopedProject(client, args.projectId, "explicit-only", { channel: "mcp" });
|
|
2092
|
+
if (!pr.success) return mcpContent(pr);
|
|
2093
|
+
issueQueryProjectId = pr.data.projectId;
|
|
2094
|
+
}
|
|
2012
2095
|
return mcpContent(
|
|
2013
2096
|
await handleListIssues(client, {
|
|
2014
2097
|
view: args.view ?? "open",
|
|
2015
2098
|
...args.status !== void 0 ? { status: args.status } : {},
|
|
2016
2099
|
...args.taskId !== void 0 ? { taskId: args.taskId } : {},
|
|
2017
|
-
...
|
|
2100
|
+
...issueQueryProjectId !== void 0 ? { projectId: issueQueryProjectId } : {},
|
|
2018
2101
|
...args.page !== void 0 ? { page: args.page } : {},
|
|
2019
2102
|
...args.limit !== void 0 ? { limit: args.limit } : {}
|
|
2020
2103
|
})
|
|
@@ -2236,18 +2319,19 @@ var PAGE_DEFAULT = 20;
|
|
|
2236
2319
|
var PAGE_MAX = 500;
|
|
2237
2320
|
function createTaskCommand() {
|
|
2238
2321
|
const task = new Command2("task").description("Task management \u2014 create, advance, approve, pause, resume, cancel, reopen, query");
|
|
2239
|
-
withCommonOpts(task.command("list"), "table").option("--status <s>", "filter by status").option("--track <t>", "filter by track").option("--project <key
|
|
2322
|
+
withCommonOpts(task.command("list"), "table").option("--status <s>", "filter by status").option("--track <t>", "filter by track").option("--project <key|id>", "filter by projectId (key|id)").option("--page <n>", "page number (default 1)", "1").option("--limit <n>", `page size (default ${PAGE_DEFAULT}, max ${PAGE_MAX})`).option("--all", `show all (limit ${PAGE_MAX})`).option("--sort <s>", "sort: progress|createdAt|updatedAt (default progress)").description("List tasks (summary projection: no dagInstance/history payloads)").action(async (opts) => {
|
|
2240
2323
|
const client = createClient(opts.url);
|
|
2241
2324
|
const filters = {};
|
|
2242
2325
|
if (opts.status) filters.status = opts.status;
|
|
2243
2326
|
if (opts.track) filters.track = opts.track;
|
|
2244
|
-
if (opts.project) {
|
|
2245
|
-
const
|
|
2246
|
-
if (!
|
|
2247
|
-
renderResult(opts.format,
|
|
2327
|
+
if (opts.project !== void 0 && opts.project.trim().length > 0) {
|
|
2328
|
+
const pr = await resolveScopedProject(client, opts.project, "explicit-only");
|
|
2329
|
+
if (!pr.success) {
|
|
2330
|
+
renderResult(opts.format, pr);
|
|
2248
2331
|
return;
|
|
2249
2332
|
}
|
|
2250
|
-
|
|
2333
|
+
const pid = pr.data.projectId;
|
|
2334
|
+
if (pid !== void 0) filters.projectId = pid;
|
|
2251
2335
|
}
|
|
2252
2336
|
if (opts.sort) {
|
|
2253
2337
|
const r = parseEnum(opts.sort, z5.enum(["progress", "createdAt", "updatedAt"]), "sort");
|
|
@@ -2303,7 +2387,7 @@ function createTaskCommand() {
|
|
|
2303
2387
|
const result = await handleQueryState(client, taskId);
|
|
2304
2388
|
renderResult(opts.format, result, { fields: result.success ? taskFields(result.data) : [] });
|
|
2305
2389
|
});
|
|
2306
|
-
task.command("create").description("Create a task from a DAG template").option("--url <url>", "server base URL").requiredOption("--title <t>", "task title").requiredOption("--template <code|name|id>", "DAG template code (preferred), name, or 24-hex id (code/name resolved within project)").requiredOption("--track <t>", "task track (e.g. backend|ui|mixed|research \u2014 research \u4E3A\u8C03\u7814\u7C7B\u578B\u4E13\u7528\uFF0C\u987B\u914D --type research)").option("--type <t>", "task type (feature|bugfix|ui-tweak|research) \u2014 \u7C7B\u578B\u2192\u8DEF\u5F84\u6620\u5C04\u7531 task-create skill \u6301\u6709").option("--skip <ids>", "node ids to prune at creation (comma-separated, repeatable) \u2014 \u53EA\u5141\u8BB8\u6765\u81EA task-create skill \u7684\u6620\u5C04\u77E9\u9635", collectArgs, []).option("--project <key
|
|
2390
|
+
task.command("create").description("Create a task from a DAG template").option("--url <url>", "server base URL").requiredOption("--title <t>", "task title").requiredOption("--template <code|name|id>", "DAG template code (preferred), name, or 24-hex id (code/name resolved within project)").requiredOption("--track <t>", "task track (e.g. backend|ui|mixed|research \u2014 research \u4E3A\u8C03\u7814\u7C7B\u578B\u4E13\u7528\uFF0C\u987B\u914D --type research)").option("--type <t>", "task type (feature|bugfix|ui-tweak|research) \u2014 \u7C7B\u578B\u2192\u8DEF\u5F84\u6620\u5C04\u7531 task-create skill \u6301\u6709").option("--skip <ids>", "node ids to prune at creation (comma-separated, repeatable) \u2014 \u53EA\u5141\u8BB8\u6765\u81EA task-create skill \u7684\u6620\u5C04\u77E9\u9635", collectArgs, []).option("--project <key|id>", "projectId (key|id; defaults to workspace defaultProject then template projectId)").action(async (opts) => {
|
|
2307
2391
|
const client = createClient(opts.url);
|
|
2308
2392
|
let type;
|
|
2309
2393
|
if (opts.type !== void 0) {
|
|
@@ -2318,21 +2402,12 @@ function createTaskCommand() {
|
|
|
2318
2402
|
if (opts.skip !== void 0 && opts.skip.length > 0) {
|
|
2319
2403
|
skipNodes = [...new Set(opts.skip.flatMap((s) => s.split(",")).map((s) => s.trim()).filter((s) => s.length > 0))];
|
|
2320
2404
|
}
|
|
2321
|
-
|
|
2322
|
-
if (
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
renderResult("json", r);
|
|
2326
|
-
return;
|
|
2327
|
-
}
|
|
2328
|
-
projectId = r.data;
|
|
2329
|
-
} else {
|
|
2330
|
-
const wsDefaultProject = readWorkspaceConfig()?.defaultProject;
|
|
2331
|
-
if (wsDefaultProject) {
|
|
2332
|
-
const r = await resolveProjectId(client, wsDefaultProject);
|
|
2333
|
-
if (r.success) projectId = r.data;
|
|
2334
|
-
}
|
|
2405
|
+
const projectR = await resolveScopedProject(client, opts.project, "ws-default", { commandLabel: "siming task create" });
|
|
2406
|
+
if (!projectR.success) {
|
|
2407
|
+
renderResult("json", projectR);
|
|
2408
|
+
return;
|
|
2335
2409
|
}
|
|
2410
|
+
const projectId = projectR.data.projectId;
|
|
2336
2411
|
let templateRef = opts.template;
|
|
2337
2412
|
if (!/^[0-9a-f]{24}$/.test(templateRef)) {
|
|
2338
2413
|
const listR = await handleListTemplates(client, projectId);
|
|
@@ -2351,20 +2426,9 @@ function createTaskCommand() {
|
|
|
2351
2426
|
...skipNodes !== void 0 && skipNodes.length > 0 ? { skipNodes } : {},
|
|
2352
2427
|
...projectId ? { projectId } : {}
|
|
2353
2428
|
});
|
|
2354
|
-
if (!result.success && !opts.project) {
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
renderResult("json", { ...result, error: { ...result.error, hint: "workspace defaultProject \u6307\u5411\u7684\u9879\u76EE\u4E0D\u5B58\u5728\u2014\u2014run `siming config unset defaultProject` or `siming config set defaultProject <key|id>`" } });
|
|
2358
|
-
return;
|
|
2359
|
-
}
|
|
2360
|
-
if (bizCode === "PROJECT_ARCHIVED") {
|
|
2361
|
-
renderResult("json", { ...result, error: { ...result.error, hint: "workspace defaultProject \u6307\u5411\u7684\u9879\u76EE\u5DF2\u5F52\u6863\u2014\u2014run `siming project list --status active` to pick an active project" } });
|
|
2362
|
-
return;
|
|
2363
|
-
}
|
|
2364
|
-
if (bizCode === "TEMPLATE_PROJECT_MISMATCH") {
|
|
2365
|
-
renderResult("json", { ...result, error: { ...result.error, hint: "template belongs to another project\u2014\u2014pass --project <key|id> of the template's project" } });
|
|
2366
|
-
return;
|
|
2367
|
-
}
|
|
2429
|
+
if (!result.success && !opts.project && result.error.bizCode === "TEMPLATE_PROJECT_MISMATCH") {
|
|
2430
|
+
renderResult("json", { ...result, error: { ...result.error, hint: "template belongs to another project\u2014\u2014pass --project <key|id> of the template's project" } });
|
|
2431
|
+
return;
|
|
2368
2432
|
}
|
|
2369
2433
|
renderResult("json", result);
|
|
2370
2434
|
});
|
|
@@ -3214,9 +3278,18 @@ async function handleScaffoldSkill(client, input) {
|
|
|
3214
3278
|
// src/commands/skill/command.ts
|
|
3215
3279
|
function createSkillCommand() {
|
|
3216
3280
|
const skill = new Command3("skill").description("Skill management \u2014 global/project-scoped skills");
|
|
3217
|
-
withCommonOpts(skill.command("list"), "table").option("--project <id>", "filter by projectId").description("List skills").action(async (opts) => {
|
|
3281
|
+
withCommonOpts(skill.command("list"), "table").option("--project <key|id>", "filter by projectId (key|id)").description("List skills").action(async (opts) => {
|
|
3218
3282
|
const client = createClient(opts.url);
|
|
3219
|
-
|
|
3283
|
+
let projectId;
|
|
3284
|
+
if (opts.project !== void 0 && opts.project.trim().length > 0) {
|
|
3285
|
+
const pr = await resolveScopedProject(client, opts.project, "explicit-only");
|
|
3286
|
+
if (!pr.success) {
|
|
3287
|
+
renderResult(opts.format, pr);
|
|
3288
|
+
return;
|
|
3289
|
+
}
|
|
3290
|
+
projectId = pr.data.projectId;
|
|
3291
|
+
}
|
|
3292
|
+
const result = await handleListSkills(client, projectId);
|
|
3220
3293
|
renderResult(opts.format, result, {
|
|
3221
3294
|
columns: [
|
|
3222
3295
|
{ key: "name", header: "Name" },
|
|
@@ -3228,7 +3301,7 @@ function createSkillCommand() {
|
|
|
3228
3301
|
]
|
|
3229
3302
|
});
|
|
3230
3303
|
});
|
|
3231
|
-
withCommonOpts(skill.command("show <name>"), "fancy").description("Show skill details").option("--scope <scope>", "global|project (asset addressing; defaults to global)").option("--project-id <
|
|
3304
|
+
withCommonOpts(skill.command("show <name>"), "fancy").description("Show skill details").option("--scope <scope>", "global|project (asset addressing; defaults to global)").option("--project-id <key|id>", "projectId (scope=project; falls back to workspace/instance default project)").action(async (name, opts) => {
|
|
3232
3305
|
const client = createClient(opts.url);
|
|
3233
3306
|
let scope;
|
|
3234
3307
|
if (opts.scope !== void 0) {
|
|
@@ -3239,13 +3312,23 @@ function createSkillCommand() {
|
|
|
3239
3312
|
}
|
|
3240
3313
|
scope = scopeR.data;
|
|
3241
3314
|
}
|
|
3315
|
+
let projectId;
|
|
3316
|
+
const explicitProject = opts.projectId !== void 0 && opts.projectId.trim().length > 0 ? opts.projectId : void 0;
|
|
3317
|
+
if (explicitProject !== void 0 || scope === "project") {
|
|
3318
|
+
const pr = await resolveScopedProject(client, explicitProject, "instance-default", { commandLabel: "siming skill show" });
|
|
3319
|
+
if (!pr.success) {
|
|
3320
|
+
renderResult(opts.format, pr);
|
|
3321
|
+
return;
|
|
3322
|
+
}
|
|
3323
|
+
projectId = pr.data.projectId;
|
|
3324
|
+
}
|
|
3242
3325
|
const result = await handleGetSkill(client, name, {
|
|
3243
3326
|
...scope !== void 0 ? { scope } : {},
|
|
3244
|
-
...
|
|
3327
|
+
...projectId !== void 0 ? { projectId } : {}
|
|
3245
3328
|
});
|
|
3246
3329
|
renderResult(opts.format, result, { fields: result.success ? skillFields(result.data) : [] });
|
|
3247
3330
|
});
|
|
3248
|
-
skill.command("create").description("Create a skill (scope required)").option("--url <url>", "server base URL").requiredOption("--name <name>", "skill name (kebab-case)").requiredOption("--description <text>", "skill description").requiredOption("--content <text>", "skill content (prompt body)").requiredOption("--category <cat>", "process|domain|tooling").requiredOption("--scope <scope>", "global|project").option("--ref <path@file>", "reference doc: <relative path>@<local file> (repeatable)", collectArgs, []).option("--project-id <
|
|
3331
|
+
skill.command("create").description("Create a skill (scope required)").option("--url <url>", "server base URL").requiredOption("--name <name>", "skill name (kebab-case)").requiredOption("--description <text>", "skill description").requiredOption("--content <text>", "skill content (prompt body)").requiredOption("--category <cat>", "process|domain|tooling").requiredOption("--scope <scope>", "global|project").option("--ref <path@file>", "reference doc: <relative path>@<local file> (repeatable)", collectArgs, []).option("--project-id <key|id>", "projectId (scope=project; falls back to workspace/instance default project)").action(async (opts) => {
|
|
3249
3332
|
const categoryR = parseEnum(opts.category, SkillCategorySchema, "category");
|
|
3250
3333
|
if (!categoryR.success) {
|
|
3251
3334
|
renderResult("json", categoryR);
|
|
@@ -3262,6 +3345,16 @@ function createSkillCommand() {
|
|
|
3262
3345
|
return;
|
|
3263
3346
|
}
|
|
3264
3347
|
const client = createClient(opts.url);
|
|
3348
|
+
let projectId;
|
|
3349
|
+
const explicitProject = opts.projectId !== void 0 && opts.projectId.trim().length > 0 ? opts.projectId : void 0;
|
|
3350
|
+
if (explicitProject !== void 0 || scopeR.data === "project") {
|
|
3351
|
+
const pr = await resolveScopedProject(client, explicitProject, "instance-default", { commandLabel: "siming skill create" });
|
|
3352
|
+
if (!pr.success) {
|
|
3353
|
+
renderResult("json", pr);
|
|
3354
|
+
return;
|
|
3355
|
+
}
|
|
3356
|
+
projectId = pr.data.projectId;
|
|
3357
|
+
}
|
|
3265
3358
|
const input = {
|
|
3266
3359
|
name: opts.name,
|
|
3267
3360
|
description: opts.description,
|
|
@@ -3270,12 +3363,12 @@ function createSkillCommand() {
|
|
|
3270
3363
|
scope: scopeR.data,
|
|
3271
3364
|
version: "1.0.0",
|
|
3272
3365
|
...refsR.data.length > 0 ? { references: refsR.data } : {},
|
|
3273
|
-
...
|
|
3366
|
+
...projectId !== void 0 ? { projectId } : {}
|
|
3274
3367
|
};
|
|
3275
3368
|
const result = await handleCreateSkill(client, input);
|
|
3276
3369
|
renderResult("json", result);
|
|
3277
3370
|
});
|
|
3278
|
-
skill.command("update <name>").description("Update a skill (partial; references untouched unless --ref/--clear-refs given)").option("--url <url>", "server base URL").option("--description <text>", "new description").option("--content <text>", "new content").option("--new-version <v>", "new version (note: --version is reserved for the program version)").option("--scope <scope>", "global|project (asset addressing)").option("--ref <path@file>", "replace all reference docs: <relative path>@<local file> (repeatable)", collectArgs, []).option("--clear-refs", "remove all reference docs (mutually exclusive with --ref)").option("--project-id <
|
|
3371
|
+
skill.command("update <name>").description("Update a skill (partial; references untouched unless --ref/--clear-refs given)").option("--url <url>", "server base URL").option("--description <text>", "new description").option("--content <text>", "new content").option("--new-version <v>", "new version (note: --version is reserved for the program version)").option("--scope <scope>", "global|project (asset addressing)").option("--ref <path@file>", "replace all reference docs: <relative path>@<local file> (repeatable)", collectArgs, []).option("--clear-refs", "remove all reference docs (mutually exclusive with --ref)").option("--project-id <key|id>", "projectId (scope=project; falls back to workspace/instance default project)").action(async (name, opts) => {
|
|
3279
3372
|
const client = createClient(opts.url);
|
|
3280
3373
|
let scope;
|
|
3281
3374
|
if (opts.scope !== void 0) {
|
|
@@ -3305,21 +3398,31 @@ function createSkillCommand() {
|
|
|
3305
3398
|
}
|
|
3306
3399
|
references = refsR.data;
|
|
3307
3400
|
}
|
|
3401
|
+
let projectId;
|
|
3402
|
+
const explicitProject = opts.projectId !== void 0 && opts.projectId.trim().length > 0 ? opts.projectId : void 0;
|
|
3403
|
+
if (explicitProject !== void 0 || scope === "project") {
|
|
3404
|
+
const pr = await resolveScopedProject(client, explicitProject, "instance-default", { commandLabel: "siming skill update" });
|
|
3405
|
+
if (!pr.success) {
|
|
3406
|
+
renderResult("json", pr);
|
|
3407
|
+
return;
|
|
3408
|
+
}
|
|
3409
|
+
projectId = pr.data.projectId;
|
|
3410
|
+
}
|
|
3308
3411
|
const patch = {
|
|
3309
3412
|
...opts.description !== void 0 ? { description: opts.description } : {},
|
|
3310
3413
|
...opts.content !== void 0 ? { content: opts.content } : {},
|
|
3311
3414
|
...opts.newVersion !== void 0 ? { version: opts.newVersion } : {},
|
|
3312
3415
|
...scope !== void 0 ? { scope } : {},
|
|
3313
3416
|
...references !== void 0 ? { references } : {},
|
|
3314
|
-
...
|
|
3417
|
+
...projectId !== void 0 ? { projectId } : {}
|
|
3315
3418
|
};
|
|
3316
3419
|
const result = await handleUpdateSkill(client, name, patch, {
|
|
3317
3420
|
...scope !== void 0 ? { scope } : {},
|
|
3318
|
-
...
|
|
3421
|
+
...projectId !== void 0 ? { projectId } : {}
|
|
3319
3422
|
});
|
|
3320
3423
|
renderResult("json", result);
|
|
3321
3424
|
});
|
|
3322
|
-
skill.command("copy <name>").description("Copy a skill to a new name/scope").option("--url <url>", "server base URL").requiredOption("--new-name <name>", "copy name").requiredOption("--new-scope <scope>", "global|project").option("--target-project-id <
|
|
3425
|
+
skill.command("copy <name>").description("Copy a skill to a new name/scope").option("--url <url>", "server base URL").requiredOption("--new-name <name>", "copy name").requiredOption("--new-scope <scope>", "global|project").option("--target-project-id <key|id>", "target projectId (newScope=project; falls back to workspace/instance default project)").option("--scope <scope>", "source asset addressing: global|project (defaults to global)").option("--source-project-id <key|id>", "source projectId (scope=project; falls back to workspace/instance default project)").action(async (name, opts) => {
|
|
3323
3426
|
const scopeR = parseEnum(opts.newScope, SkillScopeSchema, "new-scope");
|
|
3324
3427
|
if (!scopeR.success) {
|
|
3325
3428
|
renderResult("json", scopeR);
|
|
@@ -3335,22 +3438,42 @@ function createSkillCommand() {
|
|
|
3335
3438
|
srcScope = srcR.data;
|
|
3336
3439
|
}
|
|
3337
3440
|
const client = createClient(opts.url);
|
|
3441
|
+
let targetProjectId;
|
|
3442
|
+
const explicitTarget = opts.targetProjectId !== void 0 && opts.targetProjectId.trim().length > 0 ? opts.targetProjectId : void 0;
|
|
3443
|
+
if (explicitTarget !== void 0 || scopeR.data === "project") {
|
|
3444
|
+
const pr = await resolveScopedProject(client, explicitTarget, "instance-default", { commandLabel: "siming skill copy (target)" });
|
|
3445
|
+
if (!pr.success) {
|
|
3446
|
+
renderResult("json", pr);
|
|
3447
|
+
return;
|
|
3448
|
+
}
|
|
3449
|
+
targetProjectId = pr.data.projectId;
|
|
3450
|
+
}
|
|
3451
|
+
let sourceProjectId;
|
|
3452
|
+
const explicitSource = opts.sourceProjectId !== void 0 && opts.sourceProjectId.trim().length > 0 ? opts.sourceProjectId : void 0;
|
|
3453
|
+
if (explicitSource !== void 0 || srcScope === "project") {
|
|
3454
|
+
const pr = await resolveScopedProject(client, explicitSource, "instance-default", { commandLabel: "siming skill copy (source)" });
|
|
3455
|
+
if (!pr.success) {
|
|
3456
|
+
renderResult("json", pr);
|
|
3457
|
+
return;
|
|
3458
|
+
}
|
|
3459
|
+
sourceProjectId = pr.data.projectId;
|
|
3460
|
+
}
|
|
3338
3461
|
const result = await handleCopySkill(
|
|
3339
3462
|
client,
|
|
3340
3463
|
name,
|
|
3341
3464
|
{
|
|
3342
3465
|
newName: opts.newName,
|
|
3343
3466
|
newScope: scopeR.data,
|
|
3344
|
-
...
|
|
3467
|
+
...targetProjectId !== void 0 ? { targetProjectId } : {}
|
|
3345
3468
|
},
|
|
3346
3469
|
{
|
|
3347
3470
|
...srcScope !== void 0 ? { scope: srcScope } : {},
|
|
3348
|
-
...
|
|
3471
|
+
...sourceProjectId !== void 0 ? { projectId: sourceProjectId } : {}
|
|
3349
3472
|
}
|
|
3350
3473
|
);
|
|
3351
3474
|
renderResult("json", result);
|
|
3352
3475
|
});
|
|
3353
|
-
withCommonOpts(skill.command("delete <name>"), "fancy").description("Delete a skill").option("--scope <scope>", "global|project (asset addressing; defaults to global)").option("--project-id <
|
|
3476
|
+
withCommonOpts(skill.command("delete <name>"), "fancy").description("Delete a skill").option("--scope <scope>", "global|project (asset addressing; defaults to global)").option("--project-id <key|id>", "projectId (scope=project; falls back to workspace/instance default project)").action(async (name, opts) => {
|
|
3354
3477
|
const client = createClient(opts.url);
|
|
3355
3478
|
let scope;
|
|
3356
3479
|
if (opts.scope !== void 0) {
|
|
@@ -3361,13 +3484,23 @@ function createSkillCommand() {
|
|
|
3361
3484
|
}
|
|
3362
3485
|
scope = scopeR.data;
|
|
3363
3486
|
}
|
|
3487
|
+
let projectId;
|
|
3488
|
+
const explicitProject = opts.projectId !== void 0 && opts.projectId.trim().length > 0 ? opts.projectId : void 0;
|
|
3489
|
+
if (explicitProject !== void 0 || scope === "project") {
|
|
3490
|
+
const pr = await resolveScopedProject(client, explicitProject, "instance-default", { commandLabel: "siming skill delete" });
|
|
3491
|
+
if (!pr.success) {
|
|
3492
|
+
renderResult("json", pr);
|
|
3493
|
+
return;
|
|
3494
|
+
}
|
|
3495
|
+
projectId = pr.data.projectId;
|
|
3496
|
+
}
|
|
3364
3497
|
const result = await handleDeleteSkill(client, name, {
|
|
3365
3498
|
...scope !== void 0 ? { scope } : {},
|
|
3366
|
-
...
|
|
3499
|
+
...projectId !== void 0 ? { projectId } : {}
|
|
3367
3500
|
});
|
|
3368
3501
|
renderResult(opts.format, result, { successMessage: `deleted skill '${name}'` });
|
|
3369
3502
|
});
|
|
3370
|
-
skill.command("enabled <name> <on|off>").description("Enable/disable a skill (asset addressing; defaults to global)").option("--url <url>", "server base URL").option("--format <fmt>", "output format: fancy|table|json", "fancy").option("--scope <scope>", "global|project (asset addressing; defaults to global)").option("--project-id <
|
|
3503
|
+
skill.command("enabled <name> <on|off>").description("Enable/disable a skill (asset addressing; defaults to global)").option("--url <url>", "server base URL").option("--format <fmt>", "output format: fancy|table|json", "fancy").option("--scope <scope>", "global|project (asset addressing; defaults to global)").option("--project-id <key|id>", "projectId (scope=project; falls back to workspace/instance default project)").action(async (name, onOff, opts) => {
|
|
3371
3504
|
const enabledR = parseOnOff(onOff);
|
|
3372
3505
|
if (!enabledR.success) {
|
|
3373
3506
|
renderResult(opts.format, enabledR);
|
|
@@ -3383,9 +3516,19 @@ function createSkillCommand() {
|
|
|
3383
3516
|
}
|
|
3384
3517
|
scope = scopeR.data;
|
|
3385
3518
|
}
|
|
3519
|
+
let projectId;
|
|
3520
|
+
const explicitProject = opts.projectId !== void 0 && opts.projectId.trim().length > 0 ? opts.projectId : void 0;
|
|
3521
|
+
if (explicitProject !== void 0 || scope === "project") {
|
|
3522
|
+
const pr = await resolveScopedProject(client, explicitProject, "instance-default", { commandLabel: "siming skill enabled" });
|
|
3523
|
+
if (!pr.success) {
|
|
3524
|
+
renderResult(opts.format, pr);
|
|
3525
|
+
return;
|
|
3526
|
+
}
|
|
3527
|
+
projectId = pr.data.projectId;
|
|
3528
|
+
}
|
|
3386
3529
|
const result = await handleSetSkillEnabled(client, name, enabledR.data, {
|
|
3387
3530
|
...scope !== void 0 ? { scope } : {},
|
|
3388
|
-
...
|
|
3531
|
+
...projectId !== void 0 ? { projectId } : {}
|
|
3389
3532
|
});
|
|
3390
3533
|
renderResult(opts.format, result, {
|
|
3391
3534
|
successMessage: `skill '${name}' ${enabledR.data ? "enabled" : "disabled"}`
|
|
@@ -3393,16 +3536,17 @@ function createSkillCommand() {
|
|
|
3393
3536
|
});
|
|
3394
3537
|
skill.command("scaffold <template>").description(
|
|
3395
3538
|
"Scaffold an official project-scoped skill from the packaged skeleton (task-create entry; same-name conflict refused by default)"
|
|
3396
|
-
).option("--url <url>", "server base URL").
|
|
3539
|
+
).option("--url <url>", "server base URL").option("--project <key|id>", "target project (key|id; falls back to workspace/instance default project)").option("--overwrite", "explicitly replace an existing same-name project asset (version bumps monotonically; enabled state untouched)").option("--format <fmt>", "output format: fancy|table|json", "fancy").action(async (template, opts) => {
|
|
3397
3540
|
const client = createClient(opts.url);
|
|
3398
|
-
const projectR = await
|
|
3541
|
+
const projectR = await resolveScopedProject(client, opts.project, "instance-default", { commandLabel: "siming skill scaffold" });
|
|
3399
3542
|
if (!projectR.success) {
|
|
3400
3543
|
renderResult(opts.format, projectR);
|
|
3401
3544
|
return;
|
|
3402
3545
|
}
|
|
3403
3546
|
const result = await handleScaffoldSkill(client, {
|
|
3404
3547
|
template,
|
|
3405
|
-
projectId: projectR.data,
|
|
3548
|
+
projectId: projectR.data.projectId,
|
|
3549
|
+
// instance-default 成功必含 id
|
|
3406
3550
|
...opts.overwrite === true ? { overwrite: true } : {}
|
|
3407
3551
|
});
|
|
3408
3552
|
const renderOptions = result.success ? {
|
|
@@ -3493,9 +3637,18 @@ async function handleDeleteAgent(client, name, query = {}) {
|
|
|
3493
3637
|
// src/commands/agent/command.ts
|
|
3494
3638
|
function createAgentCommand() {
|
|
3495
3639
|
const agent = new Command4("agent").description("Agent management \u2014 subagent definitions (global/project scope)");
|
|
3496
|
-
withCommonOpts(agent.command("list"), "table").option("--project <id>", "filter by projectId").description("List agents").action(async (opts) => {
|
|
3640
|
+
withCommonOpts(agent.command("list"), "table").option("--project <key|id>", "filter by projectId (key|id)").description("List agents").action(async (opts) => {
|
|
3497
3641
|
const client = createClient(opts.url);
|
|
3498
|
-
|
|
3642
|
+
let projectId;
|
|
3643
|
+
if (opts.project !== void 0 && opts.project.trim().length > 0) {
|
|
3644
|
+
const pr = await resolveScopedProject(client, opts.project, "explicit-only");
|
|
3645
|
+
if (!pr.success) {
|
|
3646
|
+
renderResult(opts.format, pr);
|
|
3647
|
+
return;
|
|
3648
|
+
}
|
|
3649
|
+
projectId = pr.data.projectId;
|
|
3650
|
+
}
|
|
3651
|
+
const result = await handleListAgents(client, projectId);
|
|
3499
3652
|
renderResult(opts.format, result, {
|
|
3500
3653
|
columns: [
|
|
3501
3654
|
{ key: "name", header: "Name" },
|
|
@@ -3513,7 +3666,7 @@ function createAgentCommand() {
|
|
|
3513
3666
|
const result = await handleGetAgent(client, name);
|
|
3514
3667
|
renderResult(opts.format, result, { fields: result.success ? agentFields(result.data) : [] });
|
|
3515
3668
|
});
|
|
3516
|
-
agent.command("create").description("Create an agent (scope + system-prompt + model required)").option("--url <url>", "server base URL").requiredOption("--name <name>", "agent name").requiredOption("--description <text>", "agent description").requiredOption("--system-prompt <text>", "system prompt").requiredOption("--model <code>", "model siming-code (kebab-case)").requiredOption("--scope <scope>", "global|project").option("--function <function>", "agent function: reviewer|executor (default executor)").option("--bound-skill <name>", "bound skill name (repeatable)", collectArgs, []).option("--tool <name>", "tool name (repeatable)", collectArgs, []).option("--permission <name>", "permission name (repeatable)", collectArgs, []).option("--ref <path@file>", "reference doc: <relative path>@<local file> (repeatable)", collectArgs, []).option("--project-id <
|
|
3669
|
+
agent.command("create").description("Create an agent (scope + system-prompt + model required)").option("--url <url>", "server base URL").requiredOption("--name <name>", "agent name").requiredOption("--description <text>", "agent description").requiredOption("--system-prompt <text>", "system prompt").requiredOption("--model <code>", "model siming-code (kebab-case)").requiredOption("--scope <scope>", "global|project").option("--function <function>", "agent function: reviewer|executor (default executor)").option("--bound-skill <name>", "bound skill name (repeatable)", collectArgs, []).option("--tool <name>", "tool name (repeatable)", collectArgs, []).option("--permission <name>", "permission name (repeatable)", collectArgs, []).option("--ref <path@file>", "reference doc: <relative path>@<local file> (repeatable)", collectArgs, []).option("--project-id <key|id>", "projectId (scope=project; falls back to workspace/instance default project)").action(async (opts) => {
|
|
3517
3670
|
const scopeR = parseEnum(opts.scope, AgentScopeSchema, "scope");
|
|
3518
3671
|
if (!scopeR.success) {
|
|
3519
3672
|
renderResult("json", scopeR);
|
|
@@ -3534,6 +3687,16 @@ function createAgentCommand() {
|
|
|
3534
3687
|
return;
|
|
3535
3688
|
}
|
|
3536
3689
|
const client = createClient(opts.url);
|
|
3690
|
+
let projectId;
|
|
3691
|
+
const explicitProject = opts.projectId !== void 0 && opts.projectId.trim().length > 0 ? opts.projectId : void 0;
|
|
3692
|
+
if (explicitProject !== void 0 || scopeR.data === "project") {
|
|
3693
|
+
const pr = await resolveScopedProject(client, explicitProject, "instance-default", { commandLabel: "siming agent create" });
|
|
3694
|
+
if (!pr.success) {
|
|
3695
|
+
renderResult("json", pr);
|
|
3696
|
+
return;
|
|
3697
|
+
}
|
|
3698
|
+
projectId = pr.data.projectId;
|
|
3699
|
+
}
|
|
3537
3700
|
const input = {
|
|
3538
3701
|
name: opts.name,
|
|
3539
3702
|
description: opts.description,
|
|
@@ -3547,12 +3710,12 @@ function createAgentCommand() {
|
|
|
3547
3710
|
tools: opts.tool,
|
|
3548
3711
|
permissions: opts.permission,
|
|
3549
3712
|
...refsR.data.length > 0 ? { references: refsR.data } : {},
|
|
3550
|
-
...
|
|
3713
|
+
...projectId !== void 0 ? { projectId } : {}
|
|
3551
3714
|
};
|
|
3552
3715
|
const result = await handleCreateAgent(client, input);
|
|
3553
3716
|
renderResult("json", result);
|
|
3554
3717
|
});
|
|
3555
|
-
agent.command("update <name>").description("Update an agent (partial)").option("--url <url>", "server base URL").option("--description <text>", "new description").option("--system-prompt <text>", "new system prompt").option("--model <code>", "new model siming-code").option("--scope <scope>", "global|project (asset addressing)").option("--function <function>", "new agent function: reviewer|executor").option("--bound-skill <name>", "replace bound skills (repeatable)", collectArgs, []).option("--tool <name>", "replace tools (repeatable)", collectArgs, []).option("--permission <name>", "replace permissions (repeatable)", collectArgs, []).option("--ref <path@file>", "replace all reference docs: <relative path>@<local file> (repeatable)", collectArgs, []).option("--clear-refs", "remove all reference docs (mutually exclusive with --ref)").option("--project-id <
|
|
3718
|
+
agent.command("update <name>").description("Update an agent (partial)").option("--url <url>", "server base URL").option("--description <text>", "new description").option("--system-prompt <text>", "new system prompt").option("--model <code>", "new model siming-code").option("--scope <scope>", "global|project (asset addressing)").option("--function <function>", "new agent function: reviewer|executor").option("--bound-skill <name>", "replace bound skills (repeatable)", collectArgs, []).option("--tool <name>", "replace tools (repeatable)", collectArgs, []).option("--permission <name>", "replace permissions (repeatable)", collectArgs, []).option("--ref <path@file>", "replace all reference docs: <relative path>@<local file> (repeatable)", collectArgs, []).option("--clear-refs", "remove all reference docs (mutually exclusive with --ref)").option("--project-id <key|id>", "projectId (scope=project; falls back to workspace/instance default project)").action(async (name, opts) => {
|
|
3556
3719
|
const client = createClient(opts.url);
|
|
3557
3720
|
let scope;
|
|
3558
3721
|
if (opts.scope !== void 0) {
|
|
@@ -3591,6 +3754,16 @@ function createAgentCommand() {
|
|
|
3591
3754
|
}
|
|
3592
3755
|
references = refsR.data;
|
|
3593
3756
|
}
|
|
3757
|
+
let projectId;
|
|
3758
|
+
const explicitProject = opts.projectId !== void 0 && opts.projectId.trim().length > 0 ? opts.projectId : void 0;
|
|
3759
|
+
if (explicitProject !== void 0 || scope === "project") {
|
|
3760
|
+
const pr = await resolveScopedProject(client, explicitProject, "instance-default", { commandLabel: "siming agent update" });
|
|
3761
|
+
if (!pr.success) {
|
|
3762
|
+
renderResult("json", pr);
|
|
3763
|
+
return;
|
|
3764
|
+
}
|
|
3765
|
+
projectId = pr.data.projectId;
|
|
3766
|
+
}
|
|
3594
3767
|
const patch = {
|
|
3595
3768
|
...opts.description !== void 0 ? { description: opts.description } : {},
|
|
3596
3769
|
...opts.systemPrompt !== void 0 ? { systemPrompt: opts.systemPrompt } : {},
|
|
@@ -3601,15 +3774,15 @@ function createAgentCommand() {
|
|
|
3601
3774
|
...opts.tool.length > 0 ? { tools: opts.tool } : {},
|
|
3602
3775
|
...opts.permission.length > 0 ? { permissions: opts.permission } : {},
|
|
3603
3776
|
...references !== void 0 ? { references } : {},
|
|
3604
|
-
...
|
|
3777
|
+
...projectId !== void 0 ? { projectId } : {}
|
|
3605
3778
|
};
|
|
3606
3779
|
const result = await handleUpdateAgent(client, name, patch, {
|
|
3607
3780
|
...scope !== void 0 ? { scope } : {},
|
|
3608
|
-
...
|
|
3781
|
+
...projectId !== void 0 ? { projectId } : {}
|
|
3609
3782
|
});
|
|
3610
3783
|
renderResult("json", result);
|
|
3611
3784
|
});
|
|
3612
|
-
agent.command("copy <name>").description("Copy an agent to a new name/scope").option("--url <url>", "server base URL").requiredOption("--new-name <name>", "copy name").requiredOption("--new-scope <scope>", "global|project").option("--target-project-id <
|
|
3785
|
+
agent.command("copy <name>").description("Copy an agent to a new name/scope").option("--url <url>", "server base URL").requiredOption("--new-name <name>", "copy name").requiredOption("--new-scope <scope>", "global|project").option("--target-project-id <key|id>", "target projectId (newScope=project; falls back to workspace/instance default project)").option("--scope <scope>", "source asset addressing: global|project (defaults to global)").option("--source-project-id <key|id>", "source projectId (scope=project; falls back to workspace/instance default project)").action(async (name, opts) => {
|
|
3613
3786
|
const scopeR = parseEnum(opts.newScope, AgentScopeSchema, "new-scope");
|
|
3614
3787
|
if (!scopeR.success) {
|
|
3615
3788
|
renderResult("json", scopeR);
|
|
@@ -3625,22 +3798,42 @@ function createAgentCommand() {
|
|
|
3625
3798
|
srcScope = srcR.data;
|
|
3626
3799
|
}
|
|
3627
3800
|
const client = createClient(opts.url);
|
|
3801
|
+
let targetProjectId;
|
|
3802
|
+
const explicitTarget = opts.targetProjectId !== void 0 && opts.targetProjectId.trim().length > 0 ? opts.targetProjectId : void 0;
|
|
3803
|
+
if (explicitTarget !== void 0 || scopeR.data === "project") {
|
|
3804
|
+
const pr = await resolveScopedProject(client, explicitTarget, "instance-default", { commandLabel: "siming agent copy (target)" });
|
|
3805
|
+
if (!pr.success) {
|
|
3806
|
+
renderResult("json", pr);
|
|
3807
|
+
return;
|
|
3808
|
+
}
|
|
3809
|
+
targetProjectId = pr.data.projectId;
|
|
3810
|
+
}
|
|
3811
|
+
let sourceProjectId;
|
|
3812
|
+
const explicitSource = opts.sourceProjectId !== void 0 && opts.sourceProjectId.trim().length > 0 ? opts.sourceProjectId : void 0;
|
|
3813
|
+
if (explicitSource !== void 0 || srcScope === "project") {
|
|
3814
|
+
const pr = await resolveScopedProject(client, explicitSource, "instance-default", { commandLabel: "siming agent copy (source)" });
|
|
3815
|
+
if (!pr.success) {
|
|
3816
|
+
renderResult("json", pr);
|
|
3817
|
+
return;
|
|
3818
|
+
}
|
|
3819
|
+
sourceProjectId = pr.data.projectId;
|
|
3820
|
+
}
|
|
3628
3821
|
const result = await handleCopyAgent(
|
|
3629
3822
|
client,
|
|
3630
3823
|
name,
|
|
3631
3824
|
{
|
|
3632
3825
|
newName: opts.newName,
|
|
3633
3826
|
newScope: scopeR.data,
|
|
3634
|
-
...
|
|
3827
|
+
...targetProjectId !== void 0 ? { targetProjectId } : {}
|
|
3635
3828
|
},
|
|
3636
3829
|
{
|
|
3637
3830
|
...srcScope !== void 0 ? { scope: srcScope } : {},
|
|
3638
|
-
...
|
|
3831
|
+
...sourceProjectId !== void 0 ? { projectId: sourceProjectId } : {}
|
|
3639
3832
|
}
|
|
3640
3833
|
);
|
|
3641
3834
|
renderResult("json", result);
|
|
3642
3835
|
});
|
|
3643
|
-
withCommonOpts(agent.command("delete <name>"), "fancy").description("Delete an agent").option("--scope <scope>", "global|project (asset addressing; defaults to global)").option("--project-id <
|
|
3836
|
+
withCommonOpts(agent.command("delete <name>"), "fancy").description("Delete an agent").option("--scope <scope>", "global|project (asset addressing; defaults to global)").option("--project-id <key|id>", "projectId (scope=project; falls back to workspace/instance default project)").action(async (name, opts) => {
|
|
3644
3837
|
const client = createClient(opts.url);
|
|
3645
3838
|
let scope;
|
|
3646
3839
|
if (opts.scope !== void 0) {
|
|
@@ -3651,9 +3844,19 @@ function createAgentCommand() {
|
|
|
3651
3844
|
}
|
|
3652
3845
|
scope = scopeR.data;
|
|
3653
3846
|
}
|
|
3847
|
+
let projectId;
|
|
3848
|
+
const explicitProject = opts.projectId !== void 0 && opts.projectId.trim().length > 0 ? opts.projectId : void 0;
|
|
3849
|
+
if (explicitProject !== void 0 || scope === "project") {
|
|
3850
|
+
const pr = await resolveScopedProject(client, explicitProject, "instance-default", { commandLabel: "siming agent delete" });
|
|
3851
|
+
if (!pr.success) {
|
|
3852
|
+
renderResult(opts.format, pr);
|
|
3853
|
+
return;
|
|
3854
|
+
}
|
|
3855
|
+
projectId = pr.data.projectId;
|
|
3856
|
+
}
|
|
3654
3857
|
const result = await handleDeleteAgent(client, name, {
|
|
3655
3858
|
...scope !== void 0 ? { scope } : {},
|
|
3656
|
-
...
|
|
3859
|
+
...projectId !== void 0 ? { projectId } : {}
|
|
3657
3860
|
});
|
|
3658
3861
|
renderResult(opts.format, result, { successMessage: `deleted agent '${name}'` });
|
|
3659
3862
|
});
|
|
@@ -3684,23 +3887,13 @@ function createDagCommand() {
|
|
|
3684
3887
|
const tpl = dag.command("template").description("DAG template management");
|
|
3685
3888
|
withCommonOpts(tpl.command("list"), "table").option("--project <key|id>", "filter by project (key or id; defaults to workspace defaultProject)").description("List DAG templates (summary projection: node labels only, no prompts \u2014 use `show` for full detail)").action(async (opts) => {
|
|
3686
3889
|
const client = createClient(opts.url);
|
|
3687
|
-
const
|
|
3688
|
-
|
|
3689
|
-
if (
|
|
3690
|
-
|
|
3691
|
-
|
|
3692
|
-
if (opts.project === void 0) {
|
|
3693
|
-
renderResult(opts.format, fail({
|
|
3694
|
-
...r.error,
|
|
3695
|
-
hint: `workspace defaultProject "${projectOpt}" \u89E3\u6790\u5931\u8D25\u2014\u2014siming config unset defaultProject \u540E\u91CD\u8BD5\uFF0C\u6216\u663E\u5F0F --project <key|id>`
|
|
3696
|
-
}));
|
|
3697
|
-
} else {
|
|
3698
|
-
renderResult(opts.format, r);
|
|
3699
|
-
}
|
|
3700
|
-
return;
|
|
3701
|
-
}
|
|
3702
|
-
projectId = r.data;
|
|
3890
|
+
const explicitProject = opts.project !== void 0 && opts.project.trim().length > 0 ? opts.project : void 0;
|
|
3891
|
+
const pr = await resolveScopedProject(client, explicitProject, "ws-default", { commandLabel: "siming dag template list" });
|
|
3892
|
+
if (!pr.success) {
|
|
3893
|
+
renderResult(opts.format, pr);
|
|
3894
|
+
return;
|
|
3703
3895
|
}
|
|
3896
|
+
const projectId = pr.data.projectId;
|
|
3704
3897
|
const result = await handleListTemplates(client, projectId);
|
|
3705
3898
|
if (!result.success) {
|
|
3706
3899
|
renderResult(opts.format, result);
|
|
@@ -3728,15 +3921,13 @@ function createDagCommand() {
|
|
|
3728
3921
|
const client = createClient(opts.url);
|
|
3729
3922
|
let projectId;
|
|
3730
3923
|
if (!/^[a-f0-9]{24}$/.test(templateRef)) {
|
|
3731
|
-
const
|
|
3732
|
-
|
|
3733
|
-
|
|
3734
|
-
|
|
3735
|
-
|
|
3736
|
-
return;
|
|
3737
|
-
}
|
|
3738
|
-
projectId = r.data;
|
|
3924
|
+
const explicitProject = opts.project !== void 0 && opts.project.trim().length > 0 ? opts.project : void 0;
|
|
3925
|
+
const pr = await resolveScopedProject(client, explicitProject, "ws-default", { commandLabel: "siming dag template show" });
|
|
3926
|
+
if (!pr.success) {
|
|
3927
|
+
renderResult(opts.format, pr);
|
|
3928
|
+
return;
|
|
3739
3929
|
}
|
|
3930
|
+
projectId = pr.data.projectId;
|
|
3740
3931
|
}
|
|
3741
3932
|
const result = await handleGetTemplate(client, templateRef, projectId);
|
|
3742
3933
|
renderResult(opts.format, result, { fields: result.success ? templateFields(result.data) : [] });
|
|
@@ -3903,13 +4094,15 @@ async function runYamlImport(client, yamlText, opts, jsonParseError2) {
|
|
|
3903
4094
|
return;
|
|
3904
4095
|
}
|
|
3905
4096
|
let projectId;
|
|
3906
|
-
if (opts.project !== void 0) {
|
|
3907
|
-
const r = await
|
|
4097
|
+
if (opts.project !== void 0 && opts.project.trim().length > 0) {
|
|
4098
|
+
const r = await resolveScopedProject(client, opts.project, "explicit-only", {
|
|
4099
|
+
commandLabel: "siming dag template import"
|
|
4100
|
+
});
|
|
3908
4101
|
if (!r.success) {
|
|
3909
4102
|
renderResult("json", r);
|
|
3910
4103
|
return;
|
|
3911
4104
|
}
|
|
3912
|
-
projectId = r.data;
|
|
4105
|
+
projectId = r.data.projectId;
|
|
3913
4106
|
}
|
|
3914
4107
|
const result = await importTemplateFromYaml(client, yamlText, {
|
|
3915
4108
|
...projectId !== void 0 ? { projectId } : {},
|
|
@@ -3969,13 +4162,15 @@ async function runBundleImport(client, bundleText, opts) {
|
|
|
3969
4162
|
}));
|
|
3970
4163
|
return;
|
|
3971
4164
|
}
|
|
3972
|
-
const
|
|
3973
|
-
|
|
3974
|
-
|
|
4165
|
+
const explicitBundleTarget = opts.project !== void 0 && opts.project.trim().length > 0 ? opts.project : void 0;
|
|
4166
|
+
const pr = await resolveScopedProject(client, explicitBundleTarget, "instance-default", { commandLabel: "siming dag template import" });
|
|
4167
|
+
if (!pr.success) {
|
|
4168
|
+
renderResult("json", pr);
|
|
3975
4169
|
return;
|
|
3976
4170
|
}
|
|
3977
4171
|
const result = await importTemplateBundle(client, bundleText, {
|
|
3978
|
-
targetProjectId:
|
|
4172
|
+
targetProjectId: pr.data.projectId,
|
|
4173
|
+
// instance-default 成功必含 id
|
|
3979
4174
|
...opts.overwriteDeps === true ? { overwriteDeps: true } : {},
|
|
3980
4175
|
...opts.plan === true ? { planOnly: true } : {}
|
|
3981
4176
|
});
|
|
@@ -3985,31 +4180,6 @@ async function runBundleImport(client, bundleText, opts) {
|
|
|
3985
4180
|
}
|
|
3986
4181
|
renderBundleImportOutcome(result.data, opts.plan === true);
|
|
3987
4182
|
}
|
|
3988
|
-
async function resolveImportTargetProject(client, projectOpt) {
|
|
3989
|
-
if (projectOpt !== void 0) return resolveProjectId(client, projectOpt);
|
|
3990
|
-
const wsDefault = readWorkspaceConfig()?.defaultProject;
|
|
3991
|
-
if (wsDefault !== void 0) {
|
|
3992
|
-
const r = await resolveProjectId(client, wsDefault);
|
|
3993
|
-
if (!r.success) {
|
|
3994
|
-
return fail({
|
|
3995
|
-
...r.error,
|
|
3996
|
-
hint: `workspace defaultProject "${wsDefault}" \u89E3\u6790\u5931\u8D25\u2014\u2014siming config unset defaultProject \u540E\u91CD\u8BD5\uFF0C\u6216\u663E\u5F0F --project <key|id>`
|
|
3997
|
-
});
|
|
3998
|
-
}
|
|
3999
|
-
return r;
|
|
4000
|
-
}
|
|
4001
|
-
const list = await handleListProjects(client);
|
|
4002
|
-
if (!list.success) return list;
|
|
4003
|
-
const defaultProject = list.data.find((p) => p.key === "default");
|
|
4004
|
-
if (defaultProject?.id === void 0) {
|
|
4005
|
-
return fail({
|
|
4006
|
-
message: "bundle \u5BFC\u5165\u9700\u8981\u76EE\u6807\u9879\u76EE\uFF1A\u672A\u6307\u5B9A --project\uFF0C\u5DE5\u4F5C\u533A\u65E0 defaultProject\uFF0C\u5B9E\u4F8B\u4E2D\u4E5F\u65E0 key=default \u7684\u9879\u76EE",
|
|
4007
|
-
httpStatus: 0,
|
|
4008
|
-
hint: "pass --project <key|id>\uFF0C\u6216\u5148 siming project create + siming init --project <key>"
|
|
4009
|
-
});
|
|
4010
|
-
}
|
|
4011
|
-
return { success: true, data: defaultProject.id };
|
|
4012
|
-
}
|
|
4013
4183
|
function renderBundleImportOutcome(outcome, planOnly) {
|
|
4014
4184
|
const t = outcome.plan.template;
|
|
4015
4185
|
const overwritten = t.willOverwrite && t.currentVersion !== void 0 ? `\u8986\u76D6\u73B0\u6709 v${t.currentVersion} \u2192 ` : "";
|
|
@@ -4284,7 +4454,7 @@ ${failures.join("\n")}`,
|
|
|
4284
4454
|
// src/commands/node/command.ts
|
|
4285
4455
|
function createNodeCommand() {
|
|
4286
4456
|
const node = new Command6("node").description("NodePreset management \u2014 reusable DAG node assets (addressed by unique code)");
|
|
4287
|
-
withCommonOpts(node.command("list"), "table").option("--project <id>", "overlay visible set: global + this project").option("--scope <scope>", "exact scope filter: global|project").option("--q <keyword>", "search in code/label").description("List node presets (summary projection: no prompt \u2014 use `show` for full detail)").action(async (opts) => {
|
|
4457
|
+
withCommonOpts(node.command("list"), "table").option("--project <key|id>", "overlay visible set: global + this project (key|id)").option("--scope <scope>", "exact scope filter: global|project").option("--q <keyword>", "search in code/label").description("List node presets (summary projection: no prompt \u2014 use `show` for full detail)").action(async (opts) => {
|
|
4288
4458
|
let scope;
|
|
4289
4459
|
if (opts.scope !== void 0) {
|
|
4290
4460
|
const scopeR = parseEnum(opts.scope, SkillScopeSchema2, "scope");
|
|
@@ -4295,8 +4465,17 @@ function createNodeCommand() {
|
|
|
4295
4465
|
scope = scopeR.data;
|
|
4296
4466
|
}
|
|
4297
4467
|
const client = createClient(opts.url);
|
|
4468
|
+
let projectId;
|
|
4469
|
+
if (opts.project !== void 0 && opts.project.trim().length > 0) {
|
|
4470
|
+
const pr = await resolveScopedProject(client, opts.project, "explicit-only");
|
|
4471
|
+
if (!pr.success) {
|
|
4472
|
+
renderResult(opts.format, pr);
|
|
4473
|
+
return;
|
|
4474
|
+
}
|
|
4475
|
+
projectId = pr.data.projectId;
|
|
4476
|
+
}
|
|
4298
4477
|
const result = await handleListNodePresets(client, {
|
|
4299
|
-
...
|
|
4478
|
+
...projectId !== void 0 ? { projectId } : {},
|
|
4300
4479
|
...scope !== void 0 ? { scope } : {},
|
|
4301
4480
|
...opts.q !== void 0 ? { q: opts.q } : {}
|
|
4302
4481
|
});
|
|
@@ -4319,7 +4498,7 @@ function createNodeCommand() {
|
|
|
4319
4498
|
const result = await handleGetNodePreset(client, code);
|
|
4320
4499
|
renderResult(opts.format, result, { fields: result.success ? nodeFields2(result.data) : [] });
|
|
4321
4500
|
});
|
|
4322
|
-
node.command("create").description("Create a node preset (code globally unique & immutable; scope required)").option("--url <url>", "server base URL").requiredOption("--code <code>", "unique business code (kebab-case, immutable)").requiredOption("--label <text>", "display label").requiredOption("--node-id <id>", "default node id when assembled into templates ([A-Za-z0-9_-]+)").requiredOption("--phase <phase>", "node phase (e.g. entry|track|test|exit)").requiredOption("--track <track>", "node track (backend|ui|all)").requiredOption("--prompt <text>", "node prompt body").option("--prompt-file <path>", "read prompt from file (overrides --prompt)").option("--skill <name>", "bound skill name (repeatable)", collectArgs, []).option("--agent <name>", "callable agent name (repeatable)", collectArgs, []).option("--description <text>", "asset description").requiredOption("--scope <scope>", "global|project").option("--project-id <
|
|
4501
|
+
node.command("create").description("Create a node preset (code globally unique & immutable; scope required)").option("--url <url>", "server base URL").requiredOption("--code <code>", "unique business code (kebab-case, immutable)").requiredOption("--label <text>", "display label").requiredOption("--node-id <id>", "default node id when assembled into templates ([A-Za-z0-9_-]+)").requiredOption("--phase <phase>", "node phase (e.g. entry|track|test|exit)").requiredOption("--track <track>", "node track (backend|ui|all)").requiredOption("--prompt <text>", "node prompt body").option("--prompt-file <path>", "read prompt from file (overrides --prompt)").option("--skill <name>", "bound skill name (repeatable)", collectArgs, []).option("--agent <name>", "callable agent name (repeatable)", collectArgs, []).option("--description <text>", "asset description").requiredOption("--scope <scope>", "global|project").option("--project-id <key|id>", "projectId (scope=project; falls back to workspace/instance default project)").action(async (opts) => {
|
|
4323
4502
|
const scopeR = parseEnum(opts.scope, SkillScopeSchema2, "scope");
|
|
4324
4503
|
if (!scopeR.success) {
|
|
4325
4504
|
renderResult("json", scopeR);
|
|
@@ -4342,6 +4521,16 @@ function createNodeCommand() {
|
|
|
4342
4521
|
return;
|
|
4343
4522
|
}
|
|
4344
4523
|
const client = createClient(opts.url);
|
|
4524
|
+
let projectId;
|
|
4525
|
+
const explicitProject = opts.projectId !== void 0 && opts.projectId.trim().length > 0 ? opts.projectId : void 0;
|
|
4526
|
+
if (explicitProject !== void 0 || scopeR.data === "project") {
|
|
4527
|
+
const pr = await resolveScopedProject(client, explicitProject, "instance-default", { commandLabel: "siming node create" });
|
|
4528
|
+
if (!pr.success) {
|
|
4529
|
+
renderResult("json", pr);
|
|
4530
|
+
return;
|
|
4531
|
+
}
|
|
4532
|
+
projectId = pr.data.projectId;
|
|
4533
|
+
}
|
|
4345
4534
|
const input = {
|
|
4346
4535
|
code: opts.code,
|
|
4347
4536
|
label: opts.label,
|
|
@@ -4354,7 +4543,7 @@ function createNodeCommand() {
|
|
|
4354
4543
|
scope: scopeR.data,
|
|
4355
4544
|
version: "1.0.0",
|
|
4356
4545
|
...opts.description !== void 0 ? { description: opts.description } : {},
|
|
4357
|
-
...
|
|
4546
|
+
...projectId !== void 0 ? { projectId } : {}
|
|
4358
4547
|
};
|
|
4359
4548
|
renderResult("json", await handleCreateNodePreset(client, input));
|
|
4360
4549
|
});
|
|
@@ -4399,17 +4588,27 @@ function createNodeCommand() {
|
|
|
4399
4588
|
}
|
|
4400
4589
|
renderResult("json", await handleUpdateNodePreset(client, code, patch));
|
|
4401
4590
|
});
|
|
4402
|
-
node.command("copy <code>").description("Copy a node preset to a new code/scope (copy version resets 1.0.0)").option("--url <url>", "server base URL").requiredOption("--new-code <code>", "new unique code (kebab-case)").requiredOption("--new-scope <scope>", "global|project").option("--target-project-id <
|
|
4591
|
+
node.command("copy <code>").description("Copy a node preset to a new code/scope (copy version resets 1.0.0)").option("--url <url>", "server base URL").requiredOption("--new-code <code>", "new unique code (kebab-case)").requiredOption("--new-scope <scope>", "global|project").option("--target-project-id <key|id>", "target projectId (newScope=project; falls back to workspace/instance default project)").action(async (code, opts) => {
|
|
4403
4592
|
const scopeR = parseEnum(opts.newScope, SkillScopeSchema2, "new-scope");
|
|
4404
4593
|
if (!scopeR.success) {
|
|
4405
4594
|
renderResult("json", scopeR);
|
|
4406
4595
|
return;
|
|
4407
4596
|
}
|
|
4408
4597
|
const client = createClient(opts.url);
|
|
4598
|
+
let targetProjectId;
|
|
4599
|
+
const explicitTarget = opts.targetProjectId !== void 0 && opts.targetProjectId.trim().length > 0 ? opts.targetProjectId : void 0;
|
|
4600
|
+
if (explicitTarget !== void 0 || scopeR.data === "project") {
|
|
4601
|
+
const pr = await resolveScopedProject(client, explicitTarget, "instance-default", { commandLabel: "siming node copy" });
|
|
4602
|
+
if (!pr.success) {
|
|
4603
|
+
renderResult("json", pr);
|
|
4604
|
+
return;
|
|
4605
|
+
}
|
|
4606
|
+
targetProjectId = pr.data.projectId;
|
|
4607
|
+
}
|
|
4409
4608
|
renderResult("json", await handleCopyNodePreset(client, code, {
|
|
4410
4609
|
newCode: opts.newCode,
|
|
4411
4610
|
newScope: scopeR.data,
|
|
4412
|
-
...
|
|
4611
|
+
...targetProjectId !== void 0 ? { targetProjectId } : {}
|
|
4413
4612
|
}));
|
|
4414
4613
|
});
|
|
4415
4614
|
node.command("enabled <code>").description("Enable/disable a node preset (sole write entry for enabled; disabled presets invisible to list/compose)").option("--url <url>", "server base URL").requiredOption("--value <bool>", "true|false").action(async (code, opts) => {
|
|
@@ -4792,26 +4991,22 @@ function createFlowCommand() {
|
|
|
4792
4991
|
});
|
|
4793
4992
|
flow.command("install <pkg-spec>").description(
|
|
4794
4993
|
"Install a node library package from npm \u2014 validate 1.1 manifest \u2192 plan complete assets \u2192 confirm \u2192 apply dependencies \u2192 nodes \u2192 library"
|
|
4795
|
-
).option("--url <url>", "server base URL").option("--scope <scope>", "install scope: global|project", "global").option("--project <key|id>", "target project (
|
|
4994
|
+
).option("--url <url>", "server base URL").option("--scope <scope>", "install scope: global|project", "global").option("--project <key|id>", "target project (scope=project; falls back to workspace/instance default project)").option("--registry <url>", "npm registry for pack (e.g. private mirror; default npm config)").option("--yes", "skip interactive confirmation").option("--force", "allow version downgrade; admin may also sync a conflicting model alias display name (realModel is never overwritten)").action(async (pkgSpec, opts) => {
|
|
4796
4995
|
const scopeResult = parseEnum(opts.scope, SkillScopeSchema3, "scope");
|
|
4797
4996
|
if (!scopeResult.success) {
|
|
4798
4997
|
renderResult("json", scopeResult);
|
|
4799
4998
|
return;
|
|
4800
4999
|
}
|
|
4801
5000
|
const scope = scopeResult.data;
|
|
4802
|
-
if (scope === "project" && opts.project === void 0) {
|
|
4803
|
-
renderResult("json", fail({ message: "scope=project \u9700\u8981 --project <key|id>", httpStatus: 0 }));
|
|
4804
|
-
return;
|
|
4805
|
-
}
|
|
4806
5001
|
const client = createClient(opts.url);
|
|
4807
5002
|
let projectId;
|
|
4808
5003
|
if (scope === "project") {
|
|
4809
|
-
const
|
|
4810
|
-
if (!
|
|
4811
|
-
renderResult("json",
|
|
5004
|
+
const pr = await resolveScopedProject(client, opts.project, "instance-default", { commandLabel: "siming flow install" });
|
|
5005
|
+
if (!pr.success) {
|
|
5006
|
+
renderResult("json", pr);
|
|
4812
5007
|
return;
|
|
4813
5008
|
}
|
|
4814
|
-
projectId =
|
|
5009
|
+
projectId = pr.data.projectId;
|
|
4815
5010
|
}
|
|
4816
5011
|
const fetched = await fetchManifest(pkgSpec, opts.registry);
|
|
4817
5012
|
if (!fetched.success) {
|
|
@@ -4855,15 +5050,16 @@ ${conflicts.map((item) => ` ${item.kind}:${item.key} \u2014 ${item.reason ?? "\
|
|
|
4855
5050
|
cleanup();
|
|
4856
5051
|
}
|
|
4857
5052
|
});
|
|
4858
|
-
flow.command("compose <composition>").description("Assemble a DAG template from an installed library composition (value-copy nodes + sourcePreset baseline)").option("--url <url>", "server base URL").
|
|
5053
|
+
flow.command("compose <composition>").description("Assemble a DAG template from an installed library composition (value-copy nodes + sourcePreset baseline)").option("--url <url>", "server base URL").option("--project <key|id>", "target project (template owner; falls back to workspace/instance default project)").option("--name <name>", "generated template name (default: composition name)").option("--from <library>", "source library name (required when multiple libraries define the same composition)").action(async (composition, opts) => {
|
|
4859
5054
|
const client = createClient(opts.url);
|
|
4860
|
-
const
|
|
4861
|
-
if (!
|
|
4862
|
-
renderResult("json",
|
|
5055
|
+
const pr = await resolveScopedProject(client, opts.project, "instance-default", { commandLabel: "siming flow compose" });
|
|
5056
|
+
if (!pr.success) {
|
|
5057
|
+
renderResult("json", pr);
|
|
4863
5058
|
return;
|
|
4864
5059
|
}
|
|
4865
5060
|
const result = await composeFlowTemplate(client, composition, {
|
|
4866
|
-
projectId:
|
|
5061
|
+
projectId: pr.data.projectId,
|
|
5062
|
+
// instance-default 成功必含 id
|
|
4867
5063
|
...opts.name !== void 0 ? { name: opts.name } : {},
|
|
4868
5064
|
...opts.from !== void 0 ? { from: opts.from } : {}
|
|
4869
5065
|
});
|
|
@@ -6933,13 +7129,13 @@ function parseVersion(v) {
|
|
|
6933
7129
|
// src/commands/install/command.ts
|
|
6934
7130
|
function createInstallCommand() {
|
|
6935
7131
|
const install = new Command12("install").description("Install skills/agents from Siming to local AI platform");
|
|
6936
|
-
withCommonOpts(install.command("plan"), "table").option("--scope <s>", "install scope: global|project", "global").option("--project <key
|
|
7132
|
+
withCommonOpts(install.command("plan"), "table").option("--scope <s>", "install scope: global|project", "global").option("--project <key|id>", "project key or id (scope=project; falls back to workspace/instance default project)").option("--only <name>", 'filter by asset name (repeatable; use "siming" for the MCP entry)', collectArgs, []).description("Preview install plan (no write)").action(async (opts) => {
|
|
6937
7133
|
const scope = parseScope(opts.scope, opts.format);
|
|
6938
7134
|
if (!scope) return;
|
|
6939
7135
|
const client = createClient(opts.url);
|
|
6940
7136
|
const projectR = await resolveInstallProject(client, scope, opts.project);
|
|
6941
7137
|
if (!projectR.ok) {
|
|
6942
|
-
renderResult(opts.format, { success: false, error: { message: projectR.error.message, httpStatus: 0, ...projectR.error.hint ? { hint: projectR.error.hint } : {} } });
|
|
7138
|
+
renderResult(opts.format, { success: false, error: { message: projectR.error.message, httpStatus: projectR.error.httpStatus, ...projectR.error.bizCode !== void 0 ? { bizCode: projectR.error.bizCode } : {}, ...projectR.error.hint ? { hint: projectR.error.hint } : {} } });
|
|
6943
7139
|
return;
|
|
6944
7140
|
}
|
|
6945
7141
|
const projectId = projectR.projectId;
|
|
@@ -6951,14 +7147,14 @@ function createInstallCommand() {
|
|
|
6951
7147
|
const plan = result.data;
|
|
6952
7148
|
renderInstallPlan2(opts.format, plan, scope, resolveInstallTargets(scope).targets);
|
|
6953
7149
|
});
|
|
6954
|
-
withCommonOpts(install.command("apply"), "json").option("--scope <s>", "install scope: global|project", "global").option("--project <key
|
|
7150
|
+
withCommonOpts(install.command("apply"), "json").option("--scope <s>", "install scope: global|project", "global").option("--project <key|id>", "project key or id (scope=project; falls back to workspace/instance default project)").option("--only <name>", 'install only this asset (repeatable; use "siming" for the MCP entry)', collectArgs, []).option("--yes", "skip interactive confirmation").option("--force", "overwrite all selected local assets, including same-version and conflict items").description("Apply install plan (write to local)").action(
|
|
6955
7151
|
async (opts) => {
|
|
6956
7152
|
const scope = parseScope(opts.scope, opts.format);
|
|
6957
7153
|
if (!scope) return;
|
|
6958
7154
|
const client = createClient(opts.url);
|
|
6959
7155
|
const projectR = await resolveInstallProject(client, scope, opts.project);
|
|
6960
7156
|
if (!projectR.ok) {
|
|
6961
|
-
renderResult(opts.format, { success: false, error: { message: projectR.error.message, httpStatus: 0, ...projectR.error.hint ? { hint: projectR.error.hint } : {} } });
|
|
7157
|
+
renderResult(opts.format, { success: false, error: { message: projectR.error.message, httpStatus: projectR.error.httpStatus, ...projectR.error.bizCode !== void 0 ? { bizCode: projectR.error.bizCode } : {}, ...projectR.error.hint ? { hint: projectR.error.hint } : {} } });
|
|
6962
7158
|
return;
|
|
6963
7159
|
}
|
|
6964
7160
|
const projectId = projectR.projectId;
|
|
@@ -7034,34 +7230,19 @@ function parseScope(s, format) {
|
|
|
7034
7230
|
}
|
|
7035
7231
|
async function resolveInstallProject(client, scope, projectOpt) {
|
|
7036
7232
|
if (scope === "global") return { ok: true };
|
|
7037
|
-
|
|
7038
|
-
|
|
7039
|
-
|
|
7040
|
-
|
|
7041
|
-
|
|
7042
|
-
|
|
7043
|
-
|
|
7044
|
-
|
|
7045
|
-
|
|
7046
|
-
|
|
7047
|
-
|
|
7048
|
-
if (r.success) return { ok: true, projectId: r.data };
|
|
7049
|
-
return { ok: false, error: { message: r.error.message, ...r.error.hint ? { hint: r.error.hint } : {} } };
|
|
7050
|
-
}
|
|
7051
|
-
return {
|
|
7052
|
-
ok: false,
|
|
7053
|
-
error: {
|
|
7054
|
-
message: "scope=project requires --project <key|id> or workspace default project",
|
|
7055
|
-
hint: "run `siming config set defaultProject <key|id>` or `siming install --scope project --project <key|id>`"
|
|
7056
|
-
}
|
|
7057
|
-
};
|
|
7058
|
-
}
|
|
7059
|
-
function readWorkspaceConfigSafe(ws) {
|
|
7060
|
-
try {
|
|
7061
|
-
return readWorkspaceConfig(ws);
|
|
7062
|
-
} catch {
|
|
7063
|
-
return null;
|
|
7233
|
+
const r = await resolveScopedProject(client, projectOpt, "instance-default", { commandLabel: "siming install" });
|
|
7234
|
+
if (!r.success) {
|
|
7235
|
+
return {
|
|
7236
|
+
ok: false,
|
|
7237
|
+
error: {
|
|
7238
|
+
message: r.error.message,
|
|
7239
|
+
httpStatus: r.error.httpStatus,
|
|
7240
|
+
...r.error.bizCode !== void 0 ? { bizCode: r.error.bizCode } : {},
|
|
7241
|
+
...r.error.hint ? { hint: r.error.hint } : {}
|
|
7242
|
+
}
|
|
7243
|
+
};
|
|
7064
7244
|
}
|
|
7245
|
+
return r.data.projectId !== void 0 ? { ok: true, projectId: r.data.projectId } : { ok: true };
|
|
7065
7246
|
}
|
|
7066
7247
|
async function buildInstallPlan(client, scope, projectId, only) {
|
|
7067
7248
|
const listQuery = scope === "global" ? { scope: "global", includeDisabled: true } : { scope: "project", ...projectId ? { projectId } : {}, includeDisabled: true };
|
|
@@ -7431,7 +7612,7 @@ async function runInit(client, input) {
|
|
|
7431
7612
|
};
|
|
7432
7613
|
}
|
|
7433
7614
|
function createInitCommand() {
|
|
7434
|
-
const init = new Command13("init").description("Initialize workspace config for Siming (idempotent)").option("--url <url>", "server base URL (also used to resolve project key)").option("--server-url <url>", "server base URL to persist into workspace config").option("--project <key
|
|
7615
|
+
const init = new Command13("init").description("Initialize workspace config for Siming (idempotent)").option("--url <url>", "server base URL (also used to resolve project key)").option("--server-url <url>", "server base URL to persist into workspace config").option("--project <key|id>", "project key or id to set as workspace default project").option("--install", "run install apply after init (non-interactive; writes to .agents universal dir)").option("--install-scope <scope>", "install scope when --install: global|project (default: global; global also registers mcp.json)").option("--format <fmt>", "output format", "fancy").action(async (opts) => {
|
|
7435
7616
|
const client = createClient(opts.url);
|
|
7436
7617
|
const result = await runInit(client, {
|
|
7437
7618
|
...opts.serverUrl ? { serverUrl: opts.serverUrl } : {},
|
|
@@ -7744,7 +7925,7 @@ ${ROADMAP_TEXT}
|
|
|
7744
7925
|
\u9879\u76EE\u6807\u8BC6\u3001\u5FEB\u901F\u901A\u9053\u89C4\u5219\uFF09\uFF0C\u6309\u6E05\u5355\u66FF\u6362\u4E3A\u9879\u76EE\u771F\u5B9E\u7EA6\u5B9A\u540E\u65B9\u53EF\u7528\u4E8E\u521B\u5EFA\u4EFB\u52A1\u3002
|
|
7745
7926
|
\u540C\u540D\u51B2\u7A81\u4FDD\u62A4\uFF1A\u9879\u76EE\u5185\u5DF2\u6709\u540C\u540D\u8D44\u4EA7\u65F6\u9ED8\u8BA4\u62D2\u7EDD\u4E14\u96F6\u5199\u5165\uFF1B
|
|
7746
7927
|
\u786E\u8BA4\u66FF\u6362\u52A0 --overwrite\uFF08\u7248\u672C\u5355\u8C03\u9012\u589E\uFF0C\u542F\u505C\u72B6\u6001\u4E0D\u53D8\uFF09\u3002
|
|
7747
|
-
\u67E5\u770B\u73B0\u5B58\u8D44\u4EA7\uFF1Asiming skill show task-create --scope project --project-id <id>
|
|
7928
|
+
\u67E5\u770B\u73B0\u5B58\u8D44\u4EA7\uFF1Asiming skill show task-create --scope project --project-id <key|id>
|
|
7748
7929
|
|
|
7749
7930
|
2. siming-arch \u2014\u2014 \u67B6\u6784\u6587\u6863\u7D22\u5F15\uFF1A\u6307\u5411\u672C\u9879\u76EE\u4ED3\u5E93\u67B6\u6784\u6587\u6863\u76EE\u5F55\u7684\u9AA8\u67B6
|
|
7750
7931
|
\uFF08\u6BCF\u9879\u76EE\u4E00\u4EFD\uFF1B\u67B6\u6784\u6587\u6863\u5B9E\u4F53\u5B58\u9879\u76EE\u4ED3\u5E93\uFF0C\u7D22\u5F15\u53EA\u5B58\u4F4D\u7F6E\u4E0D\u5B58\u5185\u5BB9\uFF09\u3002
|
|
@@ -8523,7 +8704,7 @@ function parseDeclarationsMap(spec) {
|
|
|
8523
8704
|
}
|
|
8524
8705
|
function createIssueCommand() {
|
|
8525
8706
|
const issue = new Command18("issue").description("Issue pool: record \u2192 organize \u2192 convert to tasks");
|
|
8526
|
-
withCommonOpts(issue.command("add"), "fancy").description("Record an issue into the pool (source=cli)").argument("[title]", "issue title (or use --title)").option("--title <t>", "issue title (1-200 chars)").option("--description <d>", "issue description (optional)").option("--project <key
|
|
8707
|
+
withCommonOpts(issue.command("add"), "fancy").description("Record an issue into the pool (source=cli)").argument("[title]", "issue title (or use --title)").option("--title <t>", "issue title (1-200 chars)").option("--description <d>", "issue description (optional)").option("--project <key|id>", "projectId (key|id; falls back to workspace defaultProject, then server default project)").action(async (titleArg, opts) => {
|
|
8527
8708
|
const client = createClient(opts.url);
|
|
8528
8709
|
const title = opts.title ?? titleArg;
|
|
8529
8710
|
if (title === void 0 || title.length === 0) {
|
|
@@ -8533,21 +8714,12 @@ function createIssueCommand() {
|
|
|
8533
8714
|
});
|
|
8534
8715
|
return;
|
|
8535
8716
|
}
|
|
8536
|
-
|
|
8537
|
-
if (
|
|
8538
|
-
|
|
8539
|
-
|
|
8540
|
-
renderResult("json", r);
|
|
8541
|
-
return;
|
|
8542
|
-
}
|
|
8543
|
-
projectId = r.data;
|
|
8544
|
-
} else {
|
|
8545
|
-
const wsDefaultProject = readWorkspaceConfig()?.defaultProject;
|
|
8546
|
-
if (wsDefaultProject) {
|
|
8547
|
-
const r = await resolveProjectId(client, wsDefaultProject);
|
|
8548
|
-
if (r.success) projectId = r.data;
|
|
8549
|
-
}
|
|
8717
|
+
const projectR = await resolveScopedProject(client, opts.project, "ws-default", { commandLabel: "siming issue add" });
|
|
8718
|
+
if (!projectR.success) {
|
|
8719
|
+
renderResult(opts.format ?? "fancy", projectR);
|
|
8720
|
+
return;
|
|
8550
8721
|
}
|
|
8722
|
+
const projectId = projectR.data.projectId;
|
|
8551
8723
|
const result = await handleCreateIssue(client, {
|
|
8552
8724
|
title,
|
|
8553
8725
|
...opts.description !== void 0 ? { description: opts.description } : {},
|
|
@@ -8555,7 +8727,7 @@ function createIssueCommand() {
|
|
|
8555
8727
|
});
|
|
8556
8728
|
renderResult(opts.format ?? "fancy", result);
|
|
8557
8729
|
});
|
|
8558
|
-
withCommonOpts(issue.command("list"), "table").option("--status <s>", "filter by issue status (pending|partial|converted|cancelled)").option("--source <s>", "filter by source channel (mcp|cli|web)").option("--project <key
|
|
8730
|
+
withCommonOpts(issue.command("list"), "table").option("--status <s>", "filter by issue status (pending|partial|converted|cancelled)").option("--source <s>", "filter by source channel (mcp|cli|web)").option("--project <key|id>", "filter by projectId (key|id)").option("--task <taskId>", "filter by linked task").option("--q <keyword>", "search in title/description").option("--view <v>", "view: all|open (default all; open = \u6709\u6548\u672A\u8DDF\u8FDB\u5B8C)").option("--page <n>", "page number (default 1)", "1").option("--limit <n>", `page size (default ${PAGE_DEFAULT2}, max ${PAGE_MAX2})`).option("--all", `show all (limit ${PAGE_MAX2})`).description("List issues (with progress aggregation done/cancelled/total)").action(async (opts) => {
|
|
8559
8731
|
const client = createClient(opts.url);
|
|
8560
8732
|
const filters = {};
|
|
8561
8733
|
if (opts.status) filters.status = opts.status;
|
|
@@ -8570,13 +8742,14 @@ function createIssueCommand() {
|
|
|
8570
8742
|
}
|
|
8571
8743
|
filters.view = r.data;
|
|
8572
8744
|
}
|
|
8573
|
-
if (opts.project) {
|
|
8574
|
-
const
|
|
8575
|
-
if (!
|
|
8576
|
-
renderResult(opts.format ?? "table",
|
|
8745
|
+
if (opts.project !== void 0 && opts.project.trim().length > 0) {
|
|
8746
|
+
const pr = await resolveScopedProject(client, opts.project, "explicit-only");
|
|
8747
|
+
if (!pr.success) {
|
|
8748
|
+
renderResult(opts.format ?? "table", pr);
|
|
8577
8749
|
return;
|
|
8578
8750
|
}
|
|
8579
|
-
|
|
8751
|
+
const pid = pr.data.projectId;
|
|
8752
|
+
if (pid !== void 0) filters.projectId = pid;
|
|
8580
8753
|
}
|
|
8581
8754
|
if (opts.all) {
|
|
8582
8755
|
filters.limit = PAGE_MAX2;
|
|
@@ -8656,7 +8829,7 @@ function createIssueCommand() {
|
|
|
8656
8829
|
const result = await handleCancelIssue(client, issueId, opts.reason);
|
|
8657
8830
|
renderResult(opts.format ?? "fancy", result);
|
|
8658
8831
|
});
|
|
8659
|
-
withCommonOpts(issue.command("convert"), "fancy").requiredOption("--issue-ids <ids>", "comma-separated issue ids (or repeatable flag)", collectArgs, []).option("--declaration <mode>", "uniform declaration for all issues: all|partial (default all)").option("--declarations <map>", "per-issue declarations: id1:all,id2:partial (overrides --declaration)").requiredOption("--title <t>", "new task title").requiredOption("--template <code|name|id>", "DAG template code (preferred), name, or 24-hex id").requiredOption("--track <t>", "task track (backend|ui|mixed|research)").option("--type <t>", "task type (feature|bugfix|ui-tweak|research)").option("--skip <ids>", "node ids to prune (comma-separated, repeatable)", collectArgs, []).option("--project <key
|
|
8832
|
+
withCommonOpts(issue.command("convert"), "fancy").requiredOption("--issue-ids <ids>", "comma-separated issue ids (or repeatable flag)", collectArgs, []).option("--declaration <mode>", "uniform declaration for all issues: all|partial (default all)").option("--declarations <map>", "per-issue declarations: id1:all,id2:partial (overrides --declaration)").requiredOption("--title <t>", "new task title").requiredOption("--template <code|name|id>", "DAG template code (preferred), name, or 24-hex id").requiredOption("--track <t>", "task track (backend|ui|mixed|research)").option("--type <t>", "task type (feature|bugfix|ui-tweak|research)").option("--skip <ids>", "node ids to prune (comma-separated, repeatable)", collectArgs, []).option("--project <key|id>", "projectId (key|id; issues and new task must belong to it)").description("Convert issues to a task (single group: N issues \u2192 1 task; split = multiple calls)").action(async (opts) => {
|
|
8660
8833
|
const client = createClient(opts.url);
|
|
8661
8834
|
const issueIds = [
|
|
8662
8835
|
...new Set((opts.issueIds ?? []).flatMap((s) => s.split(",")).map((s) => s.trim()).filter((s) => s.length > 0))
|
|
@@ -8687,13 +8860,13 @@ function createIssueCommand() {
|
|
|
8687
8860
|
declarations = Object.fromEntries(issueIds.map((id) => [id, "all"]));
|
|
8688
8861
|
}
|
|
8689
8862
|
let projectId;
|
|
8690
|
-
if (opts.project) {
|
|
8691
|
-
const
|
|
8692
|
-
if (!
|
|
8693
|
-
renderResult(opts.format ?? "fancy",
|
|
8863
|
+
if (opts.project !== void 0 && opts.project.trim().length > 0) {
|
|
8864
|
+
const pr = await resolveScopedProject(client, opts.project, "explicit-only");
|
|
8865
|
+
if (!pr.success) {
|
|
8866
|
+
renderResult(opts.format ?? "fancy", pr);
|
|
8694
8867
|
return;
|
|
8695
8868
|
}
|
|
8696
|
-
projectId =
|
|
8869
|
+
projectId = pr.data.projectId;
|
|
8697
8870
|
} else {
|
|
8698
8871
|
const first = await handleGetIssue(client, issueIds[0]);
|
|
8699
8872
|
if (!first.success) {
|