@ahmed118glitch/get-shit-done-codex 1.19.0 → 1.19.2
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/CHANGELOG.md +16 -1
- package/agents/gsd-verifier.md +18 -2
- package/bin/install-codex.js +1 -1
- package/commands/gsd/discuss-phase.md +2 -1
- package/commands/gsd/plan-phase.md +1 -1
- package/get-shit-done/bin/gsd-tools.js +116 -1
- package/get-shit-done/bin/gsd-tools.test.js +145 -0
- package/get-shit-done/templates/config.json +2 -1
- package/get-shit-done/workflows/discuss-phase.md +61 -0
- package/get-shit-done/workflows/execute-phase.md +17 -18
- package/get-shit-done/workflows/execute-plan.md +4 -1
- package/get-shit-done/workflows/plan-phase.md +53 -1
- package/get-shit-done/workflows/settings.md +13 -2
- package/get-shit-done/workflows/transition.md +48 -2
- package/get-shit-done/workflows/verify-phase.md +18 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,20 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [1.19.1] - 2026-02-15
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
- Auto-advance pipeline: `--auto` flag on `discuss-phase` and `plan-phase` chains discuss → plan → execute without stopping. Also available as `workflow.auto_advance` config setting
|
|
13
|
+
|
|
14
|
+
### Fixed
|
|
15
|
+
- Phase transition routing now routes to `discuss-phase` (not `plan-phase`) when no CONTEXT.md exists — consistent across all workflows (#530)
|
|
16
|
+
- ROADMAP progress table plan counts are now computed from disk instead of LLM-edited — deterministic "X/Y Complete" values (#537)
|
|
17
|
+
- Verifier uses ROADMAP Success Criteria directly instead of deriving verification truths from the Goal field (#538)
|
|
18
|
+
- REQUIREMENTS.md traceability updates when a phase completes
|
|
19
|
+
- STATE.md updates after discuss-phase completes (#556)
|
|
20
|
+
- AskUserQuestion headers enforced to 12-char max to prevent UI truncation (#559)
|
|
21
|
+
- Agent model resolution returns `inherit` instead of hardcoded `opus` (#558)
|
|
22
|
+
|
|
9
23
|
## [1.19.0] - 2026-02-15
|
|
10
24
|
|
|
11
25
|
### Added
|
|
@@ -1222,7 +1236,8 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
|
|
1222
1236
|
- YOLO mode for autonomous execution
|
|
1223
1237
|
- Interactive mode with checkpoints
|
|
1224
1238
|
|
|
1225
|
-
[Unreleased]: https://github.com/glittercowboy/get-shit-done/compare/v1.19.
|
|
1239
|
+
[Unreleased]: https://github.com/glittercowboy/get-shit-done/compare/v1.19.1...HEAD
|
|
1240
|
+
[1.19.1]: https://github.com/glittercowboy/get-shit-done/releases/tag/v1.19.1
|
|
1226
1241
|
[1.19.0]: https://github.com/glittercowboy/get-shit-done/releases/tag/v1.19.0
|
|
1227
1242
|
[1.18.0]: https://github.com/glittercowboy/get-shit-done/releases/tag/v1.18.0
|
|
1228
1243
|
[1.17.0]: https://github.com/glittercowboy/get-shit-done/releases/tag/v1.17.0
|
package/agents/gsd-verifier.md
CHANGED
|
@@ -86,9 +86,25 @@ must_haves:
|
|
|
86
86
|
via: "fetch in useEffect"
|
|
87
87
|
```
|
|
88
88
|
|
|
89
|
-
**Option B:
|
|
89
|
+
**Option B: Use Success Criteria from ROADMAP.md**
|
|
90
90
|
|
|
91
|
-
If no must_haves in frontmatter:
|
|
91
|
+
If no must_haves in frontmatter, check for Success Criteria:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
PHASE_DATA=$(node ~/.claude/get-shit-done/bin/gsd-tools.js roadmap get-phase "$PHASE_NUM" --raw)
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Parse the `success_criteria` array from the JSON output. If non-empty:
|
|
98
|
+
1. **Use each Success Criterion directly as a truth** (they are already observable, testable behaviors)
|
|
99
|
+
2. **Derive artifacts:** For each truth, "What must EXIST?" — map to concrete file paths
|
|
100
|
+
3. **Derive key links:** For each artifact, "What must be CONNECTED?" — this is where stubs hide
|
|
101
|
+
4. **Document must-haves** before proceeding
|
|
102
|
+
|
|
103
|
+
Success Criteria from ROADMAP.md are the contract — they take priority over Goal-derived truths.
|
|
104
|
+
|
|
105
|
+
**Option C: Derive from phase goal (fallback)**
|
|
106
|
+
|
|
107
|
+
If no must_haves in frontmatter AND no Success Criteria in ROADMAP:
|
|
92
108
|
|
|
93
109
|
1. **State the goal** from ROADMAP.md
|
|
94
110
|
2. **Derive truths:** "What must be TRUE?" — list 3-7 observable, testable behaviors
|
package/bin/install-codex.js
CHANGED
|
@@ -89,7 +89,7 @@ if (installGlobal) {
|
|
|
89
89
|
copyCodexToDirectory(globalBase);
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
-
console.log(`\n${pkg.name} installed to:`);
|
|
92
|
+
console.log(`\n${pkg.name}@${pkg.version} installed to:`);
|
|
93
93
|
console.log(` local: ${targetDir}`);
|
|
94
94
|
if (installGlobal) {
|
|
95
95
|
console.log(' global: ~/.codex');
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: gsd:discuss-phase
|
|
3
3
|
description: Gather phase context through adaptive questioning before planning
|
|
4
|
-
argument-hint: "<phase>"
|
|
4
|
+
argument-hint: "<phase> [--auto]"
|
|
5
5
|
allowed-tools:
|
|
6
6
|
- Read
|
|
7
7
|
- Write
|
|
@@ -9,6 +9,7 @@ allowed-tools:
|
|
|
9
9
|
- Glob
|
|
10
10
|
- Grep
|
|
11
11
|
- AskUserQuestion
|
|
12
|
+
- Task
|
|
12
13
|
---
|
|
13
14
|
|
|
14
15
|
<objective>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: gsd:plan-phase
|
|
3
3
|
description: Create detailed execution plan for a phase (PLAN.md) with verification loop
|
|
4
|
-
argument-hint: "[phase] [--research] [--skip-research] [--gaps] [--skip-verify]"
|
|
4
|
+
argument-hint: "[phase] [--auto] [--research] [--skip-research] [--gaps] [--skip-verify]"
|
|
5
5
|
agent: gsd-planner
|
|
6
6
|
allowed-tools:
|
|
7
7
|
- Read
|
|
@@ -39,6 +39,7 @@
|
|
|
39
39
|
* Roadmap Operations:
|
|
40
40
|
* roadmap get-phase <phase> Extract phase section from ROADMAP.md
|
|
41
41
|
* roadmap analyze Full roadmap parse with disk status
|
|
42
|
+
* roadmap update-plan-progress <N> Update progress table row from disk (PLAN vs SUMMARY counts)
|
|
42
43
|
*
|
|
43
44
|
* Milestone Operations:
|
|
44
45
|
* milestone complete <version> Archive milestone, create MILESTONES.md
|
|
@@ -882,12 +883,19 @@ function cmdRoadmapGetPhase(cwd, phaseNum, raw) {
|
|
|
882
883
|
const goalMatch = section.match(/\*\*Goal:\*\*\s*([^\n]+)/i);
|
|
883
884
|
const goal = goalMatch ? goalMatch[1].trim() : null;
|
|
884
885
|
|
|
886
|
+
// Extract success criteria as structured array
|
|
887
|
+
const criteriaMatch = section.match(/\*\*Success Criteria\*\*[^\n]*:\s*\n((?:\s*\d+\.\s*[^\n]+\n?)+)/i);
|
|
888
|
+
const success_criteria = criteriaMatch
|
|
889
|
+
? criteriaMatch[1].trim().split('\n').map(line => line.replace(/^\s*\d+\.\s*/, '').trim()).filter(Boolean)
|
|
890
|
+
: [];
|
|
891
|
+
|
|
885
892
|
output(
|
|
886
893
|
{
|
|
887
894
|
found: true,
|
|
888
895
|
phase_number: phaseNum,
|
|
889
896
|
phase_name: phaseName,
|
|
890
897
|
goal,
|
|
898
|
+
success_criteria,
|
|
891
899
|
section,
|
|
892
900
|
},
|
|
893
901
|
raw,
|
|
@@ -2956,6 +2964,82 @@ function cmdPhaseRemove(cwd, targetPhase, options, raw) {
|
|
|
2956
2964
|
output(result, raw);
|
|
2957
2965
|
}
|
|
2958
2966
|
|
|
2967
|
+
// ─── Roadmap Update Plan Progress ────────────────────────────────────────────
|
|
2968
|
+
|
|
2969
|
+
function cmdRoadmapUpdatePlanProgress(cwd, phaseNum, raw) {
|
|
2970
|
+
if (!phaseNum) {
|
|
2971
|
+
error('phase number required for roadmap update-plan-progress');
|
|
2972
|
+
}
|
|
2973
|
+
|
|
2974
|
+
const roadmapPath = path.join(cwd, '.planning', 'ROADMAP.md');
|
|
2975
|
+
|
|
2976
|
+
const phaseInfo = findPhaseInternal(cwd, phaseNum);
|
|
2977
|
+
if (!phaseInfo) {
|
|
2978
|
+
error(`Phase ${phaseNum} not found`);
|
|
2979
|
+
}
|
|
2980
|
+
|
|
2981
|
+
const planCount = phaseInfo.plans.length;
|
|
2982
|
+
const summaryCount = phaseInfo.summaries.length;
|
|
2983
|
+
|
|
2984
|
+
if (planCount === 0) {
|
|
2985
|
+
output({ updated: false, reason: 'No plans found', plan_count: 0, summary_count: 0 }, raw, 'no plans');
|
|
2986
|
+
return;
|
|
2987
|
+
}
|
|
2988
|
+
|
|
2989
|
+
const isComplete = summaryCount >= planCount;
|
|
2990
|
+
const status = isComplete ? 'Complete' : summaryCount > 0 ? 'In Progress' : 'Planned';
|
|
2991
|
+
const today = new Date().toISOString().split('T')[0];
|
|
2992
|
+
|
|
2993
|
+
if (!fs.existsSync(roadmapPath)) {
|
|
2994
|
+
output({ updated: false, reason: 'ROADMAP.md not found', plan_count: planCount, summary_count: summaryCount }, raw, 'no roadmap');
|
|
2995
|
+
return;
|
|
2996
|
+
}
|
|
2997
|
+
|
|
2998
|
+
let roadmapContent = fs.readFileSync(roadmapPath, 'utf-8');
|
|
2999
|
+
const phaseEscaped = phaseNum.replace('.', '\\.');
|
|
3000
|
+
|
|
3001
|
+
// Progress table row: update Plans column (summaries/plans) and Status column
|
|
3002
|
+
const tablePattern = new RegExp(
|
|
3003
|
+
`(\\|\\s*${phaseEscaped}\\.?\\s[^|]*\\|)[^|]*(\\|)\\s*[^|]*(\\|)\\s*[^|]*(\\|)`,
|
|
3004
|
+
'i'
|
|
3005
|
+
);
|
|
3006
|
+
const dateField = isComplete ? ` ${today} ` : ' ';
|
|
3007
|
+
roadmapContent = roadmapContent.replace(
|
|
3008
|
+
tablePattern,
|
|
3009
|
+
`$1 ${summaryCount}/${planCount} $2 ${status.padEnd(11)}$3${dateField}$4`
|
|
3010
|
+
);
|
|
3011
|
+
|
|
3012
|
+
// Update plan count in phase detail section
|
|
3013
|
+
const planCountPattern = new RegExp(
|
|
3014
|
+
`(#{2,3}\\s*Phase\\s+${phaseEscaped}[\\s\\S]*?\\*\\*Plans:\\*\\*\\s*)[^\\n]+`,
|
|
3015
|
+
'i'
|
|
3016
|
+
);
|
|
3017
|
+
const planCountText = isComplete
|
|
3018
|
+
? `${summaryCount}/${planCount} plans complete`
|
|
3019
|
+
: `${summaryCount}/${planCount} plans executed`;
|
|
3020
|
+
roadmapContent = roadmapContent.replace(planCountPattern, `$1${planCountText}`);
|
|
3021
|
+
|
|
3022
|
+
// If complete: check checkbox
|
|
3023
|
+
if (isComplete) {
|
|
3024
|
+
const checkboxPattern = new RegExp(
|
|
3025
|
+
`(-\\s*\\[)[ ](\\]\\s*.*Phase\\s+${phaseEscaped}[:\\s][^\\n]*)`,
|
|
3026
|
+
'i'
|
|
3027
|
+
);
|
|
3028
|
+
roadmapContent = roadmapContent.replace(checkboxPattern, `$1x$2 (completed ${today})`);
|
|
3029
|
+
}
|
|
3030
|
+
|
|
3031
|
+
fs.writeFileSync(roadmapPath, roadmapContent, 'utf-8');
|
|
3032
|
+
|
|
3033
|
+
output({
|
|
3034
|
+
updated: true,
|
|
3035
|
+
phase: phaseNum,
|
|
3036
|
+
plan_count: planCount,
|
|
3037
|
+
summary_count: summaryCount,
|
|
3038
|
+
status,
|
|
3039
|
+
complete: isComplete,
|
|
3040
|
+
}, raw, `${summaryCount}/${planCount} ${status}`);
|
|
3041
|
+
}
|
|
3042
|
+
|
|
2959
3043
|
// ─── Phase Complete (Transition) ──────────────────────────────────────────────
|
|
2960
3044
|
|
|
2961
3045
|
function cmdPhaseComplete(cwd, phaseNum, raw) {
|
|
@@ -3011,6 +3095,35 @@ function cmdPhaseComplete(cwd, phaseNum, raw) {
|
|
|
3011
3095
|
);
|
|
3012
3096
|
|
|
3013
3097
|
fs.writeFileSync(roadmapPath, roadmapContent, 'utf-8');
|
|
3098
|
+
|
|
3099
|
+
// Update REQUIREMENTS.md traceability for this phase's requirements
|
|
3100
|
+
const reqPath = path.join(cwd, '.planning', 'REQUIREMENTS.md');
|
|
3101
|
+
if (fs.existsSync(reqPath)) {
|
|
3102
|
+
// Extract Requirements line from roadmap for this phase
|
|
3103
|
+
const reqMatch = roadmapContent.match(
|
|
3104
|
+
new RegExp(`Phase\\s+${phaseNum.replace('.', '\\.')}[\\s\\S]*?\\*\\*Requirements:\\*\\*\\s*([^\\n]+)`, 'i')
|
|
3105
|
+
);
|
|
3106
|
+
|
|
3107
|
+
if (reqMatch) {
|
|
3108
|
+
const reqIds = reqMatch[1].split(/[,\s]+/).map(r => r.trim()).filter(Boolean);
|
|
3109
|
+
let reqContent = fs.readFileSync(reqPath, 'utf-8');
|
|
3110
|
+
|
|
3111
|
+
for (const reqId of reqIds) {
|
|
3112
|
+
// Update checkbox: - [ ] **REQ-ID** → - [x] **REQ-ID**
|
|
3113
|
+
reqContent = reqContent.replace(
|
|
3114
|
+
new RegExp(`(-\\s*\\[)[ ](\\]\\s*\\*\\*${reqId}\\*\\*)`, 'gi'),
|
|
3115
|
+
'$1x$2'
|
|
3116
|
+
);
|
|
3117
|
+
// Update traceability table: | REQ-ID | Phase N | Pending | → | REQ-ID | Phase N | Complete |
|
|
3118
|
+
reqContent = reqContent.replace(
|
|
3119
|
+
new RegExp(`(\\|\\s*${reqId}\\s*\\|[^|]+\\|)\\s*Pending\\s*(\\|)`, 'gi'),
|
|
3120
|
+
'$1 Complete $2'
|
|
3121
|
+
);
|
|
3122
|
+
}
|
|
3123
|
+
|
|
3124
|
+
fs.writeFileSync(reqPath, reqContent, 'utf-8');
|
|
3125
|
+
}
|
|
3126
|
+
}
|
|
3014
3127
|
}
|
|
3015
3128
|
|
|
3016
3129
|
// Find next phase
|
|
@@ -4526,8 +4639,10 @@ async function main() {
|
|
|
4526
4639
|
cmdRoadmapGetPhase(cwd, args[2], raw);
|
|
4527
4640
|
} else if (subcommand === 'analyze') {
|
|
4528
4641
|
cmdRoadmapAnalyze(cwd, raw);
|
|
4642
|
+
} else if (subcommand === 'update-plan-progress') {
|
|
4643
|
+
cmdRoadmapUpdatePlanProgress(cwd, args[2], raw);
|
|
4529
4644
|
} else {
|
|
4530
|
-
error('Unknown roadmap subcommand. Available: get-phase, analyze');
|
|
4645
|
+
error('Unknown roadmap subcommand. Available: get-phase, analyze, update-plan-progress');
|
|
4531
4646
|
}
|
|
4532
4647
|
break;
|
|
4533
4648
|
}
|
|
@@ -1700,6 +1700,151 @@ describe('phase complete command', () => {
|
|
|
1700
1700
|
const state = fs.readFileSync(path.join(tmpDir, '.planning', 'STATE.md'), 'utf-8');
|
|
1701
1701
|
assert.ok(state.includes('Milestone complete'), 'status should be milestone complete');
|
|
1702
1702
|
});
|
|
1703
|
+
|
|
1704
|
+
test('updates REQUIREMENTS.md traceability when phase completes', () => {
|
|
1705
|
+
fs.writeFileSync(
|
|
1706
|
+
path.join(tmpDir, '.planning', 'ROADMAP.md'),
|
|
1707
|
+
`# Roadmap
|
|
1708
|
+
|
|
1709
|
+
- [ ] Phase 1: Auth
|
|
1710
|
+
|
|
1711
|
+
### Phase 1: Auth
|
|
1712
|
+
**Goal:** User authentication
|
|
1713
|
+
**Requirements:** AUTH-01, AUTH-02
|
|
1714
|
+
**Plans:** 1 plans
|
|
1715
|
+
|
|
1716
|
+
### Phase 2: API
|
|
1717
|
+
**Goal:** Build API
|
|
1718
|
+
**Requirements:** API-01
|
|
1719
|
+
`
|
|
1720
|
+
);
|
|
1721
|
+
fs.writeFileSync(
|
|
1722
|
+
path.join(tmpDir, '.planning', 'REQUIREMENTS.md'),
|
|
1723
|
+
`# Requirements
|
|
1724
|
+
|
|
1725
|
+
## v1 Requirements
|
|
1726
|
+
|
|
1727
|
+
### Authentication
|
|
1728
|
+
|
|
1729
|
+
- [ ] **AUTH-01**: User can sign up with email
|
|
1730
|
+
- [ ] **AUTH-02**: User can log in
|
|
1731
|
+
- [ ] **AUTH-03**: User can reset password
|
|
1732
|
+
|
|
1733
|
+
### API
|
|
1734
|
+
|
|
1735
|
+
- [ ] **API-01**: REST endpoints
|
|
1736
|
+
|
|
1737
|
+
## Traceability
|
|
1738
|
+
|
|
1739
|
+
| Requirement | Phase | Status |
|
|
1740
|
+
|-------------|-------|--------|
|
|
1741
|
+
| AUTH-01 | Phase 1 | Pending |
|
|
1742
|
+
| AUTH-02 | Phase 1 | Pending |
|
|
1743
|
+
| AUTH-03 | Phase 2 | Pending |
|
|
1744
|
+
| API-01 | Phase 2 | Pending |
|
|
1745
|
+
`
|
|
1746
|
+
);
|
|
1747
|
+
fs.writeFileSync(
|
|
1748
|
+
path.join(tmpDir, '.planning', 'STATE.md'),
|
|
1749
|
+
`# State\n\n**Current Phase:** 01\n**Current Phase Name:** Auth\n**Status:** In progress\n**Current Plan:** 01-01\n**Last Activity:** 2025-01-01\n**Last Activity Description:** Working\n`
|
|
1750
|
+
);
|
|
1751
|
+
|
|
1752
|
+
const p1 = path.join(tmpDir, '.planning', 'phases', '01-auth');
|
|
1753
|
+
fs.mkdirSync(p1, { recursive: true });
|
|
1754
|
+
fs.writeFileSync(path.join(p1, '01-01-PLAN.md'), '# Plan');
|
|
1755
|
+
fs.writeFileSync(path.join(p1, '01-01-SUMMARY.md'), '# Summary');
|
|
1756
|
+
fs.mkdirSync(path.join(tmpDir, '.planning', 'phases', '02-api'), { recursive: true });
|
|
1757
|
+
|
|
1758
|
+
const result = runGsdTools('phase complete 1', tmpDir);
|
|
1759
|
+
assert.ok(result.success, `Command failed: ${result.error}`);
|
|
1760
|
+
|
|
1761
|
+
const req = fs.readFileSync(path.join(tmpDir, '.planning', 'REQUIREMENTS.md'), 'utf-8');
|
|
1762
|
+
|
|
1763
|
+
// Checkboxes updated for phase 1 requirements
|
|
1764
|
+
assert.ok(req.includes('- [x] **AUTH-01**'), 'AUTH-01 checkbox should be checked');
|
|
1765
|
+
assert.ok(req.includes('- [x] **AUTH-02**'), 'AUTH-02 checkbox should be checked');
|
|
1766
|
+
// Other requirements unchanged
|
|
1767
|
+
assert.ok(req.includes('- [ ] **AUTH-03**'), 'AUTH-03 should remain unchecked');
|
|
1768
|
+
assert.ok(req.includes('- [ ] **API-01**'), 'API-01 should remain unchecked');
|
|
1769
|
+
|
|
1770
|
+
// Traceability table updated
|
|
1771
|
+
assert.ok(req.includes('| AUTH-01 | Phase 1 | Complete |'), 'AUTH-01 status should be Complete');
|
|
1772
|
+
assert.ok(req.includes('| AUTH-02 | Phase 1 | Complete |'), 'AUTH-02 status should be Complete');
|
|
1773
|
+
assert.ok(req.includes('| AUTH-03 | Phase 2 | Pending |'), 'AUTH-03 should remain Pending');
|
|
1774
|
+
assert.ok(req.includes('| API-01 | Phase 2 | Pending |'), 'API-01 should remain Pending');
|
|
1775
|
+
});
|
|
1776
|
+
|
|
1777
|
+
test('handles phase with no requirements mapping', () => {
|
|
1778
|
+
fs.writeFileSync(
|
|
1779
|
+
path.join(tmpDir, '.planning', 'ROADMAP.md'),
|
|
1780
|
+
`# Roadmap
|
|
1781
|
+
|
|
1782
|
+
- [ ] Phase 1: Setup
|
|
1783
|
+
|
|
1784
|
+
### Phase 1: Setup
|
|
1785
|
+
**Goal:** Project setup (no requirements)
|
|
1786
|
+
**Plans:** 1 plans
|
|
1787
|
+
`
|
|
1788
|
+
);
|
|
1789
|
+
fs.writeFileSync(
|
|
1790
|
+
path.join(tmpDir, '.planning', 'REQUIREMENTS.md'),
|
|
1791
|
+
`# Requirements
|
|
1792
|
+
|
|
1793
|
+
## v1 Requirements
|
|
1794
|
+
|
|
1795
|
+
- [ ] **REQ-01**: Some requirement
|
|
1796
|
+
|
|
1797
|
+
## Traceability
|
|
1798
|
+
|
|
1799
|
+
| Requirement | Phase | Status |
|
|
1800
|
+
|-------------|-------|--------|
|
|
1801
|
+
| REQ-01 | Phase 2 | Pending |
|
|
1802
|
+
`
|
|
1803
|
+
);
|
|
1804
|
+
fs.writeFileSync(
|
|
1805
|
+
path.join(tmpDir, '.planning', 'STATE.md'),
|
|
1806
|
+
`# State\n\n**Current Phase:** 01\n**Status:** In progress\n**Current Plan:** 01-01\n**Last Activity:** 2025-01-01\n**Last Activity Description:** Working\n`
|
|
1807
|
+
);
|
|
1808
|
+
|
|
1809
|
+
const p1 = path.join(tmpDir, '.planning', 'phases', '01-setup');
|
|
1810
|
+
fs.mkdirSync(p1, { recursive: true });
|
|
1811
|
+
fs.writeFileSync(path.join(p1, '01-01-PLAN.md'), '# Plan');
|
|
1812
|
+
fs.writeFileSync(path.join(p1, '01-01-SUMMARY.md'), '# Summary');
|
|
1813
|
+
|
|
1814
|
+
const result = runGsdTools('phase complete 1', tmpDir);
|
|
1815
|
+
assert.ok(result.success, `Command failed: ${result.error}`);
|
|
1816
|
+
|
|
1817
|
+
// REQUIREMENTS.md should be unchanged
|
|
1818
|
+
const req = fs.readFileSync(path.join(tmpDir, '.planning', 'REQUIREMENTS.md'), 'utf-8');
|
|
1819
|
+
assert.ok(req.includes('- [ ] **REQ-01**'), 'REQ-01 should remain unchecked');
|
|
1820
|
+
assert.ok(req.includes('| REQ-01 | Phase 2 | Pending |'), 'REQ-01 should remain Pending');
|
|
1821
|
+
});
|
|
1822
|
+
|
|
1823
|
+
test('handles missing REQUIREMENTS.md gracefully', () => {
|
|
1824
|
+
fs.writeFileSync(
|
|
1825
|
+
path.join(tmpDir, '.planning', 'ROADMAP.md'),
|
|
1826
|
+
`# Roadmap
|
|
1827
|
+
|
|
1828
|
+
- [ ] Phase 1: Foundation
|
|
1829
|
+
**Requirements:** REQ-01
|
|
1830
|
+
|
|
1831
|
+
### Phase 1: Foundation
|
|
1832
|
+
**Goal:** Setup
|
|
1833
|
+
`
|
|
1834
|
+
);
|
|
1835
|
+
fs.writeFileSync(
|
|
1836
|
+
path.join(tmpDir, '.planning', 'STATE.md'),
|
|
1837
|
+
`# State\n\n**Current Phase:** 01\n**Status:** In progress\n**Current Plan:** 01-01\n**Last Activity:** 2025-01-01\n**Last Activity Description:** Working\n`
|
|
1838
|
+
);
|
|
1839
|
+
|
|
1840
|
+
const p1 = path.join(tmpDir, '.planning', 'phases', '01-foundation');
|
|
1841
|
+
fs.mkdirSync(p1, { recursive: true });
|
|
1842
|
+
fs.writeFileSync(path.join(p1, '01-01-PLAN.md'), '# Plan');
|
|
1843
|
+
fs.writeFileSync(path.join(p1, '01-01-SUMMARY.md'), '# Summary');
|
|
1844
|
+
|
|
1845
|
+
const result = runGsdTools('phase complete 1', tmpDir);
|
|
1846
|
+
assert.ok(result.success, `Command should succeed even without REQUIREMENTS.md: ${result.error}`);
|
|
1847
|
+
});
|
|
1703
1848
|
});
|
|
1704
1849
|
|
|
1705
1850
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
@@ -252,6 +252,7 @@ Ask 4 questions per area before offering to continue or move on. Each answer oft
|
|
|
252
252
|
|
|
253
253
|
If "More questions" → ask 4 more, then check again
|
|
254
254
|
If "Next area" → proceed to next selected area
|
|
255
|
+
If "Other" (free text) → interpret intent: continuation phrases ("chat more", "keep going", "yes", "more") map to "More questions"; advancement phrases ("done", "move on", "next", "skip") map to "Next area". If ambiguous, ask: "Continue with more questions about [area], or move to the next area?"
|
|
255
256
|
|
|
256
257
|
4. **After all areas complete:**
|
|
257
258
|
- header: "Done"
|
|
@@ -394,6 +395,65 @@ node ~/.claude/get-shit-done/bin/gsd-tools.js commit "docs(${padded_phase}): cap
|
|
|
394
395
|
Confirm: "Committed: docs(${padded_phase}): capture phase context"
|
|
395
396
|
</step>
|
|
396
397
|
|
|
398
|
+
<step name="update_state">
|
|
399
|
+
Update STATE.md with session info:
|
|
400
|
+
|
|
401
|
+
```bash
|
|
402
|
+
node ~/.claude/get-shit-done/bin/gsd-tools.js state record-session \
|
|
403
|
+
--stopped-at "Phase ${PHASE} context gathered" \
|
|
404
|
+
--resume-file "${phase_dir}/${padded_phase}-CONTEXT.md"
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
Commit STATE.md:
|
|
408
|
+
|
|
409
|
+
```bash
|
|
410
|
+
node ~/.claude/get-shit-done/bin/gsd-tools.js commit "docs(state): record phase ${PHASE} context session" --files .planning/STATE.md
|
|
411
|
+
```
|
|
412
|
+
</step>
|
|
413
|
+
|
|
414
|
+
<step name="auto_advance">
|
|
415
|
+
Check for auto-advance trigger:
|
|
416
|
+
|
|
417
|
+
1. Parse `--auto` flag from $ARGUMENTS
|
|
418
|
+
2. Read `workflow.auto_advance` from config:
|
|
419
|
+
```bash
|
|
420
|
+
AUTO_CFG=$(node ~/.claude/get-shit-done/bin/gsd-tools.js config get workflow.auto_advance 2>/dev/null || echo "false")
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
**If `--auto` flag present OR `AUTO_CFG` is true:**
|
|
424
|
+
|
|
425
|
+
Display banner:
|
|
426
|
+
```
|
|
427
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
428
|
+
GSD ► AUTO-ADVANCING TO PLAN
|
|
429
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
430
|
+
|
|
431
|
+
Context captured. Spawning plan-phase...
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
Spawn plan-phase as Task:
|
|
435
|
+
```
|
|
436
|
+
Task(
|
|
437
|
+
prompt="Run /gsd:plan-phase ${PHASE} --auto",
|
|
438
|
+
subagent_type="general-purpose",
|
|
439
|
+
description="Plan Phase ${PHASE}"
|
|
440
|
+
)
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
**Handle plan-phase return:**
|
|
444
|
+
- **PLANNING COMPLETE** → Plan-phase handles chaining to execute-phase (via its own auto_advance step)
|
|
445
|
+
- **PLANNING INCONCLUSIVE / CHECKPOINT** → Display result, stop chain:
|
|
446
|
+
```
|
|
447
|
+
Auto-advance stopped: Planning needs input.
|
|
448
|
+
|
|
449
|
+
Review the output above and continue manually:
|
|
450
|
+
/gsd:plan-phase ${PHASE}
|
|
451
|
+
```
|
|
452
|
+
|
|
453
|
+
**If neither `--auto` nor config enabled:**
|
|
454
|
+
Route to `confirm_creation` step (existing behavior — show manual next steps).
|
|
455
|
+
</step>
|
|
456
|
+
|
|
397
457
|
</process>
|
|
398
458
|
|
|
399
459
|
<success_criteria>
|
|
@@ -404,5 +464,6 @@ Confirm: "Committed: docs(${padded_phase}): capture phase context"
|
|
|
404
464
|
- Scope creep redirected to deferred ideas
|
|
405
465
|
- CONTEXT.md captures actual decisions, not vague vision
|
|
406
466
|
- Deferred ideas preserved for future phases
|
|
467
|
+
- STATE.md updated with session info
|
|
407
468
|
- User knows next steps
|
|
408
469
|
</success_criteria>
|
|
@@ -336,34 +336,33 @@ Gap closure cycle: `/gsd:plan-phase {X} --gaps` reads VERIFICATION.md → create
|
|
|
336
336
|
</step>
|
|
337
337
|
|
|
338
338
|
<step name="update_roadmap">
|
|
339
|
-
Mark phase complete
|
|
339
|
+
**Mark phase complete and update all tracking files:**
|
|
340
340
|
|
|
341
341
|
```bash
|
|
342
|
-
node ~/.claude/get-shit-done/bin/gsd-tools.js
|
|
342
|
+
COMPLETION=$(node ~/.claude/get-shit-done/bin/gsd-tools.js phase complete "${PHASE_NUMBER}")
|
|
343
343
|
```
|
|
344
|
-
</step>
|
|
345
|
-
|
|
346
|
-
<step name="offer_next">
|
|
347
344
|
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
345
|
+
The CLI handles:
|
|
346
|
+
- Marking phase checkbox `[x]` with completion date
|
|
347
|
+
- Updating Progress table (Status → Complete, date)
|
|
348
|
+
- Updating plan count to final
|
|
349
|
+
- Advancing STATE.md to next phase
|
|
350
|
+
- Updating REQUIREMENTS.md traceability
|
|
353
351
|
|
|
354
|
-
|
|
352
|
+
Extract from result: `next_phase`, `next_phase_name`, `is_last_phase`.
|
|
355
353
|
|
|
356
|
-
|
|
354
|
+
```bash
|
|
355
|
+
node ~/.claude/get-shit-done/bin/gsd-tools.js commit "docs(phase-{X}): complete phase execution" --files .planning/ROADMAP.md .planning/STATE.md .planning/REQUIREMENTS.md .planning/phases/{phase_dir}/*-VERIFICATION.md
|
|
357
356
|
```
|
|
357
|
+
</step>
|
|
358
358
|
|
|
359
|
-
|
|
360
|
-
```
|
|
361
|
-
MILESTONE COMPLETE!
|
|
359
|
+
<step name="offer_next">
|
|
362
360
|
|
|
363
|
-
|
|
361
|
+
**Routing is handled by `transition.md`** — do NOT emit a separate "Next Up" block here.
|
|
364
362
|
|
|
365
|
-
`/gsd:
|
|
366
|
-
|
|
363
|
+
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
|
+
|
|
365
|
+
**Exception:** If `gaps_found`, the `verify_phase_goal` step already presents the gap-closure path (`/gsd:plan-phase {X} --gaps`). No additional routing needed.
|
|
367
366
|
</step>
|
|
368
367
|
|
|
369
368
|
</process>
|
|
@@ -379,7 +379,10 @@ If SUMMARY "Issues Encountered" ≠ "None": yolo → log and continue. Interacti
|
|
|
379
379
|
</step>
|
|
380
380
|
|
|
381
381
|
<step name="update_roadmap">
|
|
382
|
-
|
|
382
|
+
```bash
|
|
383
|
+
node ~/.claude/get-shit-done/bin/gsd-tools.js roadmap update-plan-progress "${PHASE}"
|
|
384
|
+
```
|
|
385
|
+
Counts PLAN vs SUMMARY files on disk. Updates progress table row with correct count and status (`In Progress` or `Complete` with date).
|
|
383
386
|
</step>
|
|
384
387
|
|
|
385
388
|
<step name="git_commit_metadata">
|
|
@@ -319,7 +319,59 @@ Offer: 1) Force proceed, 2) Provide guidance and retry, 3) Abandon
|
|
|
319
319
|
|
|
320
320
|
## 13. Present Final Status
|
|
321
321
|
|
|
322
|
-
Route to `<offer_next
|
|
322
|
+
Route to `<offer_next>` OR `auto_advance` depending on flags/config.
|
|
323
|
+
|
|
324
|
+
## 14. Auto-Advance Check
|
|
325
|
+
|
|
326
|
+
Check for auto-advance trigger:
|
|
327
|
+
|
|
328
|
+
1. Parse `--auto` flag from $ARGUMENTS
|
|
329
|
+
2. Read `workflow.auto_advance` from config:
|
|
330
|
+
```bash
|
|
331
|
+
AUTO_CFG=$(node ~/.claude/get-shit-done/bin/gsd-tools.js config get workflow.auto_advance 2>/dev/null || echo "false")
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
**If `--auto` flag present OR `AUTO_CFG` is true:**
|
|
335
|
+
|
|
336
|
+
Display banner:
|
|
337
|
+
```
|
|
338
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
339
|
+
GSD ► AUTO-ADVANCING TO EXECUTE
|
|
340
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
341
|
+
|
|
342
|
+
Plans ready. Spawning execute-phase...
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
Spawn execute-phase as Task:
|
|
346
|
+
```
|
|
347
|
+
Task(
|
|
348
|
+
prompt="Run /gsd:execute-phase ${PHASE}",
|
|
349
|
+
subagent_type="general-purpose",
|
|
350
|
+
description="Execute Phase ${PHASE}"
|
|
351
|
+
)
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
**Handle execute-phase return:**
|
|
355
|
+
- **PHASE COMPLETE** → Display final summary:
|
|
356
|
+
```
|
|
357
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
358
|
+
GSD ► PHASE ${PHASE} COMPLETE ✓
|
|
359
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
360
|
+
|
|
361
|
+
Auto-advance pipeline finished.
|
|
362
|
+
|
|
363
|
+
Next: /gsd:discuss-phase ${NEXT_PHASE} --auto
|
|
364
|
+
```
|
|
365
|
+
- **GAPS FOUND / VERIFICATION FAILED** → Display result, stop chain:
|
|
366
|
+
```
|
|
367
|
+
Auto-advance stopped: Execution needs review.
|
|
368
|
+
|
|
369
|
+
Review the output above and continue manually:
|
|
370
|
+
/gsd:execute-phase ${PHASE}
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
**If neither `--auto` nor config enabled:**
|
|
374
|
+
Route to `<offer_next>` (existing behavior).
|
|
323
375
|
|
|
324
376
|
</process>
|
|
325
377
|
|
|
@@ -74,6 +74,15 @@ AskUserQuestion([
|
|
|
74
74
|
{ label: "No", description: "Skip post-execution verification" }
|
|
75
75
|
]
|
|
76
76
|
},
|
|
77
|
+
{
|
|
78
|
+
question: "Auto-advance pipeline? (discuss → plan → execute automatically)",
|
|
79
|
+
header: "Auto",
|
|
80
|
+
multiSelect: false,
|
|
81
|
+
options: [
|
|
82
|
+
{ label: "No (Recommended)", description: "Manual /clear + paste between stages" },
|
|
83
|
+
{ label: "Yes", description: "Chain stages via Task() subagents (same isolation)" }
|
|
84
|
+
]
|
|
85
|
+
},
|
|
77
86
|
{
|
|
78
87
|
question: "Git branching strategy?",
|
|
79
88
|
header: "Branching",
|
|
@@ -98,7 +107,8 @@ Merge new settings into existing config.json:
|
|
|
98
107
|
"workflow": {
|
|
99
108
|
"research": true/false,
|
|
100
109
|
"plan_check": true/false,
|
|
101
|
-
"verifier": true/false
|
|
110
|
+
"verifier": true/false,
|
|
111
|
+
"auto_advance": true/false
|
|
102
112
|
},
|
|
103
113
|
"git": {
|
|
104
114
|
"branching_strategy": "none" | "phase" | "milestone"
|
|
@@ -123,6 +133,7 @@ Display:
|
|
|
123
133
|
| Plan Researcher | {On/Off} |
|
|
124
134
|
| Plan Checker | {On/Off} |
|
|
125
135
|
| Execution Verifier | {On/Off} |
|
|
136
|
+
| Auto-Advance | {On/Off} |
|
|
126
137
|
| Git Branching | {None/Per Phase/Per Milestone} |
|
|
127
138
|
|
|
128
139
|
These settings apply to future /gsd:plan-phase and /gsd:execute-phase runs.
|
|
@@ -139,7 +150,7 @@ Quick commands:
|
|
|
139
150
|
|
|
140
151
|
<success_criteria>
|
|
141
152
|
- [ ] Current config read
|
|
142
|
-
- [ ] User presented with
|
|
153
|
+
- [ ] User presented with 6 settings (profile + 4 workflow toggles + git branching)
|
|
143
154
|
- [ ] Config updated with model_profile, workflow, and git sections
|
|
144
155
|
- [ ] Changes confirmed to user
|
|
145
156
|
</success_criteria>
|
|
@@ -358,10 +358,18 @@ This returns all phases with goals, disk status, and completion info.
|
|
|
358
358
|
|
|
359
359
|
Read ROADMAP.md to get the next phase's name and goal.
|
|
360
360
|
|
|
361
|
+
**Check if next phase has CONTEXT.md:**
|
|
362
|
+
|
|
363
|
+
```bash
|
|
364
|
+
ls .planning/phases/*[X+1]*/*-CONTEXT.md 2>/dev/null
|
|
365
|
+
```
|
|
366
|
+
|
|
361
367
|
**If next phase exists:**
|
|
362
368
|
|
|
363
369
|
<if mode="yolo">
|
|
364
370
|
|
|
371
|
+
**If CONTEXT.md exists:**
|
|
372
|
+
|
|
365
373
|
```
|
|
366
374
|
Phase [X] marked complete.
|
|
367
375
|
|
|
@@ -372,10 +380,48 @@ Next: Phase [X+1] — [Name]
|
|
|
372
380
|
|
|
373
381
|
Exit skill and invoke SlashCommand("/gsd:plan-phase [X+1]")
|
|
374
382
|
|
|
383
|
+
**If CONTEXT.md does NOT exist:**
|
|
384
|
+
|
|
385
|
+
```
|
|
386
|
+
Phase [X] marked complete.
|
|
387
|
+
|
|
388
|
+
Next: Phase [X+1] — [Name]
|
|
389
|
+
|
|
390
|
+
⚡ Auto-continuing: Discuss Phase [X+1] first
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
Exit skill and invoke SlashCommand("/gsd:discuss-phase [X+1]")
|
|
394
|
+
|
|
375
395
|
</if>
|
|
376
396
|
|
|
377
397
|
<if mode="interactive" OR="custom with gates.confirm_transition true">
|
|
378
398
|
|
|
399
|
+
**If CONTEXT.md does NOT exist:**
|
|
400
|
+
|
|
401
|
+
```
|
|
402
|
+
## ✓ Phase [X] Complete
|
|
403
|
+
|
|
404
|
+
---
|
|
405
|
+
|
|
406
|
+
## ▶ Next Up
|
|
407
|
+
|
|
408
|
+
**Phase [X+1]: [Name]** — [Goal from ROADMAP.md]
|
|
409
|
+
|
|
410
|
+
`/gsd:discuss-phase [X+1]` — gather context and clarify approach
|
|
411
|
+
|
|
412
|
+
<sub>`/clear` first → fresh context window</sub>
|
|
413
|
+
|
|
414
|
+
---
|
|
415
|
+
|
|
416
|
+
**Also available:**
|
|
417
|
+
- `/gsd:plan-phase [X+1]` — skip discussion, plan directly
|
|
418
|
+
- `/gsd:research-phase [X+1]` — investigate unknowns
|
|
419
|
+
|
|
420
|
+
---
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
**If CONTEXT.md exists:**
|
|
424
|
+
|
|
379
425
|
```
|
|
380
426
|
## ✓ Phase [X] Complete
|
|
381
427
|
|
|
@@ -384,6 +430,7 @@ Exit skill and invoke SlashCommand("/gsd:plan-phase [X+1]")
|
|
|
384
430
|
## ▶ Next Up
|
|
385
431
|
|
|
386
432
|
**Phase [X+1]: [Name]** — [Goal from ROADMAP.md]
|
|
433
|
+
<sub>✓ Context gathered, ready to plan</sub>
|
|
387
434
|
|
|
388
435
|
`/gsd:plan-phase [X+1]`
|
|
389
436
|
|
|
@@ -392,9 +439,8 @@ Exit skill and invoke SlashCommand("/gsd:plan-phase [X+1]")
|
|
|
392
439
|
---
|
|
393
440
|
|
|
394
441
|
**Also available:**
|
|
395
|
-
- `/gsd:discuss-phase [X+1]` —
|
|
442
|
+
- `/gsd:discuss-phase [X+1]` — revisit context
|
|
396
443
|
- `/gsd:research-phase [X+1]` — investigate unknowns
|
|
397
|
-
- Review roadmap
|
|
398
444
|
|
|
399
445
|
---
|
|
400
446
|
```
|
|
@@ -59,9 +59,25 @@ Returns JSON: `{ truths: [...], artifacts: [...], key_links: [...] }`
|
|
|
59
59
|
|
|
60
60
|
Aggregate all must_haves across plans for phase-level verification.
|
|
61
61
|
|
|
62
|
-
**Option B:
|
|
62
|
+
**Option B: Use Success Criteria from ROADMAP.md**
|
|
63
63
|
|
|
64
|
-
If no must_haves in frontmatter (MUST_HAVES returns error or empty):
|
|
64
|
+
If no must_haves in frontmatter (MUST_HAVES returns error or empty), check for Success Criteria:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
PHASE_DATA=$(node ~/.claude/get-shit-done/bin/gsd-tools.js roadmap get-phase "${phase_number}" --raw)
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Parse the `success_criteria` array from the JSON output. If non-empty:
|
|
71
|
+
1. Use each Success Criterion directly as a **truth** (they are already written as observable, testable behaviors)
|
|
72
|
+
2. Derive **artifacts** (concrete file paths for each truth)
|
|
73
|
+
3. Derive **key links** (critical wiring where stubs hide)
|
|
74
|
+
4. Document the must-haves before proceeding
|
|
75
|
+
|
|
76
|
+
Success Criteria from ROADMAP.md are the contract — they override PLAN-level must_haves when both exist.
|
|
77
|
+
|
|
78
|
+
**Option C: Derive from phase goal (fallback)**
|
|
79
|
+
|
|
80
|
+
If no must_haves in frontmatter AND no Success Criteria in ROADMAP:
|
|
65
81
|
1. State the goal from ROADMAP.md
|
|
66
82
|
2. Derive **truths** (3-7 observable behaviors, each testable)
|
|
67
83
|
3. Derive **artifacts** (concrete file paths for each truth)
|
package/package.json
CHANGED