@undeemed/get-shit-done-codex 1.24.1 → 1.24.3

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.
@@ -122,25 +122,35 @@
122
122
  const fs = require('fs');
123
123
  const path = require('path');
124
124
  const { execSync } = require('child_process');
125
+ const stateLib = require('./lib/state.cjs');
126
+ const phaseLib = require('./lib/phase.cjs');
127
+ const milestoneLib = require('./lib/milestone.cjs');
128
+ const initLib = require('./lib/init.cjs');
129
+ const commandsLib = require('./lib/commands.cjs');
130
+ const configLib = require('./lib/config.cjs');
131
+ const roadmapLib = require('./lib/roadmap.cjs');
132
+ const templateLib = require('./lib/template.cjs');
133
+ const frontmatterLib = require('./lib/frontmatter.cjs');
134
+ const verifyLib = require('./lib/verify.cjs');
125
135
 
126
136
  // ─── Model Profile Table ─────────────────────────────────────────────────────
127
137
 
128
138
  const MODEL_PROFILES = {
129
- // quality balanced budget
130
- 'gsd-planner': { quality: { m: 'gpt-5.3-codex', t: 'high' }, balanced: { m: 'gpt-5.3-codex', t: 'high' }, budget: { m: 'gpt-5.3-codex', t: 'medium' } },
131
- 'gsd-roadmapper': { quality: { m: 'gpt-5.3-codex', t: 'high' }, balanced: { m: 'gpt-5.3-codex', t: 'medium' }, budget: { m: 'gpt-5.3-codex', t: 'low' } },
132
- 'gsd-executor': { quality: { m: 'gpt-5.3-codex', t: 'high' }, balanced: { m: 'gpt-5.3-codex', t: 'medium' }, budget: { m: 'gpt-5.3-codex', t: 'low' } },
133
- 'gsd-phase-researcher': { quality: { m: 'gpt-5.3-codex', t: 'medium' }, balanced: { m: 'gpt-5.3-codex', t: 'low' }, budget: { m: 'gpt-5.3-codex', t: 'low' } },
134
- 'gsd-project-researcher': { quality: { m: 'gpt-5.3-codex', t: 'medium' }, balanced: { m: 'gpt-5.3-codex', t: 'low' }, budget: { m: 'gpt-5.3-codex', t: 'low' } },
135
- 'gsd-research-synthesizer': { quality: { m: 'gpt-5.3-codex', t: 'medium' }, balanced: { m: 'gpt-5.3-codex', t: 'low' }, budget: { m: 'gpt-5.3-codex', t: 'low' } },
136
- 'gsd-debugger': { quality: { m: 'gpt-5.3-codex', t: 'high' }, balanced: { m: 'gpt-5.3-codex', t: 'high' }, budget: { m: 'gpt-5.3-codex', t: 'medium' } },
137
- 'gsd-codebase-mapper': { quality: { m: 'gpt-5.3-codex', t: 'low' }, balanced: { m: 'gpt-5.3-codex', t: 'low' }, budget: { m: 'gpt-5.3-codex', t: 'low' } },
138
- 'gsd-verifier': { quality: { m: 'gpt-5.3-codex', t: 'medium' }, balanced: { m: 'gpt-5.3-codex', t: 'medium' }, budget: { m: 'gpt-5.3-codex', t: 'low' } },
139
- 'gsd-plan-checker': { quality: { m: 'gpt-5.3-codex', t: 'medium' }, balanced: { m: 'gpt-5.3-codex', t: 'low' }, budget: { m: 'gpt-5.3-codex', t: 'low' } },
140
- 'gsd-integration-checker': { quality: { m: 'gpt-5.3-codex', t: 'medium' }, balanced: { m: 'gpt-5.3-codex', t: 'low' }, budget: { m: 'gpt-5.3-codex', t: 'low' } },
139
+ // quality balanced budget
140
+ 'gsd-planner': { quality: { m: 'gpt-5.3-codex', t: 'xhigh' }, balanced: { m: 'gpt-5.3-codex', t: 'xhigh' }, budget: { m: 'gpt-5.3-codex', t: 'high' } },
141
+ 'gsd-roadmapper': { quality: { m: 'gpt-5.3-codex', t: 'xhigh' }, balanced: { m: 'gpt-5.3-codex', t: 'high' }, budget: { m: 'gpt-5.3-codex', t: 'medium' } },
142
+ 'gsd-executor': { quality: { m: 'gpt-5.3-codex', t: 'xhigh' }, balanced: { m: 'gpt-5.3-codex', t: 'high' }, budget: { m: 'gpt-5.3-codex', t: 'medium' } },
143
+ 'gsd-phase-researcher': { quality: { m: 'gpt-5.3-codex', t: 'high' }, balanced: { m: 'gpt-5.3-codex', t: 'medium' }, budget: { m: 'gpt-5.3-codex', t: 'medium' } },
144
+ 'gsd-project-researcher': { quality: { m: 'gpt-5.3-codex', t: 'high' }, balanced: { m: 'gpt-5.3-codex', t: 'medium' }, budget: { m: 'gpt-5.3-codex', t: 'medium' } },
145
+ 'gsd-research-synthesizer': { quality: { m: 'gpt-5.3-codex', t: 'high' }, balanced: { m: 'gpt-5.3-codex', t: 'medium' }, budget: { m: 'gpt-5.3-codex', t: 'medium' } },
146
+ 'gsd-debugger': { quality: { m: 'gpt-5.3-codex', t: 'xhigh' }, balanced: { m: 'gpt-5.3-codex', t: 'xhigh' }, budget: { m: 'gpt-5.3-codex', t: 'high' } },
147
+ 'gsd-codebase-mapper': { quality: { m: 'gpt-5.3-codex', t: 'medium' }, balanced: { m: 'gpt-5.3-codex', t: 'medium' }, budget: { m: 'gpt-5.3-codex', t: 'medium' } },
148
+ 'gsd-verifier': { quality: { m: 'gpt-5.3-codex', t: 'high' }, balanced: { m: 'gpt-5.3-codex', t: 'high' }, budget: { m: 'gpt-5.3-codex', t: 'medium' } },
149
+ 'gsd-plan-checker': { quality: { m: 'gpt-5.3-codex', t: 'high' }, balanced: { m: 'gpt-5.3-codex', t: 'medium' }, budget: { m: 'gpt-5.3-codex', t: 'medium' } },
150
+ 'gsd-integration-checker': { quality: { m: 'gpt-5.3-codex', t: 'high' }, balanced: { m: 'gpt-5.3-codex', t: 'medium' }, budget: { m: 'gpt-5.3-codex', t: 'medium' } },
141
151
  };
142
152
 
