get-shit-done-cc 1.19.2 → 1.20.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/README.md CHANGED
@@ -505,7 +505,8 @@ You're never locked in. The system adapts.
505
505
  | `/gsd:add-todo [desc]` | Capture idea for later |
506
506
  | `/gsd:check-todos` | List pending todos |
507
507
  | `/gsd:debug [desc]` | Systematic debugging with persistent state |
508
- | `/gsd:quick` | Execute ad-hoc task with GSD guarantees |
508
+ | `/gsd:quick [--full]` | Execute ad-hoc task with GSD guarantees (`--full` adds plan-checking and verification) |
509
+ | `/gsd:health [--repair]` | Validate `.planning/` directory integrity, auto-repair with `--repair` |
509
510
 
510
511
  <sup>¹ Contributed by reddit user OracleGreyBeard</sup>
511
512
 
package/bin/install.js CHANGED
@@ -469,6 +469,8 @@ function convertClaudeToOpencodeFrontmatter(content) {
469
469
  convertedContent = convertedContent.replace(/\/gsd:/g, '/gsd-');
470
470
  // Replace ~/.claude with ~/.config/opencode (OpenCode's correct config location)
471
471
  convertedContent = convertedContent.replace(/~\/\.claude\b/g, '~/.config/opencode');
472
+ // Replace general-purpose subagent type with OpenCode's equivalent "general"
473
+ convertedContent = convertedContent.replace(/subagent_type="general-purpose"/g, 'subagent_type="general"');
472
474
 
473
475
  // Check if content has frontmatter
474
476
  if (!convertedContent.startsWith('---')) {
@@ -0,0 +1,22 @@
1
+ ---
2
+ name: gsd:health
3
+ description: Diagnose planning directory health and optionally repair issues
4
+ argument-hint: [--repair]
5
+ allowed-tools:
6
+ - Read
7
+ - Bash
8
+ - Write
9
+ - AskUserQuestion
10
+ ---
11
+ <objective>
12
+ Validate `.planning/` directory integrity and report actionable issues. Checks for missing files, invalid configurations, inconsistent state, and orphaned plans.
13
+ </objective>
14
+
15
+ <execution_context>
16
+ @~/.claude/get-shit-done/workflows/health.md
17
+ </execution_context>
18
+
19
+ <process>
20
+ Execute the health workflow from @~/.claude/get-shit-done/workflows/health.md end-to-end.
21
+ Parse --repair flag from arguments and pass to workflow.
22
+ </process>
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: gsd:quick
3
3
  description: Execute a quick task with GSD guarantees (atomic commits, state tracking) but skip optional agents
4
- argument-hint: ""
4
+ argument-hint: "[--full]"
5
5
  allowed-tools:
6
6
  - Read
7
7
  - Write
@@ -13,15 +13,16 @@ allowed-tools:
13
13
  - AskUserQuestion
14
14
  ---
15
15
  <objective>
16
- Execute small, ad-hoc tasks with GSD guarantees (atomic commits, STATE.md tracking) while skipping optional agents (research, plan-checker, verifier).
16
+ Execute small, ad-hoc tasks with GSD guarantees (atomic commits, STATE.md tracking).
17
17
 
18
18
  Quick mode is the same system with a shorter path:
19
19
  - Spawns gsd-planner (quick mode) + gsd-executor(s)
20
- - Skips gsd-phase-researcher, gsd-plan-checker, gsd-verifier
21
20
  - Quick tasks live in `.planning/quick/` separate from planned phases
22
21
  - Updates STATE.md "Quick Tasks Completed" table (NOT ROADMAP.md)
23
22
 
24
- Use when: You know exactly what to do and the task is small enough to not need research or verification.
23
+ **Default:** Skips research, plan-checker, verifier. Use when you know exactly what to do.
24
+
25
+ **`--full` flag:** Enables plan-checking (max 2 iterations) and post-execution verification. Use when you want quality guarantees without full milestone ceremony.
25
26
  </objective>
26
27
 
27
28
  <execution_context>
@@ -30,6 +31,7 @@ Use when: You know exactly what to do and the task is small enough to not need r
30
31
 
31
32
  <context>
32
33
  @.planning/STATE.md
34
+ $ARGUMENTS
33
35
  </context>
34
36
 
35
37
  <process>
@@ -48,6 +48,7 @@
48
48
  *
49
49
  * Validation:
50
50
  * validate consistency Check phase numbering, disk/roadmap sync
51
+ * validate health [--repair] Check .planning/ integrity, optionally repair
51
52
  *
52
53
  * Progress:
53
54
  * progress [json|table|bar] Render progress in various formats
@@ -691,6 +692,42 @@ function cmdConfigSet(cwd, keyPath, value, raw) {
691
692
  }
692
693
  }
693
694
 
695
+ function cmdConfigGet(cwd, keyPath, raw) {
696
+ const configPath = path.join(cwd, '.planning', 'config.json');
697
+
698
+ if (!keyPath) {
699
+ error('Usage: config-get <key.path>');
700
+ }
701
+
702
+ let config = {};
703
+ try {
704
+ if (fs.existsSync(configPath)) {
705
+ config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
706
+ } else {
707
+ error('No config.json found at ' + configPath);
708
+ }
709
+ } catch (err) {
710
+ if (err.message.startsWith('No config.json')) throw err;
711
+ error('Failed to read config.json: ' + err.message);
712
+ }
713
+
714
+ // Traverse dot-notation path (e.g., "workflow.auto_advance")
715
+ const keys = keyPath.split('.');
716
+ let current = config;
717
+ for (const key of keys) {
718
+ if (current === undefined || current === null || typeof current !== 'object') {
719
+ error(`Key not found: ${keyPath}`);
720
+ }
721
+ current = current[key];
722
+ }
723
+
724
+ if (current === undefined) {
725
+ error(`Key not found: ${keyPath}`);
726
+ }
727
+
728
+ output(current, raw, String(current));
729
+ }
730
+
694
731
  function cmdHistoryDigest(cwd, raw) {
695
732
  const phasesDir = path.join(cwd, '.planning', 'phases');
696
733
  const digest = { phases: {}, decisions: [], tech_stack: new Set() };
@@ -2653,8 +2690,9 @@ function cmdPhaseAdd(cwd, description, raw) {
2653
2690
  const dirName = `${paddedNum}-${slug}`;
2654
2691
  const dirPath = path.join(cwd, '.planning', 'phases', dirName);
2655
2692
 
2656
- // Create directory
2693
+ // Create directory with .gitkeep so git tracks empty folders
2657
2694
  fs.mkdirSync(dirPath, { recursive: true });
2695
+ fs.writeFileSync(path.join(dirPath, '.gitkeep'), '');
2658
2696
 
2659
2697
  // Build phase entry
2660
2698
  const phaseEntry = `\n### Phase ${newPhaseNum}: ${description}\n\n**Goal:** [To be planned]\n**Depends on:** Phase ${maxPhase}\n**Plans:** 0 plans\n\nPlans:\n- [ ] TBD (run /gsd:plan-phase ${newPhaseNum} to break down)\n`;
@@ -2725,8 +2763,9 @@ function cmdPhaseInsert(cwd, afterPhase, description, raw) {
2725
2763
  const dirName = `${decimalPhase}-${slug}`;
2726
2764
  const dirPath = path.join(cwd, '.planning', 'phases', dirName);
2727
2765
 
2728
- // Create directory
2766
+ // Create directory with .gitkeep so git tracks empty folders
2729
2767
  fs.mkdirSync(dirPath, { recursive: true });
2768
+ fs.writeFileSync(path.join(dirPath, '.gitkeep'), '');
2730
2769
 
2731
2770
  // Build phase entry
2732
2771
  const phaseEntry = `\n### Phase ${decimalPhase}: ${description} (INSERTED)\n\n**Goal:** [Urgent work - to be planned]\n**Depends on:** Phase ${afterPhase}\n**Plans:** 0 plans\n\nPlans:\n- [ ] TBD (run /gsd:plan-phase ${decimalPhase} to break down)\n`;
@@ -3522,6 +3561,247 @@ function cmdValidateConsistency(cwd, raw) {
3522
3561
  output({ passed, errors, warnings, warning_count: warnings.length }, raw, passed ? 'passed' : 'failed');
3523
3562
  }
3524
3563
 
3564
+ // ─── Validate Health ──────────────────────────────────────────────────────────
3565
+
3566
+ function cmdValidateHealth(cwd, options, raw) {
3567
+ const planningDir = path.join(cwd, '.planning');
3568
+ const projectPath = path.join(planningDir, 'PROJECT.md');
3569
+ const roadmapPath = path.join(planningDir, 'ROADMAP.md');
3570
+ const statePath = path.join(planningDir, 'STATE.md');
3571
+ const configPath = path.join(planningDir, 'config.json');
3572
+ const phasesDir = path.join(planningDir, 'phases');
3573
+
3574
+ const errors = [];
3575
+ const warnings = [];
3576
+ const info = [];
3577
+ const repairs = [];
3578
+
3579
+ // Helper to add issue
3580
+ const addIssue = (severity, code, message, fix, repairable = false) => {
3581
+ const issue = { code, message, fix, repairable };
3582
+ if (severity === 'error') errors.push(issue);
3583
+ else if (severity === 'warning') warnings.push(issue);
3584
+ else info.push(issue);
3585
+ };
3586
+
3587
+ // ─── Check 1: .planning/ exists ───────────────────────────────────────────
3588
+ if (!fs.existsSync(planningDir)) {
3589
+ addIssue('error', 'E001', '.planning/ directory not found', 'Run /gsd:new-project to initialize');
3590
+ output({
3591
+ status: 'broken',
3592
+ errors,
3593
+ warnings,
3594
+ info,
3595
+ repairable_count: 0,
3596
+ }, raw);
3597
+ return;
3598
+ }
3599
+
3600
+ // ─── Check 2: PROJECT.md exists and has required sections ─────────────────
3601
+ if (!fs.existsSync(projectPath)) {
3602
+ addIssue('error', 'E002', 'PROJECT.md not found', 'Run /gsd:new-project to create');
3603
+ } else {
3604
+ const content = fs.readFileSync(projectPath, 'utf-8');
3605
+ const requiredSections = ['## What This Is', '## Core Value', '## Requirements'];
3606
+ for (const section of requiredSections) {
3607
+ if (!content.includes(section)) {
3608
+ addIssue('warning', 'W001', `PROJECT.md missing section: ${section}`, 'Add section manually');
3609
+ }
3610
+ }
3611
+ }
3612
+
3613
+ // ─── Check 3: ROADMAP.md exists ───────────────────────────────────────────
3614
+ if (!fs.existsSync(roadmapPath)) {
3615
+ addIssue('error', 'E003', 'ROADMAP.md not found', 'Run /gsd:new-milestone to create roadmap');
3616
+ }
3617
+
3618
+ // ─── Check 4: STATE.md exists and references valid phases ─────────────────
3619
+ if (!fs.existsSync(statePath)) {
3620
+ addIssue('error', 'E004', 'STATE.md not found', 'Run /gsd:health --repair to regenerate', true);
3621
+ repairs.push('regenerateState');
3622
+ } else {
3623
+ const stateContent = fs.readFileSync(statePath, 'utf-8');
3624
+ // Extract phase references from STATE.md
3625
+ const phaseRefs = [...stateContent.matchAll(/[Pp]hase\s+(\d+(?:\.\d+)?)/g)].map(m => m[1]);
3626
+ // Get disk phases
3627
+ const diskPhases = new Set();
3628
+ try {
3629
+ const entries = fs.readdirSync(phasesDir, { withFileTypes: true });
3630
+ for (const e of entries) {
3631
+ if (e.isDirectory()) {
3632
+ const m = e.name.match(/^(\d+(?:\.\d+)?)/);
3633
+ if (m) diskPhases.add(m[1]);
3634
+ }
3635
+ }
3636
+ } catch {}
3637
+ // Check for invalid references
3638
+ for (const ref of phaseRefs) {
3639
+ const normalizedRef = String(parseInt(ref, 10)).padStart(2, '0');
3640
+ if (!diskPhases.has(ref) && !diskPhases.has(normalizedRef) && !diskPhases.has(String(parseInt(ref, 10)))) {
3641
+ // Only warn if phases dir has any content (not just an empty project)
3642
+ if (diskPhases.size > 0) {
3643
+ addIssue('warning', 'W002', `STATE.md references phase ${ref}, but only phases ${[...diskPhases].sort().join(', ')} exist`, 'Run /gsd:health --repair to regenerate STATE.md', true);
3644
+ if (!repairs.includes('regenerateState')) repairs.push('regenerateState');
3645
+ }
3646
+ }
3647
+ }
3648
+ }
3649
+
3650
+ // ─── Check 5: config.json valid JSON + valid schema ───────────────────────
3651
+ if (!fs.existsSync(configPath)) {
3652
+ addIssue('warning', 'W003', 'config.json not found', 'Run /gsd:health --repair to create with defaults', true);
3653
+ repairs.push('createConfig');
3654
+ } else {
3655
+ try {
3656
+ const raw = fs.readFileSync(configPath, 'utf-8');
3657
+ const parsed = JSON.parse(raw);
3658
+ // Validate known fields
3659
+ const validProfiles = ['quality', 'balanced', 'budget'];
3660
+ if (parsed.model_profile && !validProfiles.includes(parsed.model_profile)) {
3661
+ addIssue('warning', 'W004', `config.json: invalid model_profile "${parsed.model_profile}"`, `Valid values: ${validProfiles.join(', ')}`);
3662
+ }
3663
+ } catch (err) {
3664
+ addIssue('error', 'E005', `config.json: JSON parse error - ${err.message}`, 'Run /gsd:health --repair to reset to defaults', true);
3665
+ repairs.push('resetConfig');
3666
+ }
3667
+ }
3668
+
3669
+ // ─── Check 6: Phase directory naming (NN-name format) ─────────────────────
3670
+ try {
3671
+ const entries = fs.readdirSync(phasesDir, { withFileTypes: true });
3672
+ for (const e of entries) {
3673
+ if (e.isDirectory() && !e.name.match(/^\d{2}(?:\.\d+)?-[\w-]+$/)) {
3674
+ addIssue('warning', 'W005', `Phase directory "${e.name}" doesn't follow NN-name format`, 'Rename to match pattern (e.g., 01-setup)');
3675
+ }
3676
+ }
3677
+ } catch {}
3678
+
3679
+ // ─── Check 7: Orphaned plans (PLAN without SUMMARY) ───────────────────────
3680
+ try {
3681
+ const entries = fs.readdirSync(phasesDir, { withFileTypes: true });
3682
+ for (const e of entries) {
3683
+ if (!e.isDirectory()) continue;
3684
+ const phaseFiles = fs.readdirSync(path.join(phasesDir, e.name));
3685
+ const plans = phaseFiles.filter(f => f.endsWith('-PLAN.md') || f === 'PLAN.md');
3686
+ const summaries = phaseFiles.filter(f => f.endsWith('-SUMMARY.md') || f === 'SUMMARY.md');
3687
+ const summaryBases = new Set(summaries.map(s => s.replace('-SUMMARY.md', '').replace('SUMMARY.md', '')));
3688
+
3689
+ for (const plan of plans) {
3690
+ const planBase = plan.replace('-PLAN.md', '').replace('PLAN.md', '');
3691
+ if (!summaryBases.has(planBase)) {
3692
+ addIssue('info', 'I001', `${e.name}/${plan} has no SUMMARY.md`, 'May be in progress');
3693
+ }
3694
+ }
3695
+ }
3696
+ } catch {}
3697
+
3698
+ // ─── Check 8: Run existing consistency checks ─────────────────────────────
3699
+ // Inline subset of cmdValidateConsistency
3700
+ if (fs.existsSync(roadmapPath)) {
3701
+ const roadmapContent = fs.readFileSync(roadmapPath, 'utf-8');
3702
+ const roadmapPhases = new Set();
3703
+ const phasePattern = /#{2,4}\s*Phase\s+(\d+(?:\.\d+)?)\s*:/gi;
3704
+ let m;
3705
+ while ((m = phasePattern.exec(roadmapContent)) !== null) {
3706
+ roadmapPhases.add(m[1]);
3707
+ }
3708
+
3709
+ const diskPhases = new Set();
3710
+ try {
3711
+ const entries = fs.readdirSync(phasesDir, { withFileTypes: true });
3712
+ for (const e of entries) {
3713
+ if (e.isDirectory()) {
3714
+ const dm = e.name.match(/^(\d+(?:\.\d+)?)/);
3715
+ if (dm) diskPhases.add(dm[1]);
3716
+ }
3717
+ }
3718
+ } catch {}
3719
+
3720
+ // Phases in ROADMAP but not on disk
3721
+ for (const p of roadmapPhases) {
3722
+ const padded = String(parseInt(p, 10)).padStart(2, '0');
3723
+ if (!diskPhases.has(p) && !diskPhases.has(padded)) {
3724
+ addIssue('warning', 'W006', `Phase ${p} in ROADMAP.md but no directory on disk`, 'Create phase directory or remove from roadmap');
3725
+ }
3726
+ }
3727
+
3728
+ // Phases on disk but not in ROADMAP
3729
+ for (const p of diskPhases) {
3730
+ const unpadded = String(parseInt(p, 10));
3731
+ if (!roadmapPhases.has(p) && !roadmapPhases.has(unpadded)) {
3732
+ addIssue('warning', 'W007', `Phase ${p} exists on disk but not in ROADMAP.md`, 'Add to roadmap or remove directory');
3733
+ }
3734
+ }
3735
+ }
3736
+
3737
+ // ─── Perform repairs if requested ─────────────────────────────────────────
3738
+ const repairActions = [];
3739
+ if (options.repair && repairs.length > 0) {
3740
+ for (const repair of repairs) {
3741
+ try {
3742
+ switch (repair) {
3743
+ case 'createConfig':
3744
+ case 'resetConfig': {
3745
+ const defaults = {
3746
+ model_profile: 'balanced',
3747
+ commit_docs: true,
3748
+ search_gitignored: false,
3749
+ branching_strategy: 'none',
3750
+ research: true,
3751
+ plan_checker: true,
3752
+ verifier: true,
3753
+ parallelization: true,
3754
+ };
3755
+ fs.writeFileSync(configPath, JSON.stringify(defaults, null, 2), 'utf-8');
3756
+ repairActions.push({ action: repair, success: true, path: 'config.json' });
3757
+ break;
3758
+ }
3759
+ case 'regenerateState': {
3760
+ // Generate minimal STATE.md from ROADMAP.md structure
3761
+ const milestone = getMilestoneInfo(cwd);
3762
+ let stateContent = `# Session State\n\n`;
3763
+ stateContent += `## Project Reference\n\n`;
3764
+ stateContent += `See: .planning/PROJECT.md\n\n`;
3765
+ stateContent += `## Position\n\n`;
3766
+ stateContent += `**Milestone:** ${milestone.version} ${milestone.name}\n`;
3767
+ stateContent += `**Current phase:** (determining...)\n`;
3768
+ stateContent += `**Status:** Resuming\n\n`;
3769
+ stateContent += `## Session Log\n\n`;
3770
+ stateContent += `- ${new Date().toISOString().split('T')[0]}: STATE.md regenerated by /gsd:health --repair\n`;
3771
+ fs.writeFileSync(statePath, stateContent, 'utf-8');
3772
+ repairActions.push({ action: repair, success: true, path: 'STATE.md' });
3773
+ break;
3774
+ }
3775
+ }
3776
+ } catch (err) {
3777
+ repairActions.push({ action: repair, success: false, error: err.message });
3778
+ }
3779
+ }
3780
+ }
3781
+
3782
+ // ─── Determine overall status ─────────────────────────────────────────────
3783
+ let status;
3784
+ if (errors.length > 0) {
3785
+ status = 'broken';
3786
+ } else if (warnings.length > 0) {
3787
+ status = 'degraded';
3788
+ } else {
3789
+ status = 'healthy';
3790
+ }
3791
+
3792
+ const repairableCount = errors.filter(e => e.repairable).length +
3793
+ warnings.filter(w => w.repairable).length;
3794
+
3795
+ output({
3796
+ status,
3797
+ errors,
3798
+ warnings,
3799
+ info,
3800
+ repairable_count: repairableCount,
3801
+ repairs_performed: repairActions.length > 0 ? repairActions : undefined,
3802
+ }, raw);
3803
+ }
3804
+
3525
3805
  // ─── Progress Render ──────────────────────────────────────────────────────────
3526
3806
 
3527
3807
  function cmdProgressRender(cwd, format, raw) {
@@ -4157,6 +4437,8 @@ function cmdInitQuick(cwd, description, raw) {
4157
4437
  // Models
4158
4438
  planner_model: resolveModelInternal(cwd, 'gsd-planner'),
4159
4439
  executor_model: resolveModelInternal(cwd, 'gsd-executor'),
4440
+ checker_model: resolveModelInternal(cwd, 'gsd-plan-checker'),
4441
+ verifier_model: resolveModelInternal(cwd, 'gsd-verifier'),
4160
4442
 
4161
4443
  // Config
4162
4444
  commit_docs: config.commit_docs,
@@ -4755,6 +5037,11 @@ async function main() {
4755
5037
  break;
4756
5038
  }
4757
5039
 
5040
+ case 'config-get': {
5041
+ cmdConfigGet(cwd, args[1], raw);
5042
+ break;
5043
+ }
5044
+
4758
5045
  case 'history-digest': {
4759
5046
  cmdHistoryDigest(cwd, raw);
4760
5047
  break;
@@ -4836,8 +5123,11 @@ async function main() {
4836
5123
  const subcommand = args[1];
4837
5124
  if (subcommand === 'consistency') {
4838
5125
  cmdValidateConsistency(cwd, raw);
5126
+ } else if (subcommand === 'health') {
5127
+ const repairFlag = args.includes('--repair');
5128
+ cmdValidateHealth(cwd, { repair: repairFlag }, raw);
4839
5129
  } else {
4840
- error('Unknown validate subcommand. Available: consistency');
5130
+ error('Unknown validate subcommand. Available: consistency, health');
4841
5131
  }
4842
5132
  break;
4843
5133
  }
@@ -101,6 +101,8 @@ To use uncommitted mode:
101
101
  git commit -m "chore: stop tracking planning docs"
102
102
  ```
103
103
 
104
+ 4. **Branch merges:** When using `branching_strategy: phase` or `milestone`, the `complete-milestone` workflow automatically strips `.planning/` files from staging before merge commits when `commit_docs: false`.
105
+
104
106
  </setup_uncommitted_mode>
105
107
 
106
108
  <branching_strategy_behavior>
@@ -95,6 +95,9 @@ User mentions "frustrated with current tools"
95
95
  - question: "What specifically frustrates you?"
96
96
  - options: ["Too many clicks", "Missing features", "Unreliable", "Let me explain"]
97
97
 
98
+ **Tip for users — modifying an option:**
99
+ Users who want a slightly modified version of an option can select "Other" and reference the option by number: `#1 but for finger joints only` or `#2 with pagination disabled`. This avoids retyping the full option text.
100
+
98
101
  </using_askuserquestion>
99
102
 
100
103
  <context_checklist>
@@ -447,7 +447,7 @@ Use `init milestone-op` for context, or load config directly:
447
447
  INIT=$(node ~/.claude/get-shit-done/bin/gsd-tools.cjs init execute-phase "1")
448
448
  ```
449
449
 
450
- Extract `branching_strategy`, `phase_branch_template`, `milestone_branch_template` from init JSON.
450
+ Extract `branching_strategy`, `phase_branch_template`, `milestone_branch_template`, and `commit_docs` from init JSON.
451
451
 
452
452
  **If "none":** Skip to git_tag.
453
453
 
@@ -492,12 +492,20 @@ git checkout main
492
492
  if [ "$BRANCHING_STRATEGY" = "phase" ]; then
493
493
  for branch in $PHASE_BRANCHES; do
494
494
  git merge --squash "$branch"
495
+ # Strip .planning/ from staging if commit_docs is false
496
+ if [ "$COMMIT_DOCS" = "false" ]; then
497
+ git reset HEAD .planning/ 2>/dev/null || true
498
+ fi
495
499
  git commit -m "feat: $branch for v[X.Y]"
496
500
  done
497
501
  fi
498
502
 
499
503
  if [ "$BRANCHING_STRATEGY" = "milestone" ]; then
500
504
  git merge --squash "$MILESTONE_BRANCH"
505
+ # Strip .planning/ from staging if commit_docs is false
506
+ if [ "$COMMIT_DOCS" = "false" ]; then
507
+ git reset HEAD .planning/ 2>/dev/null || true
508
+ fi
501
509
  git commit -m "feat: $MILESTONE_BRANCH for v[X.Y]"
502
510
  fi
503
511
 
@@ -512,12 +520,22 @@ git checkout main
512
520
 
513
521
  if [ "$BRANCHING_STRATEGY" = "phase" ]; then
514
522
  for branch in $PHASE_BRANCHES; do
515
- git merge --no-ff "$branch" -m "Merge branch '$branch' for v[X.Y]"
523
+ git merge --no-ff --no-commit "$branch"
524
+ # Strip .planning/ from staging if commit_docs is false
525
+ if [ "$COMMIT_DOCS" = "false" ]; then
526
+ git reset HEAD .planning/ 2>/dev/null || true
527
+ fi
528
+ git commit -m "Merge branch '$branch' for v[X.Y]"
516
529
  done
517
530
  fi
518
531
 
519
532
  if [ "$BRANCHING_STRATEGY" = "milestone" ]; then
520
- git merge --no-ff "$MILESTONE_BRANCH" -m "Merge branch '$MILESTONE_BRANCH' for v[X.Y]"
533
+ git merge --no-ff --no-commit "$MILESTONE_BRANCH"
534
+ # Strip .planning/ from staging if commit_docs is false
535
+ if [ "$COMMIT_DOCS" = "false" ]; then
536
+ git reset HEAD .planning/ 2>/dev/null || true
537
+ fi
538
+ git commit -m "Merge branch '$MILESTONE_BRANCH' for v[X.Y]"
521
539
  fi
522
540
 
523
541
  git checkout "$CURRENT_BRANCH"
@@ -147,7 +147,23 @@ If "Update": Load existing, continue to analyze_phase
147
147
  If "View": Display CONTEXT.md, then offer update/skip
148
148
  If "Skip": Exit workflow
149
149
 
150
- **If doesn't exist:** Continue to analyze_phase.
150
+ **If doesn't exist:**
151
+
152
+ Check `has_plans` and `plan_count` from init. **If `has_plans` is true:**
153
+
154
+ Use AskUserQuestion:
155
+ - header: "Plans exist"
156
+ - question: "Phase [X] already has {plan_count} plan(s) created without user context. Your decisions here won't affect existing plans unless you replan."
157
+ - options:
158
+ - "Continue and replan after" — Capture context, then run /gsd:plan-phase {X} to replan
159
+ - "View existing plans" — Show plans before deciding
160
+ - "Cancel" — Skip discuss-phase
161
+
162
+ If "Continue and replan after": Continue to analyze_phase.
163
+ If "View existing plans": Display plan files, then offer "Continue" / "Cancel".
164
+ If "Cancel": Exit workflow.
165
+
166
+ **If `has_plans` is false:** Continue to analyze_phase.
151
167
  </step>
152
168
 
153
169
  <step name="analyze_phase">
@@ -417,7 +433,7 @@ Check for auto-advance trigger:
417
433
  1. Parse `--auto` flag from $ARGUMENTS
418
434
  2. Read `workflow.auto_advance` from config:
419
435
  ```bash
420
- AUTO_CFG=$(node ~/.claude/get-shit-done/bin/gsd-tools.cjs config get workflow.auto_advance 2>/dev/null || echo "false")
436
+ AUTO_CFG=$(node ~/.claude/get-shit-done/bin/gsd-tools.cjs config-get workflow.auto_advance 2>/dev/null || echo "false")
421
437
  ```
422
438
 
423
439
  **If `--auto` flag present OR `AUTO_CFG` is true:**
@@ -359,11 +359,32 @@ node ~/.claude/get-shit-done/bin/gsd-tools.cjs commit "docs(phase-{X}): complete
359
359
 
360
360
  <step name="offer_next">
361
361
 
362
- **Routing is handled by `transition.md`** do NOT emit a separate "Next Up" block here.
362
+ **Exception:** If `gaps_found`, the `verify_phase_goal` step already presents the gap-closure path (`/gsd:plan-phase {X} --gaps`). No additional routing needed — skip auto-advance.
363
363
 
364
- After `verify_phase_goal` passes (or human approves), the workflow ends. The user runs `/gsd:progress` or the transition workflow handles next-step routing.
364
+ **Auto-advance detection:**
365
365
 
366
- **Exception:** If `gaps_found`, the `verify_phase_goal` step already presents the gap-closure path (`/gsd:plan-phase {X} --gaps`). No additional routing needed.
366
+ 1. Parse `--auto` flag from $ARGUMENTS
367
+ 2. Read `workflow.auto_advance` from config:
368
+ ```bash
369
+ AUTO_CFG=$(node ~/.claude/get-shit-done/bin/gsd-tools.cjs config-get workflow.auto_advance 2>/dev/null || echo "false")
370
+ ```
371
+
372
+ **If `--auto` flag present OR `AUTO_CFG` is true (AND verification passed with no gaps):**
373
+
374
+ ```
375
+ ╔══════════════════════════════════════════╗
376
+ ║ AUTO-ADVANCING → TRANSITION ║
377
+ ║ Phase {X} verified, continuing chain ║
378
+ ╚══════════════════════════════════════════╝
379
+ ```
380
+
381
+ Execute the transition workflow inline (do NOT use Task — orchestrator context is ~10-15%, transition needs phase completion data already in context):
382
+
383
+ Read and follow `~/.claude/get-shit-done/workflows/transition.md`, passing through the `--auto` flag so it propagates to the next phase invocation.
384
+
385
+ **If neither `--auto` nor `AUTO_CFG` is true:**
386
+
387
+ The workflow ends. The user runs `/gsd:progress` or invokes the transition workflow manually.
367
388
  </step>
368
389
 
369
390
  </process>
@@ -0,0 +1,156 @@
1
+ <purpose>
2
+ Validate `.planning/` directory integrity and report actionable issues. Checks for missing files, invalid configurations, inconsistent state, and orphaned plans. Optionally repairs auto-fixable issues.
3
+ </purpose>
4
+
5
+ <required_reading>
6
+ Read all files referenced by the invoking prompt's execution_context before starting.
7
+ </required_reading>
8
+
9
+ <process>
10
+
11
+ <step name="parse_args">
12
+ **Parse arguments:**
13
+
14
+ Check if `--repair` flag is present in the command arguments.
15
+
16
+ ```
17
+ REPAIR_FLAG=""
18
+ if arguments contain "--repair"; then
19
+ REPAIR_FLAG="--repair"
20
+ fi
21
+ ```
22
+ </step>
23
+
24
+ <step name="run_health_check">
25
+ **Run health validation:**
26
+
27
+ ```bash
28
+ node ~/.claude/get-shit-done/bin/gsd-tools.cjs validate health $REPAIR_FLAG
29
+ ```
30
+
31
+ Parse JSON output:
32
+ - `status`: "healthy" | "degraded" | "broken"
33
+ - `errors[]`: Critical issues (code, message, fix, repairable)
34
+ - `warnings[]`: Non-critical issues
35
+ - `info[]`: Informational notes
36
+ - `repairable_count`: Number of auto-fixable issues
37
+ - `repairs_performed[]`: Actions taken if --repair was used
38
+ </step>
39
+
40
+ <step name="format_output">
41
+ **Format and display results:**
42
+
43
+ ```
44
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
45
+ GSD Health Check
46
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
47
+
48
+ Status: HEALTHY | DEGRADED | BROKEN
49
+ Errors: N | Warnings: N | Info: N
50
+ ```
51
+
52
+ **If repairs were performed:**
53
+ ```
54
+ ## Repairs Performed
55
+
56
+ - ✓ config.json: Created with defaults
57
+ - ✓ STATE.md: Regenerated from roadmap
58
+ ```
59
+
60
+ **If errors exist:**
61
+ ```
62
+ ## Errors
63
+
64
+ - [E001] config.json: JSON parse error at line 5
65
+ Fix: Run /gsd:health --repair to reset to defaults
66
+
67
+ - [E002] PROJECT.md not found
68
+ Fix: Run /gsd:new-project to create
69
+ ```
70
+
71
+ **If warnings exist:**
72
+ ```
73
+ ## Warnings
74
+
75
+ - [W001] STATE.md references phase 5, but only phases 1-3 exist
76
+ Fix: Run /gsd:health --repair to regenerate
77
+
78
+ - [W005] Phase directory "1-setup" doesn't follow NN-name format
79
+ Fix: Rename to match pattern (e.g., 01-setup)
80
+ ```
81
+
82
+ **If info exists:**
83
+ ```
84
+ ## Info
85
+
86
+ - [I001] 02-implementation/02-01-PLAN.md has no SUMMARY.md
87
+ Note: May be in progress
88
+ ```
89
+
90
+ **Footer (if repairable issues exist and --repair was NOT used):**
91
+ ```
92
+ ---
93
+ N issues can be auto-repaired. Run: /gsd:health --repair
94
+ ```
95
+ </step>
96
+
97
+ <step name="offer_repair">
98
+ **If repairable issues exist and --repair was NOT used:**
99
+
100
+ Ask user if they want to run repairs:
101
+
102
+ ```
103
+ Would you like to run /gsd:health --repair to fix N issues automatically?
104
+ ```
105
+
106
+ If yes, re-run with --repair flag and display results.
107
+ </step>
108
+
109
+ <step name="verify_repairs">
110
+ **If repairs were performed:**
111
+
112
+ Re-run health check without --repair to confirm issues are resolved:
113
+
114
+ ```bash
115
+ node ~/.claude/get-shit-done/bin/gsd-tools.cjs validate health
116
+ ```
117
+
118
+ Report final status.
119
+ </step>
120
+
121
+ </process>
122
+
123
+ <error_codes>
124
+
125
+ | Code | Severity | Description | Repairable |
126
+ |------|----------|-------------|------------|
127
+ | E001 | error | .planning/ directory not found | No |
128
+ | E002 | error | PROJECT.md not found | No |
129
+ | E003 | error | ROADMAP.md not found | No |
130
+ | E004 | error | STATE.md not found | Yes |
131
+ | E005 | error | config.json parse error | Yes |
132
+ | W001 | warning | PROJECT.md missing required section | No |
133
+ | W002 | warning | STATE.md references invalid phase | Yes |
134
+ | W003 | warning | config.json not found | Yes |
135
+ | W004 | warning | config.json invalid field value | No |
136
+ | W005 | warning | Phase directory naming mismatch | No |
137
+ | W006 | warning | Phase in ROADMAP but no directory | No |
138
+ | W007 | warning | Phase on disk but not in ROADMAP | No |
139
+ | I001 | info | Plan without SUMMARY (may be in progress) | No |
140
+
141
+ </error_codes>
142
+
143
+ <repair_actions>
144
+
145
+ | Action | Effect | Risk |
146
+ |--------|--------|------|
147
+ | createConfig | Create config.json with defaults | None |
148
+ | resetConfig | Delete + recreate config.json | Loses custom settings |
149
+ | regenerateState | Create STATE.md from ROADMAP structure | Loses session history |
150
+
151
+ **Not repairable (too risky):**
152
+ - PROJECT.md, ROADMAP.md content
153
+ - Phase directory renaming
154
+ - Orphaned plan cleanup
155
+
156
+ </repair_actions>
@@ -14,7 +14,7 @@ Check if `--auto` flag is present in $ARGUMENTS.
14
14
  **If auto mode:**
15
15
  - Skip brownfield mapping offer (assume greenfield)
16
16
  - Skip deep questioning (extract context from provided document)
17
- - Config questions still required (Step 5)
17
+ - Config: YOLO mode is implicit (skip that question), but ask depth/git/agents FIRST (Step 2a)
18
18
  - After config: run Steps 6-9 automatically with smart defaults:
19
19
  - Research: Always yes
20
20
  - Requirements: Include all table stakes + features from provided document
@@ -22,12 +22,18 @@ Check if `--auto` flag is present in $ARGUMENTS.
22
22
  - Roadmap approval: Auto-approve
23
23
 
24
24
  **Document requirement:**
25
- Auto mode requires an idea document via @ reference (e.g., `/gsd:new-project --auto @prd.md`). If no document provided, error:
25
+ Auto mode requires an idea document either:
26
+ - File reference: `/gsd:new-project --auto @prd.md`
27
+ - Pasted/written text in the prompt
28
+
29
+ If no document content provided, error:
26
30
 
27
31
  ```
28
- Error: --auto requires an idea document via @ reference.
32
+ Error: --auto requires an idea document.
29
33
 
30
- Usage: /gsd:new-project --auto @your-idea.md
34
+ Usage:
35
+ /gsd:new-project --auto @your-idea.md
36
+ /gsd:new-project --auto [paste or write your idea here]
31
37
 
32
38
  The document should describe what you want to build.
33
39
  ```
@@ -73,9 +79,122 @@ Exit command.
73
79
 
74
80
  **If "Skip mapping" OR `needs_codebase_map` is false:** Continue to Step 3.
75
81
 
82
+ ## 2a. Auto Mode Config (auto mode only)
83
+
84
+ **If auto mode:** Collect config settings upfront before processing the idea document.
85
+
86
+ YOLO mode is implicit (auto = YOLO). Ask remaining config questions:
87
+
88
+ **Round 1 — Core settings (3 questions, no Mode question):**
89
+
90
+ ```
91
+ AskUserQuestion([
92
+ {
93
+ header: "Depth",
94
+ question: "How thorough should planning be?",
95
+ multiSelect: false,
96
+ options: [
97
+ { label: "Quick (Recommended)", description: "Ship fast (3-5 phases, 1-3 plans each)" },
98
+ { label: "Standard", description: "Balanced scope and speed (5-8 phases, 3-5 plans each)" },
99
+ { label: "Comprehensive", description: "Thorough coverage (8-12 phases, 5-10 plans each)" }
100
+ ]
101
+ },
102
+ {
103
+ header: "Execution",
104
+ question: "Run plans in parallel?",
105
+ multiSelect: false,
106
+ options: [
107
+ { label: "Parallel (Recommended)", description: "Independent plans run simultaneously" },
108
+ { label: "Sequential", description: "One plan at a time" }
109
+ ]
110
+ },
111
+ {
112
+ header: "Git Tracking",
113
+ question: "Commit planning docs to git?",
114
+ multiSelect: false,
115
+ options: [
116
+ { label: "Yes (Recommended)", description: "Planning docs tracked in version control" },
117
+ { label: "No", description: "Keep .planning/ local-only (add to .gitignore)" }
118
+ ]
119
+ }
120
+ ])
121
+ ```
122
+
123
+ **Round 2 — Workflow agents (same as Step 5):**
124
+
125
+ ```
126
+ AskUserQuestion([
127
+ {
128
+ header: "Research",
129
+ question: "Research before planning each phase? (adds tokens/time)",
130
+ multiSelect: false,
131
+ options: [
132
+ { label: "Yes (Recommended)", description: "Investigate domain, find patterns, surface gotchas" },
133
+ { label: "No", description: "Plan directly from requirements" }
134
+ ]
135
+ },
136
+ {
137
+ header: "Plan Check",
138
+ question: "Verify plans will achieve their goals? (adds tokens/time)",
139
+ multiSelect: false,
140
+ options: [
141
+ { label: "Yes (Recommended)", description: "Catch gaps before execution starts" },
142
+ { label: "No", description: "Execute plans without verification" }
143
+ ]
144
+ },
145
+ {
146
+ header: "Verifier",
147
+ question: "Verify work satisfies requirements after each phase? (adds tokens/time)",
148
+ multiSelect: false,
149
+ options: [
150
+ { label: "Yes (Recommended)", description: "Confirm deliverables match phase goals" },
151
+ { label: "No", description: "Trust execution, skip verification" }
152
+ ]
153
+ },
154
+ {
155
+ header: "AI Models",
156
+ question: "Which AI models for planning agents?",
157
+ multiSelect: false,
158
+ options: [
159
+ { label: "Balanced (Recommended)", description: "Sonnet for most agents — good quality/cost ratio" },
160
+ { label: "Quality", description: "Opus for research/roadmap — higher cost, deeper analysis" },
161
+ { label: "Budget", description: "Haiku where possible — fastest, lowest cost" }
162
+ ]
163
+ }
164
+ ])
165
+ ```
166
+
167
+ Create `.planning/config.json` with mode set to "yolo":
168
+
169
+ ```json
170
+ {
171
+ "mode": "yolo",
172
+ "depth": "[selected]",
173
+ "parallelization": true|false,
174
+ "commit_docs": true|false,
175
+ "model_profile": "quality|balanced|budget",
176
+ "workflow": {
177
+ "research": true|false,
178
+ "plan_check": true|false,
179
+ "verifier": true|false
180
+ }
181
+ }
182
+ ```
183
+
184
+ **If commit_docs = No:** Add `.planning/` to `.gitignore`.
185
+
186
+ **Commit config.json:**
187
+
188
+ ```bash
189
+ mkdir -p .planning
190
+ node ~/.claude/get-shit-done/bin/gsd-tools.cjs commit "chore: add project config" --files .planning/config.json
191
+ ```
192
+
193
+ Proceed to Step 4 (skip Steps 3 and 5).
194
+
76
195
  ## 3. Deep Questioning
77
196
 
78
- **If auto mode:** Skip. Extract project context from provided document instead and proceed to Step 4.
197
+ **If auto mode:** Skip (already handled in Step 2a). Extract project context from provided document instead and proceed to Step 4.
79
198
 
80
199
  **Display stage banner:**
81
200
 
@@ -217,6 +336,8 @@ node ~/.claude/get-shit-done/bin/gsd-tools.cjs commit "docs: initialize project"
217
336
 
218
337
  ## 5. Workflow Preferences
219
338
 
339
+ **If auto mode:** Skip — config was collected in Step 2a. Proceed to Step 5.5.
340
+
220
341
  **Check for global defaults** at `~/.gsd/defaults.json`. If the file exists, offer to use saved defaults:
221
342
 
222
343
  ```
@@ -898,7 +1019,7 @@ node ~/.claude/get-shit-done/bin/gsd-tools.cjs commit "docs: create roadmap ([N]
898
1019
 
899
1020
  ## 9. Done
900
1021
 
901
- Present completion with next steps:
1022
+ Present completion summary:
902
1023
 
903
1024
  ```
904
1025
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
@@ -916,7 +1037,21 @@ Present completion with next steps:
916
1037
  | Roadmap | `.planning/ROADMAP.md` |
917
1038
 
918
1039
  **[N] phases** | **[X] requirements** | Ready to build ✓
1040
+ ```
1041
+
1042
+ **If auto mode:**
1043
+
1044
+ ```
1045
+ ╔══════════════════════════════════════════╗
1046
+ ║ AUTO-ADVANCING → DISCUSS PHASE 1 ║
1047
+ ╚══════════════════════════════════════════╝
1048
+ ```
919
1049
 
1050
+ Exit skill and invoke SlashCommand("/gsd:discuss-phase 1 --auto")
1051
+
1052
+ **If interactive mode:**
1053
+
1054
+ ```
920
1055
  ───────────────────────────────────────────────────────────────
921
1056
 
922
1057
  ## ▶ Next Up
@@ -61,6 +61,18 @@ Use `context_content` from init JSON (already loaded via `--include context`).
61
61
 
62
62
  If `context_content` is not null, display: `Using phase context from: ${PHASE_DIR}/*-CONTEXT.md`
63
63
 
64
+ **If `context_content` is null (no CONTEXT.md exists):**
65
+
66
+ Use AskUserQuestion:
67
+ - header: "No context"
68
+ - question: "No CONTEXT.md found for Phase {X}. Plans will use research and requirements only — your design preferences won't be included. Continue or capture context first?"
69
+ - options:
70
+ - "Continue without context" — Plan using research + requirements only
71
+ - "Run discuss-phase first" — Capture design decisions before planning
72
+
73
+ If "Continue without context": Proceed to step 5.
74
+ If "Run discuss-phase first": Display `/gsd:discuss-phase {X}` and exit workflow.
75
+
64
76
  ## 5. Handle Research
65
77
 
66
78
  **Skip if:** `--gaps` flag, `--skip-research` flag, or `research_enabled` is false (from init) without `--research` override.
@@ -336,7 +348,7 @@ Check for auto-advance trigger:
336
348
  1. Parse `--auto` flag from $ARGUMENTS
337
349
  2. Read `workflow.auto_advance` from config:
338
350
  ```bash
339
- AUTO_CFG=$(node ~/.claude/get-shit-done/bin/gsd-tools.cjs config get workflow.auto_advance 2>/dev/null || echo "false")
351
+ AUTO_CFG=$(node ~/.claude/get-shit-done/bin/gsd-tools.cjs config-get workflow.auto_advance 2>/dev/null || echo "false")
340
352
  ```
341
353
 
342
354
  **If `--auto` flag present OR `AUTO_CFG` is true:**
@@ -1,5 +1,7 @@
1
1
  <purpose>
2
- Execute small, ad-hoc tasks with GSD guarantees (atomic commits, STATE.md tracking) while skipping optional agents (research, plan-checker, verifier). Quick mode spawns gsd-planner (quick mode) + gsd-executor(s), tracks tasks in `.planning/quick/`, and updates STATE.md's "Quick Tasks Completed" table.
2
+ Execute small, ad-hoc tasks with GSD guarantees (atomic commits, STATE.md tracking). Quick mode spawns gsd-planner (quick mode) + gsd-executor(s), tracks tasks in `.planning/quick/`, and updates STATE.md's "Quick Tasks Completed" table.
3
+
4
+ With `--full` flag: enables plan-checking (max 2 iterations) and post-execution verification for quality guarantees without full milestone ceremony.
3
5
  </purpose>
4
6
 
5
7
  <required_reading>
@@ -7,9 +9,13 @@ Read all files referenced by the invoking prompt's execution_context before star
7
9
  </required_reading>
8
10
 
9
11
  <process>
10
- **Step 1: Get task description**
12
+ **Step 1: Parse arguments and get task description**
13
+
14
+ Parse `$ARGUMENTS` for:
15
+ - `--full` flag → store as `$FULL_MODE` (true/false)
16
+ - Remaining text → use as `$DESCRIPTION` if non-empty
11
17
 
12
- Prompt user interactively for the task description:
18
+ If `$DESCRIPTION` is empty after parsing, prompt user interactively:
13
19
 
14
20
  ```
15
21
  AskUserQuestion(
@@ -21,7 +27,16 @@ AskUserQuestion(
21
27
 
22
28
  Store response as `$DESCRIPTION`.
23
29
 
24
- If empty, re-prompt: "Please provide a task description."
30
+ If still empty, re-prompt: "Please provide a task description."
31
+
32
+ If `$FULL_MODE`:
33
+ ```
34
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
35
+ GSD ► QUICK TASK (FULL MODE)
36
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
37
+
38
+ ◆ Plan checking + verification enabled
39
+ ```
25
40
 
26
41
  ---
27
42
 
@@ -31,7 +46,7 @@ If empty, re-prompt: "Please provide a task description."
31
46
  INIT=$(node ~/.claude/get-shit-done/bin/gsd-tools.cjs init quick "$DESCRIPTION")
32
47
  ```
33
48
 
34
- Parse JSON for: `planner_model`, `executor_model`, `commit_docs`, `next_num`, `slug`, `date`, `timestamp`, `quick_dir`, `task_dir`, `roadmap_exists`, `planning_exists`.
49
+ Parse JSON for: `planner_model`, `executor_model`, `checker_model`, `verifier_model`, `commit_docs`, `next_num`, `slug`, `date`, `timestamp`, `quick_dir`, `task_dir`, `roadmap_exists`, `planning_exists`.
35
50
 
36
51
  **If `roadmap_exists` is false:** Error — Quick mode requires an active project with ROADMAP.md. Run `/gsd:new-project` first.
37
52
 
@@ -68,14 +83,16 @@ Store `$QUICK_DIR` for use in orchestration.
68
83
 
69
84
  **Step 5: Spawn planner (quick mode)**
70
85
 
71
- Spawn gsd-planner with quick mode context:
86
+ **If `$FULL_MODE`:** Use `quick-full` mode with stricter constraints.
87
+
88
+ **If NOT `$FULL_MODE`:** Use standard `quick` mode.
72
89
 
73
90
  ```
74
91
  Task(
75
92
  prompt="
76
93
  <planning_context>
77
94
 
78
- **Mode:** quick
95
+ **Mode:** ${FULL_MODE ? 'quick-full' : 'quick'}
79
96
  **Directory:** ${QUICK_DIR}
80
97
  **Description:** ${DESCRIPTION}
81
98
 
@@ -87,8 +104,10 @@ Task(
87
104
  <constraints>
88
105
  - Create a SINGLE plan with 1-3 focused tasks
89
106
  - Quick tasks should be atomic and self-contained
90
- - No research phase, no checker phase
91
- - Target ~30% context usage (simple, focused)
107
+ - No research phase
108
+ ${FULL_MODE ? '- Target ~40% context usage (structured for verification)' : '- Target ~30% context usage (simple, focused)'}
109
+ ${FULL_MODE ? '- MUST generate `must_haves` in plan frontmatter (truths, artifacts, key_links)' : ''}
110
+ ${FULL_MODE ? '- Each task MUST have `files`, `action`, `verify`, `done` fields' : ''}
92
111
  </constraints>
93
112
 
94
113
  <output>
@@ -111,6 +130,114 @@ If plan not found, error: "Planner failed to create ${next_num}-PLAN.md"
111
130
 
112
131
  ---
113
132
 
133
+ **Step 5.5: Plan-checker loop (only when `$FULL_MODE`)**
134
+
135
+ Skip this step entirely if NOT `$FULL_MODE`.
136
+
137
+ Display banner:
138
+ ```
139
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
140
+ GSD ► CHECKING PLAN
141
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
142
+
143
+ ◆ Spawning plan checker...
144
+ ```
145
+
146
+ ```bash
147
+ PLAN_CONTENT=$(cat "${QUICK_DIR}/${next_num}-PLAN.md" 2>/dev/null)
148
+ ```
149
+
150
+ Checker prompt:
151
+
152
+ ```markdown
153
+ <verification_context>
154
+ **Mode:** quick-full
155
+ **Task Description:** ${DESCRIPTION}
156
+
157
+ **Plan to verify:** ${PLAN_CONTENT}
158
+
159
+ **Scope:** This is a quick task, not a full phase. Skip checks that require a ROADMAP phase goal.
160
+ </verification_context>
161
+
162
+ <check_dimensions>
163
+ - Requirement coverage: Does the plan address the task description?
164
+ - Task completeness: Do tasks have files, action, verify, done fields?
165
+ - Key links: Are referenced files real?
166
+ - Scope sanity: Is this appropriately sized for a quick task (1-3 tasks)?
167
+ - must_haves derivation: Are must_haves traceable to the task description?
168
+
169
+ Skip: context compliance (no CONTEXT.md), cross-plan deps (single plan), ROADMAP alignment
170
+ </check_dimensions>
171
+
172
+ <expected_output>
173
+ - ## VERIFICATION PASSED — all checks pass
174
+ - ## ISSUES FOUND — structured issue list
175
+ </expected_output>
176
+ ```
177
+
178
+ ```
179
+ Task(
180
+ prompt=checker_prompt,
181
+ subagent_type="gsd-plan-checker",
182
+ model="{checker_model}",
183
+ description="Check quick plan: ${DESCRIPTION}"
184
+ )
185
+ ```
186
+
187
+ **Handle checker return:**
188
+
189
+ - **`## VERIFICATION PASSED`:** Display confirmation, proceed to step 6.
190
+ - **`## ISSUES FOUND`:** Display issues, check iteration count, enter revision loop.
191
+
192
+ **Revision loop (max 2 iterations):**
193
+
194
+ Track `iteration_count` (starts at 1 after initial plan + check).
195
+
196
+ **If iteration_count < 2:**
197
+
198
+ Display: `Sending back to planner for revision... (iteration ${N}/2)`
199
+
200
+ ```bash
201
+ PLAN_CONTENT=$(cat "${QUICK_DIR}/${next_num}-PLAN.md" 2>/dev/null)
202
+ ```
203
+
204
+ Revision prompt:
205
+
206
+ ```markdown
207
+ <revision_context>
208
+ **Mode:** quick-full (revision)
209
+
210
+ **Existing plan:** ${PLAN_CONTENT}
211
+ **Checker issues:** ${structured_issues_from_checker}
212
+
213
+ </revision_context>
214
+
215
+ <instructions>
216
+ Make targeted updates to address checker issues.
217
+ Do NOT replan from scratch unless issues are fundamental.
218
+ Return what changed.
219
+ </instructions>
220
+ ```
221
+
222
+ ```
223
+ Task(
224
+ prompt="First, read ~/.claude/agents/gsd-planner.md for your role and instructions.\n\n" + revision_prompt,
225
+ subagent_type="general-purpose",
226
+ model="{planner_model}",
227
+ description="Revise quick plan: ${DESCRIPTION}"
228
+ )
229
+ ```
230
+
231
+ After planner returns → spawn checker again, increment iteration_count.
232
+
233
+ **If iteration_count >= 2:**
234
+
235
+ Display: `Max iterations reached. ${N} issues remain:` + issue list
236
+
237
+ Offer: 1) Force proceed, 2) Abort
238
+
239
+ ---
240
+
114
241
  **Step 6: Spawn executor**
115
242
 
116
243
  Spawn gsd-executor with plan reference:
@@ -149,6 +276,47 @@ Note: For quick tasks producing multiple plans (rare), spawn executors in parall
149
276
 
150
277
  ---
151
278
 
279
+ **Step 6.5: Verification (only when `$FULL_MODE`)**
280
+
281
+ Skip this step entirely if NOT `$FULL_MODE`.
282
+
283
+ Display banner:
284
+ ```
285
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
286
+ GSD ► VERIFYING RESULTS
287
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
288
+
289
+ ◆ Spawning verifier...
290
+ ```
291
+
292
+ ```
293
+ Task(
294
+ prompt="Verify quick task goal achievement.
295
+ Task directory: ${QUICK_DIR}
296
+ Task goal: ${DESCRIPTION}
297
+ Plan: @${QUICK_DIR}/${next_num}-PLAN.md
298
+ Check must_haves against actual codebase. Create VERIFICATION.md at ${QUICK_DIR}/${next_num}-VERIFICATION.md.",
299
+ subagent_type="gsd-verifier",
300
+ model="{verifier_model}",
301
+ description="Verify: ${DESCRIPTION}"
302
+ )
303
+ ```
304
+
305
+ Read verification status:
306
+ ```bash
307
+ grep "^status:" "${QUICK_DIR}/${next_num}-VERIFICATION.md" | cut -d: -f2 | tr -d ' '
308
+ ```
309
+
310
+ Store as `$VERIFICATION_STATUS`.
311
+
312
+ | Status | Action |
313
+ |--------|--------|
314
+ | `passed` | Store `$VERIFICATION_STATUS = "Verified"`, continue to step 7 |
315
+ | `human_needed` | Display items needing manual check, store `$VERIFICATION_STATUS = "Needs Review"`, continue |
316
+ | `gaps_found` | Display gap summary, offer: 1) Re-run executor to fix gaps, 2) Accept as-is. Store `$VERIFICATION_STATUS = "Gaps"` |
317
+
318
+ ---
319
+
152
320
  **Step 7: Update STATE.md**
153
321
 
154
322
  Update STATE.md with quick task completion record.
@@ -161,6 +329,15 @@ Read STATE.md and check for `### Quick Tasks Completed` section.
161
329
 
162
330
  Insert after `### Blockers/Concerns` section:
163
331
 
332
+ **If `$FULL_MODE`:**
333
+ ```markdown
334
+ ### Quick Tasks Completed
335
+
336
+ | # | Description | Date | Commit | Status | Directory |
337
+ |---|-------------|------|--------|--------|-----------|
338
+ ```
339
+
340
+ **If NOT `$FULL_MODE`:**
164
341
  ```markdown
165
342
  ### Quick Tasks Completed
166
343
 
@@ -168,9 +345,18 @@ Insert after `### Blockers/Concerns` section:
168
345
  |---|-------------|------|--------|-----------|
169
346
  ```
170
347
 
348
+ **Note:** If the table already exists, match its existing column format. If adding `--full` to a project that already has quick tasks without a Status column, add the Status column to the header and separator rows, and leave Status empty for the new row's predecessors.
349
+
171
350
  **7c. Append new row to table:**
172
351
 
173
352
  Use `date` from init:
353
+
354
+ **If `$FULL_MODE` (or table has Status column):**
355
+ ```markdown
356
+ | ${next_num} | ${DESCRIPTION} | ${date} | ${commit_hash} | ${VERIFICATION_STATUS} | [${next_num}-${slug}](./quick/${next_num}-${slug}/) |
357
+ ```
358
+
359
+ **If NOT `$FULL_MODE` (and table has no Status column):**
174
360
  ```markdown
175
361
  | ${next_num} | ${DESCRIPTION} | ${date} | ${commit_hash} | [${next_num}-${slug}](./quick/${next_num}-${slug}/) |
176
362
  ```
@@ -190,8 +376,14 @@ Use Edit tool to make these changes atomically
190
376
 
191
377
  Stage and commit quick task artifacts:
192
378
 
379
+ Build file list:
380
+ - `${QUICK_DIR}/${next_num}-PLAN.md`
381
+ - `${QUICK_DIR}/${next_num}-SUMMARY.md`
382
+ - `.planning/STATE.md`
383
+ - If `$FULL_MODE` and verification file exists: `${QUICK_DIR}/${next_num}-VERIFICATION.md`
384
+
193
385
  ```bash
194
- node ~/.claude/get-shit-done/bin/gsd-tools.cjs commit "docs(quick-${next_num}): ${DESCRIPTION}" --files ${QUICK_DIR}/${next_num}-PLAN.md ${QUICK_DIR}/${next_num}-SUMMARY.md .planning/STATE.md
386
+ node ~/.claude/get-shit-done/bin/gsd-tools.cjs commit "docs(quick-${next_num}): ${DESCRIPTION}" --files ${file_list}
195
387
  ```
196
388
 
197
389
  Get final commit hash:
@@ -200,6 +392,25 @@ commit_hash=$(git rev-parse --short HEAD)
200
392
  ```
201
393
 
202
394
  Display completion output:
395
+
396
+ **If `$FULL_MODE`:**
397
+ ```
398
+ ---
399
+
400
+ GSD > QUICK TASK COMPLETE (FULL MODE)
401
+
402
+ Quick Task ${next_num}: ${DESCRIPTION}
403
+
404
+ Summary: ${QUICK_DIR}/${next_num}-SUMMARY.md
405
+ Verification: ${QUICK_DIR}/${next_num}-VERIFICATION.md (${VERIFICATION_STATUS})
406
+ Commit: ${commit_hash}
407
+
408
+ ---
409
+
410
+ Ready for next task: /gsd:quick
411
+ ```
412
+
413
+ **If NOT `$FULL_MODE`:**
203
414
  ```
204
415
  ---
205
416
 
@@ -220,11 +431,14 @@ Ready for next task: /gsd:quick
220
431
  <success_criteria>
221
432
  - [ ] ROADMAP.md validation passes
222
433
  - [ ] User provides task description
434
+ - [ ] `--full` flag parsed from arguments when present
223
435
  - [ ] Slug generated (lowercase, hyphens, max 40 chars)
224
436
  - [ ] Next number calculated (001, 002, 003...)
225
437
  - [ ] Directory created at `.planning/quick/NNN-slug/`
226
438
  - [ ] `${next_num}-PLAN.md` created by planner
439
+ - [ ] (--full) Plan checker validates plan, revision loop capped at 2
227
440
  - [ ] `${next_num}-SUMMARY.md` created by executor
228
- - [ ] STATE.md updated with quick task row
441
+ - [ ] (--full) `${next_num}-VERIFICATION.md` created by verifier
442
+ - [ ] STATE.md updated with quick task row (Status column when --full)
229
443
  - [ ] Artifacts committed
230
444
  </success_criteria>
@@ -378,7 +378,7 @@ Next: Phase [X+1] — [Name]
378
378
  ⚡ Auto-continuing: Plan Phase [X+1] in detail
379
379
  ```
380
380
 
381
- Exit skill and invoke SlashCommand("/gsd:plan-phase [X+1]")
381
+ Exit skill and invoke SlashCommand("/gsd:plan-phase [X+1] --auto")
382
382
 
383
383
  **If CONTEXT.md does NOT exist:**
384
384
 
@@ -390,7 +390,7 @@ Next: Phase [X+1] — [Name]
390
390
  ⚡ Auto-continuing: Discuss Phase [X+1] first
391
391
  ```
392
392
 
393
- Exit skill and invoke SlashCommand("/gsd:discuss-phase [X+1]")
393
+ Exit skill and invoke SlashCommand("/gsd:discuss-phase [X+1] --auto")
394
394
 
395
395
  </if>
396
396
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "get-shit-done-cc",
3
- "version": "1.19.2",
3
+ "version": "1.20.0",
4
4
  "description": "A meta-prompting, context engineering and spec-driven development system for Claude Code, OpenCode and Gemini by TÂCHES.",
5
5
  "bin": {
6
6
  "get-shit-done-cc": "bin/install.js"