mancode 0.3.5 → 0.3.6
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/README.md +20 -19
- package/README.zh-CN.md +19 -18
- package/dist/cli.js +164 -99
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -308,8 +308,8 @@ var HEAD_COACH_AGENT = {
|
|
|
308
308
|
- \u5C06\u5173\u952E\u51B3\u7B56\u4EA4\u7ED9\u8C03\u7528\u65B9 appendTeamDecision\uFF0C\u5E76\u66F4\u65B0 Active Plans\u3002
|
|
309
309
|
- \u5408\u5E76 worktree \u524D\u53D6\u5F97\u7528\u6237\u786E\u8BA4\uFF1B\u6E05\u7406\u4E34\u65F6\u6587\u4EF6\u3002
|
|
310
310
|
|
|
311
|
-
**/
|
|
312
|
-
- \u5F53\u771F\u5B9E\u6D4F\u89C8\u5668\u9A8C\u8BC1\u3001\u590D\u6742\u590D\u73B0\u6216\u56DE\u5F52\u9700\u8981\u4E13\u95E8\u8BCA\u65AD\u65F6\uFF0C\u901A\u8FC7 \`mancode workflow create
|
|
311
|
+
**/manba \u4EA4\u63A5\u9636\u6BB5**\uFF1A
|
|
312
|
+
- \u5F53\u771F\u5B9E\u6D4F\u89C8\u5668\u9A8C\u8BC1\u3001\u590D\u6742\u590D\u73B0\u6216\u56DE\u5F52\u9700\u8981\u4E13\u95E8\u8BCA\u65AD\u65F6\uFF0C\u901A\u8FC7 \`mancode workflow create manba ... --parent-task <taskId>\` \u521B\u5EFA\u5B50 workflow\uFF1B\u6240\u6709 metadata \u53D8\u5316\u90FD\u8D70 workflow CLI\u3002
|
|
313
313
|
- \u5B50\u4EFB\u52A1 fixed/verified/no_repro \u540E\u56DE\u5230\u7236 /man Step 6\uFF1B\u82E5\u7236\u66FE\u56E0\u8BE5\u5B50\u4EFB\u52A1 blocked\uFF0C\u5148\u7528 workflow CLI \u6062\u590D\u4E3A in_progress\u3002blocked \u6216 manual_test_required \u65F6\u8BA9\u7236 workflow \u540C\u6B65 blocked\uFF0C\u540E\u8005\u4E0D\u5F97\u81EA\u52A8\u6062\u590D\u3002
|
|
314
314
|
|
|
315
315
|
\u4E3B\u89C1\u5F3A\uFF0C\u5FC5\u8981\u65F6\u624D\u95EE\u7528\u6237\u3002\u5F00\u5E72\u3002`
|
|
@@ -531,7 +531,8 @@ if (!state) {
|
|
|
531
531
|
process.exit(0);
|
|
532
532
|
}
|
|
533
533
|
|
|
534
|
-
const
|
|
534
|
+
const storedMode = text(state.currentMode) || 'solo';
|
|
535
|
+
const mode = storedMode === 'mamba' ? 'manba' : storedMode;
|
|
535
536
|
const techStack = sanitize(state.techStack);
|
|
536
537
|
const uiLibrary = sanitize(state.uiLibrary);
|
|
537
538
|
const output = [
|
|
@@ -848,7 +849,7 @@ var MAN_SKILL = {
|
|
|
848
849
|
|
|
849
850
|
### Step 6: \u81EA\u6D4B\u3001\u8BCA\u65AD\u4E0E\u56DE\u5F52
|
|
850
851
|
|
|
851
|
-
\u8FD0\u884C\u5B9E\u9645 build/lint/typecheck/test \u548C smoke test\u3002\u76F8\u540C\u4EE3\u7801\u3001\u73AF\u5883\u3001\u547D\u4EE4\u4E0B\u76F8\u540C\u9519\u8BEF\u7B7E\u540D\u5931\u8D25\u4E24\u6B21\uFF0C\u505C\u6B62\u76F2\u8BD5\u5E76\u8BCA\u65AD\u6839\u56E0\u3002\u9700\u8981\u771F\u5B9E\u6D4F\u89C8\u5668\u3001\u590D\u6742\u590D\u73B0\u6216\u56DE\u5F52\u65F6\uFF0C\u7528 \`mancode workflow create
|
|
852
|
+
\u8FD0\u884C\u5B9E\u9645 build/lint/typecheck/test \u548C smoke test\u3002\u76F8\u540C\u4EE3\u7801\u3001\u73AF\u5883\u3001\u547D\u4EE4\u4E0B\u76F8\u540C\u9519\u8BEF\u7B7E\u540D\u5931\u8D25\u4E24\u6B21\uFF0C\u505C\u6B62\u76F2\u8BD5\u5E76\u8BCA\u65AD\u6839\u56E0\u3002\u9700\u8981\u771F\u5B9E\u6D4F\u89C8\u5668\u3001\u590D\u6742\u590D\u73B0\u6216\u56DE\u5F52\u65F6\uFF0C\u7528 \`mancode workflow create manba "<\u95EE\u9898>" --parent-task <taskId> --json\` \u521B\u5EFA\u5B50 workflow\uFF1B\u7236\u4EFB\u52A1\u4FDD\u6301 Step 6\u3002\u5B50\u4EFB\u52A1 fixed/verified/no_repro \u540E\u6062\u590D\u672C\u4EFB\u52A1\uFF1B\u82E5\u7236\u66FE\u56E0\u8BE5\u5B50\u4EFB\u52A1 blocked\uFF0C\u5148\u901A\u8FC7 \`workflow update --status in_progress\` \u6062\u590D\uFF0C\u518D\u66F4\u65B0\u81F3 Step 7\u3002blocked \u6216 manual_test_required \u4F1A\u7531 CLI \u81EA\u52A8\u963B\u585E\u7236\u4EFB\u52A1\uFF0C\u4E0D\u5F97\u624B\u6539\u7236 metadata\uFF0C\u4E5F\u4E0D\u5F97\u81EA\u52A8\u8D8A\u8FC7\u4EBA\u5DE5\u9A8C\u8BC1\u8981\u6C42\u3002
|
|
852
853
|
|
|
853
854
|
\u9A8C\u8BC1\u540E\u57FA\u4E8E**\u5B9E\u9645 diff**\u5199 \`review-scope.md\`\uFF1Abase\u3001\u6539\u52A8\u6587\u4EF6\u3001\u9700\u6C42\u3001\u5DF2\u8DD1\u9A8C\u8BC1\u3001\u786C\u98CE\u9669\u548C\u5BA1\u67E5\u6DF1\u5EA6\u3002\u9274\u6743\u3001\u652F\u4ED8\u3001\u654F\u611F\u6570\u636E\u3001\u8FC1\u79FB/\u5220\u9664\u3001\u516C\u5F00 API\u3001\u672A\u53EF\u4FE1\u8F93\u5165\u3001\u5E76\u53D1\u3001\u8DE8\u670D\u52A1\u6216\u57FA\u7840\u8BBE\u65BD\u547D\u4E2D\u4EFB\u4E00\u9879\u65F6\u7528\u5B8C\u6574\u5BA1\u67E5 \`full\`\uFF1B\u5426\u5219\u7528\u5B9A\u5411\u5BA1\u67E5 \`targeted\`\u3002\u8FD0\u884C \`mancode workflow review <taskId> init --review-depth targeted --review-domain quality\` \u6216 \`--review-depth full\`\u3002\u7528\u6237\u660E\u786E\u8DF3\u8FC7\u5BA1\u67E5\u65F6\u624D\u628A \`review\` \u5199\u5165\u7D2F\u8BA1 skippedSteps\uFF0C\u5E76\u8BB0\u5F55\u6B8B\u4F59\u98CE\u9669\u3002
|
|
854
855
|
|
|
@@ -877,15 +878,15 @@ ${CORE_CODING_PRINCIPLES}
|
|
|
877
878
|
|
|
878
879
|
// src/templates/skills/mamba.ts
|
|
879
880
|
var MAMBA_SKILL = {
|
|
880
|
-
name: "
|
|
881
|
+
name: "manba",
|
|
881
882
|
description: "Diagnose bugs and validate real user flows. Reproduce, find the root cause, run targeted regression checks, and use browser automation when the platform supports it.",
|
|
882
|
-
body: `# mancode \xB7 /
|
|
883
|
+
body: `# mancode \xB7 /manba (Diagnosis & Real Validation)
|
|
883
884
|
|
|
884
|
-
\u7528\u6237\u7528 \`/
|
|
885
|
+
\u7528\u6237\u7528 \`/manba <\u95EE\u9898\u6216\u6A21\u5757>\` \u89E6\u53D1\u4F60\u3002\u76EE\u6807\u662F\u7528\u8BC1\u636E\u56DE\u7B54\uFF1A\u80FD\u5426\u590D\u73B0\u3001\u6839\u56E0\u5728\u54EA\u91CC\u3001\u4FEE\u590D\u662F\u5426\u6709\u6548\u3001\u5173\u952E\u8DEF\u5F84\u662F\u5426\u56DE\u5F52\u3002\u5BF9\u5916\u6A21\u5F0F\u540D\u662F manba\uFF1B\u6301\u4E45\u5316 workflow/state \u4E3A\u517C\u5BB9\u5386\u53F2\u6570\u636E\u7EE7\u7EED\u4F7F\u7528\u5185\u90E8\u503C mamba\u3002
|
|
885
886
|
|
|
886
887
|
## 1. \u5EFA\u7ACB\u4EFB\u52A1
|
|
887
888
|
|
|
888
|
-
\u5148\u8BFB state\u3002\u82E5 \`currentTask\` \u6307\u5411 unrelated active workflow\uFF0C\u505C\u6B62\u5E76\u8BA9\u7528\u6237\u9009\u62E9\u6062\u590D\u8BE5\u6D41\u7A0B\u6216\u5148\u7528 /mansolo \u653E\u5F03\uFF1B\u4E0D\u5F97\u8986\u76D6\u65E7\u6307\u9488\u3002\u72EC\u7ACB\u4EFB\u52A1\u8FD0\u884C \`mancode workflow create
|
|
889
|
+
\u5148\u8BFB state\u3002\u82E5 \`currentTask\` \u6307\u5411 unrelated active workflow\uFF0C\u505C\u6B62\u5E76\u8BA9\u7528\u6237\u9009\u62E9\u6062\u590D\u8BE5\u6D41\u7A0B\u6216\u5148\u7528 /mansolo \u653E\u5F03\uFF1B\u4E0D\u5F97\u8986\u76D6\u65E7\u6307\u9488\u3002\u72EC\u7ACB\u4EFB\u52A1\u8FD0\u884C \`mancode workflow create manba "<\u95EE\u9898\u6216\u6A21\u5757>" --json\`\uFF1B\u7531 /man \u6216 /manteam Step 6 \u8F6C\u5165\u65F6\u8FD0\u884C \`mancode workflow create manba "<\u95EE\u9898\u6216\u6A21\u5757>" --parent-task <\u7236taskId> --json\`\u3002\u8BFB\u53D6\u8FD4\u56DE taskId \u540E\uFF0C\u5C06 state \u7684 currentMode/currentTask/currentWorkflowMode \u6307\u5411\u5185\u90E8\u517C\u5BB9\u503C mamba\u3002\u4E0D\u5F97\u76F4\u63A5\u521B\u5EFA\u6216\u6539\u5199 metadata.json\u3002
|
|
889
890
|
|
|
890
891
|
\u8BB0\u5F55\u73B0\u8C61\u3001\u73AF\u5883\u3001\u590D\u73B0\u6761\u4EF6\u3001\u9884\u671F\u4E0E\u5B9E\u9645\u7ED3\u679C\u3001\u4E0D\u53EF\u89E6\u78B0\u7684\u6570\u636E\u3002\u5148\u68C0\u67E5\u5DF2\u6709\u6D4B\u8BD5\u3001\u8DEF\u7531\u3001\u6A21\u5757\u5165\u53E3\u548C README\uFF1B\u4ECD\u65E0\u6CD5\u786E\u5B9A\u6700\u5C0F\u8DEF\u5F84\u65F6\u53EA\u95EE\u5173\u952E\u8DEF\u5F84\u95EE\u9898\u3002\u5B8C\u6210\u540E\u7528 CLI \u66F4\u65B0\u81F3 Step 2\u3002
|
|
891
892
|
|
|
@@ -900,7 +901,7 @@ var MAMBA_SKILL = {
|
|
|
900
901
|
|
|
901
902
|
\u4EC5\u5F53 profile \u786E\u8BA4 Web UI \u4E14\u6D4F\u89C8\u5668\u80FD\u529B\u53EF\u7528\u65F6\uFF0C\u68C0\u67E5 \`npx\` \u5E76\u4F7F\u7528\u9879\u76EE\u7684 Playwright CLI wrapper\u3002\u5176\u4ED6\u9879\u76EE\u7C7B\u578B\u4F7F\u7528\u5DF2\u68C0\u6D4B\u5230\u7684 API\u3001\u6A21\u62DF\u5668\u3001\u8BBE\u5907\u3001\u547D\u4EE4\u6216\u5951\u7EA6\u9A8C\u8BC1\u65B9\u5F0F\u3002\u6D4F\u89C8\u5668\u9A8C\u8BC1\u65F6\u5148 snapshot \u518D\u4F7F\u7528\u5143\u7D20\u5F15\u7528\uFF1B\u5BFC\u822A\u3001\u5F39\u7A97\u6216 UI \u5927\u53D8\u5316\u540E\u91CD\u65B0 snapshot\u3002\u622A\u56FE\u3001trace \u548C\u6D4F\u89C8\u5668\u65E5\u5FD7\u5199\u5165 \`.mancode/workflows/<taskId>/artifacts/playwright/\`\uFF0C\u62A5\u544A\u53EA\u5199\u76F8\u5BF9\u8DEF\u5F84\uFF0C\u5E76\u8131\u654F Token\u3001Cookie\u3001\u4E2A\u4EBA\u6216\u4E1A\u52A1\u654F\u611F\u6570\u636E\u3002
|
|
902
903
|
|
|
903
|
-
\u73AF\u5883\u5C31\u7EEA\u540E\u7528 CLI \u66F4\u65B0\u81F3 Step 3\uFF1B\u7F3A\u5C11\u73AF\u5883\u3001\u6743\u9650\u6216\u6570\u636E\u5219\u76F4\u63A5\u5199 blocked + blockingReason\uFF0C\u5E76\u4FDD\u7559 state \u6307\u5411\u5F53\u524D
|
|
904
|
+
\u73AF\u5883\u5C31\u7EEA\u540E\u7528 CLI \u66F4\u65B0\u81F3 Step 3\uFF1B\u7F3A\u5C11\u73AF\u5883\u3001\u6743\u9650\u6216\u6570\u636E\u5219\u76F4\u63A5\u5199 blocked + blockingReason\uFF0C\u5E76\u4FDD\u7559 state \u6307\u5411\u5F53\u524D manba \u4EE5\u4FBF\u6062\u590D\u3002
|
|
904
905
|
|
|
905
906
|
## 3. \u590D\u73B0\u4E0E\u8BCA\u65AD
|
|
906
907
|
|
|
@@ -920,7 +921,7 @@ var MAMBA_SKILL = {
|
|
|
920
921
|
- \u7F3A\u5C11\u73AF\u5883\u3001\u6743\u9650\u6216\u6570\u636E\uFF0C\u6216\u4FEE\u590D\u4ECD\u5931\u8D25\uFF1A\`status: "blocked"\` + \`blockingReason\`
|
|
921
922
|
- \u53D7\u9650\u5E73\u53F0\u53EA\u80FD\u751F\u6210\u624B\u6D4B\u65B9\u6848\uFF1A\`status: "completed", outcome: "manual_test_required"\`\uFF1B\u5FC5\u987B\u660E\u786E\u6CA1\u6709\u6267\u884C\u771F\u5B9E\u6D4B\u8BD5
|
|
922
923
|
|
|
923
|
-
\u7528 \`mancode workflow update <taskId> --status <status> [--outcome <outcome>] [--blocking-reason <\u539F\u56E0>]\` \u5199\u7ED3\u8BBA\u3002\u7236\u5B50\u4EFB\u52A1\u7684 blocked/manual_test_required \u4F20\u64AD\u7531 CLI \u8D1F\u8D23\u3002\u5173\u8054\u5B50\u4EFB\u52A1\u4EE5 fixed/verified/no_repro \u5B8C\u6210\u540E\uFF0C\u5148\u8BFB\u53D6\u7236 workflow\uFF1B\u82E5\u7236\u4ECD\u56E0\u672C\u5B50\u4EFB\u52A1 blocked\uFF0C\u8FD0\u884C \`mancode workflow update <parentTaskId> --status in_progress\` \u6E05\u9664\u963B\u585E\uFF0C\u518D\u628A state \u6062\u590D\u5230\u7236 workflow \u7684 Step 6\u3002manual_test_required \u4E0D\u5F97\u81EA\u52A8\u6062\u590D\u7236\u4EFB\u52A1\u3002\u72EC\u7ACB\u4EFB\u52A1\u5B8C\u6210\u540E\u56DE solo\uFF1Bblocked \u7684\u72EC\u7ACB\u4EFB\u52A1\u7EE7\u7EED\u4FDD\u6301
|
|
924
|
+
\u7528 \`mancode workflow update <taskId> --status <status> [--outcome <outcome>] [--blocking-reason <\u539F\u56E0>]\` \u5199\u7ED3\u8BBA\u3002\u7236\u5B50\u4EFB\u52A1\u7684 blocked/manual_test_required \u4F20\u64AD\u7531 CLI \u8D1F\u8D23\u3002\u5173\u8054\u5B50\u4EFB\u52A1\u4EE5 fixed/verified/no_repro \u5B8C\u6210\u540E\uFF0C\u5148\u8BFB\u53D6\u7236 workflow\uFF1B\u82E5\u7236\u4ECD\u56E0\u672C\u5B50\u4EFB\u52A1 blocked\uFF0C\u8FD0\u884C \`mancode workflow update <parentTaskId> --status in_progress\` \u6E05\u9664\u963B\u585E\uFF0C\u518D\u628A state \u6062\u590D\u5230\u7236 workflow \u7684 Step 6\u3002manual_test_required \u4E0D\u5F97\u81EA\u52A8\u6062\u590D\u7236\u4EFB\u52A1\u3002\u72EC\u7ACB\u4EFB\u52A1\u5B8C\u6210\u540E\u56DE solo\uFF1Bblocked \u7684\u72EC\u7ACB\u4EFB\u52A1\u7EE7\u7EED\u4FDD\u6301 manba \u6A21\u5F0F\uFF08state \u5185\u90E8\u503C\u4E3A mamba\uFF09\u3002\u4EFB\u4F55\u60C5\u51B5\u4E0B\u90FD\u4E0D\u5F97\u76F4\u63A5\u7F16\u8F91 metadata \u7ED5\u8FC7 CLI\u3002
|
|
924
925
|
|
|
925
926
|
${CORE_CODING_PRINCIPLES}
|
|
926
927
|
`
|
|
@@ -1121,8 +1122,8 @@ var MANSOLO_SKILL = {
|
|
|
1121
1122
|
|
|
1122
1123
|
- **\u6CA1\u6709 .mancode/state.json**\uFF1A\u544A\u8BC9\u7528\u6237\uFF1A"\u9879\u76EE\u672A\u521D\u59CB\u5316\uFF0C\u8FD0\u884C \`mancode init\`\u3002"
|
|
1123
1124
|
- **state.json \u5DF2\u662F solo**\uFF1A\u4ECD\u6B63\u5E38\u6267\u884C\uFF0C\u544A\u77E5\u7528\u6237\u5F53\u524D\u5DF2\u662F solo\u3002
|
|
1124
|
-
- **\u5F53\u524D task \u5DF2\u662F completed/abandoned**\uFF1A\u4E0D\u8981\u5C1D\u8BD5\u628A\u7EC8\u6001\u6539\u6210 abandoned\uFF1B\u76F4\u63A5\u6E05\u7406 state\u3002\u82E5\u5B83\u662F\u5173\u8054
|
|
1125
|
-
- **\u5F53\u524D\u5728 active /man /
|
|
1125
|
+
- **\u5F53\u524D task \u5DF2\u662F completed/abandoned**\uFF1A\u4E0D\u8981\u5C1D\u8BD5\u628A\u7EC8\u6001\u6539\u6210 abandoned\uFF1B\u76F4\u63A5\u6E05\u7406 state\u3002\u82E5\u5B83\u662F\u5173\u8054 manba \u4E14\u7236\u4EFB\u52A1\u4ECD active\uFF0C\u5148\u5C55\u793A\u7236\u4EFB\u52A1\u5E76\u6309\u4E0B\u4E00\u6761\u786E\u8BA4\u662F\u5426\u4E00\u5E76\u653E\u5F03\u3002
|
|
1126
|
+
- **\u5F53\u524D\u5728 active /man /manba /manteam \u6D41\u7A0B\u4E2D**\uFF1A\u7528 AskUserQuestion \u95EE\u7528\u6237\uFF1A
|
|
1126
1127
|
\`\`\`
|
|
1127
1128
|
AskUserQuestion({
|
|
1128
1129
|
questions: [{
|
|
@@ -1138,7 +1139,7 @@ var MANSOLO_SKILL = {
|
|
|
1138
1139
|
\`\`\`
|
|
1139
1140
|
\u7528\u6237\u786E\u8BA4\u540E\uFF1A
|
|
1140
1141
|
- \u5148\u7528 \`mancode workflow show <taskId> --json\` \u68C0\u67E5\u7236\u5B50\u5173\u7CFB\u548C activeChildren\u3002
|
|
1141
|
-
- \u82E5\u5B58\u5728\u6D3B\u8DC3\u5B50\u4EFB\u52A1\u6216\u5F53\u524D\u662F\u5E26 parentTaskId \u7684
|
|
1142
|
+
- \u82E5\u5B58\u5728\u6D3B\u8DC3\u5B50\u4EFB\u52A1\u6216\u5F53\u524D\u662F\u5E26 parentTaskId \u7684 manba\uFF0C\u660E\u786E\u8BF4\u660E\u5C06\u653E\u5F03\u7684 workflow \u94FE\uFF1B\u5148\u9010\u4E2A\u7528 CLI \u6807\u8BB0\u5B50\u4EFB\u52A1 abandoned\uFF0C\u518D\u6807\u8BB0\u7236/\u5F53\u524D\u4EFB\u52A1 abandoned\u3002
|
|
1142
1143
|
- \u6240\u6709 metadata \u72B6\u6001\u90FD\u5FC5\u987B\u901A\u8FC7 \`mancode workflow update <taskId> --status abandoned\` \u66F4\u65B0\uFF1BCLI \u62D2\u7EDD\u65F6\u505C\u6B62\uFF0C\u4E0D\u5F97\u76F4\u63A5 Edit \u7ED5\u8FC7\u3002
|
|
1143
1144
|
- \u6210\u529F\u540E\u518D\u66F4\u65B0 state.json \u5207\u56DE solo\uFF1BCLI \u4F1A\u540C\u6B65\u6E05\u7406 Active Plans\u3002
|
|
1144
1145
|
|
|
@@ -1193,12 +1194,12 @@ var MANTEAM_SKILL = {
|
|
|
1193
1194
|
3. Game Plan\uFF1A\u8BA1\u5212\u91CC\u5FC5\u987B\u5305\u542B\u53D8\u66F4\u8FB9\u754C\u3001\u517C\u5BB9\u6027\u98CE\u9669\u3001\u56DE\u6EDA\u65B9\u5F0F\uFF1BPlan Coach \u53EA\u8FD4\u56DE\u8BA1\u5212\u6587\u672C\uFF0C\u7981\u6B62\u63D0\u524D\u4FEE\u6539\u4E1A\u52A1\u6587\u4EF6\u6216\u56E2\u961F memory\u3002
|
|
1194
1195
|
4. \u8BA1\u5212\u5173\u5361\uFF1A\u7528\u6237\u53EF\u53EA\u4FDD\u7559\u8BA1\u5212\u3001\u7EE7\u7EED\u6267\u884C\u6216\u91CD\u5199\u8BA1\u5212\uFF1BActive Plans \u6309 taskId \u66F4\u65B0\u3002
|
|
1195
1196
|
5. \u5B9E\u65BD\uFF1A\u6539\u52A8\u524D\u518D\u6B21\u68C0\u67E5 \`git status --short\`\uFF0C\u907F\u514D\u8E29\u7528\u6237\u6216\u961F\u53CB\u6539\u52A8\u3002
|
|
1196
|
-
6. Self-test\uFF1A\u4F18\u5148\u8DD1\u9879\u76EE\u5DF2\u6709\u9A8C\u8BC1\u547D\u4EE4\uFF1B\u5931\u8D25\u4E24\u6B21\u505C\u4E0B\u8BCA\u65AD\u6839\u56E0\u3002\u9700\u8981\u771F\u5B9E\u9A8C\u8BC1\u65F6\u521B\u5EFA\u5E26 parentTaskId \u7684 /
|
|
1197
|
+
6. Self-test\uFF1A\u4F18\u5148\u8DD1\u9879\u76EE\u5DF2\u6709\u9A8C\u8BC1\u547D\u4EE4\uFF1B\u5931\u8D25\u4E24\u6B21\u505C\u4E0B\u8BCA\u65AD\u6839\u56E0\u3002\u9700\u8981\u771F\u5B9E\u9A8C\u8BC1\u65F6\u521B\u5EFA\u5E26 parentTaskId \u7684 /manba \u5B50\u4EFB\u52A1\u3002\u5B50\u4EFB\u52A1\u4FEE\u590D\u540E\u82E5\u7236\u4EFB\u52A1\u66FE\u56E0\u6B64 blocked\uFF0C\u5148\u7528 workflow CLI \u6062\u590D\u7236\u4EFB\u52A1\u4E3A in_progress\uFF1Bmanual_test_required \u4E0D\u5F97\u81EA\u52A8\u6062\u590D\u3002
|
|
1197
1198
|
7. Review scope + Film #1\uFF1A\u57FA\u4E8E\u5B9E\u9645 diff \u5199 \`review-scope.md\`\uFF0C\u7528 \`workflow review ... init\` \u9009\u62E9 targeted \u6216 full\uFF1B\u91CD\u70B9\u5BA1\u67E5\u884C\u4E3A\u3001\u53EF\u7EF4\u62A4\u6027\u3001\u56E2\u961F\u98CE\u683C\u4E0E\u6D4B\u8BD5\uFF0Cfinding \u5FC5\u987B\u6709\u8BC1\u636E\u548C\u7A33\u5B9A ID\u3002
|
|
1198
1199
|
8. Film #2\uFF1A\u4EC5 full \u6267\u884C\uFF0C\u5148\u8BFB Film #1 \u62A5\u544A\u5E76\u53BB\u91CD\uFF0C\u53EA\u5BA1\u67E5\u8FB9\u754C\u3001\u5B89\u5168\u3001\u6027\u80FD\u3001\u5E76\u53D1\u548C\u517C\u5BB9\u6027\u3002\u7528\u6237\u660E\u786E\u8981\u6C42\u624D\u53EF\u8DF3\u8FC7\u5168\u90E8 review\uFF0C\u5E76\u5199\u5165 \`skippedSteps\` \u548C\u6B8B\u4F59\u98CE\u9669\u3002
|
|
1199
1200
|
9. Post-game\uFF1A\u6C47\u603B blocker\uFF0C\u53EA\u505A\u4E00\u8F6E\u4FEE\u590D\u5E76\u7528 \`workflow review ... remediate\` \u8BB0\u5F55\uFF1B\u590D\u9A8C\u540E\u5199 summary \u4E0E hand-off\u3002\u9A8C\u8BC1\u5931\u8D25\u3001\u5BA1\u67E5\u4E0D\u5B8C\u6574\u6216\u4ECD\u6709 blocker \u65F6\u6807\u8BB0 blocked\uFF0C\u4E0D\u5F97\u6807 completed\u3002
|
|
1200
1201
|
|
|
1201
|
-
\u5982\u679C\u7528\u6237\u5728\u786E\u8BA4\u9636\u6BB5\u9009\u62E9"\u9000\u51FA"\u6216\u653E\u5F03\u56E2\u961F workflow\uFF1A\u7528 \`mancode workflow update <taskId> --status abandoned\` \u66F4\u65B0\u5E76\u6E05\u7406 Active Plans\uFF1B\u82E5\u6709\u6D3B\u8DC3
|
|
1202
|
+
\u5982\u679C\u7528\u6237\u5728\u786E\u8BA4\u9636\u6BB5\u9009\u62E9"\u9000\u51FA"\u6216\u653E\u5F03\u56E2\u961F workflow\uFF1A\u7528 \`mancode workflow update <taskId> --status abandoned\` \u66F4\u65B0\u5E76\u6E05\u7406 Active Plans\uFF1B\u82E5\u6709\u6D3B\u8DC3 manba \u5B50\u4EFB\u52A1\uFF0C\u5148\u53D6\u5F97\u786E\u8BA4\u5E76\u9010\u4E2A abandoned\u3002\u6210\u529F\u540E\u518D\u7528 Edit \u66F4\u65B0 state \u56DE solo\u3002\u4E0D\u8981\u76F4\u63A5\u6539 metadata\uFF0C\u4E5F\u4E0D\u8981\u628A abandoned workflow \u7559\u5728 active state\u3002
|
|
1202
1203
|
|
|
1203
1204
|
## Team Hand-off Summary
|
|
1204
1205
|
|
|
@@ -1493,6 +1494,7 @@ var LEGACY_CLAUDE_SKILL_SETTINGS = {
|
|
|
1493
1494
|
man: ".claude/skills/mancode-man.md",
|
|
1494
1495
|
mansolo: ".claude/skills/mancode-mansolo.md"
|
|
1495
1496
|
};
|
|
1497
|
+
var LEGACY_MVP2_SKILL_NAMES = ["mamba", "man8"];
|
|
1496
1498
|
async function validateClaudeCodeSettings(projectRoot) {
|
|
1497
1499
|
await readClaudeSettings(path3.join(projectRoot, ".claude"));
|
|
1498
1500
|
}
|
|
@@ -1500,6 +1502,7 @@ async function installClaudeCode(projectRoot, options) {
|
|
|
1500
1502
|
const claudeDir = path3.join(projectRoot, ".claude");
|
|
1501
1503
|
const settings = await readClaudeSettings(claudeDir);
|
|
1502
1504
|
const force = options.force ?? false;
|
|
1505
|
+
await validateClaudeWriteTargets(claudeDir, options.minimal ?? false, force);
|
|
1503
1506
|
await installMancodeCore(projectRoot);
|
|
1504
1507
|
await mkdir3(path3.join(claudeDir, "skills"), { recursive: true });
|
|
1505
1508
|
await installSoloSkill(path3.join(claudeDir, "skills"), force);
|
|
@@ -1516,6 +1519,33 @@ async function installClaudeCode(projectRoot, options) {
|
|
|
1516
1519
|
await updateClaudeSettings(claudeDir, settings);
|
|
1517
1520
|
await removeLegacyHookFiles(projectRoot);
|
|
1518
1521
|
}
|
|
1522
|
+
async function validateClaudeWriteTargets(claudeDir, minimal, force) {
|
|
1523
|
+
if (!force) return;
|
|
1524
|
+
const skillsDir = path3.join(claudeDir, "skills");
|
|
1525
|
+
await assertWritableClaudeSkill(skillsDir, "solo");
|
|
1526
|
+
if (minimal) return;
|
|
1527
|
+
for (const skill of MVP2_SKILLS) {
|
|
1528
|
+
await assertWritableClaudeSkill(skillsDir, skill.name);
|
|
1529
|
+
}
|
|
1530
|
+
for (const agent of ALL_AGENTS) {
|
|
1531
|
+
const agentPath = path3.join(claudeDir, "agents", `${agent.name}.md`);
|
|
1532
|
+
const existing = await readTextIfExists2(agentPath);
|
|
1533
|
+
if (existing !== null && !isGeneratedClaudeAgent(existing, agent.name)) {
|
|
1534
|
+
throw new Error(
|
|
1535
|
+
`refusing to overwrite user-authored Claude Code agent: ${agentPath}`
|
|
1536
|
+
);
|
|
1537
|
+
}
|
|
1538
|
+
}
|
|
1539
|
+
}
|
|
1540
|
+
async function assertWritableClaudeSkill(skillsDir, modeName) {
|
|
1541
|
+
const skillPath = path3.join(skillsDir, modeName, "SKILL.md");
|
|
1542
|
+
const existing = await readTextIfExists2(skillPath);
|
|
1543
|
+
if (existing !== null && !isGeneratedClaudeSkill(existing, modeName)) {
|
|
1544
|
+
throw new Error(
|
|
1545
|
+
`refusing to overwrite user-authored Claude Code skill: ${skillPath}`
|
|
1546
|
+
);
|
|
1547
|
+
}
|
|
1548
|
+
}
|
|
1519
1549
|
async function removeLegacyHookFiles(projectRoot) {
|
|
1520
1550
|
const hooksDir = path3.join(projectRoot, ".mancode", "hooks");
|
|
1521
1551
|
await Promise.all([
|
|
@@ -1536,20 +1566,24 @@ async function installSoloSkill(skillsDir, force) {
|
|
|
1536
1566
|
await removeLegacyFlatSkill(skillsDir, "mancode-solo", "solo");
|
|
1537
1567
|
}
|
|
1538
1568
|
async function installMvp2Skills(skillsDir, force) {
|
|
1539
|
-
await removeManagedLegacyMan8Skill(skillsDir);
|
|
1540
1569
|
for (const skill of MVP2_SKILLS) {
|
|
1541
1570
|
await installProjectSkill(skillsDir, skill, force);
|
|
1542
1571
|
await removeLegacyFlatSkill(skillsDir, `mancode-${skill.name}`, skill.name);
|
|
1543
1572
|
}
|
|
1573
|
+
await removeManagedLegacyMvp2Skills(skillsDir);
|
|
1544
1574
|
}
|
|
1545
|
-
async function
|
|
1546
|
-
|
|
1575
|
+
async function removeManagedLegacyMvp2Skills(skillsDir) {
|
|
1576
|
+
for (const modeName of LEGACY_MVP2_SKILL_NAMES) {
|
|
1577
|
+
await removeGeneratedSkillDir(skillsDir, modeName);
|
|
1578
|
+
await removeLegacyFlatSkill(skillsDir, `mancode-${modeName}`, modeName);
|
|
1579
|
+
}
|
|
1547
1580
|
}
|
|
1548
1581
|
async function uninstallMvp2Skills(skillsDir) {
|
|
1549
1582
|
for (const skill of MVP2_SKILLS) {
|
|
1550
1583
|
await removeGeneratedSkillDir(skillsDir, skill.name);
|
|
1551
1584
|
await removeLegacyFlatSkill(skillsDir, `mancode-${skill.name}`, skill.name);
|
|
1552
1585
|
}
|
|
1586
|
+
await removeManagedLegacyMvp2Skills(skillsDir);
|
|
1553
1587
|
}
|
|
1554
1588
|
async function installProjectSkill(skillsDir, skill, force = true) {
|
|
1555
1589
|
const skillDir = path3.join(skillsDir, skill.name);
|
|
@@ -1615,7 +1649,7 @@ async function removeClaudeGeneratedContent(projectRoot) {
|
|
|
1615
1649
|
const skillsDir = path3.join(claudeDir, "skills");
|
|
1616
1650
|
for (const modeName of [
|
|
1617
1651
|
"solo",
|
|
1618
|
-
|
|
1652
|
+
...LEGACY_MVP2_SKILL_NAMES,
|
|
1619
1653
|
...MVP2_SKILLS.map((skill) => skill.name)
|
|
1620
1654
|
]) {
|
|
1621
1655
|
await removeGeneratedSkillDir(skillsDir, modeName);
|
|
@@ -1650,8 +1684,9 @@ ${marker}
|
|
|
1650
1684
|
async function readTextIfExists2(filePath) {
|
|
1651
1685
|
try {
|
|
1652
1686
|
return await readFile3(filePath, "utf-8");
|
|
1653
|
-
} catch {
|
|
1654
|
-
return null;
|
|
1687
|
+
} catch (error) {
|
|
1688
|
+
if (isNodeError2(error) && error.code === "ENOENT") return null;
|
|
1689
|
+
throw error;
|
|
1655
1690
|
}
|
|
1656
1691
|
}
|
|
1657
1692
|
async function removeIfEmpty(dir) {
|
|
@@ -1783,13 +1818,13 @@ import path6 from "path";
|
|
|
1783
1818
|
import { mkdir as mkdir4, readFile as readFile4, readdir as readdir2, rm as rm2, writeFile as writeFile4 } from "fs/promises";
|
|
1784
1819
|
import path4 from "path";
|
|
1785
1820
|
var MODE_NAMES = [
|
|
1786
|
-
"
|
|
1821
|
+
"manba",
|
|
1787
1822
|
"man",
|
|
1788
1823
|
"manteam",
|
|
1789
1824
|
"manps",
|
|
1790
1825
|
"mansolo"
|
|
1791
1826
|
];
|
|
1792
|
-
var LEGACY_MODE_NAMES = ["man8"];
|
|
1827
|
+
var LEGACY_MODE_NAMES = ["mamba", "man8"];
|
|
1793
1828
|
var CODEX_SKILL_MANAGED_MARKER = "<!-- Managed by mancode:codex-skill. Do not edit this file manually. -->";
|
|
1794
1829
|
var ZCODE_SKILL_MANAGED_MARKER = "<!-- Managed by mancode:zcode-skill. Do not edit this file manually. -->";
|
|
1795
1830
|
var MODE_FILE_MANAGED_MARKER = "<!-- Managed by mancode:mode-file. Do not edit this file manually. -->";
|
|
@@ -1799,7 +1834,7 @@ var MANCODE_AGENT_SKILL_MARKERS = [
|
|
|
1799
1834
|
];
|
|
1800
1835
|
function renderModeSkill(mode, commandPrefix = "$") {
|
|
1801
1836
|
const meta = MODE_META[mode];
|
|
1802
|
-
const stateMode = mode === "mansolo" ? "solo" : mode;
|
|
1837
|
+
const stateMode = mode === "mansolo" ? "solo" : mode === "manba" ? "mamba" : mode;
|
|
1803
1838
|
const modesList = MODE_NAMES.map((m) => `${commandPrefix}${m}`).join(", ");
|
|
1804
1839
|
return [
|
|
1805
1840
|
meta.intro,
|
|
@@ -1840,7 +1875,6 @@ async function installCodexSkills(projectRoot, minimal) {
|
|
|
1840
1875
|
return;
|
|
1841
1876
|
}
|
|
1842
1877
|
const skillsDir = path4.join(projectRoot, ".agents", "skills");
|
|
1843
|
-
await removeLegacyManagedSkills(skillsDir, MANCODE_AGENT_SKILL_MARKERS);
|
|
1844
1878
|
for (const mode of MODE_NAMES) {
|
|
1845
1879
|
const modeDir = path4.join(skillsDir, mode);
|
|
1846
1880
|
await mkdir4(modeDir, { recursive: true });
|
|
@@ -1864,6 +1898,7 @@ async function installCodexSkills(projectRoot, minimal) {
|
|
|
1864
1898
|
MANCODE_AGENT_SKILL_MARKERS
|
|
1865
1899
|
);
|
|
1866
1900
|
}
|
|
1901
|
+
await removeLegacyManagedSkills(skillsDir, MANCODE_AGENT_SKILL_MARKERS);
|
|
1867
1902
|
}
|
|
1868
1903
|
async function installZcodeSkills(projectRoot, minimal) {
|
|
1869
1904
|
if (minimal) {
|
|
@@ -1871,7 +1906,6 @@ async function installZcodeSkills(projectRoot, minimal) {
|
|
|
1871
1906
|
return;
|
|
1872
1907
|
}
|
|
1873
1908
|
const skillsDir = path4.join(projectRoot, ".agents", "skills");
|
|
1874
|
-
await removeLegacyManagedSkills(skillsDir, MANCODE_AGENT_SKILL_MARKERS);
|
|
1875
1909
|
for (const mode of MODE_NAMES) {
|
|
1876
1910
|
const modeDir = path4.join(skillsDir, mode);
|
|
1877
1911
|
await mkdir4(modeDir, { recursive: true });
|
|
@@ -1895,6 +1929,7 @@ async function installZcodeSkills(projectRoot, minimal) {
|
|
|
1895
1929
|
MANCODE_AGENT_SKILL_MARKERS
|
|
1896
1930
|
);
|
|
1897
1931
|
}
|
|
1932
|
+
await removeLegacyManagedSkills(skillsDir, MANCODE_AGENT_SKILL_MARKERS);
|
|
1898
1933
|
}
|
|
1899
1934
|
async function installCursorCommands(projectRoot, minimal) {
|
|
1900
1935
|
if (minimal) {
|
|
@@ -1903,7 +1938,6 @@ async function installCursorCommands(projectRoot, minimal) {
|
|
|
1903
1938
|
}
|
|
1904
1939
|
const commandsDir = path4.join(projectRoot, ".cursor", "commands");
|
|
1905
1940
|
await mkdir4(commandsDir, { recursive: true });
|
|
1906
|
-
await removeLegacyGeneratedModeFile(path4.join(commandsDir, "man8.md"));
|
|
1907
1941
|
for (const mode of MODE_NAMES) {
|
|
1908
1942
|
const meta = MODE_META[mode];
|
|
1909
1943
|
const content = [
|
|
@@ -1923,6 +1957,8 @@ async function installCursorCommands(projectRoot, minimal) {
|
|
|
1923
1957
|
"Cursor"
|
|
1924
1958
|
);
|
|
1925
1959
|
}
|
|
1960
|
+
await removeManagedModeFile(path4.join(commandsDir, "mamba.md"), "mamba");
|
|
1961
|
+
await removeLegacyGeneratedModeFile(path4.join(commandsDir, "man8.md"));
|
|
1926
1962
|
}
|
|
1927
1963
|
async function installCopilotPrompts(projectRoot, minimal) {
|
|
1928
1964
|
if (minimal) {
|
|
@@ -1931,7 +1967,6 @@ async function installCopilotPrompts(projectRoot, minimal) {
|
|
|
1931
1967
|
}
|
|
1932
1968
|
const promptsDir = path4.join(projectRoot, ".github", "prompts");
|
|
1933
1969
|
await mkdir4(promptsDir, { recursive: true });
|
|
1934
|
-
await removeLegacyGeneratedModeFile(path4.join(promptsDir, "man8.prompt.md"));
|
|
1935
1970
|
for (const mode of MODE_NAMES) {
|
|
1936
1971
|
const meta = MODE_META[mode];
|
|
1937
1972
|
const content = [
|
|
@@ -1952,6 +1987,11 @@ async function installCopilotPrompts(projectRoot, minimal) {
|
|
|
1952
1987
|
"GitHub Copilot"
|
|
1953
1988
|
);
|
|
1954
1989
|
}
|
|
1990
|
+
await removeManagedModeFile(
|
|
1991
|
+
path4.join(promptsDir, "mamba.prompt.md"),
|
|
1992
|
+
"mamba"
|
|
1993
|
+
);
|
|
1994
|
+
await removeLegacyGeneratedModeFile(path4.join(promptsDir, "man8.prompt.md"));
|
|
1955
1995
|
}
|
|
1956
1996
|
async function removeCodexSkills(projectRoot) {
|
|
1957
1997
|
if (!await platformNeedsSharedSkills(projectRoot, "zcode")) {
|
|
@@ -2090,18 +2130,22 @@ function isRecord2(value) {
|
|
|
2090
2130
|
async function readTextIfExists3(filePath) {
|
|
2091
2131
|
try {
|
|
2092
2132
|
return await readFile4(filePath, "utf-8");
|
|
2093
|
-
} catch {
|
|
2094
|
-
return null;
|
|
2133
|
+
} catch (error) {
|
|
2134
|
+
if (isNodeError3(error) && error.code === "ENOENT") return null;
|
|
2135
|
+
throw error;
|
|
2095
2136
|
}
|
|
2096
2137
|
}
|
|
2138
|
+
function isNodeError3(error) {
|
|
2139
|
+
return error instanceof Error && "code" in error;
|
|
2140
|
+
}
|
|
2097
2141
|
var MODE_META = {
|
|
2098
|
-
|
|
2142
|
+
manba: {
|
|
2099
2143
|
description: "Diagnose bugs and validate real user flows with targeted regression checks.",
|
|
2100
|
-
intro: "# mancode
|
|
2144
|
+
intro: "# mancode manba \u2014 Diagnosis and Real Validation",
|
|
2101
2145
|
workflow: [
|
|
2102
2146
|
"## Five-step workflow (simulate roles in one conversation)",
|
|
2103
2147
|
"",
|
|
2104
|
-
'Use `mancode workflow create
|
|
2148
|
+
'Use `mancode workflow create manba "<task>" --json`; when called from',
|
|
2105
2149
|
"a /man or /manteam Step 6 workflow, add `--parent-task <taskId>`. Persist the returned",
|
|
2106
2150
|
"taskId in `.mancode/state.json` as currentTask; set currentMode and",
|
|
2107
2151
|
"currentWorkflowMode to mamba. Never edit metadata.json directly; use",
|
|
@@ -2137,7 +2181,7 @@ var MODE_META = {
|
|
|
2137
2181
|
"Step 3 \u2014 Plan: write `plan.md` with scope, reuse, exclusions, risks, completion criteria, and real validation. First plan is v1; revisions use `--plan-version <current+1>` and Active Plans is updated by the CLI.",
|
|
2138
2182
|
"Step 4 \u2014 Plan gate: the user chooses plan-only (`status planned`), continue to execution, or revise the plan. Do not implement before this choice.",
|
|
2139
2183
|
"Step 5 \u2014 Implement the confirmed minimum change.",
|
|
2140
|
-
"Step 6 \u2014 Run detected build/lint/typecheck/test and smoke checks. A real or complex diagnosis creates a linked
|
|
2184
|
+
"Step 6 \u2014 Run detected build/lint/typecheck/test and smoke checks. A real or complex diagnosis creates a linked manba child while the parent remains at Step 6. After a resolved child, restore a parent blocked by that child with `workflow update --status in_progress` before Step 7; never auto-resume manual_test_required. Then write `review-scope.md` from the actual diff, verification evidence, and hard-risk triggers. Initialize a targeted review for routine governed changes or a full review for auth, payment, sensitive data, migrations/deletion, public APIs, untrusted input, concurrency, cross-service, or infrastructure changes using `mancode workflow review <taskId> init ...`.",
|
|
2141
2185
|
"Step 7 \u2014 Run one quality review limited to the changed diff and direct impact. Findings require changed-line evidence and user impact, with at most three new findings. Record stable blocker IDs through `workflow review ... complete`; do not fix yet.",
|
|
2142
2186
|
"Step 8 \u2014 Only full review runs the security/boundary reviewer. It must read Film #1, mark the same root cause duplicate, and stay within security, permissions, recovery, resources, and boundaries. A targeted review ends after Film #1.",
|
|
2143
2187
|
"Step 9 \u2014 If open blockers exist, fix them in one remediation round and record resolved IDs through `workflow review ... remediate`; with no blockers, do not create a remediation round. Re-run affected verification without re-running completed reviewers. Write `summary.md` and set completed only when required domains are complete and blockers are zero; otherwise set blocked+blockingReason.",
|
|
@@ -2158,9 +2202,9 @@ var MODE_META = {
|
|
|
2158
2202
|
"",
|
|
2159
2203
|
"Then execute every /man Step 1 through Step 9, including clarification,",
|
|
2160
2204
|
"plan gate, validation, bounded risk-based review, conditional completion, planVersion,",
|
|
2161
|
-
"Active Plans, and linked
|
|
2205
|
+
"Active Plans, and linked manba child behavior. Add compatibility, rollback,",
|
|
2162
2206
|
"ownership, conflict, and handoff notes at each relevant step.",
|
|
2163
|
-
"When a resolved
|
|
2207
|
+
"When a resolved manba child had blocked the parent, restore the parent through",
|
|
2164
2208
|
"`workflow update --status in_progress`; never auto-resume manual_test_required.",
|
|
2165
2209
|
"",
|
|
2166
2210
|
"Read `.mancode/memory/prd.md`, `spec.md`, and `decisions.md`; append durable",
|
|
@@ -2234,7 +2278,7 @@ function renderProjectContext(state, tokens, profile, options) {
|
|
|
2234
2278
|
const currentProfile = options.projectProfile ?? profile;
|
|
2235
2279
|
const techStack = options.projectProfile ? options.techStack.join(" + ") || "Unknown" : state?.techStack || options.techStack.join(" + ") || "Unknown";
|
|
2236
2280
|
const uiLibrary = options.projectProfile ? options.uiLibrary || "None" : state?.uiLibrary || tokens?.uiLibrary || options.uiLibrary || "None";
|
|
2237
|
-
const mode = state?.currentMode || "solo";
|
|
2281
|
+
const mode = state?.currentMode === "mamba" ? "manba" : state?.currentMode || "solo";
|
|
2238
2282
|
return [
|
|
2239
2283
|
"## mancode Project Context",
|
|
2240
2284
|
"",
|
|
@@ -2298,7 +2342,7 @@ function renderAesthetics(tokens) {
|
|
|
2298
2342
|
function renderModes(options) {
|
|
2299
2343
|
let commandLabel;
|
|
2300
2344
|
if (options.capabilities.skills === "agents-skills") {
|
|
2301
|
-
commandLabel = "Invoke mode skills with `$man`, `$
|
|
2345
|
+
commandLabel = "Invoke mode skills with `$man`, `$manba`, `$manteam`, `$manps`, `$mansolo`.";
|
|
2302
2346
|
} else if (options.capabilities.slashCommands === "native") {
|
|
2303
2347
|
commandLabel = "Use the named commands directly when available.";
|
|
2304
2348
|
} else {
|
|
@@ -2309,7 +2353,7 @@ function renderModes(options) {
|
|
|
2309
2353
|
"",
|
|
2310
2354
|
`- solo: default lightweight mode. ${commandLabel}`,
|
|
2311
2355
|
"- man: progressive governance workflow with planning and optional full execution.",
|
|
2312
|
-
"-
|
|
2356
|
+
"- manba: diagnose bugs and validate real user flows or regressions.",
|
|
2313
2357
|
"- manteam: use team memory and leave handoff-friendly summaries.",
|
|
2314
2358
|
"- manps: run project health and cleanup scans before remediation.",
|
|
2315
2359
|
"- mansolo: return to solo mode."
|
|
@@ -2371,11 +2415,15 @@ var MANCODE_CURSOR_CORE_RULE_FILES = [
|
|
|
2371
2415
|
"mancode-solo.mdc"
|
|
2372
2416
|
];
|
|
2373
2417
|
var MANCODE_CURSOR_ADVANCED_RULE_FILES = [
|
|
2374
|
-
"mancode-
|
|
2418
|
+
"mancode-manba.mdc",
|
|
2375
2419
|
"mancode-man.mdc",
|
|
2376
2420
|
"mancode-manteam.mdc",
|
|
2377
2421
|
"mancode-manps.mdc"
|
|
2378
2422
|
];
|
|
2423
|
+
var MANCODE_CURSOR_LEGACY_RULE_FILES = [
|
|
2424
|
+
"mancode-mamba.mdc",
|
|
2425
|
+
"mancode-man8.mdc"
|
|
2426
|
+
];
|
|
2379
2427
|
var CURSOR_RULE_MANAGED_MARKER = "<!-- Managed by mancode:cursor-rule. Do not edit this marker. -->";
|
|
2380
2428
|
var MANCODE_CURSOR_RULE_FILES = [
|
|
2381
2429
|
...MANCODE_CURSOR_CORE_RULE_FILES,
|
|
@@ -2427,13 +2475,12 @@ async function installCursor(projectRoot, options) {
|
|
|
2427
2475
|
await installCursorCommands(projectRoot, true);
|
|
2428
2476
|
return;
|
|
2429
2477
|
}
|
|
2430
|
-
await removeLegacyCursorRules(projectRoot);
|
|
2431
2478
|
await writeRule(
|
|
2432
2479
|
rulesDir,
|
|
2433
|
-
"mancode-
|
|
2480
|
+
"mancode-manba.mdc",
|
|
2434
2481
|
"Use for bug diagnosis and real regression testing",
|
|
2435
2482
|
false,
|
|
2436
|
-
|
|
2483
|
+
renderManbaRule()
|
|
2437
2484
|
);
|
|
2438
2485
|
await writeRule(
|
|
2439
2486
|
rulesDir,
|
|
@@ -2456,6 +2503,7 @@ async function installCursor(projectRoot, options) {
|
|
|
2456
2503
|
false,
|
|
2457
2504
|
renderManpsRule()
|
|
2458
2505
|
);
|
|
2506
|
+
await removeLegacyCursorRules(projectRoot);
|
|
2459
2507
|
await installCursorCommands(projectRoot, options.minimal ?? false);
|
|
2460
2508
|
}
|
|
2461
2509
|
async function writeRule(rulesDir, fileName, description, alwaysApply, body) {
|
|
@@ -2503,18 +2551,9 @@ async function removeCursorGeneratedRules(projectRoot) {
|
|
|
2503
2551
|
await removeLegacyCursorRules(projectRoot);
|
|
2504
2552
|
}
|
|
2505
2553
|
async function removeLegacyCursorRules(projectRoot) {
|
|
2506
|
-
const
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
"rules",
|
|
2510
|
-
"mancode-man8.mdc"
|
|
2511
|
-
);
|
|
2512
|
-
try {
|
|
2513
|
-
const content = await readFile6(legacyPath, "utf-8");
|
|
2514
|
-
if (content.includes("# mancode man8 \u2014 Investigate and Plan") && content.includes("## Mode Persistence")) {
|
|
2515
|
-
await rm3(legacyPath, { force: true });
|
|
2516
|
-
}
|
|
2517
|
-
} catch {
|
|
2554
|
+
const rulesDir = path6.join(projectRoot, ".cursor", "rules");
|
|
2555
|
+
for (const fileName of MANCODE_CURSOR_LEGACY_RULE_FILES) {
|
|
2556
|
+
await removeGeneratedCursorRule(rulesDir, fileName);
|
|
2518
2557
|
}
|
|
2519
2558
|
}
|
|
2520
2559
|
async function removeGeneratedCursorRule(rulesDir, fileName) {
|
|
@@ -2541,10 +2580,14 @@ function isGeneratedCursorRule(content, fileName) {
|
|
|
2541
2580
|
async function readTextIfExists4(filePath) {
|
|
2542
2581
|
try {
|
|
2543
2582
|
return await readFile6(filePath, "utf-8");
|
|
2544
|
-
} catch {
|
|
2545
|
-
return null;
|
|
2583
|
+
} catch (error) {
|
|
2584
|
+
if (isNodeError4(error) && error.code === "ENOENT") return null;
|
|
2585
|
+
throw error;
|
|
2546
2586
|
}
|
|
2547
2587
|
}
|
|
2588
|
+
function isNodeError4(error) {
|
|
2589
|
+
return error instanceof Error && "code" in error;
|
|
2590
|
+
}
|
|
2548
2591
|
function renderPracticeRule() {
|
|
2549
2592
|
return [
|
|
2550
2593
|
"# mancode Practice",
|
|
@@ -2575,8 +2618,8 @@ function renderSoloRule() {
|
|
|
2575
2618
|
"- Recommend /man only for auth, payment, sensitive data, migrations/deletion, public APIs, untrusted input, concurrency, or infrastructure risk."
|
|
2576
2619
|
].join("\n");
|
|
2577
2620
|
}
|
|
2578
|
-
function
|
|
2579
|
-
return renderModeSkill("
|
|
2621
|
+
function renderManbaRule() {
|
|
2622
|
+
return renderModeSkill("manba", "/");
|
|
2580
2623
|
}
|
|
2581
2624
|
function renderManRule() {
|
|
2582
2625
|
return renderModeSkill("man", "/");
|
|
@@ -2763,7 +2806,7 @@ function renderCopilotPromptConventions() {
|
|
|
2763
2806
|
"GitHub Copilot does not provide native mancode slash commands, hooks, or isolated subagents. Treat these names as user prompt conventions:",
|
|
2764
2807
|
"",
|
|
2765
2808
|
"- man: use progressive research, planning, implementation, verification, and bounded risk-based review.",
|
|
2766
|
-
"-
|
|
2809
|
+
"- manba: diagnose bugs and validate real user flows or regressions.",
|
|
2767
2810
|
"- manteam: read team memory and write handoff-friendly summaries.",
|
|
2768
2811
|
"- manps: prefer `mancode manps [area]` before cleanup.",
|
|
2769
2812
|
"- mansolo: exit any active mode and return to default solo behavior.",
|
|
@@ -4402,7 +4445,9 @@ function getInitManagedFilePaths(rootDir, platforms) {
|
|
|
4402
4445
|
".mancode/hooks/user-prompt-submit.sh",
|
|
4403
4446
|
".claude/settings.json",
|
|
4404
4447
|
".claude/skills/man8/SKILL.md",
|
|
4448
|
+
".claude/skills/mamba/SKILL.md",
|
|
4405
4449
|
".claude/skills/solo/SKILL.md",
|
|
4450
|
+
".claude/skills/mancode-mamba.md",
|
|
4406
4451
|
".claude/skills/mancode-solo.md",
|
|
4407
4452
|
".claude/skills/mancode-man8.md"
|
|
4408
4453
|
);
|
|
@@ -4417,7 +4462,12 @@ function getInitManagedFilePaths(rootDir, platforms) {
|
|
|
4417
4462
|
}
|
|
4418
4463
|
}
|
|
4419
4464
|
if (platforms.includes("cursor")) {
|
|
4420
|
-
files.push(
|
|
4465
|
+
files.push(
|
|
4466
|
+
".cursor/rules/mancode-mamba.mdc",
|
|
4467
|
+
".cursor/rules/mancode-man8.mdc",
|
|
4468
|
+
".cursor/commands/mamba.md",
|
|
4469
|
+
".cursor/commands/man8.md"
|
|
4470
|
+
);
|
|
4421
4471
|
for (const fileName of MANCODE_CURSOR_RULE_FILES) {
|
|
4422
4472
|
files.push(`.cursor/rules/${fileName}`);
|
|
4423
4473
|
}
|
|
@@ -4426,19 +4476,23 @@ function getInitManagedFilePaths(rootDir, platforms) {
|
|
|
4426
4476
|
}
|
|
4427
4477
|
}
|
|
4428
4478
|
if (platforms.includes("codex") || platforms.includes("zcode")) {
|
|
4429
|
-
files.push(
|
|
4479
|
+
files.push(
|
|
4480
|
+
"AGENTS.md",
|
|
4481
|
+
".agents/skills/mamba/SKILL.md",
|
|
4482
|
+
".agents/skills/man8/SKILL.md"
|
|
4483
|
+
);
|
|
4430
4484
|
for (const mode of MODE_NAMES) {
|
|
4431
4485
|
files.push(`.agents/skills/${mode}/SKILL.md`);
|
|
4432
4486
|
}
|
|
4433
4487
|
}
|
|
4434
4488
|
if (platforms.includes("codex")) {
|
|
4435
|
-
files.push(".codex/skills/man8/SKILL.md");
|
|
4489
|
+
files.push(".codex/skills/mamba/SKILL.md", ".codex/skills/man8/SKILL.md");
|
|
4436
4490
|
for (const mode of MODE_NAMES) {
|
|
4437
4491
|
files.push(`.codex/skills/${mode}/SKILL.md`);
|
|
4438
4492
|
}
|
|
4439
4493
|
}
|
|
4440
4494
|
if (platforms.includes("zcode")) {
|
|
4441
|
-
files.push(".zcode/skills/man8/SKILL.md");
|
|
4495
|
+
files.push(".zcode/skills/mamba/SKILL.md", ".zcode/skills/man8/SKILL.md");
|
|
4442
4496
|
for (const mode of MODE_NAMES) {
|
|
4443
4497
|
files.push(`.zcode/skills/${mode}/SKILL.md`);
|
|
4444
4498
|
}
|
|
@@ -4446,6 +4500,7 @@ function getInitManagedFilePaths(rootDir, platforms) {
|
|
|
4446
4500
|
if (platforms.includes("copilot")) {
|
|
4447
4501
|
files.push(
|
|
4448
4502
|
".github/copilot-instructions.md",
|
|
4503
|
+
".github/prompts/mamba.prompt.md",
|
|
4449
4504
|
".github/prompts/man8.prompt.md"
|
|
4450
4505
|
);
|
|
4451
4506
|
for (const mode of MODE_NAMES) {
|
|
@@ -4460,7 +4515,7 @@ async function snapshotFiles(filePaths) {
|
|
|
4460
4515
|
try {
|
|
4461
4516
|
return { filePath, content: await fs3.readFile(filePath, "utf-8") };
|
|
4462
4517
|
} catch (error) {
|
|
4463
|
-
if (
|
|
4518
|
+
if (isNodeError5(error) && error.code === "ENOENT") {
|
|
4464
4519
|
return { filePath, content: null };
|
|
4465
4520
|
}
|
|
4466
4521
|
throw error;
|
|
@@ -4506,7 +4561,7 @@ async function removeNewEmptyDirectories(snapshots) {
|
|
|
4506
4561
|
function isRecord3(value) {
|
|
4507
4562
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4508
4563
|
}
|
|
4509
|
-
function
|
|
4564
|
+
function isNodeError5(error) {
|
|
4510
4565
|
return error instanceof Error && "code" in error;
|
|
4511
4566
|
}
|
|
4512
4567
|
function printPlatformCreatedFiles(platform, locale) {
|
|
@@ -4935,13 +4990,13 @@ async function readConfig(rootDir) {
|
|
|
4935
4990
|
const raw = await fs5.readFile(configPath, "utf-8");
|
|
4936
4991
|
return { config: JSON.parse(raw), valid: true };
|
|
4937
4992
|
} catch (err) {
|
|
4938
|
-
if (
|
|
4993
|
+
if (isNodeError6(err) && err.code === "ENOENT") {
|
|
4939
4994
|
return { config: {}, valid: false };
|
|
4940
4995
|
}
|
|
4941
4996
|
throw err;
|
|
4942
4997
|
}
|
|
4943
4998
|
}
|
|
4944
|
-
function
|
|
4999
|
+
function isNodeError6(err) {
|
|
4945
5000
|
return err instanceof Error && "code" in err;
|
|
4946
5001
|
}
|
|
4947
5002
|
async function updateConfig(rootDir, config) {
|
|
@@ -5749,7 +5804,7 @@ async function readIssueDatabase(issueDbPath) {
|
|
|
5749
5804
|
try {
|
|
5750
5805
|
raw = await readFile8(issueDbPath, "utf-8");
|
|
5751
5806
|
} catch (err) {
|
|
5752
|
-
if (
|
|
5807
|
+
if (isNodeError7(err) && err.code === "ENOENT") {
|
|
5753
5808
|
return emptyIssueDatabase();
|
|
5754
5809
|
}
|
|
5755
5810
|
throw err;
|
|
@@ -5960,7 +6015,7 @@ async function pathExists6(file) {
|
|
|
5960
6015
|
return false;
|
|
5961
6016
|
}
|
|
5962
6017
|
}
|
|
5963
|
-
function
|
|
6018
|
+
function isNodeError7(err) {
|
|
5964
6019
|
return err instanceof Error && "code" in err;
|
|
5965
6020
|
}
|
|
5966
6021
|
function isRecord6(value) {
|
|
@@ -6255,7 +6310,7 @@ async function ensureReplaceableFile(filePath) {
|
|
|
6255
6310
|
throw new Error(`cannot replace non-file path: ${filePath}`);
|
|
6256
6311
|
}
|
|
6257
6312
|
} catch (error) {
|
|
6258
|
-
if (
|
|
6313
|
+
if (isNodeError8(error) && error.code === "ENOENT") return;
|
|
6259
6314
|
throw error;
|
|
6260
6315
|
}
|
|
6261
6316
|
}
|
|
@@ -6272,7 +6327,7 @@ async function readOptionalText(filePath) {
|
|
|
6272
6327
|
try {
|
|
6273
6328
|
return await fs7.readFile(filePath, "utf-8");
|
|
6274
6329
|
} catch (error) {
|
|
6275
|
-
if (
|
|
6330
|
+
if (isNodeError8(error) && error.code === "ENOENT") return null;
|
|
6276
6331
|
throw error;
|
|
6277
6332
|
}
|
|
6278
6333
|
}
|
|
@@ -6335,7 +6390,7 @@ async function readRequiredState(filePath) {
|
|
|
6335
6390
|
function isRecord7(value) {
|
|
6336
6391
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
6337
6392
|
}
|
|
6338
|
-
function
|
|
6393
|
+
function isNodeError8(error) {
|
|
6339
6394
|
return error instanceof Error && "code" in error;
|
|
6340
6395
|
}
|
|
6341
6396
|
async function pathExists8(filePath) {
|
|
@@ -6755,7 +6810,7 @@ async function allocateTaskId(projectRoot, baseTaskId) {
|
|
|
6755
6810
|
await mkdir9(workflowDir(projectRoot, taskId));
|
|
6756
6811
|
return taskId;
|
|
6757
6812
|
} catch (err) {
|
|
6758
|
-
if (
|
|
6813
|
+
if (isNodeError9(err) && err.code === "EEXIST") {
|
|
6759
6814
|
continue;
|
|
6760
6815
|
}
|
|
6761
6816
|
throw err;
|
|
@@ -6871,7 +6926,7 @@ function isWorkflowOutcome(value) {
|
|
|
6871
6926
|
async function validateParentTask(projectRoot, mode, parentTaskId, requireStepSix = false) {
|
|
6872
6927
|
if (!parentTaskId) return;
|
|
6873
6928
|
if (mode !== "mamba") {
|
|
6874
|
-
throw new Error("only
|
|
6929
|
+
throw new Error("only manba workflows can have a parent task");
|
|
6875
6930
|
}
|
|
6876
6931
|
const parent = await readWorkflow(projectRoot, parentTaskId);
|
|
6877
6932
|
if (!parent || parent.mode !== "man" && parent.mode !== "manteam") {
|
|
@@ -6911,14 +6966,14 @@ async function validateWorkflowMeta(projectRoot, updated, existing) {
|
|
|
6911
6966
|
);
|
|
6912
6967
|
}
|
|
6913
6968
|
if (updated.status === "planned" && updated.mode === "mamba") {
|
|
6914
|
-
throw new Error("
|
|
6969
|
+
throw new Error("manba workflows cannot be planned");
|
|
6915
6970
|
}
|
|
6916
6971
|
if (updated.status === "planned" && updated.currentStep !== 4) {
|
|
6917
6972
|
throw new Error("planned workflows must be at step 4");
|
|
6918
6973
|
}
|
|
6919
6974
|
if (updated.status === "completed" && updated.currentStep !== maxWorkflowStep(updated.mode)) {
|
|
6920
6975
|
throw new Error(
|
|
6921
|
-
`completed ${updated.mode} workflows must be at step ${maxWorkflowStep(updated.mode)}`
|
|
6976
|
+
`completed ${updated.mode === "mamba" ? "manba" : updated.mode} workflows must be at step ${maxWorkflowStep(updated.mode)}`
|
|
6922
6977
|
);
|
|
6923
6978
|
}
|
|
6924
6979
|
if (updated.blockingReason !== void 0 && typeof updated.blockingReason !== "string") {
|
|
@@ -6932,25 +6987,25 @@ async function validateWorkflowMeta(projectRoot, updated, existing) {
|
|
|
6932
6987
|
throw new Error("only blocked workflows can have a blocking reason");
|
|
6933
6988
|
}
|
|
6934
6989
|
if (updated.mode !== "mamba" && updated.outcome !== void 0) {
|
|
6935
|
-
throw new Error("only
|
|
6990
|
+
throw new Error("only manba workflows can have an outcome");
|
|
6936
6991
|
}
|
|
6937
6992
|
if (updated.outcome !== void 0 && !isWorkflowOutcome(updated.outcome)) {
|
|
6938
6993
|
throw new Error(`invalid workflow outcome: ${updated.outcome}`);
|
|
6939
6994
|
}
|
|
6940
6995
|
if (updated.outcome !== void 0 && updated.status !== "completed") {
|
|
6941
|
-
throw new Error("
|
|
6996
|
+
throw new Error("manba outcomes can only be set on completed workflows");
|
|
6942
6997
|
}
|
|
6943
6998
|
if (updated.mode === "mamba" && updated.status === "completed" && !updated.outcome) {
|
|
6944
|
-
throw new Error("completed
|
|
6999
|
+
throw new Error("completed manba workflows require an outcome");
|
|
6945
7000
|
}
|
|
6946
7001
|
if (updated.mode === "mamba" && updated.planVersion !== void 0) {
|
|
6947
|
-
throw new Error("
|
|
7002
|
+
throw new Error("manba workflows cannot have a plan version");
|
|
6948
7003
|
}
|
|
6949
7004
|
if (updated.reviewPolicyVersion !== void 0 && updated.reviewPolicyVersion !== 1) {
|
|
6950
7005
|
throw new Error("invalid workflow review policy version");
|
|
6951
7006
|
}
|
|
6952
7007
|
if (updated.mode === "mamba" && updated.reviewPolicyVersion !== void 0) {
|
|
6953
|
-
throw new Error("
|
|
7008
|
+
throw new Error("manba workflows cannot have a review policy version");
|
|
6954
7009
|
}
|
|
6955
7010
|
if (updated.planVersion !== void 0 && (!Number.isInteger(updated.planVersion) || updated.planVersion < 1)) {
|
|
6956
7011
|
throw new Error("workflow plan version must be a positive integer");
|
|
@@ -6963,7 +7018,7 @@ async function validateWorkflowMeta(projectRoot, updated, existing) {
|
|
|
6963
7018
|
}
|
|
6964
7019
|
await validateParentTask(projectRoot, updated.mode, updated.parentTaskId);
|
|
6965
7020
|
if ((isTerminalWorkflowStatus(updated.status) || updated.status === "planned") && (await listActiveMambaChildren(projectRoot, updated.taskId)).length > 0) {
|
|
6966
|
-
throw new Error("cannot finish workflow with an active
|
|
7021
|
+
throw new Error("cannot finish workflow with an active manba child");
|
|
6967
7022
|
}
|
|
6968
7023
|
if (updated.status === "completed" && updated.reviewPolicyVersion === 1 && !reviewWasExplicitlySkipped(updated) && !await reviewCanComplete(projectRoot, updated.taskId)) {
|
|
6969
7024
|
throw new Error("workflow review is incomplete or still has open blockers");
|
|
@@ -7034,7 +7089,7 @@ async function propagateChildStatus(projectRoot, child) {
|
|
|
7034
7089
|
if (!parentTaskId) return;
|
|
7035
7090
|
const parent = await readWorkflow(projectRoot, parentTaskId);
|
|
7036
7091
|
if (!parent || parent.status !== "in_progress") return;
|
|
7037
|
-
const reason = child.status === "blocked" ? `
|
|
7092
|
+
const reason = child.status === "blocked" ? `manba child ${child.taskId} is blocked: ${child.blockingReason ?? "unknown reason"}` : `manba child ${child.taskId} requires manual testing`;
|
|
7038
7093
|
await writeMetadata(workflowDir(projectRoot, parent.taskId), {
|
|
7039
7094
|
...parent,
|
|
7040
7095
|
status: "blocked",
|
|
@@ -7049,7 +7104,7 @@ async function propagateChildStatus(projectRoot, child) {
|
|
|
7049
7104
|
});
|
|
7050
7105
|
}
|
|
7051
7106
|
}
|
|
7052
|
-
function
|
|
7107
|
+
function isNodeError9(err) {
|
|
7053
7108
|
return err instanceof Error && "code" in err;
|
|
7054
7109
|
}
|
|
7055
7110
|
function assertValidTaskId2(taskId) {
|
|
@@ -7309,7 +7364,8 @@ function runHookEstimate(rootDir, hookPath) {
|
|
|
7309
7364
|
});
|
|
7310
7365
|
}
|
|
7311
7366
|
function printText(r) {
|
|
7312
|
-
const
|
|
7367
|
+
const publicMode = r.mode === "mamba" ? "manba" : r.mode;
|
|
7368
|
+
const modeLabel = publicMode === "solo" ? `${publicMode} (default)` : publicMode;
|
|
7313
7369
|
console.log("");
|
|
7314
7370
|
console.log(`mancode v${r.version}`);
|
|
7315
7371
|
console.log("");
|
|
@@ -7686,7 +7742,7 @@ async function workflow(rootDir, subcommand, args = [], options = {}) {
|
|
|
7686
7742
|
} else {
|
|
7687
7743
|
console.error(`\u2717 Invalid workflow subcommand: ${subcommand}`);
|
|
7688
7744
|
console.error(
|
|
7689
|
-
" Use: create <man|
|
|
7745
|
+
" Use: create <man|manba|manteam> <task> | update <taskId> | review <taskId> <init|complete|remediate|show> | list | show <taskId> | clean"
|
|
7690
7746
|
);
|
|
7691
7747
|
}
|
|
7692
7748
|
return EXIT_INVALID_ARG2;
|
|
@@ -7790,20 +7846,21 @@ function parseCsv(value) {
|
|
|
7790
7846
|
return (value ?? "").split(",").map((item) => item.trim()).filter(Boolean);
|
|
7791
7847
|
}
|
|
7792
7848
|
async function workflowCreate(rootDir, args, options) {
|
|
7793
|
-
const
|
|
7849
|
+
const requestedMode = args[0];
|
|
7850
|
+
const mode = parsePublicWorkflowMode(requestedMode);
|
|
7794
7851
|
const task = args.slice(1).join(" ").trim();
|
|
7795
|
-
if (mode
|
|
7852
|
+
if (!mode) {
|
|
7796
7853
|
return invalidArg(
|
|
7797
7854
|
options,
|
|
7798
|
-
`invalid workflow mode: ${
|
|
7799
|
-
"Use: mancode workflow create <man|
|
|
7855
|
+
`invalid workflow mode: ${requestedMode ?? ""}`,
|
|
7856
|
+
"Use: mancode workflow create <man|manba|manteam> <task> [--parent-task <taskId>]"
|
|
7800
7857
|
);
|
|
7801
7858
|
}
|
|
7802
7859
|
if (!task) {
|
|
7803
7860
|
return invalidArg(
|
|
7804
7861
|
options,
|
|
7805
7862
|
"missing workflow task",
|
|
7806
|
-
"Use: mancode workflow create <man|
|
|
7863
|
+
"Use: mancode workflow create <man|manba|manteam> <task> [--parent-task <taskId>]"
|
|
7807
7864
|
);
|
|
7808
7865
|
}
|
|
7809
7866
|
try {
|
|
@@ -7873,7 +7930,7 @@ async function workflowUpdate(rootDir, taskId, options) {
|
|
|
7873
7930
|
if (existing.mode !== "mamba" || nextStatus !== "completed") {
|
|
7874
7931
|
return invalidArg(
|
|
7875
7932
|
options,
|
|
7876
|
-
"--outcome is only valid when completing a
|
|
7933
|
+
"--outcome is only valid when completing a manba workflow"
|
|
7877
7934
|
);
|
|
7878
7935
|
}
|
|
7879
7936
|
patch.outcome = options.outcome;
|
|
@@ -7981,7 +8038,7 @@ async function workflowShow(rootDir, taskId, options) {
|
|
|
7981
8038
|
}
|
|
7982
8039
|
console.log(`Workflow: ${meta.taskId}`);
|
|
7983
8040
|
console.log(`Task: ${meta.task}`);
|
|
7984
|
-
console.log(`Mode: ${meta.mode}`);
|
|
8041
|
+
console.log(`Mode: ${formatPublicWorkflowMode(meta.mode)}`);
|
|
7985
8042
|
console.log(`Status: ${meta.status}`);
|
|
7986
8043
|
console.log(`Current step:${meta.currentStep}/${maxWorkflowStep(meta.mode)}`);
|
|
7987
8044
|
console.log(
|
|
@@ -7996,7 +8053,7 @@ async function workflowShow(rootDir, taskId, options) {
|
|
|
7996
8053
|
if (meta.blockingReason) console.log(`Blocked: ${meta.blockingReason}`);
|
|
7997
8054
|
if (children !== void 0) {
|
|
7998
8055
|
if (children.length > 0) {
|
|
7999
|
-
console.log(`Children: ${children.length} active
|
|
8056
|
+
console.log(`Children: ${children.length} active manba workflow(s)`);
|
|
8000
8057
|
for (const child of children) {
|
|
8001
8058
|
console.log(
|
|
8002
8059
|
` - ${child.taskId} (Step ${child.currentStep}/5, ${child.status})`
|
|
@@ -8084,7 +8141,15 @@ function formatWorkflowRow(meta) {
|
|
|
8084
8141
|
meta.blockingReason ? `blocked=${meta.blockingReason}` : "",
|
|
8085
8142
|
meta.activeChildren && meta.activeChildren.length > 0 ? `children=${meta.activeChildren.map((child) => child.taskId).join(",")}` : ""
|
|
8086
8143
|
].filter(Boolean);
|
|
8087
|
-
return `${meta.taskId.padEnd(42)} ${meta.mode.padEnd(7)} ${meta.status.padEnd(11)} ${step}${details.length > 0 ? ` | ${details.join(" | ")}` : ""}`;
|
|
8144
|
+
return `${meta.taskId.padEnd(42)} ${formatPublicWorkflowMode(meta.mode).padEnd(7)} ${meta.status.padEnd(11)} ${step}${details.length > 0 ? ` | ${details.join(" | ")}` : ""}`;
|
|
8145
|
+
}
|
|
8146
|
+
function parsePublicWorkflowMode(value) {
|
|
8147
|
+
if (value === "manba" || value === "mamba") return "mamba";
|
|
8148
|
+
if (value === "man" || value === "manteam") return value;
|
|
8149
|
+
return null;
|
|
8150
|
+
}
|
|
8151
|
+
function formatPublicWorkflowMode(mode) {
|
|
8152
|
+
return mode === "mamba" ? "manba" : mode;
|
|
8088
8153
|
}
|
|
8089
8154
|
function attachActiveChildren(workflows) {
|
|
8090
8155
|
return workflows.map((meta) => {
|
|
@@ -8142,7 +8207,7 @@ async function pathExists12(p) {
|
|
|
8142
8207
|
|
|
8143
8208
|
// src/cli.ts
|
|
8144
8209
|
program.name("mancode").description(
|
|
8145
|
-
"AI coding agent harness. Modes: solo, man,
|
|
8210
|
+
"AI coding agent harness. Modes: solo, man, manba, manteam, manps."
|
|
8146
8211
|
).version(VERSION);
|
|
8147
8212
|
program.command("init").description("Initialize mancode in the current project").option("--force", "Reinstall even if already initialized").option("--yes", "Skip all confirmations (CI mode)").option("--team", "Force enable team mode (MVP-2)").option("--no-team", "Force disable team mode (MVP-2)").option("--style <name>", "Specify aesthetic style (MVP-2)").option("--platform <platforms>", "Adapters: comma-separated names or all").option("--empty", "Initialize a safe empty directory as a generic project").option("--lang <locale>", "Initialization language: zh-CN or en").action(async (options) => {
|
|
8148
8213
|
const code = await init(process.cwd(), {
|
|
@@ -8175,8 +8240,8 @@ program.command("uninstall [platform]").description("Remove platform adapter or
|
|
|
8175
8240
|
});
|
|
8176
8241
|
program.command("workflow <subcommand> [args...]").description("Manage mancode workflows").option("--dry-run", "Preview clean without deleting").option("--older-than <duration>", "Clean workflows older than (e.g. 30d)").option("--step <n>", "Update workflow current step").option("--status <status>", "Update workflow status").option(
|
|
8177
8242
|
"--parent-task <taskId>",
|
|
8178
|
-
"Parent /man or /manteam workflow for
|
|
8179
|
-
).option("--blocking-reason <reason>", "Explain why a workflow is blocked").option("--outcome <outcome>", "Set
|
|
8243
|
+
"Parent /man or /manteam workflow for manba"
|
|
8244
|
+
).option("--blocking-reason <reason>", "Explain why a workflow is blocked").option("--outcome <outcome>", "Set manba outcome").option("--plan-version <n>", "Set the next man/manteam plan revision").option("--skipped <steps>", "Update skipped steps as comma-separated values").option("--review-depth <depth>", "Review depth: targeted or full").option("--review-domain <domain>", "Review domain: quality or security").option(
|
|
8180
8245
|
"--report <path>",
|
|
8181
8246
|
"Relative Markdown report path for a review domain"
|
|
8182
8247
|
).option("--blockers <ids>", "Comma-separated blocker ids found by a review").option(
|