143
- const DEFAULT_ENTRY = { m: 'gpt-5.3-codex', t: 'medium' };
153
+ const DEFAULT_ENTRY = { m: 'gpt-5.3-codex', t: 'high' };
144
154
 
145
155
  // ─── Helpers ──────────────────────────────────────────────────────────────────
146
156
 
@@ -247,12 +257,80 @@ function execGit(cwd, args) {
247
257
  }
248
258
 
249
259
  function normalizePhaseName(phase) {
250
- const match = phase.match(/^(\d+(?:\.\d+)?)/);
260
+ const match = String(phase).match(/^(\d+)([A-Z])?((?:\.\d+)*)/i);
251
261
  if (!match) return phase;
252
- const num = match[1];
253
- const parts = num.split('.');
254
- const padded = parts[0].padStart(2, '0');
255
- return parts.length > 1 ? `${padded}.${parts[1]}` : padded;
262
+ const padded = match[1].padStart(2, '0');
263
+ const letter = match[2] ? match[2].toUpperCase() : '';
264
+ const decimal = match[3] || '';
265
+ return padded + letter + decimal;
266
+ }
267
+
268
+ function escapeRegex(value) {
269
+ return String(value).replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
270
+ }
271
+
272
+ function comparePhaseNum(a, b) {
273
+ const pa = String(a).match(/^(\d+)([A-Z])?((?:\.\d+)*)/i);
274
+ const pb = String(b).match(/^(\d+)([A-Z])?((?:\.\d+)*)/i);
275
+ if (!pa || !pb) return String(a).localeCompare(String(b));
276
+
277
+ const intDiff = parseInt(pa[1], 10) - parseInt(pb[1], 10);
278
+ if (intDiff !== 0) return intDiff;
279
+
280
+ const la = (pa[2] || '').toUpperCase();
281
+ const lb = (pb[2] || '').toUpperCase();
282
+ if (la !== lb) {
283
+ if (!la) return -1;
284
+ if (!lb) return 1;
285
+ return la < lb ? -1 : 1;
286
+ }
287
+
288
+ const aDecParts = pa[3] ? pa[3].slice(1).split('.').map(p => parseInt(p, 10)) : [];
289
+ const bDecParts = pb[3] ? pb[3].slice(1).split('.').map(p => parseInt(p, 10)) : [];
290
+ const maxLen = Math.max(aDecParts.length, bDecParts.length);
291
+
292
+ if (aDecParts.length === 0 && bDecParts.length > 0) return -1;
293
+ if (bDecParts.length === 0 && aDecParts.length > 0) return 1;
294
+
295
+ for (let i = 0; i < maxLen; i++) {
296
+ const av = Number.isFinite(aDecParts[i]) ? aDecParts[i] : 0;
297
+ const bv = Number.isFinite(bDecParts[i]) ? bDecParts[i] : 0;
298
+ if (av !== bv) return av - bv;
299
+ }
300
+
301
+ return 0;
302
+ }
303
+
304
+ function getMilestonePhaseFilter(cwd) {
305
+ const milestonePhaseNums = new Set();
306
+
307
+ try {
308
+ const roadmap = fs.readFileSync(path.join(cwd, '.planning', 'ROADMAP.md'), 'utf-8');
309
+ const phasePattern = /#{2,4}\s*Phase\s+(\d+[A-Z]?(?:\.\d+)*)\s*:/gi;
310
+ let m;
311
+ while ((m = phasePattern.exec(roadmap)) !== null) {
312
+ milestonePhaseNums.add(m[1]);
313
+ }
314
+ } catch {}
315
+
316
+ if (milestonePhaseNums.size === 0) {
317
+ const passAll = () => true;
318
+ passAll.phaseCount = 0;
319
+ return passAll;
320
+ }
321
+
322
+ const normalized = new Set(
323
+ [...milestonePhaseNums].map(n => (n.replace(/^0+/, '') || '0').toLowerCase())
324
+ );
325
+
326
+ function isDirInMilestone(dirName) {
327
+ const m = dirName.match(/^0*(\d+[A-Za-z]?(?:\.\d+)*)/);
328
+ if (!m) return false;
329
+ return normalized.has(m[1].toLowerCase());
330
+ }
331
+
332
+ isDirInMilestone.phaseCount = milestonePhaseNums.size;
333
+ return isDirInMilestone;
256
334
  }
257
335
 
258
336
  function extractFrontmatter(content) {
@@ -859,12 +937,8 @@ function cmdPhasesList(cwd, options, raw) {
859
937
  }
860
938
  }
861
939
 
862
- // Sort numerically (handles decimals: 01, 02, 02.1, 02.2, 03)
863
- dirs.sort((a, b) => {
864
- const aNum = parseFloat(a.match(/^(\d+(?:\.\d+)?)/)?.[1] || '0');
865
- const bNum = parseFloat(b.match(/^(\d+(?:\.\d+)?)/)?.[1] || '0');
866
- return aNum - bNum;
867
- });
940
+ // Sort by canonical phase ordering (integers, decimals, letter suffixes)
941
+ dirs.sort((a, b) => comparePhaseNum(a, b));
868
942
 
869
943
  // If filtering by phase number
