maxsimcli 4.7.1 → 4.9.0
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/assets/CHANGELOG.md +20 -0
- package/dist/assets/hooks/maxsim-check-update.cjs +38 -0
- package/dist/assets/hooks/maxsim-check-update.cjs.map +1 -1
- package/dist/assets/hooks/maxsim-statusline.cjs +116 -48
- package/dist/assets/hooks/maxsim-statusline.cjs.map +1 -1
- package/dist/assets/hooks/maxsim-sync-reminder.cjs +117 -0
- package/dist/assets/hooks/maxsim-sync-reminder.cjs.map +1 -0
- package/dist/assets/templates/agents/AGENTS.md +78 -106
- package/dist/assets/templates/agents/executor.md +101 -0
- package/dist/assets/templates/agents/planner.md +86 -0
- package/dist/assets/templates/agents/researcher.md +71 -0
- package/dist/assets/templates/agents/verifier.md +88 -0
- package/dist/assets/templates/commands/maxsim/debug.md +7 -7
- package/dist/assets/templates/commands/maxsim/execute.md +45 -0
- package/dist/assets/templates/commands/maxsim/go.md +29 -0
- package/dist/assets/templates/commands/maxsim/help.md +2 -2
- package/dist/assets/templates/commands/maxsim/init.md +52 -0
- package/dist/assets/templates/commands/maxsim/plan.md +50 -0
- package/dist/assets/templates/commands/maxsim/progress.md +4 -3
- package/dist/assets/templates/commands/maxsim/quick.md +6 -4
- package/dist/assets/templates/commands/maxsim/settings.md +4 -3
- package/dist/assets/templates/references/continuation-format.md +16 -16
- package/dist/assets/templates/references/model-profile-resolution.md +1 -1
- package/dist/assets/templates/references/model-profiles.md +12 -19
- package/dist/assets/templates/rules/conventions.md +51 -0
- package/dist/assets/templates/rules/verification-protocol.md +57 -0
- package/dist/assets/templates/skills/agent-system-map/SKILL.md +92 -0
- package/dist/assets/templates/skills/brainstorming/SKILL.md +48 -36
- package/dist/assets/templates/skills/code-review/SKILL.md +40 -61
- package/dist/assets/templates/skills/commit-conventions/SKILL.md +75 -0
- package/dist/assets/templates/skills/evidence-collection/SKILL.md +87 -0
- package/dist/assets/templates/skills/handoff-contract/SKILL.md +70 -0
- package/dist/assets/templates/skills/input-validation/SKILL.md +51 -0
- package/dist/assets/templates/skills/maxsim-batch/SKILL.md +41 -45
- package/dist/assets/templates/skills/maxsim-simplify/SKILL.md +37 -90
- package/dist/assets/templates/skills/memory-management/SKILL.md +32 -67
- package/dist/assets/templates/skills/research-methodology/SKILL.md +137 -0
- package/dist/assets/templates/skills/roadmap-writing/SKILL.md +40 -58
- package/dist/assets/templates/skills/sdd/SKILL.md +34 -69
- package/dist/assets/templates/skills/systematic-debugging/SKILL.md +20 -26
- package/dist/assets/templates/skills/tdd/SKILL.md +25 -33
- package/dist/assets/templates/skills/tool-priority-guide/SKILL.md +80 -0
- package/dist/assets/templates/skills/using-maxsim/SKILL.md +42 -73
- package/dist/assets/templates/skills/verification-before-completion/SKILL.md +12 -24
- package/dist/assets/templates/skills/verification-gates/SKILL.md +169 -0
- package/dist/assets/templates/templates/UAT.md +3 -3
- package/dist/assets/templates/templates/VALIDATION.md +1 -1
- package/dist/assets/templates/templates/context.md +4 -4
- package/dist/assets/templates/templates/debug-subagent-prompt.md +3 -3
- package/dist/assets/templates/templates/discovery.md +2 -2
- package/dist/assets/templates/templates/phase-prompt.md +2 -2
- package/dist/assets/templates/templates/planner-subagent-prompt.md +7 -7
- package/dist/assets/templates/templates/project.md +1 -1
- package/dist/assets/templates/templates/research.md +1 -1
- package/dist/assets/templates/templates/state.md +2 -2
- package/dist/assets/templates/templates/summary.md +41 -0
- package/dist/assets/templates/workflows/batch.md +5 -5
- package/dist/assets/templates/workflows/diagnose-issues.md +2 -2
- package/dist/assets/templates/workflows/discovery-phase.md +3 -3
- package/dist/assets/templates/workflows/discuss-phase.md +11 -11
- package/dist/assets/templates/workflows/execute-phase.md +205 -11
- package/dist/assets/templates/workflows/execute-plan.md +299 -34
- package/dist/assets/templates/workflows/execute.md +421 -0
- package/dist/assets/templates/workflows/go.md +250 -0
- package/dist/assets/templates/workflows/health.md +5 -5
- package/dist/assets/templates/workflows/help.md +165 -435
- package/dist/assets/templates/workflows/init-existing.md +23 -23
- package/dist/assets/templates/workflows/init.md +205 -0
- package/dist/assets/templates/workflows/new-milestone.md +9 -9
- package/dist/assets/templates/workflows/new-project.md +26 -26
- package/dist/assets/templates/workflows/plan-create.md +298 -0
- package/dist/assets/templates/workflows/plan-discuss.md +347 -0
- package/dist/assets/templates/workflows/plan-phase.md +29 -29
- package/dist/assets/templates/workflows/plan-research.md +177 -0
- package/dist/assets/templates/workflows/plan.md +231 -0
- package/dist/assets/templates/workflows/progress.md +46 -42
- package/dist/assets/templates/workflows/quick.md +195 -14
- package/dist/assets/templates/workflows/research-phase.md +5 -5
- package/dist/assets/templates/workflows/sdd.md +20 -12
- package/dist/assets/templates/workflows/settings.md +18 -14
- package/dist/assets/templates/workflows/verify-phase.md +1 -1
- package/dist/assets/templates/workflows/verify-work.md +16 -16
- package/dist/cli.cjs +496 -91
- package/dist/cli.cjs.map +1 -1
- package/dist/core-D5zUr9cb.cjs.map +1 -1
- package/dist/install.cjs +274 -355
- package/dist/install.cjs.map +1 -1
- package/dist/mcp-server.cjs +5213 -2248
- package/dist/mcp-server.cjs.map +1 -1
- package/dist/skills-CjFWZIGM.cjs.map +1 -1
- package/package.json +4 -1
- package/dist/assets/hooks/maxsim-context-monitor.cjs +0 -121
- package/dist/assets/hooks/maxsim-context-monitor.cjs.map +0 -1
- package/dist/assets/templates/agents/maxsim-code-reviewer.md +0 -239
- package/dist/assets/templates/agents/maxsim-codebase-mapper.md +0 -214
- package/dist/assets/templates/agents/maxsim-debugger.md +0 -572
- package/dist/assets/templates/agents/maxsim-drift-checker.md +0 -522
- package/dist/assets/templates/agents/maxsim-executor.md +0 -504
- package/dist/assets/templates/agents/maxsim-integration-checker.md +0 -273
- package/dist/assets/templates/agents/maxsim-phase-researcher.md +0 -305
- package/dist/assets/templates/agents/maxsim-plan-checker.md +0 -343
- package/dist/assets/templates/agents/maxsim-planner.md +0 -610
- package/dist/assets/templates/agents/maxsim-project-researcher.md +0 -359
- package/dist/assets/templates/agents/maxsim-research-synthesizer.md +0 -263
- package/dist/assets/templates/agents/maxsim-roadmapper.md +0 -324
- package/dist/assets/templates/agents/maxsim-spec-reviewer.md +0 -245
- package/dist/assets/templates/agents/maxsim-verifier.md +0 -393
- package/dist/assets/templates/commands/maxsim/add-phase.md +0 -43
- package/dist/assets/templates/commands/maxsim/add-tests.md +0 -41
- package/dist/assets/templates/commands/maxsim/add-todo.md +0 -57
- package/dist/assets/templates/commands/maxsim/artefakte.md +0 -122
- package/dist/assets/templates/commands/maxsim/audit-milestone.md +0 -36
- package/dist/assets/templates/commands/maxsim/batch.md +0 -42
- package/dist/assets/templates/commands/maxsim/check-drift.md +0 -56
- package/dist/assets/templates/commands/maxsim/check-todos.md +0 -46
- package/dist/assets/templates/commands/maxsim/cleanup.md +0 -18
- package/dist/assets/templates/commands/maxsim/complete-milestone.md +0 -136
- package/dist/assets/templates/commands/maxsim/discuss-phase.md +0 -87
- package/dist/assets/templates/commands/maxsim/discuss.md +0 -70
- package/dist/assets/templates/commands/maxsim/execute-phase.md +0 -41
- package/dist/assets/templates/commands/maxsim/health.md +0 -22
- package/dist/assets/templates/commands/maxsim/init-existing.md +0 -46
- package/dist/assets/templates/commands/maxsim/insert-phase.md +0 -32
- package/dist/assets/templates/commands/maxsim/list-phase-assumptions.md +0 -46
- package/dist/assets/templates/commands/maxsim/map-codebase.md +0 -71
- package/dist/assets/templates/commands/maxsim/new-milestone.md +0 -44
- package/dist/assets/templates/commands/maxsim/new-project.md +0 -46
- package/dist/assets/templates/commands/maxsim/pause-work.md +0 -38
- package/dist/assets/templates/commands/maxsim/plan-milestone-gaps.md +0 -34
- package/dist/assets/templates/commands/maxsim/plan-phase.md +0 -44
- package/dist/assets/templates/commands/maxsim/realign.md +0 -39
- package/dist/assets/templates/commands/maxsim/reapply-patches.md +0 -110
- package/dist/assets/templates/commands/maxsim/remove-phase.md +0 -31
- package/dist/assets/templates/commands/maxsim/research-phase.md +0 -189
- package/dist/assets/templates/commands/maxsim/resume-work.md +0 -40
- package/dist/assets/templates/commands/maxsim/roadmap.md +0 -19
- package/dist/assets/templates/commands/maxsim/sdd.md +0 -39
- package/dist/assets/templates/commands/maxsim/set-profile.md +0 -34
- package/dist/assets/templates/commands/maxsim/update.md +0 -37
- package/dist/assets/templates/commands/maxsim/verify-work.md +0 -38
- package/dist/assets/templates/workflows/add-phase.md +0 -111
- package/dist/assets/templates/workflows/add-tests.md +0 -351
- package/dist/assets/templates/workflows/add-todo.md +0 -247
- package/dist/assets/templates/workflows/audit-milestone.md +0 -297
- package/dist/assets/templates/workflows/check-drift.md +0 -248
- package/dist/assets/templates/workflows/check-todos.md +0 -261
- package/dist/assets/templates/workflows/cleanup.md +0 -153
- package/dist/assets/templates/workflows/complete-milestone.md +0 -701
- package/dist/assets/templates/workflows/discuss.md +0 -343
- package/dist/assets/templates/workflows/insert-phase.md +0 -129
- package/dist/assets/templates/workflows/list-phase-assumptions.md +0 -178
- package/dist/assets/templates/workflows/map-codebase.md +0 -315
- package/dist/assets/templates/workflows/pause-work.md +0 -122
- package/dist/assets/templates/workflows/plan-milestone-gaps.md +0 -274
- package/dist/assets/templates/workflows/realign.md +0 -288
- package/dist/assets/templates/workflows/remove-phase.md +0 -154
- package/dist/assets/templates/workflows/resume-project.md +0 -306
- package/dist/assets/templates/workflows/roadmap.md +0 -130
- package/dist/assets/templates/workflows/set-profile.md +0 -81
- package/dist/assets/templates/workflows/transition.md +0 -544
- package/dist/assets/templates/workflows/update.md +0 -220
package/dist/cli.cjs
CHANGED
|
@@ -69,7 +69,15 @@ const PLANNING_CONFIG_DEFAULTS = {
|
|
|
69
69
|
verifier: true
|
|
70
70
|
},
|
|
71
71
|
parallelization: true,
|
|
72
|
-
brave_search: false
|
|
72
|
+
brave_search: false,
|
|
73
|
+
worktree_mode: "auto",
|
|
74
|
+
max_parallel_agents: 10,
|
|
75
|
+
review: {
|
|
76
|
+
spec_review: true,
|
|
77
|
+
code_review: true,
|
|
78
|
+
simplify_review: true,
|
|
79
|
+
retry_limit: 3
|
|
80
|
+
}
|
|
73
81
|
};
|
|
74
82
|
|
|
75
83
|
//#endregion
|
|
@@ -4655,73 +4663,25 @@ var require_slugify = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
4655
4663
|
*/
|
|
4656
4664
|
var import_slugify = /* @__PURE__ */ __toESM(require_slugify());
|
|
4657
4665
|
const MODEL_PROFILES = {
|
|
4658
|
-
"
|
|
4659
|
-
quality: "opus",
|
|
4660
|
-
balanced: "opus",
|
|
4661
|
-
budget: "sonnet",
|
|
4662
|
-
tokenburner: "opus"
|
|
4663
|
-
},
|
|
4664
|
-
"maxsim-roadmapper": {
|
|
4666
|
+
"executor": {
|
|
4665
4667
|
quality: "opus",
|
|
4666
4668
|
balanced: "sonnet",
|
|
4667
4669
|
budget: "sonnet",
|
|
4668
4670
|
tokenburner: "opus"
|
|
4669
4671
|
},
|
|
4670
|
-
"
|
|
4672
|
+
"planner": {
|
|
4671
4673
|
quality: "opus",
|
|
4672
|
-
balanced: "
|
|
4674
|
+
balanced: "opus",
|
|
4673
4675
|
budget: "sonnet",
|
|
4674
4676
|
tokenburner: "opus"
|
|
4675
4677
|
},
|
|
4676
|
-
"
|
|
4678
|
+
"researcher": {
|
|
4677
4679
|
quality: "opus",
|
|
4678
4680
|
balanced: "sonnet",
|
|
4679
4681
|
budget: "haiku",
|
|
4680
4682
|
tokenburner: "opus"
|
|
4681
4683
|
},
|
|
4682
|
-
"
|
|
4683
|
-
quality: "opus",
|
|
4684
|
-
balanced: "sonnet",
|
|
4685
|
-
budget: "haiku",
|
|
4686
|
-
tokenburner: "opus"
|
|
4687
|
-
},
|
|
4688
|
-
"maxsim-research-synthesizer": {
|
|
4689
|
-
quality: "sonnet",
|
|
4690
|
-
balanced: "sonnet",
|
|
4691
|
-
budget: "haiku",
|
|
4692
|
-
tokenburner: "opus"
|
|
4693
|
-
},
|
|
4694
|
-
"maxsim-debugger": {
|
|
4695
|
-
quality: "opus",
|
|
4696
|
-
balanced: "sonnet",
|
|
4697
|
-
budget: "sonnet",
|
|
4698
|
-
tokenburner: "opus"
|
|
4699
|
-
},
|
|
4700
|
-
"maxsim-codebase-mapper": {
|
|
4701
|
-
quality: "sonnet",
|
|
4702
|
-
balanced: "haiku",
|
|
4703
|
-
budget: "haiku",
|
|
4704
|
-
tokenburner: "opus"
|
|
4705
|
-
},
|
|
4706
|
-
"maxsim-verifier": {
|
|
4707
|
-
quality: "sonnet",
|
|
4708
|
-
balanced: "sonnet",
|
|
4709
|
-
budget: "haiku",
|
|
4710
|
-
tokenburner: "opus"
|
|
4711
|
-
},
|
|
4712
|
-
"maxsim-plan-checker": {
|
|
4713
|
-
quality: "sonnet",
|
|
4714
|
-
balanced: "sonnet",
|
|
4715
|
-
budget: "haiku",
|
|
4716
|
-
tokenburner: "opus"
|
|
4717
|
-
},
|
|
4718
|
-
"maxsim-integration-checker": {
|
|
4719
|
-
quality: "sonnet",
|
|
4720
|
-
balanced: "sonnet",
|
|
4721
|
-
budget: "haiku",
|
|
4722
|
-
tokenburner: "opus"
|
|
4723
|
-
},
|
|
4724
|
-
"maxsim-drift-checker": {
|
|
4684
|
+
"verifier": {
|
|
4725
4685
|
quality: "sonnet",
|
|
4726
4686
|
balanced: "sonnet",
|
|
4727
4687
|
budget: "haiku",
|
|
@@ -4921,6 +4881,12 @@ async function pathExistsInternal(p) {
|
|
|
4921
4881
|
async function loadConfig(cwd) {
|
|
4922
4882
|
if (_configCache && _configCache.cwd === cwd) return _configCache.config;
|
|
4923
4883
|
const cfgPath = configPath(cwd);
|
|
4884
|
+
const reviewDefaults = {
|
|
4885
|
+
spec_review: true,
|
|
4886
|
+
code_review: true,
|
|
4887
|
+
simplify_review: true,
|
|
4888
|
+
retry_limit: 3
|
|
4889
|
+
};
|
|
4924
4890
|
const defaults = {
|
|
4925
4891
|
model_profile: "balanced",
|
|
4926
4892
|
commit_docs: true,
|
|
@@ -4932,7 +4898,10 @@ async function loadConfig(cwd) {
|
|
|
4932
4898
|
plan_checker: true,
|
|
4933
4899
|
verifier: true,
|
|
4934
4900
|
parallelization: true,
|
|
4935
|
-
brave_search: false
|
|
4901
|
+
brave_search: false,
|
|
4902
|
+
worktree_mode: "auto",
|
|
4903
|
+
max_parallel_agents: 10,
|
|
4904
|
+
review: reviewDefaults
|
|
4936
4905
|
};
|
|
4937
4906
|
try {
|
|
4938
4907
|
const raw = await node_fs.promises.readFile(cfgPath, "utf-8");
|
|
@@ -4989,7 +4958,17 @@ async function loadConfig(cwd) {
|
|
|
4989
4958
|
}) ?? defaults.verifier,
|
|
4990
4959
|
parallelization,
|
|
4991
4960
|
brave_search: get("brave_search") ?? defaults.brave_search,
|
|
4992
|
-
model_overrides: parsed["model_overrides"]
|
|
4961
|
+
model_overrides: parsed["model_overrides"],
|
|
4962
|
+
worktree_mode: get("worktree_mode") ?? defaults.worktree_mode,
|
|
4963
|
+
max_parallel_agents: get("max_parallel_agents") ?? defaults.max_parallel_agents,
|
|
4964
|
+
review: (() => {
|
|
4965
|
+
const userReview = get("review");
|
|
4966
|
+
if (!userReview || typeof userReview !== "object") return reviewDefaults;
|
|
4967
|
+
return {
|
|
4968
|
+
...reviewDefaults,
|
|
4969
|
+
...userReview
|
|
4970
|
+
};
|
|
4971
|
+
})()
|
|
4993
4972
|
};
|
|
4994
4973
|
_configCache = {
|
|
4995
4974
|
cwd,
|
|
@@ -12041,6 +12020,10 @@ function cmdConfigEnsureSection(cwd, raw) {
|
|
|
12041
12020
|
workflow: {
|
|
12042
12021
|
...hardcoded.workflow,
|
|
12043
12022
|
...userDefaults.workflow || {}
|
|
12023
|
+
},
|
|
12024
|
+
review: {
|
|
12025
|
+
...hardcoded.review,
|
|
12026
|
+
...userDefaults.review || {}
|
|
12044
12027
|
}
|
|
12045
12028
|
};
|
|
12046
12029
|
try {
|
|
@@ -14177,6 +14160,122 @@ async function cmdVerifyKeyLinks(cwd, planFilePath) {
|
|
|
14177
14160
|
links: results
|
|
14178
14161
|
}, verified === results.length ? "valid" : "invalid");
|
|
14179
14162
|
}
|
|
14163
|
+
/**
|
|
14164
|
+
* Gate G1: Validate that all requirement IDs from a plan's frontmatter exist in REQUIREMENTS.md.
|
|
14165
|
+
* Parses REQUIREMENTS.md for **{ID}**: patterns and checks each reqId is present.
|
|
14166
|
+
*/
|
|
14167
|
+
async function validateRequirementExistence(cwd, reqIds) {
|
|
14168
|
+
const content = await safeReadFile(planningPath(cwd, "REQUIREMENTS.md"));
|
|
14169
|
+
if (!content) return {
|
|
14170
|
+
valid: false,
|
|
14171
|
+
missing: reqIds,
|
|
14172
|
+
found: []
|
|
14173
|
+
};
|
|
14174
|
+
const idPattern = /\*\*([A-Z]+-\d+)\*\*/g;
|
|
14175
|
+
const existingIds = /* @__PURE__ */ new Set();
|
|
14176
|
+
let m;
|
|
14177
|
+
while ((m = idPattern.exec(content)) !== null) existingIds.add(m[1]);
|
|
14178
|
+
const found = [];
|
|
14179
|
+
const missing = [];
|
|
14180
|
+
for (const id of reqIds) {
|
|
14181
|
+
const trimmed = id.trim();
|
|
14182
|
+
if (!trimmed) continue;
|
|
14183
|
+
if (existingIds.has(trimmed)) found.push(trimmed);
|
|
14184
|
+
else missing.push(trimmed);
|
|
14185
|
+
}
|
|
14186
|
+
return {
|
|
14187
|
+
valid: missing.length === 0,
|
|
14188
|
+
missing,
|
|
14189
|
+
found
|
|
14190
|
+
};
|
|
14191
|
+
}
|
|
14192
|
+
async function cmdValidateRequirementExistence(cwd, reqIds) {
|
|
14193
|
+
if (!reqIds || reqIds.length === 0) return cmdErr("At least one requirement ID required");
|
|
14194
|
+
const result = await validateRequirementExistence(cwd, reqIds);
|
|
14195
|
+
return cmdOk(result, result.valid ? "valid" : "invalid");
|
|
14196
|
+
}
|
|
14197
|
+
/**
|
|
14198
|
+
* Gate G2: Validate that requirement IDs are not already marked Complete in REQUIREMENTS.md.
|
|
14199
|
+
* Checks checkbox status: [x] = complete, [ ] = pending.
|
|
14200
|
+
*/
|
|
14201
|
+
async function validateRequirementStatus(cwd, reqIds) {
|
|
14202
|
+
const content = await safeReadFile(planningPath(cwd, "REQUIREMENTS.md"));
|
|
14203
|
+
if (!content) return {
|
|
14204
|
+
valid: true,
|
|
14205
|
+
already_complete: [],
|
|
14206
|
+
pending: reqIds
|
|
14207
|
+
};
|
|
14208
|
+
const lines = content.split("\n");
|
|
14209
|
+
const statusMap = /* @__PURE__ */ new Map();
|
|
14210
|
+
for (const line of lines) {
|
|
14211
|
+
const match = line.match(/^-\s*\[([ xX])\]\s*\*\*([A-Z]+-\d+)\*\*/);
|
|
14212
|
+
if (match) {
|
|
14213
|
+
const isComplete = match[1].toLowerCase() === "x";
|
|
14214
|
+
statusMap.set(match[2], isComplete);
|
|
14215
|
+
}
|
|
14216
|
+
}
|
|
14217
|
+
const already_complete = [];
|
|
14218
|
+
const pending = [];
|
|
14219
|
+
for (const id of reqIds) {
|
|
14220
|
+
const trimmed = id.trim();
|
|
14221
|
+
if (!trimmed) continue;
|
|
14222
|
+
if (statusMap.get(trimmed) === true) already_complete.push(trimmed);
|
|
14223
|
+
else pending.push(trimmed);
|
|
14224
|
+
}
|
|
14225
|
+
return {
|
|
14226
|
+
valid: already_complete.length === 0,
|
|
14227
|
+
already_complete,
|
|
14228
|
+
pending
|
|
14229
|
+
};
|
|
14230
|
+
}
|
|
14231
|
+
async function cmdValidateRequirementStatus(cwd, reqIds) {
|
|
14232
|
+
if (!reqIds || reqIds.length === 0) return cmdErr("At least one requirement ID required");
|
|
14233
|
+
const result = await validateRequirementStatus(cwd, reqIds);
|
|
14234
|
+
return cmdOk(result, result.valid ? "valid" : "invalid");
|
|
14235
|
+
}
|
|
14236
|
+
/**
|
|
14237
|
+
* Gate G6: Validate that SUMMARY.md has evidence for each requirement ID.
|
|
14238
|
+
* Parses the ## Requirement Evidence section table rows and checks Status != UNMET.
|
|
14239
|
+
*/
|
|
14240
|
+
async function validateEvidenceCompleteness(summaryPath, reqIds) {
|
|
14241
|
+
const content = await safeReadFile(summaryPath);
|
|
14242
|
+
if (!content) return {
|
|
14243
|
+
valid: false,
|
|
14244
|
+
missing_evidence: reqIds,
|
|
14245
|
+
has_evidence: []
|
|
14246
|
+
};
|
|
14247
|
+
const sectionMatch = content.match(/##\s*Requirement Evidence[\s\S]*?(?=\n##\s|\n---\s*\n|$)/);
|
|
14248
|
+
if (!sectionMatch) return {
|
|
14249
|
+
valid: false,
|
|
14250
|
+
missing_evidence: reqIds,
|
|
14251
|
+
has_evidence: []
|
|
14252
|
+
};
|
|
14253
|
+
const section = sectionMatch[0];
|
|
14254
|
+
const evidenceIds = /* @__PURE__ */ new Map();
|
|
14255
|
+
const rowPattern = /\|\s*([A-Z]+-\d+)\s*\|[^|]*\|\s*(\w+)\s*\|/g;
|
|
14256
|
+
let rm;
|
|
14257
|
+
while ((rm = rowPattern.exec(section)) !== null) evidenceIds.set(rm[1], rm[2].toUpperCase());
|
|
14258
|
+
const has_evidence = [];
|
|
14259
|
+
const missing_evidence = [];
|
|
14260
|
+
for (const id of reqIds) {
|
|
14261
|
+
const trimmed = id.trim();
|
|
14262
|
+
if (!trimmed) continue;
|
|
14263
|
+
const status = evidenceIds.get(trimmed);
|
|
14264
|
+
if (status && status !== "UNMET") has_evidence.push(trimmed);
|
|
14265
|
+
else missing_evidence.push(trimmed);
|
|
14266
|
+
}
|
|
14267
|
+
return {
|
|
14268
|
+
valid: missing_evidence.length === 0,
|
|
14269
|
+
missing_evidence,
|
|
14270
|
+
has_evidence
|
|
14271
|
+
};
|
|
14272
|
+
}
|
|
14273
|
+
async function cmdValidateEvidenceCompleteness(cwd, summaryFilePath, reqIds) {
|
|
14274
|
+
if (!summaryFilePath) return cmdErr("summary file path required");
|
|
14275
|
+
if (!reqIds || reqIds.length === 0) return cmdErr("At least one requirement ID required");
|
|
14276
|
+
const result = await validateEvidenceCompleteness(node_path.default.isAbsolute(summaryFilePath) ? summaryFilePath : node_path.default.join(cwd, summaryFilePath), reqIds);
|
|
14277
|
+
return cmdOk(result, result.valid ? "valid" : "invalid");
|
|
14278
|
+
}
|
|
14180
14279
|
async function cmdValidateConsistency(cwd) {
|
|
14181
14280
|
const rmPath = roadmapPath(cwd);
|
|
14182
14281
|
const phasesDir = phasesPath(cwd);
|
|
@@ -16044,8 +16143,8 @@ async function cmdInitExecutePhase(cwd, phase) {
|
|
|
16044
16143
|
const milestone = await getMilestoneInfo(cwd);
|
|
16045
16144
|
const phase_req_ids = await extractReqIds(cwd, phase);
|
|
16046
16145
|
return cmdOk({
|
|
16047
|
-
executor_model: await resolveModelInternal(cwd, "
|
|
16048
|
-
verifier_model: await resolveModelInternal(cwd, "
|
|
16146
|
+
executor_model: await resolveModelInternal(cwd, "executor"),
|
|
16147
|
+
verifier_model: await resolveModelInternal(cwd, "verifier"),
|
|
16049
16148
|
commit_docs: config.commit_docs,
|
|
16050
16149
|
parallelization: config.parallelization,
|
|
16051
16150
|
branching_strategy: config.branching_strategy,
|
|
@@ -16072,7 +16171,15 @@ async function cmdInitExecutePhase(cwd, phase) {
|
|
|
16072
16171
|
config_exists: await pathExistsInternal(planningPath(cwd, "config.json")),
|
|
16073
16172
|
state_path: ".planning/STATE.md",
|
|
16074
16173
|
roadmap_path: ".planning/ROADMAP.md",
|
|
16075
|
-
config_path: ".planning/config.json"
|
|
16174
|
+
config_path: ".planning/config.json",
|
|
16175
|
+
worktree_mode: config.worktree_mode ?? "auto",
|
|
16176
|
+
max_parallel_agents: config.max_parallel_agents ?? 10,
|
|
16177
|
+
review_config: config.review ?? {
|
|
16178
|
+
spec_review: true,
|
|
16179
|
+
code_review: true,
|
|
16180
|
+
simplify_review: true,
|
|
16181
|
+
retry_limit: 3
|
|
16182
|
+
}
|
|
16076
16183
|
});
|
|
16077
16184
|
}
|
|
16078
16185
|
async function cmdInitPlanPhase(cwd, phase) {
|
|
@@ -16081,9 +16188,9 @@ async function cmdInitPlanPhase(cwd, phase) {
|
|
|
16081
16188
|
const phaseInfo = await findPhaseInternal(cwd, phase);
|
|
16082
16189
|
const phase_req_ids = await extractReqIds(cwd, phase);
|
|
16083
16190
|
const result = {
|
|
16084
|
-
researcher_model: await resolveModelInternal(cwd, "
|
|
16085
|
-
planner_model: await resolveModelInternal(cwd, "
|
|
16086
|
-
checker_model: await resolveModelInternal(cwd, "
|
|
16191
|
+
researcher_model: await resolveModelInternal(cwd, "researcher"),
|
|
16192
|
+
planner_model: await resolveModelInternal(cwd, "planner"),
|
|
16193
|
+
checker_model: await resolveModelInternal(cwd, "planner"),
|
|
16087
16194
|
research_enabled: config.research,
|
|
16088
16195
|
plan_checker_enabled: config.plan_checker,
|
|
16089
16196
|
commit_docs: config.commit_docs,
|
|
@@ -16123,9 +16230,9 @@ async function cmdInitNewProject(cwd) {
|
|
|
16123
16230
|
const hasPackageFile = await pathExistsInternal(node_path.default.join(cwd, "package.json")) || await pathExistsInternal(node_path.default.join(cwd, "requirements.txt")) || await pathExistsInternal(node_path.default.join(cwd, "Cargo.toml")) || await pathExistsInternal(node_path.default.join(cwd, "go.mod")) || await pathExistsInternal(node_path.default.join(cwd, "Package.swift"));
|
|
16124
16231
|
const hasCodebaseMap = await pathExistsInternal(planningPath(cwd, "codebase"));
|
|
16125
16232
|
return cmdOk({
|
|
16126
|
-
researcher_model: await resolveModelInternal(cwd, "
|
|
16127
|
-
synthesizer_model: await resolveModelInternal(cwd, "
|
|
16128
|
-
roadmapper_model: await resolveModelInternal(cwd, "
|
|
16233
|
+
researcher_model: await resolveModelInternal(cwd, "researcher"),
|
|
16234
|
+
synthesizer_model: await resolveModelInternal(cwd, "researcher"),
|
|
16235
|
+
roadmapper_model: await resolveModelInternal(cwd, "planner"),
|
|
16129
16236
|
commit_docs: config.commit_docs,
|
|
16130
16237
|
project_exists: await pathExistsInternal(planningPath(cwd, "PROJECT.md")),
|
|
16131
16238
|
has_codebase_map: hasCodebaseMap,
|
|
@@ -16143,9 +16250,9 @@ async function cmdInitNewMilestone(cwd) {
|
|
|
16143
16250
|
const config = await loadConfig(cwd);
|
|
16144
16251
|
const milestone = await getMilestoneInfo(cwd);
|
|
16145
16252
|
return cmdOk({
|
|
16146
|
-
researcher_model: await resolveModelInternal(cwd, "
|
|
16147
|
-
synthesizer_model: await resolveModelInternal(cwd, "
|
|
16148
|
-
roadmapper_model: await resolveModelInternal(cwd, "
|
|
16253
|
+
researcher_model: await resolveModelInternal(cwd, "researcher"),
|
|
16254
|
+
synthesizer_model: await resolveModelInternal(cwd, "researcher"),
|
|
16255
|
+
roadmapper_model: await resolveModelInternal(cwd, "planner"),
|
|
16149
16256
|
commit_docs: config.commit_docs,
|
|
16150
16257
|
research_enabled: config.research,
|
|
16151
16258
|
current_milestone: milestone.version,
|
|
@@ -16171,10 +16278,10 @@ async function cmdInitQuick(cwd, description) {
|
|
|
16171
16278
|
debugLog(e);
|
|
16172
16279
|
}
|
|
16173
16280
|
return cmdOk({
|
|
16174
|
-
planner_model: await resolveModelInternal(cwd, "
|
|
16175
|
-
executor_model: await resolveModelInternal(cwd, "
|
|
16176
|
-
checker_model: await resolveModelInternal(cwd, "
|
|
16177
|
-
verifier_model: await resolveModelInternal(cwd, "
|
|
16281
|
+
planner_model: await resolveModelInternal(cwd, "planner"),
|
|
16282
|
+
executor_model: await resolveModelInternal(cwd, "executor"),
|
|
16283
|
+
checker_model: await resolveModelInternal(cwd, "planner"),
|
|
16284
|
+
verifier_model: await resolveModelInternal(cwd, "verifier"),
|
|
16178
16285
|
commit_docs: config.commit_docs,
|
|
16179
16286
|
next_num: nextNum,
|
|
16180
16287
|
slug,
|
|
@@ -16213,8 +16320,8 @@ async function cmdInitVerifyWork(cwd, phase) {
|
|
|
16213
16320
|
const config = await loadConfig(cwd);
|
|
16214
16321
|
const phaseInfo = await findPhaseInternal(cwd, phase);
|
|
16215
16322
|
return cmdOk({
|
|
16216
|
-
planner_model: await resolveModelInternal(cwd, "
|
|
16217
|
-
checker_model: await resolveModelInternal(cwd, "
|
|
16323
|
+
planner_model: await resolveModelInternal(cwd, "planner"),
|
|
16324
|
+
checker_model: await resolveModelInternal(cwd, "planner"),
|
|
16218
16325
|
commit_docs: config.commit_docs,
|
|
16219
16326
|
phase_found: !!phaseInfo,
|
|
16220
16327
|
phase_dir: phaseInfo?.directory ?? null,
|
|
@@ -16369,7 +16476,7 @@ async function cmdInitMapCodebase(cwd) {
|
|
|
16369
16476
|
debugLog(e);
|
|
16370
16477
|
}
|
|
16371
16478
|
return cmdOk({
|
|
16372
|
-
mapper_model: await resolveModelInternal(cwd, "
|
|
16479
|
+
mapper_model: await resolveModelInternal(cwd, "researcher"),
|
|
16373
16480
|
commit_docs: config.commit_docs,
|
|
16374
16481
|
search_gitignored: config.search_gitignored,
|
|
16375
16482
|
parallelization: config.parallelization,
|
|
@@ -16395,10 +16502,10 @@ async function cmdInitExisting(cwd) {
|
|
|
16395
16502
|
debugLog(e);
|
|
16396
16503
|
}
|
|
16397
16504
|
return cmdOk({
|
|
16398
|
-
researcher_model: await resolveModelInternal(cwd, "
|
|
16399
|
-
synthesizer_model: await resolveModelInternal(cwd, "
|
|
16400
|
-
roadmapper_model: await resolveModelInternal(cwd, "
|
|
16401
|
-
mapper_model: await resolveModelInternal(cwd, "
|
|
16505
|
+
researcher_model: await resolveModelInternal(cwd, "researcher"),
|
|
16506
|
+
synthesizer_model: await resolveModelInternal(cwd, "researcher"),
|
|
16507
|
+
roadmapper_model: await resolveModelInternal(cwd, "planner"),
|
|
16508
|
+
mapper_model: await resolveModelInternal(cwd, "researcher"),
|
|
16402
16509
|
commit_docs: config.commit_docs,
|
|
16403
16510
|
project_exists: await pathExistsInternal(planningPath(cwd, "PROJECT.md")),
|
|
16404
16511
|
planning_exists: await pathExistsInternal(planningPath(cwd)),
|
|
@@ -16459,8 +16566,8 @@ async function cmdInitProgress(cwd) {
|
|
|
16459
16566
|
debugLog(e);
|
|
16460
16567
|
}
|
|
16461
16568
|
return cmdOk({
|
|
16462
|
-
executor_model: await resolveModelInternal(cwd, "
|
|
16463
|
-
planner_model: await resolveModelInternal(cwd, "
|
|
16569
|
+
executor_model: await resolveModelInternal(cwd, "executor"),
|
|
16570
|
+
planner_model: await resolveModelInternal(cwd, "planner"),
|
|
16464
16571
|
commit_docs: config.commit_docs,
|
|
16465
16572
|
milestone_version: milestone.version,
|
|
16466
16573
|
milestone_name: milestone.name,
|
|
@@ -16499,8 +16606,8 @@ async function cmdInitExecutor(cwd, phase) {
|
|
|
16499
16606
|
const phaseInfo = await findPhaseInternal(cwd, phase);
|
|
16500
16607
|
const codebaseDocs = listCodebaseDocs(cwd);
|
|
16501
16608
|
const result = {
|
|
16502
|
-
executor_model: await resolveModelInternal(cwd, "
|
|
16503
|
-
verifier_model: await resolveModelInternal(cwd, "
|
|
16609
|
+
executor_model: await resolveModelInternal(cwd, "executor"),
|
|
16610
|
+
verifier_model: await resolveModelInternal(cwd, "verifier"),
|
|
16504
16611
|
commit_docs: config.commit_docs,
|
|
16505
16612
|
parallelization: config.parallelization,
|
|
16506
16613
|
branching_strategy: config.branching_strategy,
|
|
@@ -16523,8 +16630,8 @@ async function cmdInitPlanner(cwd, phase) {
|
|
|
16523
16630
|
const phase_req_ids = await extractReqIds(cwd, phase);
|
|
16524
16631
|
const codebaseDocs = listCodebaseDocs(cwd);
|
|
16525
16632
|
const result = {
|
|
16526
|
-
planner_model: await resolveModelInternal(cwd, "
|
|
16527
|
-
checker_model: await resolveModelInternal(cwd, "
|
|
16633
|
+
planner_model: await resolveModelInternal(cwd, "planner"),
|
|
16634
|
+
checker_model: await resolveModelInternal(cwd, "planner"),
|
|
16528
16635
|
commit_docs: config.commit_docs,
|
|
16529
16636
|
research_enabled: config.research,
|
|
16530
16637
|
plan_checker_enabled: config.plan_checker,
|
|
@@ -16557,7 +16664,7 @@ async function cmdInitResearcher(cwd, phase) {
|
|
|
16557
16664
|
const phase_req_ids = await extractReqIds(cwd, phase);
|
|
16558
16665
|
const codebaseDocs = listCodebaseDocs(cwd);
|
|
16559
16666
|
const result = {
|
|
16560
|
-
researcher_model: await resolveModelInternal(cwd, "
|
|
16667
|
+
researcher_model: await resolveModelInternal(cwd, "researcher"),
|
|
16561
16668
|
commit_docs: config.commit_docs,
|
|
16562
16669
|
brave_search: config.brave_search,
|
|
16563
16670
|
phase_found: !!phaseInfo,
|
|
@@ -16587,7 +16694,7 @@ async function cmdInitVerifier(cwd, phase) {
|
|
|
16587
16694
|
const phase_req_ids = await extractReqIds(cwd, phase);
|
|
16588
16695
|
const codebaseDocs = listCodebaseDocs(cwd);
|
|
16589
16696
|
return cmdOk({
|
|
16590
|
-
verifier_model: await resolveModelInternal(cwd, "
|
|
16697
|
+
verifier_model: await resolveModelInternal(cwd, "verifier"),
|
|
16591
16698
|
commit_docs: config.commit_docs,
|
|
16592
16699
|
phase_found: !!phaseInfo,
|
|
16593
16700
|
phase_dir: phaseInfo?.directory ?? null,
|
|
@@ -16605,7 +16712,7 @@ async function cmdInitDebugger(cwd, phase) {
|
|
|
16605
16712
|
const phaseInfo = phase ? await findPhaseInternal(cwd, phase) : null;
|
|
16606
16713
|
const codebaseDocs = listCodebaseDocs(cwd);
|
|
16607
16714
|
const result = {
|
|
16608
|
-
debugger_model: await resolveModelInternal(cwd, "
|
|
16715
|
+
debugger_model: await resolveModelInternal(cwd, "verifier"),
|
|
16609
16716
|
commit_docs: config.commit_docs,
|
|
16610
16717
|
phase_found: !!phaseInfo,
|
|
16611
16718
|
phase_dir: phaseInfo?.directory ?? null,
|
|
@@ -16619,7 +16726,7 @@ async function cmdInitDebugger(cwd, phase) {
|
|
|
16619
16726
|
}
|
|
16620
16727
|
async function cmdInitCheckDrift(cwd) {
|
|
16621
16728
|
const config = await loadConfig(cwd);
|
|
16622
|
-
const driftModel = await resolveModelInternal(cwd, "
|
|
16729
|
+
const driftModel = await resolveModelInternal(cwd, "verifier");
|
|
16623
16730
|
const hasPlanning = await pathExistsInternal(planningPath(cwd));
|
|
16624
16731
|
const hasRequirements = await pathExistsInternal(planningPath(cwd, "REQUIREMENTS.md"));
|
|
16625
16732
|
const hasRoadmap = await pathExistsInternal(planningPath(cwd, "ROADMAP.md"));
|
|
@@ -16686,6 +16793,285 @@ async function cmdInitRealign(cwd, direction) {
|
|
|
16686
16793
|
});
|
|
16687
16794
|
}
|
|
16688
16795
|
|
|
16796
|
+
//#endregion
|
|
16797
|
+
//#region src/core/worktree.ts
|
|
16798
|
+
/**
|
|
16799
|
+
* Worktree — Git worktree lifecycle management for parallel execution
|
|
16800
|
+
*
|
|
16801
|
+
* Provides functions to create, list, cleanup worktrees and to assign
|
|
16802
|
+
* plans to worktree slots for batch execution.
|
|
16803
|
+
*/
|
|
16804
|
+
const WORKTREE_DIR = ".maxsim-worktrees";
|
|
16805
|
+
const WORKTREE_BRANCH_PREFIX = "maxsim/worktree";
|
|
16806
|
+
/** Ensure .maxsim-worktrees/ directory exists */
|
|
16807
|
+
function ensureWorktreeDir(cwd) {
|
|
16808
|
+
const dir = node_path.default.join(cwd, WORKTREE_DIR);
|
|
16809
|
+
if (!node_fs.default.existsSync(dir)) node_fs.default.mkdirSync(dir, { recursive: true });
|
|
16810
|
+
return dir;
|
|
16811
|
+
}
|
|
16812
|
+
/** Add .maxsim-worktrees/ to .gitignore if not already present */
|
|
16813
|
+
function ensureGitignoreEntry(cwd) {
|
|
16814
|
+
const gitignorePath = node_path.default.join(cwd, ".gitignore");
|
|
16815
|
+
const entry = WORKTREE_DIR + "/";
|
|
16816
|
+
try {
|
|
16817
|
+
if (node_fs.default.existsSync(gitignorePath)) {
|
|
16818
|
+
if (node_fs.default.readFileSync(gitignorePath, "utf-8").includes(WORKTREE_DIR)) return;
|
|
16819
|
+
node_fs.default.appendFileSync(gitignorePath, "\n" + entry + "\n", "utf-8");
|
|
16820
|
+
} else node_fs.default.writeFileSync(gitignorePath, entry + "\n", "utf-8");
|
|
16821
|
+
} catch (e) {
|
|
16822
|
+
debugLog("worktree-gitignore-failed", errorMsg(e));
|
|
16823
|
+
}
|
|
16824
|
+
}
|
|
16825
|
+
/**
|
|
16826
|
+
* Create a new git worktree for a plan.
|
|
16827
|
+
* Branch: maxsim/worktree-{phaseNum}-{planId}
|
|
16828
|
+
* Path: {cwd}/.maxsim-worktrees/{planId}
|
|
16829
|
+
*/
|
|
16830
|
+
async function createWorktree(cwd, phaseNum, planId, wave) {
|
|
16831
|
+
ensureWorktreeDir(cwd);
|
|
16832
|
+
ensureGitignoreEntry(cwd);
|
|
16833
|
+
const branch = `${WORKTREE_BRANCH_PREFIX}-${phaseNum}-${planId}`;
|
|
16834
|
+
const worktreePath = node_path.default.join(cwd, WORKTREE_DIR, planId);
|
|
16835
|
+
const git = simpleGit(cwd);
|
|
16836
|
+
try {
|
|
16837
|
+
await git.raw([
|
|
16838
|
+
"worktree",
|
|
16839
|
+
"add",
|
|
16840
|
+
"-b",
|
|
16841
|
+
branch,
|
|
16842
|
+
worktreePath
|
|
16843
|
+
]);
|
|
16844
|
+
} catch (e) {
|
|
16845
|
+
const msg = errorMsg(e);
|
|
16846
|
+
if (msg.includes("already exists")) try {
|
|
16847
|
+
await git.raw([
|
|
16848
|
+
"worktree",
|
|
16849
|
+
"add",
|
|
16850
|
+
worktreePath,
|
|
16851
|
+
branch
|
|
16852
|
+
]);
|
|
16853
|
+
} catch (e2) {
|
|
16854
|
+
throw new Error(`Failed to create worktree: ${errorMsg(e2)}`);
|
|
16855
|
+
}
|
|
16856
|
+
else throw new Error(`Failed to create worktree: ${msg}`);
|
|
16857
|
+
}
|
|
16858
|
+
return {
|
|
16859
|
+
id: planId,
|
|
16860
|
+
path: worktreePath,
|
|
16861
|
+
branch,
|
|
16862
|
+
wave,
|
|
16863
|
+
plan_id: planId,
|
|
16864
|
+
status: "active",
|
|
16865
|
+
created_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
16866
|
+
};
|
|
16867
|
+
}
|
|
16868
|
+
/**
|
|
16869
|
+
* List all MAXSIM-managed worktrees.
|
|
16870
|
+
* Parses `git worktree list --porcelain` and filters to .maxsim-worktrees/.
|
|
16871
|
+
*/
|
|
16872
|
+
async function listWorktrees(cwd) {
|
|
16873
|
+
const git = simpleGit(cwd);
|
|
16874
|
+
const worktrees = [];
|
|
16875
|
+
try {
|
|
16876
|
+
const blocks = (await git.raw([
|
|
16877
|
+
"worktree",
|
|
16878
|
+
"list",
|
|
16879
|
+
"--porcelain"
|
|
16880
|
+
])).split("\n\n").filter((b) => b.trim());
|
|
16881
|
+
for (const block of blocks) {
|
|
16882
|
+
const lines = block.split("\n");
|
|
16883
|
+
let wtPath = "";
|
|
16884
|
+
let branch = "";
|
|
16885
|
+
for (const line of lines) if (line.startsWith("worktree ")) wtPath = line.slice(9).trim();
|
|
16886
|
+
else if (line.startsWith("branch ")) branch = line.slice(7).trim().replace("refs/heads/", "");
|
|
16887
|
+
if (!wtPath || !wtPath.includes(WORKTREE_DIR)) continue;
|
|
16888
|
+
const planId = node_path.default.basename(wtPath);
|
|
16889
|
+
worktrees.push({
|
|
16890
|
+
id: planId,
|
|
16891
|
+
path: wtPath,
|
|
16892
|
+
branch,
|
|
16893
|
+
wave: 0,
|
|
16894
|
+
plan_id: planId,
|
|
16895
|
+
status: "active",
|
|
16896
|
+
created_at: ""
|
|
16897
|
+
});
|
|
16898
|
+
}
|
|
16899
|
+
} catch (e) {
|
|
16900
|
+
debugLog("worktree-list-failed", errorMsg(e));
|
|
16901
|
+
}
|
|
16902
|
+
return worktrees;
|
|
16903
|
+
}
|
|
16904
|
+
/**
|
|
16905
|
+
* Remove a single worktree by its ID (directory name under .maxsim-worktrees/).
|
|
16906
|
+
* Removes the worktree and deletes the branch.
|
|
16907
|
+
*/
|
|
16908
|
+
async function cleanupWorktree(cwd, worktreeId) {
|
|
16909
|
+
const git = simpleGit(cwd);
|
|
16910
|
+
const worktreePath = node_path.default.join(cwd, WORKTREE_DIR, worktreeId);
|
|
16911
|
+
try {
|
|
16912
|
+
await git.raw([
|
|
16913
|
+
"worktree",
|
|
16914
|
+
"remove",
|
|
16915
|
+
worktreePath
|
|
16916
|
+
]);
|
|
16917
|
+
} catch (e) {
|
|
16918
|
+
debugLog("worktree-remove-failed", errorMsg(e));
|
|
16919
|
+
try {
|
|
16920
|
+
await git.raw([
|
|
16921
|
+
"worktree",
|
|
16922
|
+
"remove",
|
|
16923
|
+
"--force",
|
|
16924
|
+
worktreePath
|
|
16925
|
+
]);
|
|
16926
|
+
} catch (e2) {
|
|
16927
|
+
debugLog("worktree-force-remove-failed", errorMsg(e2));
|
|
16928
|
+
try {
|
|
16929
|
+
if (node_fs.default.existsSync(worktreePath)) node_fs.default.rmSync(worktreePath, {
|
|
16930
|
+
recursive: true,
|
|
16931
|
+
force: true
|
|
16932
|
+
});
|
|
16933
|
+
await git.raw(["worktree", "prune"]);
|
|
16934
|
+
} catch (e3) {
|
|
16935
|
+
throw new Error(`Failed to cleanup worktree ${worktreeId}: ${errorMsg(e3)}`);
|
|
16936
|
+
}
|
|
16937
|
+
}
|
|
16938
|
+
}
|
|
16939
|
+
try {
|
|
16940
|
+
const branchName = (await git.raw([
|
|
16941
|
+
"branch",
|
|
16942
|
+
"--list",
|
|
16943
|
+
`${WORKTREE_BRANCH_PREFIX}-*${worktreeId}*`
|
|
16944
|
+
])).trim().replace(/^\*?\s*/, "").split("\n")[0]?.trim();
|
|
16945
|
+
if (branchName) await git.raw([
|
|
16946
|
+
"branch",
|
|
16947
|
+
"-D",
|
|
16948
|
+
branchName
|
|
16949
|
+
]);
|
|
16950
|
+
} catch (e) {
|
|
16951
|
+
debugLog("worktree-branch-delete-failed", errorMsg(e));
|
|
16952
|
+
}
|
|
16953
|
+
}
|
|
16954
|
+
/**
|
|
16955
|
+
* Remove all MAXSIM-managed worktrees.
|
|
16956
|
+
* Returns the count of worktrees removed.
|
|
16957
|
+
*/
|
|
16958
|
+
async function cleanupAllWorktrees(cwd) {
|
|
16959
|
+
const worktrees = await listWorktrees(cwd);
|
|
16960
|
+
let removed = 0;
|
|
16961
|
+
for (const wt of worktrees) try {
|
|
16962
|
+
await cleanupWorktree(cwd, wt.id);
|
|
16963
|
+
removed++;
|
|
16964
|
+
} catch (e) {
|
|
16965
|
+
debugLog("worktree-cleanup-failed", {
|
|
16966
|
+
id: wt.id,
|
|
16967
|
+
error: errorMsg(e)
|
|
16968
|
+
});
|
|
16969
|
+
}
|
|
16970
|
+
const worktreeDir = node_path.default.join(cwd, WORKTREE_DIR);
|
|
16971
|
+
try {
|
|
16972
|
+
if (node_fs.default.existsSync(worktreeDir)) {
|
|
16973
|
+
if (node_fs.default.readdirSync(worktreeDir).length === 0) node_fs.default.rmSync(worktreeDir, {
|
|
16974
|
+
recursive: true,
|
|
16975
|
+
force: true
|
|
16976
|
+
});
|
|
16977
|
+
}
|
|
16978
|
+
} catch (e) {
|
|
16979
|
+
debugLog("worktree-dir-cleanup-failed", errorMsg(e));
|
|
16980
|
+
}
|
|
16981
|
+
return removed;
|
|
16982
|
+
}
|
|
16983
|
+
/**
|
|
16984
|
+
* Pure function: decide whether to use batch (worktree) or standard execution mode.
|
|
16985
|
+
*
|
|
16986
|
+
* Returns 'batch' if:
|
|
16987
|
+
* - flagOverride is 'worktrees', OR
|
|
16988
|
+
* - worktree_mode is 'always', OR
|
|
16989
|
+
* - worktree_mode is 'auto' AND waveCount === 1 AND planCount > 2
|
|
16990
|
+
*
|
|
16991
|
+
* Returns 'standard' if:
|
|
16992
|
+
* - flagOverride is 'no-worktrees', OR
|
|
16993
|
+
* - worktree_mode is 'never', OR
|
|
16994
|
+
* - auto-detect doesn't trigger
|
|
16995
|
+
*/
|
|
16996
|
+
function decideExecutionMode(planCount, waveCount, config) {
|
|
16997
|
+
if (config.flagOverride === "worktrees") return "batch";
|
|
16998
|
+
if (config.flagOverride === "no-worktrees") return "standard";
|
|
16999
|
+
if (config.worktree_mode === "always") return "batch";
|
|
17000
|
+
if (config.worktree_mode === "never") return "standard";
|
|
17001
|
+
if (config.worktree_mode === "auto" && waveCount === 1 && planCount > 2) return "batch";
|
|
17002
|
+
return "standard";
|
|
17003
|
+
}
|
|
17004
|
+
/**
|
|
17005
|
+
* Pure function: validate that plans are independent (no file overlaps).
|
|
17006
|
+
* Returns conflicts if any file appears in multiple plans.
|
|
17007
|
+
*/
|
|
17008
|
+
function validatePlanIndependence(plans) {
|
|
17009
|
+
const fileMap = /* @__PURE__ */ new Map();
|
|
17010
|
+
for (const plan of plans) for (const file of plan.files_modified) {
|
|
17011
|
+
const normalized = file.replace(/\\/g, "/");
|
|
17012
|
+
const existing = fileMap.get(normalized) || [];
|
|
17013
|
+
existing.push(plan.id);
|
|
17014
|
+
fileMap.set(normalized, existing);
|
|
17015
|
+
}
|
|
17016
|
+
const conflicts = [];
|
|
17017
|
+
for (const [file, planIds] of fileMap) if (planIds.length > 1) conflicts.push({
|
|
17018
|
+
file,
|
|
17019
|
+
plans: planIds
|
|
17020
|
+
});
|
|
17021
|
+
return {
|
|
17022
|
+
valid: conflicts.length === 0,
|
|
17023
|
+
conflicts
|
|
17024
|
+
};
|
|
17025
|
+
}
|
|
17026
|
+
async function cmdWorktreeCreate(cwd, phaseNum, planId, wave) {
|
|
17027
|
+
if (!phaseNum) return cmdErr("phaseNum required for worktree-create");
|
|
17028
|
+
if (!planId) return cmdErr("planId required for worktree-create");
|
|
17029
|
+
const waveNum = wave ? parseInt(wave, 10) : 1;
|
|
17030
|
+
try {
|
|
17031
|
+
return cmdOk(await createWorktree(cwd, phaseNum, planId, waveNum));
|
|
17032
|
+
} catch (e) {
|
|
17033
|
+
return cmdErr(`worktree-create failed: ${errorMsg(e)}`);
|
|
17034
|
+
}
|
|
17035
|
+
}
|
|
17036
|
+
async function cmdWorktreeList(cwd) {
|
|
17037
|
+
try {
|
|
17038
|
+
return cmdOk(await listWorktrees(cwd));
|
|
17039
|
+
} catch (e) {
|
|
17040
|
+
return cmdErr(`worktree-list failed: ${errorMsg(e)}`);
|
|
17041
|
+
}
|
|
17042
|
+
}
|
|
17043
|
+
async function cmdWorktreeCleanup(cwd, worktreeId, all) {
|
|
17044
|
+
try {
|
|
17045
|
+
if (all) return cmdOk({
|
|
17046
|
+
removed: await cleanupAllWorktrees(cwd),
|
|
17047
|
+
all: true
|
|
17048
|
+
});
|
|
17049
|
+
if (!worktreeId) return cmdErr("worktreeId required for worktree-cleanup (or use --all)");
|
|
17050
|
+
await cleanupWorktree(cwd, worktreeId);
|
|
17051
|
+
return cmdOk({
|
|
17052
|
+
removed: 1,
|
|
17053
|
+
worktree_id: worktreeId
|
|
17054
|
+
});
|
|
17055
|
+
} catch (e) {
|
|
17056
|
+
return cmdErr(`worktree-cleanup failed: ${errorMsg(e)}`);
|
|
17057
|
+
}
|
|
17058
|
+
}
|
|
17059
|
+
function cmdDecideExecutionMode(planCount, waveCount, worktreeMode, flagOverride) {
|
|
17060
|
+
if (!planCount || !waveCount) return cmdErr("planCount and waveCount required");
|
|
17061
|
+
return cmdOk({ mode: decideExecutionMode(parseInt(planCount, 10), parseInt(waveCount, 10), {
|
|
17062
|
+
worktree_mode: worktreeMode || "auto",
|
|
17063
|
+
flagOverride
|
|
17064
|
+
}) });
|
|
17065
|
+
}
|
|
17066
|
+
function cmdValidatePlanIndependence(plansJson) {
|
|
17067
|
+
if (!plansJson) return cmdErr("plans JSON required");
|
|
17068
|
+
try {
|
|
17069
|
+
return cmdOk(validatePlanIndependence(JSON.parse(plansJson)));
|
|
17070
|
+
} catch (e) {
|
|
17071
|
+
return cmdErr(`validate-plan-independence failed: ${errorMsg(e)}`);
|
|
17072
|
+
}
|
|
17073
|
+
}
|
|
17074
|
+
|
|
16689
17075
|
//#endregion
|
|
16690
17076
|
//#region src/cli.ts
|
|
16691
17077
|
/**
|
|
@@ -16806,10 +17192,13 @@ const handleVerify = async (args, cwd, raw) => {
|
|
|
16806
17192
|
"references": async () => handleResult(await cmdVerifyReferences(cwd, args[2]), raw),
|
|
16807
17193
|
"commits": async () => handleResult(await cmdVerifyCommits(cwd, args.slice(2)), raw),
|
|
16808
17194
|
"artifacts": async () => handleResult(await cmdVerifyArtifacts(cwd, args[2]), raw),
|
|
16809
|
-
"key-links": async () => handleResult(await cmdVerifyKeyLinks(cwd, args[2]), raw)
|
|
17195
|
+
"key-links": async () => handleResult(await cmdVerifyKeyLinks(cwd, args[2]), raw),
|
|
17196
|
+
"requirement-existence": async () => handleResult(await cmdValidateRequirementExistence(cwd, args.slice(2)), raw),
|
|
17197
|
+
"requirement-status": async () => handleResult(await cmdValidateRequirementStatus(cwd, args.slice(2)), raw),
|
|
17198
|
+
"evidence-completeness": async () => handleResult(await cmdValidateEvidenceCompleteness(cwd, args[2], args.slice(3)), raw)
|
|
16810
17199
|
}[sub] : void 0;
|
|
16811
17200
|
if (handler) return handler();
|
|
16812
|
-
error("Unknown verify subcommand. Available: plan-structure, phase-completeness, references, commits, artifacts, key-links");
|
|
17201
|
+
error("Unknown verify subcommand. Available: plan-structure, phase-completeness, references, commits, artifacts, key-links, requirement-existence, requirement-status, evidence-completeness");
|
|
16813
17202
|
};
|
|
16814
17203
|
const handlePhases = async (args, cwd, raw) => {
|
|
16815
17204
|
if (args[1] === "list") {
|
|
@@ -16887,6 +17276,16 @@ const handleDrift = async (args, cwd, raw) => {
|
|
|
16887
17276
|
if (handler) return handleResult(await handler(), raw);
|
|
16888
17277
|
error("Unknown drift subcommand. Available: read-report, extract-requirements, extract-nogos, extract-conventions, write-report, previous-hash");
|
|
16889
17278
|
};
|
|
17279
|
+
const handleWorktree = async (args, cwd, raw) => {
|
|
17280
|
+
const sub = args[1];
|
|
17281
|
+
const handler = sub ? {
|
|
17282
|
+
"create": () => cmdWorktreeCreate(cwd, args[2], args[3], args[4]),
|
|
17283
|
+
"list": () => cmdWorktreeList(cwd),
|
|
17284
|
+
"cleanup": () => cmdWorktreeCleanup(cwd, args[2], hasFlag(args, "all"))
|
|
17285
|
+
}[sub] : void 0;
|
|
17286
|
+
if (handler) return handleResult(await handler(), raw);
|
|
17287
|
+
error("Unknown worktree subcommand. Available: create, list, cleanup");
|
|
17288
|
+
};
|
|
16890
17289
|
const handleInit = async (args, cwd, raw) => {
|
|
16891
17290
|
const workflow = args[1];
|
|
16892
17291
|
const handler = workflow ? {
|
|
@@ -16948,6 +17347,12 @@ const COMMANDS = {
|
|
|
16948
17347
|
"milestone": handleMilestone,
|
|
16949
17348
|
"validate": handleValidate,
|
|
16950
17349
|
"drift": handleDrift,
|
|
17350
|
+
"worktree": handleWorktree,
|
|
17351
|
+
"decide-execution-mode": (args, _cwd, raw) => {
|
|
17352
|
+
const f = getFlags(args, "worktree-mode", "flag-override");
|
|
17353
|
+
handleResult(cmdDecideExecutionMode(args[1], args[2], f["worktree-mode"] ?? void 0, f["flag-override"] ?? void 0), raw);
|
|
17354
|
+
},
|
|
17355
|
+
"validate-plan-independence": (args, _cwd, raw) => handleResult(cmdValidatePlanIndependence(args[1]), raw),
|
|
16951
17356
|
"progress": async (args, cwd, raw) => handleResult(await cmdProgressRender(cwd, args[1] || "json", raw), raw),
|
|
16952
17357
|
"todo": (args, cwd, raw) => {
|
|
16953
17358
|
if (args[1] === "complete") handleResult(cmdTodoComplete(cwd, args[2], raw), raw);
|