870
944
  if (phase) {
@@ -899,7 +973,7 @@ function cmdPhasesList(cwd, options, raw) {
899
973
  const result = {
900
974
  files,
901
975
  count: files.length,
902
- phase_dir: phase ? dirs[0].replace(/^\d+(?:\.\d+)?-?/, '') : null,
976
+ phase_dir: phase ? dirs[0].replace(/^\d+[A-Za-z]?(?:\.\d+)*-?/, '') : null,
903
977
  };
904
978
  output(result, raw, files.join('\n'));
905
979
  return;
@@ -1863,7 +1937,7 @@ function cmdPhasePlanIndex(cwd, phase, raw) {
1863
1937
  let phaseDirName = null;
1864
1938
  try {
1865
1939
  const entries = fs.readdirSync(phasesDir, { withFileTypes: true });
1866
- const dirs = entries.filter(e => e.isDirectory()).map(e => e.name).sort();
1940
+ const dirs = entries.filter(e => e.isDirectory()).map(e => e.name).sort((a, b) => comparePhaseNum(a, b));
1867
1941
  const match = dirs.find(d => d.startsWith(normalized));
1868
1942
  if (match) {
1869
1943
  phaseDir = path.join(phasesDir, match);
@@ -1899,9 +1973,10 @@ function cmdPhasePlanIndex(cwd, phase, raw) {
1899
1973
  const content = fs.readFileSync(planPath, 'utf-8');
1900
1974
  const fm = extractFrontmatter(content);
1901
1975
 
1902
- // Count tasks (## Task N patterns)
1903
- const taskMatches = content.match(/##\s*Task\s*\d+/gi) || [];
1904
- const taskCount = taskMatches.length;
1976
+ // Count tasks from canonical XML first, fallback to markdown task headings.
1977
+ const xmlTaskMatches = content.match(/<task\b[^>]*>/gi) || [];
1978
+ const markdownTaskMatches = content.match(/##\s*Task\s*\d+/gi) || [];
1979
+ const taskCount = xmlTaskMatches.length > 0 ? xmlTaskMatches.length : markdownTaskMatches.length;
1905
1980
 
1906
1981
  // Parse wave as integer
1907
1982
  const wave = parseInt(fm.wave, 10) || 1;
@@ -1916,10 +1991,24 @@ function cmdPhasePlanIndex(cwd, phase, raw) {
1916
1991
  hasCheckpoints = true;
1917
1992
  }
1918
1993
 
1919
- // Parse files-modified
1994
+ // Parse files-modified/files_modified (both accepted).
1920
1995
  let filesModified = [];
1921
- if (fm['files-modified']) {
1922
- filesModified = Array.isArray(fm['files-modified']) ? fm['files-modified'] : [fm['files-modified']];
1996
+ const filesModifiedField = fm.files_modified ?? fm['files-modified'];
1997
+ if (filesModifiedField) {
1998
+ filesModified = Array.isArray(filesModifiedField) ? filesModifiedField : [filesModifiedField];
1999
+ }
2000
+
2001
+ // Objective: canonical <objective> block first line overrides frontmatter objective.
2002
+ let objective = fm.objective || null;
2003
+ const objectiveTagMatch = content.match(/<objective>\s*([\s\S]*?)<\/objective>/i);
2004
+ if (objectiveTagMatch) {
2005
+ const firstLine = objectiveTagMatch[1]
2006
+ .split('\n')
2007
+ .map(line => line.trim())
2008
+ .find(Boolean);
2009
+ if (firstLine) {
2010
+ objective = firstLine;
2011
+ }
1923
2012
  }
1924
2013
 
1925
2014
  const hasSummary = completedPlanIds.has(planId);
@@ -1931,7 +2020,7 @@ function cmdPhasePlanIndex(cwd, phase, raw) {
1931
2020
  id: planId,
1932
2021
  wave,
1933
2022
  autonomous,
1934
- objective: fm.objective || null,
2023
+ objective,
1935
2024
  files_modified: filesModified,
1936
2025
  task_count: taskCount,
1937
2026
  has_summary: hasSummary,
@@ -3158,16 +3247,16 @@ function cmdPhaseComplete(cwd, phaseNum, raw) {
3158
3247
  // Update ROADMAP.md: mark phase complete
3159
3248
  if (fs.existsSync(roadmapPath)) {
3160
3249
  let roadmapContent = fs.readFileSync(roadmapPath, 'utf-8');
3250
+ const phaseEscaped = escapeRegex(phaseNum);
3161
3251
 
3162
3252
  // Checkbox: - [ ] Phase N: → - [x] Phase N: (...completed DATE)
3163
3253
  const checkboxPattern = new RegExp(
3164
- `(-\\s*\\[)[ ](\\]\\s*.*Phase\\s+${phaseNum.replace('.', '\\.')}[:\\s][^\\n]*)`,
3254
+ `(-\\s*\\[)[ ](\\]\\s*.*Phase\\s+${phaseEscaped}[:\\s][^\\n]*)`,
3165
3255
  'i'
3166
3256
  );
3167
3257
  roadmapContent = roadmapContent.replace(checkboxPattern, `$1x$2 (completed ${today})`);
3168
3258
 
3169
3259
  // Progress table: update Status to Complete, add date
3170
- const phaseEscaped = phaseNum.replace('.', '\\.');
3171
3260
  const tablePattern = new RegExp(
3172
3261
  `(\\|\\s*${phaseEscaped}\\.?\\s[^|]*\\|[^|]*\\|)\\s*[^|]*(\\|)\\s*[^|]*(\\|)`,
3173
3262
  'i'
@@ -3192,24 +3281,26 @@ function cmdPhaseComplete(cwd, phaseNum, raw) {
3192
3281
  // Update REQUIREMENTS.md traceability for this phase's requirements
3193
3282
  const reqPath = path.join(cwd, '.planning', 'REQUIREMENTS.md');
3194
3283
  if (fs.existsSync(reqPath)) {
3195
- // Extract Requirements line from roadmap for this phase
3196
- const reqMatch = roadmapContent.match(
3197
- new RegExp(`Phase\\s+${phaseNum.replace('.', '\\.')}[\\s\\S]*?\\*\\*Requirements:\\*\\*\\s*([^\\n]+)`, 'i')
3284
+ // Extract only this phase's section to avoid leaking into later phases.
3285
+ const sectionMatch = roadmapContent.match(
3286
+ new RegExp(`#{2,4}\\s*Phase\\s+${phaseEscaped}\\s*:[\\s\\S]*?(?=\\n#{2,4}\\s*Phase\\s+\\d|$)`, 'i')
3198
3287
  );
3199
3288
 
3200
- if (reqMatch) {
3201
- const reqIds = reqMatch[1].split(/[,\s]+/).map(r => r.trim()).filter(Boolean);
3289
+ if (sectionMatch) {
3290
+ const reqMatch = sectionMatch[0].match(/\*\*Requirements:\*\*\s*([^\n]+)/i);
3291
+ const reqIds = reqMatch ? (reqMatch[1].match(/\b[A-Z][A-Z0-9_-]*-\d+\b/g) || []) : [];
3202
3292
  let reqContent = fs.readFileSync(reqPath, 'utf-8');
3203
3293
 
3204
3294
  for (const reqId of reqIds) {
3295
+ const escapedReqId = escapeRegex(reqId);
3205
3296
  // Update checkbox: - [ ] **REQ-ID** → - [x] **REQ-ID**
3206
3297
  reqContent = reqContent.replace(
3207
- new RegExp(`(-\\s*\\[)[ ](\\]\\s*\\*\\*${reqId}\\*\\*)`, 'gi'),
3298
+ new RegExp(`(-\\s*\\[)[ ](\\]\\s*\\*\\*${escapedReqId}\\*\\*)`, 'gi'),
3208
3299
  '$1x$2'
3209
3300
  );
3210
3301
  // Update traceability table: | REQ-ID | Phase N | Pending | → | REQ-ID | Phase N | Complete |
3211
3302
  reqContent = reqContent.replace(
3212
- new RegExp(`(\\|\\s*${reqId}\\s*\\|[^|]+\\|)\\s*Pending\\s*(\\|)`, 'gi'),
3303
+ new RegExp(`(\\|\\s*${escapedReqId}\\s*\\|[^|]+\\|)\\s*Pending\\s*(\\|)`, 'gi'),
3213
3304
  '$1 Complete $2'
3214
3305
  );
3215
3306
  }
@@ -3225,16 +3316,20 @@ function cmdPhaseComplete(cwd, phaseNum, raw) {
3225
3316
  let isLastPhase = true;
3226
3317
 
3227
3318
  try {
3319
+ const isMilestonePhase = getMilestonePhaseFilter(cwd);
3228
3320
  const entries = fs.readdirSync(phasesDir, { withFileTypes: true });
3229
- const dirs = entries.filter(e => e.isDirectory()).map(e => e.name).sort();
3230
- const currentFloat = parseFloat(phaseNum);
3321
+ const dirs = entries
3322
+ .filter(e => e.isDirectory())
3323
+ .map(e => e.name)
3324
+ .filter(d => isMilestonePhase(d))
3325
+ .sort((a, b) => comparePhaseNum(a, b));
3326
+ const currentPhase = normalizePhaseName(phaseNum);
3231
3327
 
3232
3328
  // Find the next phase directory after current
3233
3329
  for (const dir of dirs) {
3234
- const dm = dir.match(/^(\d+(?:\.\d+)?)-?(.*)/);
3330
+ const dm = dir.match(/^(\d+[A-Z]?(?:\.\d+)*)-?(.*)/i);
3235
3331
  if (dm) {
3236
- const dirFloat = parseFloat(dm[1]);
3237
- if (dirFloat > currentFloat) {
3332
+ if (comparePhaseNum(dm[1], currentPhase) > 0) {
3238
3333
  nextPhaseNum = dm[1];
3239
3334
  nextPhaseName = dm[2] || null;
3240
3335
  isLastPhase = false;
@@ -3328,10 +3423,15 @@ function cmdMilestoneComplete(cwd, version, options, raw) {
3328
3423
  let totalPlans = 0;
3329
3424
  let totalTasks = 0;
3330
3425
  const accomplishments = [];
3426
+ const isMilestonePhase = getMilestonePhaseFilter(cwd);
3331
3427
 
3332
3428
  try {
3333
3429
  const entries = fs.readdirSync(phasesDir, { withFileTypes: true });
3334
- const dirs = entries.filter(e => e.isDirectory()).map(e => e.name).sort();
3430
+ const dirs = entries
3431
+ .filter(e => e.isDirectory())
3432
+ .map(e => e.name)
3433
+ .filter(d => isMilestonePhase(d))
3434
+ .sort((a, b) => comparePhaseNum(a, b));
3335
3435
 
3336
3436
  for (const dir of dirs) {
3337
3437
  phaseCount++;
@@ -3375,13 +3475,16 @@ function cmdMilestoneComplete(cwd, version, options, raw) {
3375
3475
  fs.renameSync(auditFile, path.join(archiveDir, `${version}-MILESTONE-AUDIT.md`));
3376
3476
  }
3377
3477
 
3378
- // Create/append MILESTONES.md entry
3478
+ // Create/prepend MILESTONES.md entry (reverse chronological order)
3379
3479
  const accomplishmentsList = accomplishments.map(a => `- ${a}`).join('\n');
3380
3480
  const milestoneEntry = `## ${version} ${milestoneName} (Shipped: ${today})\n\n**Phases completed:** ${phaseCount} phases, ${totalPlans} plans, ${totalTasks} tasks\n\n**Key accomplishments:**\n${accomplishmentsList || '- (none recorded)'}\n\n---\n\n`;
3381
3481
 
3382
3482
  if (fs.existsSync(milestonesPath)) {
3383
3483
  const existing = fs.readFileSync(milestonesPath, 'utf-8');
3384
- fs.writeFileSync(milestonesPath, existing + '\n' + milestoneEntry, 'utf-8');
3484
+ const existingBody = existing
3485
+ .replace(/^#\s*Milestones[^\n]*\n*/i, '')
3486
+ .trimStart();
3487
+ fs.writeFileSync(milestonesPath, `# Milestones\n\n${milestoneEntry}${existingBody}`, 'utf-8');
3385
3488
  } else {
3386
3489
  fs.writeFileSync(milestonesPath, `# Milestones\n\n${milestoneEntry}`, 'utf-8');
3387
3490
  }
@@ -3412,7 +3515,11 @@ function cmdMilestoneComplete(cwd, version, options, raw) {
3412
3515
  fs.mkdirSync(phaseArchiveDir, { recursive: true });
3413
3516
 
3414
3517
  const phaseEntries = fs.readdirSync(phasesDir, { withFileTypes: true });
3415
- const phaseDirNames = phaseEntries.filter(e => e.isDirectory()).map(e => e.name);
3518
+ const phaseDirNames = phaseEntries
3519
+ .filter(e => e.isDirectory())
3520
+ .map(e => e.name)
3521
+ .filter(d => isMilestonePhase(d))
3522
+ .sort((a, b) => comparePhaseNum(a, b));
3416
3523
  for (const dir of phaseDirNames) {
3417
3524
  fs.renameSync(path.join(phasesDir, dir), path.join(phaseArchiveDir, dir));
3418
3525
  }
@@ -3977,15 +4084,15 @@ function resolveModelInternal(cwd, agentType) {
3977
4084
  if (override) {
3978
4085
  // Override can be a string (legacy) or { m, t } object
3979
4086
  if (typeof override === 'string') {
3980
- return { model: 'inherit', thinking: override === 'high' || override === 'medium' || override === 'low' ? override : 'medium' };
4087
+ return { model: 'inherit', thinking: override === 'xhigh' || override === 'high' || override === 'medium' || override === 'low' ? override : 'high' };
3981
4088
  }
3982
- return { model: 'inherit', thinking: override.t || 'medium' };
4089
+ return { model: 'inherit', thinking: override.t || 'high' };
3983
4090
  }
3984
4091
 
3985
4092
  // Fall back to profile lookup
3986
4093
  const profile = config.model_profile || 'balanced';
3987
4094
  const agentModels = MODEL_PROFILES[agentType];
3988
- if (!agentModels) return { model: 'inherit', thinking: 'medium' };
4095
+ if (!agentModels) return { model: 'inherit', thinking: 'high' };
3989
4096
  const entry = agentModels[profile] || agentModels['balanced'] || DEFAULT_ENTRY;
3990
4097
  return { model: 'inherit', thinking: entry.t };
3991
4098
  }
@@ -4844,12 +4951,54 @@ function cmdInitProgress(cwd, includes, raw) {
4844
4951
 
4845
4952
  async function main() {
4846
4953
  const args = process.argv.slice(2);
4847
- const rawIndex = args.indexOf('--raw');
4848
- const raw = rawIndex !== -1;
4849
- if (rawIndex !== -1) args.splice(rawIndex, 1);
4954
+ let raw = false;
4955
+ let cwd = process.cwd();
4956
+
4957
+ const setCwd = (value) => {
4958
+ if (!value) {
4959
+ error('Missing value for --cwd');
4960
+ }
4961
+ const resolved = path.resolve(process.cwd(), value);
4962
+ try {
4963
+ const stat = fs.statSync(resolved);
4964
+ if (!stat.isDirectory()) {
4965
+ throw new Error('not-a-dir');
4966
+ }
4967
+ } catch {
4968
+ error(`Invalid --cwd: ${value}`);
4969
+ }
4970
+ cwd = resolved;
4971
+ };
4972
+
4973
+ for (let i = 0; i < args.length;) {
4974
+ const arg = args[i];
4975
+ if (arg === '--raw') {
4976
+ raw = true;
4977
+ args.splice(i, 1);
4978
+ continue;
4979
+ }
4980
+ if (arg === '--cwd') {
4981
+ const value = args[i + 1];
4982
+ if (!value || value.startsWith('--')) {
4983
+ error('Missing value for --cwd');
4984
+ }
4985
+ setCwd(value);
4986
+ args.splice(i, 2);
4987
+ continue;
4988
+ }
4989
+ if (arg.startsWith('--cwd=')) {
4990
+ const value = arg.slice('--cwd='.length);
4991
+ if (!value) {
4992
+ error('Missing value for --cwd');
4993
+ }
4994
+ setCwd(value);
4995
+ args.splice(i, 1);
4996
+ continue;
4997
+ }
4998
+ i++;
4999
+ }
4850
5000
 
4851
5001
  const command = args[0];
4852
- const cwd = process.cwd();
4853
5002
 
4854
5003
  if (!command) {
4855
5004
  error('Usage: gsd-tools <command> [args] [--raw]\nCommands: state, resolve-model, find-phase, commit, verify-summary, verify, frontmatter, template, generate-slug, current-timestamp, list-todos, verify-path-exists, config-ensure-section, init');
@@ -4859,9 +5008,9 @@ async function main() {
4859
5008
  case 'state': {
4860
5009
  const subcommand = args[1];
4861
5010
  if (subcommand === 'update') {
4862
- cmdStateUpdate(cwd, args[2], args[3]);
5011
+ stateLib.cmdStateUpdate(cwd, args[2], args[3]);
4863
5012
  } else if (subcommand === 'get') {
4864
- cmdStateGet(cwd, args[2], raw);
5013
+ stateLib.cmdStateGet(cwd, args[2], raw);
4865
5014
  } else if (subcommand === 'patch') {
4866
5015
  const patches = {};
4867
5016
  for (let i = 2; i < args.length; i += 2) {
@@ -4871,16 +5020,18 @@ async function main() {
4871
5020
  patches[key] = value;
4872
5021
  }
4873
5022
  }
4874
- cmdStatePatch(cwd, patches, raw);
5023
+ stateLib.cmdStatePatch(cwd, patches, raw);
5024
+ } else if (subcommand === 'json') {
5025
+ stateLib.cmdStateJson(cwd, raw);
4875
5026
  } else if (subcommand === 'advance-plan') {
4876
- cmdStateAdvancePlan(cwd, raw);
5027
+ stateLib.cmdStateAdvancePlan(cwd, raw);
4877
5028
  } else if (subcommand === 'record-metric') {
4878
5029
  const phaseIdx = args.indexOf('--phase');
4879
5030
  const planIdx = args.indexOf('--plan');
4880
5031
  const durationIdx = args.indexOf('--duration');
4881
5032
  const tasksIdx = args.indexOf('--tasks');
4882
5033
  const filesIdx = args.indexOf('--files');
4883
- cmdStateRecordMetric(cwd, {
5034
+ stateLib.cmdStateRecordMetric(cwd, {
4884
5035
  phase: phaseIdx !== -1 ? args[phaseIdx + 1] : null,
4885
5036
  plan: planIdx !== -1 ? args[planIdx + 1] : null,
4886
5037
  duration: durationIdx !== -1 ? args[durationIdx + 1] : null,
@@ -4888,42 +5039,50 @@ async function main() {
4888
5039
  files: filesIdx !== -1 ? args[filesIdx + 1] : null,
4889
5040
  }, raw);
4890
5041
  } else if (subcommand === 'update-progress') {
4891
- cmdStateUpdateProgress(cwd, raw);
5042
+ stateLib.cmdStateUpdateProgress(cwd, raw);
4892
5043
  } else if (subcommand === 'add-decision') {
4893
5044
  const phaseIdx = args.indexOf('--phase');
4894
5045
  const summaryIdx = args.indexOf('--summary');
5046
+ const summaryFileIdx = args.indexOf('--summary-file');
4895
5047
  const rationaleIdx = args.indexOf('--rationale');
4896
- cmdStateAddDecision(cwd, {
5048
+ const rationaleFileIdx = args.indexOf('--rationale-file');
5049
+ stateLib.cmdStateAddDecision(cwd, {
4897
5050
  phase: phaseIdx !== -1 ? args[phaseIdx + 1] : null,
4898
5051
  summary: summaryIdx !== -1 ? args[summaryIdx + 1] : null,
5052
+ summary_file: summaryFileIdx !== -1 ? args[summaryFileIdx + 1] : null,
4899
5053
  rationale: rationaleIdx !== -1 ? args[rationaleIdx + 1] : '',
5054
+ rationale_file: rationaleFileIdx !== -1 ? args[rationaleFileIdx + 1] : null,
4900
5055
  }, raw);
4901
5056
  } else if (subcommand === 'add-blocker') {
4902
5057
  const textIdx = args.indexOf('--text');
4903
- cmdStateAddBlocker(cwd, textIdx !== -1 ? args[textIdx + 1] : null, raw);
5058
+ const textFileIdx = args.indexOf('--text-file');
5059
+ stateLib.cmdStateAddBlocker(cwd, {
5060
+ text: textIdx !== -1 ? args[textIdx + 1] : null,
5061
+ text_file: textFileIdx !== -1 ? args[textFileIdx + 1] : null,
5062
+ }, raw);
4904
5063
  } else if (subcommand === 'resolve-blocker') {
4905
5064
  const textIdx = args.indexOf('--text');
4906
- cmdStateResolveBlocker(cwd, textIdx !== -1 ? args[textIdx + 1] : null, raw);
5065
+ stateLib.cmdStateResolveBlocker(cwd, textIdx !== -1 ? args[textIdx + 1] : null, raw);
4907
5066
  } else if (subcommand === 'record-session') {
4908
5067
  const stoppedIdx = args.indexOf('--stopped-at');
4909
5068
  const resumeIdx = args.indexOf('--resume-file');
4910
- cmdStateRecordSession(cwd, {
5069
+ stateLib.cmdStateRecordSession(cwd, {
4911
5070
  stopped_at: stoppedIdx !== -1 ? args[stoppedIdx + 1] : null,
4912
5071
  resume_file: resumeIdx !== -1 ? args[resumeIdx + 1] : 'None',
4913
5072
  }, raw);
4914
5073
  } else {
4915
- cmdStateLoad(cwd, raw);
5074
+ stateLib.cmdStateLoad(cwd, raw);
4916
5075
  }
4917
5076
  break;
4918
5077
  }
4919
5078
 
4920
5079
  case 'resolve-model': {
4921
- cmdResolveModel(cwd, args[1], raw);
5080
+ commandsLib.cmdResolveModel(cwd, args[1], raw);
4922
5081
  break;
4923
5082
  }
4924
5083
 
4925
5084
  case 'find-phase': {
4926
- cmdFindPhase(cwd, args[1], raw);
5085
+ phaseLib.cmdFindPhase(cwd, args[1], raw);
4927
5086
  break;
4928
5087
  }
4929
5088
 
@@ -4933,7 +5092,7 @@ async function main() {
4933
5092
  // Parse --files flag (collect args after --files, stopping at other flags)
4934
5093
  const filesIndex = args.indexOf('--files');
4935
5094
  const files = filesIndex !== -1 ? args.slice(filesIndex + 1).filter(a => !a.startsWith('--')) : [];
4936
- cmdCommit(cwd, message, files, raw, amend);
5095
+ commandsLib.cmdCommit(cwd, message, files, raw, amend);
4937
5096
  break;
4938
5097
  }
4939
5098
 
@@ -4941,14 +5100,14 @@ async function main() {
4941
5100
  const summaryPath = args[1];
4942
5101
  const countIndex = args.indexOf('--check-count');
4943
5102
  const checkCount = countIndex !== -1 ? parseInt(args[countIndex + 1], 10) : 2;
4944
- cmdVerifySummary(cwd, summaryPath, checkCount, raw);
5103
+ verifyLib.cmdVerifySummary(cwd, summaryPath, checkCount, raw);
4945
5104
  break;
4946
5105
  }
4947
5106
 
4948
5107
  case 'template': {
4949
5108
  const subcommand = args[1];
4950
5109
  if (subcommand === 'select') {
4951
- cmdTemplateSelect(cwd, args[2], raw);
5110
+ templateLib.cmdTemplateSelect(cwd, args[2], raw);
4952
5111
  } else if (subcommand === 'fill') {
4953
5112
  const templateType = args[2];
4954
5113
  const phaseIdx = args.indexOf('--phase');
@@ -4957,7 +5116,7 @@ async function main() {
4957
5116
  const typeIdx = args.indexOf('--type');
4958
5117
  const waveIdx = args.indexOf('--wave');
4959
5118
  const fieldsIdx = args.indexOf('--fields');
4960
- cmdTemplateFill(cwd, templateType, {
5119
+ templateLib.cmdTemplateFill(cwd, templateType, {
4961
5120
  phase: phaseIdx !== -1 ? args[phaseIdx + 1] : null,
4962
5121
  plan: planIdx !== -1 ? args[planIdx + 1] : null,
4963
5122
  name: nameIdx !== -1 ? args[nameIdx + 1] : null,
@@ -4976,17 +5135,17 @@ async function main() {
4976
5135
  const file = args[2];
4977
5136
  if (subcommand === 'get') {
4978
5137
  const fieldIdx = args.indexOf('--field');
4979
- cmdFrontmatterGet(cwd, file, fieldIdx !== -1 ? args[fieldIdx + 1] : null, raw);
5138
+ frontmatterLib.cmdFrontmatterGet(cwd, file, fieldIdx !== -1 ? args[fieldIdx + 1] : null, raw);
4980
5139
  } else if (subcommand === 'set') {
4981
5140
  const fieldIdx = args.indexOf('--field');
4982
5141
  const valueIdx = args.indexOf('--value');
4983
- cmdFrontmatterSet(cwd, file, fieldIdx !== -1 ? args[fieldIdx + 1] : null, valueIdx !== -1 ? args[valueIdx + 1] : undefined, raw);
5142
+ frontmatterLib.cmdFrontmatterSet(cwd, file, fieldIdx !== -1 ? args[fieldIdx + 1] : null, valueIdx !== -1 ? args[valueIdx + 1] : undefined, raw);
4984
5143
  } else if (subcommand === 'merge') {
4985
5144
  const dataIdx = args.indexOf('--data');
4986
- cmdFrontmatterMerge(cwd, file, dataIdx !== -1 ? args[dataIdx + 1] : null, raw);
5145
+ frontmatterLib.cmdFrontmatterMerge(cwd, file, dataIdx !== -1 ? args[dataIdx + 1] : null, raw);
4987
5146
  } else if (subcommand === 'validate') {
4988
5147
  const schemaIdx = args.indexOf('--schema');
4989
- cmdFrontmatterValidate(cwd, file, schemaIdx !== -1 ? args[schemaIdx + 1] : null, raw);
5148
+ frontmatterLib.cmdFrontmatterValidate(cwd, file, schemaIdx !== -1 ? args[schemaIdx + 1] : null, raw);
4990
5149
  } else {
4991
5150
  error('Unknown frontmatter subcommand. Available: get, set, merge, validate');
4992
5151
  }
@@ -4996,17 +5155,17 @@ async function main() {
4996
5155
  case 'verify': {
4997
5156
  const subcommand = args[1];
4998
5157
  if (subcommand === 'plan-structure') {
4999
- cmdVerifyPlanStructure(cwd, args[2], raw);
5158
+ verifyLib.cmdVerifyPlanStructure(cwd, args[2], raw);
5000
5159
  } else if (subcommand === 'phase-completeness') {
5001
- cmdVerifyPhaseCompleteness(cwd, args[2], raw);
5160
+ verifyLib.cmdVerifyPhaseCompleteness(cwd, args[2], raw);
5002
5161
  } else if (subcommand === 'references') {
5003
- cmdVerifyReferences(cwd, args[2], raw);
5162
+ verifyLib.cmdVerifyReferences(cwd, args[2], raw);
5004
5163
  } else if (subcommand === 'commits') {
5005
- cmdVerifyCommits(cwd, args.slice(2), raw);
5164
+ verifyLib.cmdVerifyCommits(cwd, args.slice(2), raw);
5006
5165
  } else if (subcommand === 'artifacts') {
5007
- cmdVerifyArtifacts(cwd, args[2], raw);
5166
+ verifyLib.cmdVerifyArtifacts(cwd, args[2], raw);
5008
5167
  } else if (subcommand === 'key-links') {
5009
- cmdVerifyKeyLinks(cwd, args[2], raw);
5168
+ verifyLib.cmdVerifyKeyLinks(cwd, args[2], raw);
5010
5169
  } else {
5011
5170
  error('Unknown verify subcommand. Available: plan-structure, phase-completeness, references, commits, artifacts, key-links');
5012
5171
  }
@@ -5014,42 +5173,42 @@ async function main() {
5014
5173
  }
5015
5174
 
5016
5175
  case 'generate-slug': {
5017
- cmdGenerateSlug(args[1], raw);
5176
+ commandsLib.cmdGenerateSlug(args[1], raw);
5018
5177
  break;
5019
5178
  }
5020
5179
 
5021
5180
  case 'current-timestamp': {
5022
- cmdCurrentTimestamp(args[1] || 'full', raw);
5181
+ commandsLib.cmdCurrentTimestamp(args[1] || 'full', raw);
5023
5182
  break;
5024
5183
  }
5025
5184
 
5026
5185
  case 'list-todos': {
5027
- cmdListTodos(cwd, args[1], raw);
5186
+ commandsLib.cmdListTodos(cwd, args[1], raw);
5028
5187
  break;
5029
5188
  }
5030
5189
 
5031
5190
  case 'verify-path-exists': {
5032
- cmdVerifyPathExists(cwd, args[1], raw);
5191
+ commandsLib.cmdVerifyPathExists(cwd, args[1], raw);
5033
5192
  break;
5034
5193
  }
5035
5194
 
5036
5195
  case 'config-ensure-section': {
5037
- cmdConfigEnsureSection(cwd, raw);
5196
+ configLib.cmdConfigEnsureSection(cwd, raw);
5038
5197
  break;
5039
5198
  }
5040
5199
 
5041
5200
  case 'config-set': {
5042
- cmdConfigSet(cwd, args[1], args[2], raw);
5201
+ configLib.cmdConfigSet(cwd, args[1], args[2], raw);
5043
5202
  break;
5044
5203
  }
5045
5204
 
5046
5205
  case 'config-get': {
5047
- cmdConfigGet(cwd, args[1], raw);
5206
+ configLib.cmdConfigGet(cwd, args[1], raw);
5048
5207
  break;
5049
5208
  }
5050
5209
 
5051
5210
  case 'history-digest': {
5052
- cmdHistoryDigest(cwd, raw);
5211
+ commandsLib.cmdHistoryDigest(cwd, raw);
5053
5212
  break;
5054
5213
  }
5055
5214
 
@@ -5063,7 +5222,7 @@ async function main() {
5063
5222
  phase: phaseIndex !== -1 ? args[phaseIndex + 1] : null,
5064
5223
  includeArchived: args.includes('--include-archived'),
5065
5224
  };
5066
- cmdPhasesList(cwd, options, raw);
5225
+ phaseLib.cmdPhasesList(cwd, options, raw);
5067
5226
  } else {
5068
5227
  error('Unknown phases subcommand. Available: list');
5069
5228
  }
@@ -5073,11 +5232,11 @@ async function main() {
5073
5232
  case 'roadmap': {
5074
5233
  const subcommand = args[1];
5075
5234
  if (subcommand === 'get-phase') {
5076
- cmdRoadmapGetPhase(cwd, args[2], raw);
5235
+ roadmapLib.cmdRoadmapGetPhase(cwd, args[2], raw);
5077
5236
  } else if (subcommand === 'analyze') {
5078
- cmdRoadmapAnalyze(cwd, raw);
5237
+ roadmapLib.cmdRoadmapAnalyze(cwd, raw);
5079
5238
  } else if (subcommand === 'update-plan-progress') {
5080
- cmdRoadmapUpdatePlanProgress(cwd, args[2], raw);
5239
+ roadmapLib.cmdRoadmapUpdatePlanProgress(cwd, args[2], raw);
5081
5240
  } else {
5082
5241
  error('Unknown roadmap subcommand. Available: get-phase, analyze, update-plan-progress');
5083
5242
  }
@@ -5087,22 +5246,32 @@ async function main() {
5087
5246
  case 'phase': {
5088
5247
  const subcommand = args[1];
5089
5248
  if (subcommand === 'next-decimal') {
5090
- cmdPhaseNextDecimal(cwd, args[2], raw);
5249
+ phaseLib.cmdPhaseNextDecimal(cwd, args[2], raw);
5091
5250
  } else if (subcommand === 'add') {
5092
- cmdPhaseAdd(cwd, args.slice(2).join(' '), raw);
5251
+ phaseLib.cmdPhaseAdd(cwd, args.slice(2).join(' '), raw);
5093
5252
  } else if (subcommand === 'insert') {
5094
- cmdPhaseInsert(cwd, args[2], args.slice(3).join(' '), raw);
5253
+ phaseLib.cmdPhaseInsert(cwd, args[2], args.slice(3).join(' '), raw);
5095
5254
  } else if (subcommand === 'remove') {
5096
5255
  const forceFlag = args.includes('--force');
5097
- cmdPhaseRemove(cwd, args[2], { force: forceFlag }, raw);
5256
+ phaseLib.cmdPhaseRemove(cwd, args[2], { force: forceFlag }, raw);
5098
5257
  } else if (subcommand === 'complete') {
5099
- cmdPhaseComplete(cwd, args[2], raw);
5258
+ phaseLib.cmdPhaseComplete(cwd, args[2], raw);
5100
5259
  } else {
5101
5260
  error('Unknown phase subcommand. Available: next-decimal, add, insert, remove, complete');
5102
5261
  }
5103
5262
  break;
5104
5263
  }
5105
5264
 
5265
+ case 'requirements': {
5266
+ const subcommand = args[1];
5267
+ if (subcommand === 'mark-complete') {
5268
+ milestoneLib.cmdRequirementsMarkComplete(cwd, args.slice(2), raw);
5269
+ } else {
5270
+ error('Unknown requirements subcommand. Available: mark-complete');
5271
+ }
5272
+ break;
5273
+ }
5274
+
5106
5275
  case 'milestone': {
5107
5276
  const subcommand = args[1];
5108
5277
  if (subcommand === 'complete') {
@@ -5118,7 +5287,7 @@ async function main() {
5118
5287
  }
5119
5288
  milestoneName = nameArgs.join(' ') || null;
5120
5289
  }
5121
- cmdMilestoneComplete(cwd, args[2], { name: milestoneName, archivePhases }, raw);
5290
+ milestoneLib.cmdMilestoneComplete(cwd, args[2], { name: milestoneName, archivePhases }, raw);
5122
5291
  } else {
5123
5292
  error('Unknown milestone subcommand. Available: complete');
5124
5293
  }
@@ -5128,10 +5297,10 @@ async function main() {
5128
5297
  case 'validate': {
5129
5298
  const subcommand = args[1];
5130
5299
  if (subcommand === 'consistency') {
5131
- cmdValidateConsistency(cwd, raw);
5300
+ verifyLib.cmdValidateConsistency(cwd, raw);
5132
5301
  } else if (subcommand === 'health') {
5133
5302
  const repairFlag = args.includes('--repair');
5134
- cmdValidateHealth(cwd, { repair: repairFlag }, raw);
5303
+ verifyLib.cmdValidateHealth(cwd, { repair: repairFlag }, raw);
5135
5304
  } else {
5136
5305
  error('Unknown validate subcommand. Available: consistency, health');
5137
5306
  }
@@ -5140,14 +5309,14 @@ async function main() {
5140
5309
 
5141
5310
  case 'progress': {
5142
5311
  const subcommand = args[1] || 'json';
5143
- cmdProgressRender(cwd, subcommand, raw);
5312
+ commandsLib.cmdProgressRender(cwd, subcommand, raw);
5144
5313
  break;
5145
5314
  }
5146
5315
 
5147
5316
  case 'todo': {
5148
5317
  const subcommand = args[1];
5149
5318
  if (subcommand === 'complete') {
5150
- cmdTodoComplete(cwd, args[2], raw);
5319
+ commandsLib.cmdTodoComplete(cwd, args[2], raw);
5151
5320
  } else {
5152
5321
  error('Unknown todo subcommand. Available: complete');
5153
5322
  }
@@ -5162,7 +5331,7 @@ async function main() {
5162
5331
  phase: phaseIndex !== -1 ? args[phaseIndex + 1] : null,
5163
5332
  name: nameIndex !== -1 ? args.slice(nameIndex + 1).join(' ') : null,
5164
5333
  };
5165
- cmdScaffold(cwd, scaffoldType, scaffoldOptions, raw);
5334
+ commandsLib.cmdScaffold(cwd, scaffoldType, scaffoldOptions, raw);
5166
5335
  break;
5167
5336
  }
5168
5337
 
@@ -5171,40 +5340,40 @@ async function main() {
5171
5340
  const includes = parseIncludeFlag(args);
5172
5341
  switch (workflow) {
5173
5342
  case 'execute-phase':
5174
- cmdInitExecutePhase(cwd, args[2], includes, raw);
5343
+ initLib.cmdInitExecutePhase(cwd, args[2], raw);
5175
5344
  break;
5176
5345
  case 'plan-phase':
5177
- cmdInitPlanPhase(cwd, args[2], includes, raw);
5346
+ initLib.cmdInitPlanPhase(cwd, args[2], raw);
5178
5347
  break;
5179
5348
  case 'new-project':
5180
- cmdInitNewProject(cwd, raw);
5349
+ initLib.cmdInitNewProject(cwd, raw);
5181
5350
  break;
5182
5351
  case 'new-milestone':
5183
- cmdInitNewMilestone(cwd, raw);
5352
+ initLib.cmdInitNewMilestone(cwd, raw);
5184
5353
  break;
5185
5354
  case 'quick':
5186
- cmdInitQuick(cwd, args.slice(2).join(' '), raw);
5355
+ initLib.cmdInitQuick(cwd, args.slice(2).join(' '), raw);
5187
5356
  break;
5188
5357
  case 'resume':
5189
- cmdInitResume(cwd, raw);
5358
+ initLib.cmdInitResume(cwd, raw);
5190
5359
  break;
5191
5360
  case 'verify-work':
5192
- cmdInitVerifyWork(cwd, args[2], raw);
5361
+ initLib.cmdInitVerifyWork(cwd, args[2], raw);
5193
5362
  break;
5194
5363
  case 'phase-op':
5195
- cmdInitPhaseOp(cwd, args[2], raw);
5364
+ initLib.cmdInitPhaseOp(cwd, args[2], raw);
5196
5365
  break;
5197
5366
  case 'todos':
5198
- cmdInitTodos(cwd, args[2], raw);
5367
+ initLib.cmdInitTodos(cwd, args[2], raw);
5199
5368
  break;
5200
5369
  case 'milestone-op':
5201
- cmdInitMilestoneOp(cwd, raw);
5370
+ initLib.cmdInitMilestoneOp(cwd, raw);
5202
5371
  break;
5203
5372
  case 'map-codebase':
5204
- cmdInitMapCodebase(cwd, raw);
5373
+ initLib.cmdInitMapCodebase(cwd, raw);
5205
5374
  break;
5206
5375
  case 'progress':
5207
- cmdInitProgress(cwd, includes, raw);
5376
+ initLib.cmdInitProgress(cwd, includes, raw);
5208
5377
  break;
5209
5378
  default:
5210
5379
  error(`Unknown init workflow: ${workflow}\nAvailable: execute-phase, plan-phase, new-project, new-milestone, quick, resume, verify-work, phase-op, todos, milestone-op, map-codebase, progress`);
@@ -5213,12 +5382,12 @@ async function main() {
5213
5382
  }
5214
5383
 
5215
5384
  case 'phase-plan-index': {
5216
- cmdPhasePlanIndex(cwd, args[1], raw);
5385
+ phaseLib.cmdPhasePlanIndex(cwd, args[1], raw);
5217
5386
  break;
5218
5387
  }
5219
5388
 
5220
5389
  case 'state-snapshot': {
5221
- cmdStateSnapshot(cwd, raw);
5390
+ stateLib.cmdStateSnapshot(cwd, raw);
5222
5391
  break;
5223
5392
  }
5224
5393
 
@@ -5226,7 +5395,7 @@ async function main() {
5226
5395
  const summaryPath = args[1];
5227
5396
  const fieldsIndex = args.indexOf('--fields');
5228
5397
  const fields = fieldsIndex !== -1 ? args[fieldsIndex + 1].split(',') : null;
5229
- cmdSummaryExtract(cwd, summaryPath, fields, raw);
5398
+ commandsLib.cmdSummaryExtract(cwd, summaryPath, fields, raw);
5230
5399
  break;
5231
5400
  }
5232
5401
 
@@ -5234,7 +5403,7 @@ async function main() {
5234
5403
  const query = args[1];
5235
5404
  const limitIdx = args.indexOf('--limit');
5236
5405
  const freshnessIdx = args.indexOf('--freshness');
5237
- await cmdWebsearch(query, {
5406
+ await commandsLib.cmdWebsearch(query, {
5238
5407
  limit: limitIdx !== -1 ? parseInt(args[limitIdx + 1], 10) : 10,
5239
5408
  freshness: freshnessIdx !== -1 ? args[freshnessIdx + 1] : null,
5240
5409
  }, raw);