gsd-antigravity-kit 1.24.0 → 1.25.1
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/.agent/skills/gsd/SKILL.md +6 -2
- package/.agent/skills/gsd/assets/templates/config.json +3 -0
- package/.agent/skills/gsd/bin/help-manifest.json +7 -1
- package/.agent/skills/gsd/bin/hooks/gsd-context-monitor.js +14 -0
- package/.agent/skills/gsd/bin/lib/commands.cjs +58 -16
- package/.agent/skills/gsd/bin/lib/core.cjs +10 -19
- package/.agent/skills/gsd/bin/lib/init.cjs +23 -0
- package/.agent/skills/gsd/bin/lib/verify.cjs +20 -4
- package/.agent/skills/gsd/references/agents/gsd-executor.md +2 -0
- package/.agent/skills/gsd/references/agents/gsd-phase-researcher.md +6 -0
- package/.agent/skills/gsd/references/commands/discuss-phase.md +2 -1
- package/.agent/skills/gsd/references/commands/do.md +30 -0
- package/.agent/skills/gsd/references/commands/note.md +34 -0
- package/.agent/skills/gsd/references/workflows/discuss-phase.md +3 -1
- package/.agent/skills/gsd/references/workflows/do.md +104 -0
- package/.agent/skills/gsd/references/workflows/execute-plan.md +9 -0
- package/.agent/skills/gsd/references/workflows/help.md +29 -0
- package/.agent/skills/gsd/references/workflows/note.md +156 -0
- package/.agent/skills/gsd/references/workflows/plan-phase.md +22 -1
- package/.agent/skills/gsd/references/workflows/settings.md +14 -1
- package/.agent/skills/gsd/references/workflows/stats.md +5 -2
- package/CHANGELOG.md +11 -0
- package/README.md +2 -2
- package/docs/DEV_KNOWLEDGEBASE.md +11 -0
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: gsd
|
|
3
|
-
version: 1.
|
|
3
|
+
version: 1.25.1
|
|
4
4
|
description: "Antigravity GSD (Get Stuff Done) - A spec-driven hierarchical planning and execution system. Triggers on project planning, phase management, and GSD slash commands."
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -31,6 +31,7 @@ This skill should be used when:
|
|
|
31
31
|
- `gsd:complete-milestone`
|
|
32
32
|
- `gsd:debug`
|
|
33
33
|
- `gsd:discuss-phase`
|
|
34
|
+
- `gsd:do`
|
|
34
35
|
- `gsd:execute-phase`
|
|
35
36
|
- `gsd:gsd-tools`
|
|
36
37
|
- `gsd:health`
|
|
@@ -41,6 +42,7 @@ This skill should be used when:
|
|
|
41
42
|
- `gsd:map-codebase`
|
|
42
43
|
- `gsd:new-milestone`
|
|
43
44
|
- `gsd:new-project`
|
|
45
|
+
- `gsd:note`
|
|
44
46
|
- `gsd:pause-work`
|
|
45
47
|
- `gsd:plan-milestone-gaps`
|
|
46
48
|
- `gsd:plan-phase`
|
|
@@ -80,6 +82,7 @@ The following slash commands are available in this skill. Use them to drive the
|
|
|
80
82
|
- **[`gsd:complete-milestone`](references/commands/complete-milestone.md)**: Archive completed milestone and prepare for next version
|
|
81
83
|
- **[`gsd:debug`](references/commands/debug.md)**: Systematic debugging with persistent state across context resets
|
|
82
84
|
- **[`gsd:discuss-phase`](references/commands/discuss-phase.md)**: Gather phase context through adaptive questioning before planning. Use --auto to skip interactive questions (Antigravity picks recommended defaults).
|
|
85
|
+
- **[`gsd:do`](references/commands/do.md)**: Route freeform text to the right GSD command automatically
|
|
83
86
|
- **[`gsd:execute-phase`](references/commands/execute-phase.md)**: Execute all plans in a phase with wave-based parallelization
|
|
84
87
|
- **[`gsd:gsd-tools`](references/commands/gsd-tools.md)**: Direct access to GSD internal CLI tools for atomic operations (state, roadmap, phase, config, etc.)
|
|
85
88
|
- **[`gsd:health`](references/commands/health.md)**: Diagnose planning directory health and optionally repair issues
|
|
@@ -90,6 +93,7 @@ The following slash commands are available in this skill. Use them to drive the
|
|
|
90
93
|
- **[`gsd:map-codebase`](references/commands/map-codebase.md)**: Analyze codebase with parallel mapper agents to produce .planning/codebase/ documents
|
|
91
94
|
- **[`gsd:new-milestone`](references/commands/new-milestone.md)**: Start a new milestone cycle — update PROJECT.md and route to requirements
|
|
92
95
|
- **[`gsd:new-project`](references/commands/new-project.md)**: Initialize a new project with deep context gathering and PROJECT.md
|
|
96
|
+
- **[`gsd:note`](references/commands/note.md)**: Zero-friction idea capture. Append, list, or promote notes to todos.
|
|
93
97
|
- **[`gsd:pause-work`](references/commands/pause-work.md)**: Create context handoff when pausing work mid-phase
|
|
94
98
|
- **[`gsd:plan-milestone-gaps`](references/commands/plan-milestone-gaps.md)**: Create phases to close all gaps identified by milestone audit
|
|
95
99
|
- **[`gsd:plan-phase`](references/commands/plan-phase.md)**: Create detailed phase plan (PLAN.md) with verification loop
|
|
@@ -141,4 +145,4 @@ General documentation on the GSD philosophy, usage patterns, and configuration.
|
|
|
141
145
|
5. **CLI Invocation**: `gsd-tools` is **NOT** a global command. Always invoke it with the full node path: `node .agent/skills/gsd/bin/gsd-tools.cjs <command> [args]`. Never run `gsd-tools` bare.
|
|
142
146
|
|
|
143
147
|
---
|
|
144
|
-
*Generated by gsd-converter on 2026-03-
|
|
148
|
+
*Generated by gsd-converter on 2026-03-16*
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.
|
|
2
|
+
"version": "1.25.1",
|
|
3
3
|
"commands": {
|
|
4
4
|
"add-phase": {
|
|
5
5
|
"description": "Add phase to end of current milestone in roadmap"
|
|
@@ -31,6 +31,9 @@
|
|
|
31
31
|
"discuss-phase": {
|
|
32
32
|
"description": "Gather phase context through adaptive questioning before planning. Use --auto to skip interactive questions (Antigravity picks recommended defaults)."
|
|
33
33
|
},
|
|
34
|
+
"do": {
|
|
35
|
+
"description": "Route freeform text to the right GSD command automatically"
|
|
36
|
+
},
|
|
34
37
|
"execute-phase": {
|
|
35
38
|
"description": "Execute all plans in a phase with wave-based parallelization"
|
|
36
39
|
},
|
|
@@ -58,6 +61,9 @@
|
|
|
58
61
|
"new-project": {
|
|
59
62
|
"description": "Initialize a new project with deep context gathering and PROJECT.md"
|
|
60
63
|
},
|
|
64
|
+
"note": {
|
|
65
|
+
"description": "Zero-friction idea capture. Append, list, or promote notes to todos."
|
|
66
|
+
},
|
|
61
67
|
"pause-work": {
|
|
62
68
|
"description": "Create context handoff when pausing work mid-phase"
|
|
63
69
|
},
|
|
@@ -43,6 +43,20 @@ process.stdin.on('end', () => {
|
|
|
43
43
|
process.exit(0);
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
+
// Check if context warnings are disabled via config
|
|
47
|
+
const cwd = data.cwd || process.cwd();
|
|
48
|
+
const configPath = path.join(cwd, '.planning', 'config.json');
|
|
49
|
+
if (fs.existsSync(configPath)) {
|
|
50
|
+
try {
|
|
51
|
+
const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
|
52
|
+
if (config.hooks?.context_warnings === false) {
|
|
53
|
+
process.exit(0);
|
|
54
|
+
}
|
|
55
|
+
} catch (e) {
|
|
56
|
+
// Ignore config parse errors
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
46
60
|
const tmpDir = os.tmpdir();
|
|
47
61
|
const metricsPath = path.join(tmpDir, `antigravity-ctx-${sessionId}.json`);
|
|
48
62
|
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
const fs = require('fs');
|
|
5
5
|
const path = require('path');
|
|
6
6
|
const { execSync } = require('child_process');
|
|
7
|
-
const { safeReadFile, loadConfig, isGitIgnored, execGit, normalizePhaseName, comparePhaseNum, getArchivedPhaseDirs, generateSlugInternal, getMilestoneInfo, resolveModelInternal, toPosixPath, output, error, findPhaseInternal } = require('./core.cjs');
|
|
7
|
+
const { safeReadFile, loadConfig, isGitIgnored, execGit, normalizePhaseName, comparePhaseNum, getArchivedPhaseDirs, generateSlugInternal, getMilestoneInfo, getMilestonePhaseFilter, resolveModelInternal, stripShippedMilestones, toPosixPath, output, error, findPhaseInternal } = require('./core.cjs');
|
|
8
8
|
const { extractFrontmatter } = require('./frontmatter.cjs');
|
|
9
9
|
const { MODEL_PROFILES } = require('./model-profiles.cjs');
|
|
10
10
|
|
|
@@ -535,21 +535,42 @@ function cmdScaffold(cwd, type, options, raw) {
|
|
|
535
535
|
|
|
536
536
|
function cmdStats(cwd, format, raw) {
|
|
537
537
|
const phasesDir = path.join(cwd, '.planning', 'phases');
|
|
538
|
+
const roadmapPath = path.join(cwd, '.planning', 'ROADMAP.md');
|
|
538
539
|
const reqPath = path.join(cwd, '.planning', 'REQUIREMENTS.md');
|
|
539
540
|
const statePath = path.join(cwd, '.planning', 'STATE.md');
|
|
540
541
|
const milestone = getMilestoneInfo(cwd);
|
|
542
|
+
const isDirInMilestone = getMilestonePhaseFilter(cwd);
|
|
541
543
|
|
|
542
544
|
// Phase & plan stats (reuse progress pattern)
|
|
543
|
-
const
|
|
545
|
+
const phasesByNumber = new Map();
|
|
544
546
|
let totalPlans = 0;
|
|
545
547
|
let totalSummaries = 0;
|
|
546
548
|
|
|
549
|
+
try {
|
|
550
|
+
const roadmapContent = stripShippedMilestones(fs.readFileSync(roadmapPath, 'utf-8'));
|
|
551
|
+
const headingPattern = /#{2,4}\s*Phase\s+(\d+[A-Z]?(?:\.\d+)*)\s*:\s*([^\n]+)/gi;
|
|
552
|
+
let match;
|
|
553
|
+
while ((match = headingPattern.exec(roadmapContent)) !== null) {
|
|
554
|
+
phasesByNumber.set(match[1], {
|
|
555
|
+
number: match[1],
|
|
556
|
+
name: match[2].replace(/\(INSERTED\)/i, '').trim(),
|
|
557
|
+
plans: 0,
|
|
558
|
+
summaries: 0,
|
|
559
|
+
status: 'Not Started',
|
|
560
|
+
});
|
|
561
|
+
}
|
|
562
|
+
} catch {}
|
|
563
|
+
|
|
547
564
|
try {
|
|
548
565
|
const entries = fs.readdirSync(phasesDir, { withFileTypes: true });
|
|
549
|
-
const dirs = entries
|
|
566
|
+
const dirs = entries
|
|
567
|
+
.filter(e => e.isDirectory())
|
|
568
|
+
.map(e => e.name)
|
|
569
|
+
.filter(isDirInMilestone)
|
|
570
|
+
.sort((a, b) => comparePhaseNum(a, b));
|
|
550
571
|
|
|
551
572
|
for (const dir of dirs) {
|
|
552
|
-
const dm = dir.match(/^(\d+(?:\.\d+)*)-?(.*)/);
|
|
573
|
+
const dm = dir.match(/^(\d+[A-Z]?(?:\.\d+)*)-?(.*)/i);
|
|
553
574
|
const phaseNum = dm ? dm[1] : dir;
|
|
554
575
|
const phaseName = dm && dm[2] ? dm[2].replace(/-/g, ' ') : '';
|
|
555
576
|
const phaseFiles = fs.readdirSync(path.join(phasesDir, dir));
|
|
@@ -560,16 +581,26 @@ function cmdStats(cwd, format, raw) {
|
|
|
560
581
|
totalSummaries += summaries;
|
|
561
582
|
|
|
562
583
|
let status;
|
|
563
|
-
if (plans === 0) status = '
|
|
584
|
+
if (plans === 0) status = 'Not Started';
|
|
564
585
|
else if (summaries >= plans) status = 'Complete';
|
|
565
586
|
else if (summaries > 0) status = 'In Progress';
|
|
566
587
|
else status = 'Planned';
|
|
567
588
|
|
|
568
|
-
|
|
589
|
+
const existing = phasesByNumber.get(phaseNum);
|
|
590
|
+
phasesByNumber.set(phaseNum, {
|
|
591
|
+
number: phaseNum,
|
|
592
|
+
name: existing?.name || phaseName,
|
|
593
|
+
plans,
|
|
594
|
+
summaries,
|
|
595
|
+
status,
|
|
596
|
+
});
|
|
569
597
|
}
|
|
570
598
|
} catch {}
|
|
571
599
|
|
|
572
|
-
const
|
|
600
|
+
const phases = [...phasesByNumber.values()].sort((a, b) => comparePhaseNum(a.number, b.number));
|
|
601
|
+
const completedPhases = phases.filter(p => p.status === 'Complete').length;
|
|
602
|
+
const planPercent = totalPlans > 0 ? Math.min(100, Math.round((totalSummaries / totalPlans) * 100)) : 0;
|
|
603
|
+
const percent = phases.length > 0 ? Math.min(100, Math.round((completedPhases / phases.length) * 100)) : 0;
|
|
573
604
|
|
|
574
605
|
// Requirements stats
|
|
575
606
|
let requirementsTotal = 0;
|
|
@@ -589,7 +620,10 @@ function cmdStats(cwd, format, raw) {
|
|
|
589
620
|
try {
|
|
590
621
|
if (fs.existsSync(statePath)) {
|
|
591
622
|
const stateContent = fs.readFileSync(statePath, 'utf-8');
|
|
592
|
-
const activityMatch = stateContent.match(
|
|
623
|
+
const activityMatch = stateContent.match(/^last_activity:\s*(.+)$/im)
|
|
624
|
+
|| stateContent.match(/\*\*Last Activity:\*\*\s*(.+)/i)
|
|
625
|
+
|| stateContent.match(/^Last Activity:\s*(.+)$/im)
|
|
626
|
+
|| stateContent.match(/^Last activity:\s*(.+)$/im);
|
|
593
627
|
if (activityMatch) lastActivity = activityMatch[1].trim();
|
|
594
628
|
}
|
|
595
629
|
} catch {}
|
|
@@ -597,14 +631,18 @@ function cmdStats(cwd, format, raw) {
|
|
|
597
631
|
// Git stats
|
|
598
632
|
let gitCommits = 0;
|
|
599
633
|
let gitFirstCommitDate = null;
|
|
600
|
-
try {
|
|
601
634
|
const commitCount = execGit(cwd, ['rev-list', '--count', 'HEAD']);
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
const
|
|
635
|
+
if (commitCount.exitCode === 0) {
|
|
636
|
+
gitCommits = parseInt(commitCount.stdout, 10) || 0;
|
|
637
|
+
}
|
|
638
|
+
const rootHash = execGit(cwd, ['rev-list', '--max-parents=0', 'HEAD']);
|
|
639
|
+
if (rootHash.exitCode === 0 && rootHash.stdout) {
|
|
640
|
+
const firstCommit = rootHash.stdout.split('\n')[0].trim();
|
|
641
|
+
const firstDate = execGit(cwd, ['show', '-s', '--format=%as', firstCommit]);
|
|
642
|
+
if (firstDate.exitCode === 0) {
|
|
643
|
+
gitFirstCommitDate = firstDate.stdout || null;
|
|
644
|
+
}
|
|
645
|
+
}
|
|
608
646
|
|
|
609
647
|
const result = {
|
|
610
648
|
milestone_version: milestone.version,
|
|
@@ -615,6 +653,7 @@ function cmdStats(cwd, format, raw) {
|
|
|
615
653
|
total_plans: totalPlans,
|
|
616
654
|
total_summaries: totalSummaries,
|
|
617
655
|
percent,
|
|
656
|
+
plan_percent: planPercent,
|
|
618
657
|
requirements_total: requirementsTotal,
|
|
619
658
|
requirements_complete: requirementsComplete,
|
|
620
659
|
git_commits: gitCommits,
|
|
@@ -627,7 +666,10 @@ function cmdStats(cwd, format, raw) {
|
|
|
627
666
|
const filled = Math.round((percent / 100) * barWidth);
|
|
628
667
|
const bar = '\u2588'.repeat(filled) + '\u2591'.repeat(barWidth - filled);
|
|
629
668
|
let out = `# ${milestone.version} ${milestone.name} \u2014 Statistics\n\n`;
|
|
630
|
-
out += `**Progress:** [${bar}] ${
|
|
669
|
+
out += `**Progress:** [${bar}] ${completedPhases}/${phases.length} phases (${percent}%)\n`;
|
|
670
|
+
if (totalPlans > 0) {
|
|
671
|
+
out += `**Plans:** ${totalSummaries}/${totalPlans} complete (${planPercent}%)\n`;
|
|
672
|
+
}
|
|
631
673
|
out += `**Phases:** ${completedPhases}/${phases.length} complete\n`;
|
|
632
674
|
if (requirementsTotal > 0) {
|
|
633
675
|
out += `**Requirements:** ${requirementsComplete}/${requirementsTotal} complete\n`;
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
const fs = require('fs');
|
|
6
6
|
const path = require('path');
|
|
7
|
-
const { execSync } = require('child_process');
|
|
7
|
+
const { execSync, spawnSync } = require('child_process');
|
|
8
8
|
const { MODEL_PROFILES } = require('./model-profiles.cjs');
|
|
9
9
|
|
|
10
10
|
// ─── Path helpers ────────────────────────────────────────────────────────────
|
|
@@ -187,24 +187,16 @@ function isGitIgnored(cwd, targetPath) {
|
|
|
187
187
|
}
|
|
188
188
|
|
|
189
189
|
function execGit(cwd, args) {
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
190
|
+
const result = spawnSync('git', args, {
|
|
191
|
+
cwd,
|
|
192
|
+
stdio: 'pipe',
|
|
193
|
+
encoding: 'utf-8',
|
|
194
194
|
});
|
|
195
|
-
const stdout = execSync('git ' + escaped.join(' '), {
|
|
196
|
-
cwd,
|
|
197
|
-
stdio: 'pipe',
|
|
198
|
-
encoding: 'utf-8',
|
|
199
|
-
});
|
|
200
|
-
return { exitCode: 0, stdout: stdout.trim(), stderr: '' };
|
|
201
|
-
} catch (err) {
|
|
202
195
|
return {
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
196
|
+
exitCode: result.status ?? 1,
|
|
197
|
+
stdout: (result.stdout ?? '').toString().trim(),
|
|
198
|
+
stderr: (result.stderr ?? '').toString().trim(),
|
|
206
199
|
};
|
|
207
|
-
}
|
|
208
200
|
}
|
|
209
201
|
|
|
210
202
|
// ─── Phase utilities ──────────────────────────────────────────────────────────
|
|
@@ -437,7 +429,7 @@ function resolveModelInternal(cwd, agentType) {
|
|
|
437
429
|
// Check per-agent override first
|
|
438
430
|
const override = config.model_overrides?.[agentType];
|
|
439
431
|
if (override) {
|
|
440
|
-
return override
|
|
432
|
+
return override;
|
|
441
433
|
}
|
|
442
434
|
|
|
443
435
|
// Fall back to profile lookup
|
|
@@ -445,8 +437,7 @@ function resolveModelInternal(cwd, agentType) {
|
|
|
445
437
|
const agentModels = MODEL_PROFILES[agentType];
|
|
446
438
|
if (!agentModels) return 'sonnet';
|
|
447
439
|
if (profile === 'inherit') return 'inherit';
|
|
448
|
-
|
|
449
|
-
return resolved === 'opus' ? 'inherit' : resolved;
|
|
440
|
+
return agentModels[profile] || agentModels['balanced'] || 'sonnet';
|
|
450
441
|
}
|
|
451
442
|
|
|
452
443
|
// ─── Misc utilities ───────────────────────────────────────────────────────────
|
|
@@ -357,6 +357,29 @@ function cmdInitPhaseOp(cwd, phase, raw) {
|
|
|
357
357
|
const config = loadConfig(cwd);
|
|
358
358
|
let phaseInfo = findPhaseInternal(cwd, phase);
|
|
359
359
|
|
|
360
|
+
// If the only disk match comes from an archived milestone, prefer the
|
|
361
|
+
// current milestone's ROADMAP entry so discuss-phase and similar flows
|
|
362
|
+
// don't attach to shipped work that reused the same phase number.
|
|
363
|
+
if (phaseInfo?.archived) {
|
|
364
|
+
const roadmapPhase = getRoadmapPhaseInternal(cwd, phase);
|
|
365
|
+
if (roadmapPhase?.found) {
|
|
366
|
+
const phaseName = roadmapPhase.phase_name;
|
|
367
|
+
phaseInfo = {
|
|
368
|
+
found: true,
|
|
369
|
+
directory: null,
|
|
370
|
+
phase_number: roadmapPhase.phase_number,
|
|
371
|
+
phase_name: phaseName,
|
|
372
|
+
phase_slug: phaseName ? phaseName.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '') : null,
|
|
373
|
+
plans: [],
|
|
374
|
+
summaries: [],
|
|
375
|
+
incomplete_plans: [],
|
|
376
|
+
has_research: false,
|
|
377
|
+
has_context: false,
|
|
378
|
+
has_verification: false,
|
|
379
|
+
};
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
|
|
360
383
|
// Fallback to ROADMAP.md if no directory exists (e.g., Plans: TBD)
|
|
361
384
|
if (!phaseInfo) {
|
|
362
385
|
const roadmapPhase = getRoadmapPhaseInternal(cwd, phase);
|
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
const fs = require('fs');
|
|
6
6
|
const path = require('path');
|
|
7
|
-
const
|
|
7
|
+
const os = require('os');
|
|
8
|
+
const { safeReadFile, normalizePhaseName, execGit, findPhaseInternal, getMilestoneInfo, stripShippedMilestones, output, error } = require('./core.cjs');
|
|
8
9
|
const { extractFrontmatter, parseMustHavesBlock } = require('./frontmatter.cjs');
|
|
9
10
|
const { writeStateMd } = require('./state.cjs');
|
|
10
11
|
|
|
@@ -407,9 +408,10 @@ function cmdValidateConsistency(cwd, raw) {
|
|
|
407
408
|
return;
|
|
408
409
|
}
|
|
409
410
|
|
|
410
|
-
const
|
|
411
|
+
const roadmapContentRaw = fs.readFileSync(roadmapPath, 'utf-8');
|
|
412
|
+
const roadmapContent = stripShippedMilestones(roadmapContentRaw);
|
|
411
413
|
|
|
412
|
-
// Extract phases from ROADMAP
|
|
414
|
+
// Extract phases from ROADMAP (archived milestones already stripped)
|
|
413
415
|
const roadmapPhases = new Set();
|
|
414
416
|
const phasePattern = /#{2,4}\s*Phase\s+(\d+[A-Z]?(?:\.\d+)*)\s*:/gi;
|
|
415
417
|
let m;
|
|
@@ -515,6 +517,19 @@ function cmdValidateConsistency(cwd, raw) {
|
|
|
515
517
|
}
|
|
516
518
|
|
|
517
519
|
function cmdValidateHealth(cwd, options, raw) {
|
|
520
|
+
// Guard: detect if CWD is the home directory (likely accidental)
|
|
521
|
+
const resolved = path.resolve(cwd);
|
|
522
|
+
if (resolved === os.homedir()) {
|
|
523
|
+
output({
|
|
524
|
+
status: 'error',
|
|
525
|
+
errors: [{ code: 'E010', message: `CWD is home directory (${resolved}) — health check would read the wrong .planning/ directory. Run from your project root instead.`, fix: 'cd into your project directory and retry' }],
|
|
526
|
+
warnings: [],
|
|
527
|
+
info: [{ code: 'I010', message: `Resolved CWD: ${resolved}` }],
|
|
528
|
+
repairable_count: 0,
|
|
529
|
+
}, raw);
|
|
530
|
+
return;
|
|
531
|
+
}
|
|
532
|
+
|
|
518
533
|
const planningDir = path.join(cwd, '.planning');
|
|
519
534
|
const projectPath = path.join(planningDir, 'PROJECT.md');
|
|
520
535
|
const roadmapPath = path.join(planningDir, 'ROADMAP.md');
|
|
@@ -679,7 +694,8 @@ function cmdValidateHealth(cwd, options, raw) {
|
|
|
679
694
|
// ─── Check 8: Run existing consistency checks ─────────────────────────────
|
|
680
695
|
// Inline subset of cmdValidateConsistency
|
|
681
696
|
if (fs.existsSync(roadmapPath)) {
|
|
682
|
-
const
|
|
697
|
+
const roadmapContentRaw = fs.readFileSync(roadmapPath, 'utf-8');
|
|
698
|
+
const roadmapContent = stripShippedMilestones(roadmapContentRaw);
|
|
683
699
|
const roadmapPhases = new Set();
|
|
684
700
|
const phasePattern = /#{2,4}\s*Phase\s+(\d+[A-Z]?(?:\.\d+)*)\s*:/gi;
|
|
685
701
|
let m;
|
|
@@ -337,6 +337,8 @@ git commit -m "{type}({phase}-{plan}): {concise task description}
|
|
|
337
337
|
```
|
|
338
338
|
|
|
339
339
|
**5. Record hash:** `TASK_COMMIT=$(git rev-parse --short HEAD)` — track for SUMMARY.
|
|
340
|
+
|
|
341
|
+
**6. Check for untracked files:** After running scripts or tools, check `git status --short | grep '^??'`. For any new untracked files: commit if intentional, add to `.gitignore` if generated/runtime output. Never leave generated files untracked.
|
|
340
342
|
</task_commit_protocol>
|
|
341
343
|
|
|
342
344
|
<summary_creation>
|
|
@@ -238,6 +238,12 @@ Priority: Context7 > Official Docs > Official GitHub > Verified WebSearch > Unve
|
|
|
238
238
|
npm install [packages]
|
|
239
239
|
\`\`\`
|
|
240
240
|
|
|
241
|
+
**Version verification:** Before writing the Standard Stack table, verify each recommended package version is current:
|
|
242
|
+
\`\`\`bash
|
|
243
|
+
npm view [package] version
|
|
244
|
+
\`\`\`
|
|
245
|
+
Document the verified version and publish date. Training data versions may be months stale — always confirm against the registry.
|
|
246
|
+
|
|
241
247
|
## Architecture Patterns
|
|
242
248
|
|
|
243
249
|
### Recommended Project Structure
|
|
@@ -68,7 +68,8 @@ Generate 3-4 **phase-specific** gray areas, not generic categories.
|
|
|
68
68
|
|
|
69
69
|
**Probing depth:**
|
|
70
70
|
- Ask 4 questions per area before checking
|
|
71
|
-
- "More questions about [area], or move to next?"
|
|
71
|
+
- "More questions about [area], or move to next? (Remaining: [list unvisited areas])"
|
|
72
|
+
- Show remaining unvisited areas so user knows what's still ahead
|
|
72
73
|
- If more → ask 4 more, check again
|
|
73
74
|
- After all areas → "Ready to create context?"
|
|
74
75
|
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gsd:do
|
|
3
|
+
description: Route freeform text to the right GSD command automatically
|
|
4
|
+
argument-hint: "<description of what you want to do>"
|
|
5
|
+
allowed-tools:
|
|
6
|
+
- Read
|
|
7
|
+
- Bash
|
|
8
|
+
- AskUserQuestion
|
|
9
|
+
---
|
|
10
|
+
<objective>
|
|
11
|
+
Analyze freeform natural language input and dispatch to the most appropriate GSD command.
|
|
12
|
+
|
|
13
|
+
Acts as a smart dispatcher — never does the work itself. Matches intent to the best GSD command using routing rules, confirms the match, then hands off.
|
|
14
|
+
|
|
15
|
+
Use when you know what you want but don't know which `/gsd:*` command to run.
|
|
16
|
+
</objective>
|
|
17
|
+
|
|
18
|
+
<execution_context>
|
|
19
|
+
@C:/projects/GSD-Antigravityreferences/workflows/do.md
|
|
20
|
+
@C:/projects/GSD-Antigravity/.antigravity/get-shit-done/references/ui-brand.md
|
|
21
|
+
</execution_context>
|
|
22
|
+
|
|
23
|
+
<context>
|
|
24
|
+
$ARGUMENTS
|
|
25
|
+
</context>
|
|
26
|
+
|
|
27
|
+
<process>
|
|
28
|
+
Execute the do workflow from @C:/projects/GSD-Antigravityreferences/workflows/do.md end-to-end.
|
|
29
|
+
Route user intent to the best GSD command and invoke it.
|
|
30
|
+
</process>
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gsd:note
|
|
3
|
+
description: Zero-friction idea capture. Append, list, or promote notes to todos.
|
|
4
|
+
argument-hint: "<text> | list | promote <N> [--global]"
|
|
5
|
+
allowed-tools:
|
|
6
|
+
- Read
|
|
7
|
+
- Write
|
|
8
|
+
- Glob
|
|
9
|
+
- Grep
|
|
10
|
+
---
|
|
11
|
+
<objective>
|
|
12
|
+
Zero-friction idea capture — one Write call, one confirmation line.
|
|
13
|
+
|
|
14
|
+
Three subcommands:
|
|
15
|
+
- **append** (default): Save a timestamped note file. No questions, no formatting.
|
|
16
|
+
- **list**: Show all notes from project and global scopes.
|
|
17
|
+
- **promote**: Convert a note into a structured todo.
|
|
18
|
+
|
|
19
|
+
Runs inline — no Task, no AskUserQuestion, no Bash.
|
|
20
|
+
</objective>
|
|
21
|
+
|
|
22
|
+
<execution_context>
|
|
23
|
+
@C:/projects/GSD-Antigravityreferences/workflows/note.md
|
|
24
|
+
@C:/projects/GSD-Antigravity/.antigravity/get-shit-done/references/ui-brand.md
|
|
25
|
+
</execution_context>
|
|
26
|
+
|
|
27
|
+
<context>
|
|
28
|
+
$ARGUMENTS
|
|
29
|
+
</context>
|
|
30
|
+
|
|
31
|
+
<process>
|
|
32
|
+
Execute the note workflow from @C:/projects/GSD-Antigravityreferences/workflows/note.md end-to-end.
|
|
33
|
+
Capture the note, list notes, or promote to todo — depending on arguments.
|
|
34
|
+
</process>
|
|
@@ -456,9 +456,11 @@ After all areas are auto-resolved, skip the "Explore more gray areas" prompt and
|
|
|
456
456
|
|
|
457
457
|
3. **After the current set of questions, check:**
|
|
458
458
|
- header: "[Area]" (max 12 chars)
|
|
459
|
-
- question: "More questions about [area], or move to next?"
|
|
459
|
+
- question: "More questions about [area], or move to next? (Remaining: [list other unvisited areas])"
|
|
460
460
|
- options: "More questions" / "Next area"
|
|
461
461
|
|
|
462
|
+
When building the question text, list the remaining unvisited areas so the user knows what's ahead. For example: "More questions about Layout, or move to next? (Remaining: Loading behavior, Content ordering)"
|
|
463
|
+
|
|
462
464
|
If "More questions" → ask another 4 single questions, or another 2-5 question batch when `--batch` is active, then check again
|
|
463
465
|
If "Next area" → proceed to next selected area
|
|
464
466
|
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?"
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
<purpose>
|
|
2
|
+
Analyze freeform text from the user and route to the most appropriate GSD command. This is a dispatcher — it never does the work itself. Match user intent to the best command, confirm the routing, and hand off.
|
|
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="validate">
|
|
12
|
+
**Check for input.**
|
|
13
|
+
|
|
14
|
+
If `$ARGUMENTS` is empty, ask via AskUserQuestion:
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
What would you like to do? Describe the task, bug, or idea and I'll route it to the right GSD command.
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Wait for response before continuing.
|
|
21
|
+
</step>
|
|
22
|
+
|
|
23
|
+
<step name="check_project">
|
|
24
|
+
**Check if project exists.**
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
INIT=$(node "C:/projects/GSD-Antigravity.agent/skills/gsd/bin/gsd-tools.cjs" state load 2>/dev/null)
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Track whether `.planning/` exists — some routes require it, others don't.
|
|
31
|
+
</step>
|
|
32
|
+
|
|
33
|
+
<step name="route">
|
|
34
|
+
**Match intent to command.**
|
|
35
|
+
|
|
36
|
+
Evaluate `$ARGUMENTS` against these routing rules. Apply the **first matching** rule:
|
|
37
|
+
|
|
38
|
+
| If the text describes... | Route to | Why |
|
|
39
|
+
|--------------------------|----------|-----|
|
|
40
|
+
| Starting a new project, "set up", "initialize" | `/gsd:new-project` | Needs full project initialization |
|
|
41
|
+
| Mapping or analyzing an existing codebase | `/gsd:map-codebase` | Codebase discovery |
|
|
42
|
+
| A bug, error, crash, failure, or something broken | `/gsd:debug` | Needs systematic investigation |
|
|
43
|
+
| Exploring, researching, comparing, or "how does X work" | `/gsd:research-phase` | Domain research before planning |
|
|
44
|
+
| Discussing vision, "how should X look", brainstorming | `/gsd:discuss-phase` | Needs context gathering |
|
|
45
|
+
| A complex task: refactoring, migration, multi-file architecture, system redesign | `/gsd:add-phase` | Needs a full phase with plan/build cycle |
|
|
46
|
+
| Planning a specific phase or "plan phase N" | `/gsd:plan-phase` | Direct planning request |
|
|
47
|
+
| Executing a phase or "build phase N", "run phase N" | `/gsd:execute-phase` | Direct execution request |
|
|
48
|
+
| Running all remaining phases automatically | `/gsd:autonomous` | Full autonomous execution |
|
|
49
|
+
| A review or quality concern about existing work | `/gsd:verify-work` | Needs verification |
|
|
50
|
+
| Checking progress, status, "where am I" | `/gsd:progress` | Status check |
|
|
51
|
+
| Resuming work, "pick up where I left off" | `/gsd:resume-work` | Session restoration |
|
|
52
|
+
| A note, idea, or "remember to..." | `/gsd:add-todo` | Capture for later |
|
|
53
|
+
| Adding tests, "write tests", "test coverage" | `/gsd:add-tests` | Test generation |
|
|
54
|
+
| Completing a milestone, shipping, releasing | `/gsd:complete-milestone` | Milestone lifecycle |
|
|
55
|
+
| A specific, actionable, small task (add feature, fix typo, update config) | `/gsd:quick` | Self-contained, single executor |
|
|
56
|
+
|
|
57
|
+
**Requires `.planning/` directory:** All routes except `/gsd:new-project`, `/gsd:map-codebase`, `/gsd:help`, and `/gsd:join-discord`. If the project doesn't exist and the route requires it, suggest `/gsd:new-project` first.
|
|
58
|
+
|
|
59
|
+
**Ambiguity handling:** If the text could reasonably match multiple routes, ask the user via AskUserQuestion with the top 2-3 options. For example:
|
|
60
|
+
|
|
61
|
+
```
|
|
62
|
+
"Refactor the authentication system" could be:
|
|
63
|
+
1. /gsd:add-phase — Full planning cycle (recommended for multi-file refactors)
|
|
64
|
+
2. /gsd:quick — Quick execution (if scope is small and clear)
|
|
65
|
+
|
|
66
|
+
Which approach fits better?
|
|
67
|
+
```
|
|
68
|
+
</step>
|
|
69
|
+
|
|
70
|
+
<step name="display">
|
|
71
|
+
**Show the routing decision.**
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
75
|
+
GSD ► ROUTING
|
|
76
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
77
|
+
|
|
78
|
+
**Input:** {first 80 chars of $ARGUMENTS}
|
|
79
|
+
**Routing to:** {chosen command}
|
|
80
|
+
**Reason:** {one-line explanation}
|
|
81
|
+
```
|
|
82
|
+
</step>
|
|
83
|
+
|
|
84
|
+
<step name="dispatch">
|
|
85
|
+
**Invoke the chosen command.**
|
|
86
|
+
|
|
87
|
+
Run the selected `/gsd:*` command, passing `$ARGUMENTS` as args.
|
|
88
|
+
|
|
89
|
+
If the chosen command expects a phase number and one wasn't provided in the text, extract it from context or ask via AskUserQuestion.
|
|
90
|
+
|
|
91
|
+
After invoking the command, stop. The dispatched command handles everything from here.
|
|
92
|
+
</step>
|
|
93
|
+
|
|
94
|
+
</process>
|
|
95
|
+
|
|
96
|
+
<success_criteria>
|
|
97
|
+
- [ ] Input validated (not empty)
|
|
98
|
+
- [ ] Intent matched to exactly one GSD command
|
|
99
|
+
- [ ] Ambiguity resolved via user question (if needed)
|
|
100
|
+
- [ ] Project existence checked for routes that require it
|
|
101
|
+
- [ ] Routing decision displayed before dispatch
|
|
102
|
+
- [ ] Command invoked with appropriate arguments
|
|
103
|
+
- [ ] No work done directly — dispatcher only
|
|
104
|
+
</success_criteria>
|
|
@@ -279,6 +279,15 @@ TASK_COMMIT=$(git rev-parse --short HEAD)
|
|
|
279
279
|
TASK_COMMITS+=("Task ${TASK_NUM}: ${TASK_COMMIT}")
|
|
280
280
|
```
|
|
281
281
|
|
|
282
|
+
**6. Check for untracked generated files:**
|
|
283
|
+
```bash
|
|
284
|
+
git status --short | grep '^??'
|
|
285
|
+
```
|
|
286
|
+
If new untracked files appeared after running scripts or tools, decide for each:
|
|
287
|
+
- **Commit it** — if it's a source file, config, or intentional artifact
|
|
288
|
+
- **Add to .gitignore** — if it's a generated/runtime output (build artifacts, `.env` files, cache files, compiled output)
|
|
289
|
+
- Do NOT leave generated files untracked
|
|
290
|
+
|
|
282
291
|
</task_commit>
|
|
283
292
|
|
|
284
293
|
<step name="checkpoint_protocol">
|
|
@@ -116,6 +116,20 @@ Execute all plans in a phase.
|
|
|
116
116
|
|
|
117
117
|
Usage: `/gsd:execute-phase 5`
|
|
118
118
|
|
|
119
|
+
### Smart Router
|
|
120
|
+
|
|
121
|
+
**`/gsd:do <description>`**
|
|
122
|
+
Route freeform text to the right GSD command automatically.
|
|
123
|
+
|
|
124
|
+
- Analyzes natural language input to find the best matching GSD command
|
|
125
|
+
- Acts as a dispatcher — never does the work itself
|
|
126
|
+
- Resolves ambiguity by asking you to pick between top matches
|
|
127
|
+
- Use when you know what you want but don't know which `/gsd:*` command to run
|
|
128
|
+
|
|
129
|
+
Usage: `/gsd:do fix the login button`
|
|
130
|
+
Usage: `/gsd:do refactor the auth system`
|
|
131
|
+
Usage: `/gsd:do I want to start a new milestone`
|
|
132
|
+
|
|
119
133
|
### Quick Mode
|
|
120
134
|
|
|
121
135
|
**`/gsd:quick [--full] [--discuss] [--research]`**
|
|
@@ -241,6 +255,21 @@ Systematic debugging with persistent state across context resets.
|
|
|
241
255
|
Usage: `/gsd:debug "login button doesn't work"`
|
|
242
256
|
Usage: `/gsd:debug` (resume active session)
|
|
243
257
|
|
|
258
|
+
### Quick Notes
|
|
259
|
+
|
|
260
|
+
**`/gsd:note <text>`**
|
|
261
|
+
Zero-friction idea capture — one command, instant save, no questions.
|
|
262
|
+
|
|
263
|
+
- Saves timestamped note to `.planning/notes/` (or `C:/projects/GSD-Antigravity/.antigravity/notes/` globally)
|
|
264
|
+
- Three subcommands: append (default), list, promote
|
|
265
|
+
- Promote converts a note into a structured todo
|
|
266
|
+
- Works without a project (falls back to global scope)
|
|
267
|
+
|
|
268
|
+
Usage: `/gsd:note refactor the hook system`
|
|
269
|
+
Usage: `/gsd:note list`
|
|
270
|
+
Usage: `/gsd:note promote 3`
|
|
271
|
+
Usage: `/gsd:note --global cross-project idea`
|
|
272
|
+
|
|
244
273
|
### Todo Management
|
|
245
274
|
|
|
246
275
|
**`/gsd:add-todo [description]`**
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
<purpose>
|
|
2
|
+
Zero-friction idea capture. One Write call, one confirmation line. No questions, no prompts.
|
|
3
|
+
Runs inline — no Task, no AskUserQuestion, no Bash.
|
|
4
|
+
</purpose>
|
|
5
|
+
|
|
6
|
+
<required_reading>
|
|
7
|
+
Read all files referenced by the invoking prompt's execution_context before starting.
|
|
8
|
+
</required_reading>
|
|
9
|
+
|
|
10
|
+
<process>
|
|
11
|
+
|
|
12
|
+
<step name="storage_format">
|
|
13
|
+
**Note storage format.**
|
|
14
|
+
|
|
15
|
+
Notes are stored as individual markdown files:
|
|
16
|
+
|
|
17
|
+
- **Project scope**: `.planning/notes/{YYYY-MM-DD}-{slug}.md` — used when `.planning/` exists in cwd
|
|
18
|
+
- **Global scope**: `C:/projects/GSD-Antigravity/.antigravity/notes/{YYYY-MM-DD}-{slug}.md` — fallback when no `.planning/`, or when `--global` flag is present
|
|
19
|
+
|
|
20
|
+
Each note file:
|
|
21
|
+
|
|
22
|
+
```markdown
|
|
23
|
+
---
|
|
24
|
+
date: "YYYY-MM-DD HH:mm"
|
|
25
|
+
promoted: false
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
{note text verbatim}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
**`--global` flag**: Strip `--global` from anywhere in `$ARGUMENTS` before parsing. When present, force global scope regardless of whether `.planning/` exists.
|
|
32
|
+
|
|
33
|
+
**Important**: Do NOT create `.planning/` if it doesn't exist. Fall back to global scope silently.
|
|
34
|
+
</step>
|
|
35
|
+
|
|
36
|
+
<step name="parse_subcommand">
|
|
37
|
+
**Parse subcommand from $ARGUMENTS (after stripping --global).**
|
|
38
|
+
|
|
39
|
+
| Condition | Subcommand |
|
|
40
|
+
|-----------|------------|
|
|
41
|
+
| Arguments are exactly `list` (case-insensitive) | **list** |
|
|
42
|
+
| Arguments are exactly `promote <N>` where N is a number | **promote** |
|
|
43
|
+
| Arguments are empty (no text at all) | **list** |
|
|
44
|
+
| Anything else | **append** (the text IS the note) |
|
|
45
|
+
|
|
46
|
+
**Critical**: `list` is only a subcommand when it's the ENTIRE argument. `/gsd:note list of groceries` saves a note with text "list of groceries". Same for `promote` — only a subcommand when followed by exactly one number.
|
|
47
|
+
</step>
|
|
48
|
+
|
|
49
|
+
<step name="append">
|
|
50
|
+
**Subcommand: append — create a timestamped note file.**
|
|
51
|
+
|
|
52
|
+
1. Determine scope (project or global) per storage format above
|
|
53
|
+
2. Ensure the notes directory exists (`.planning/notes/` or `C:/projects/GSD-Antigravity/.antigravity/notes/`)
|
|
54
|
+
3. Generate slug: first ~4 meaningful words of the note text, lowercase, hyphen-separated (strip articles/prepositions from the start)
|
|
55
|
+
4. Generate filename: `{YYYY-MM-DD}-{slug}.md`
|
|
56
|
+
- If a file with that name already exists, append `-2`, `-3`, etc.
|
|
57
|
+
5. Write the file with frontmatter and note text (see storage format)
|
|
58
|
+
6. Confirm with exactly one line: `Noted ({scope}): {note text}`
|
|
59
|
+
- Where `{scope}` is "project" or "global"
|
|
60
|
+
|
|
61
|
+
**Constraints:**
|
|
62
|
+
- **Never modify the note text** — capture verbatim, including typos
|
|
63
|
+
- **Never ask questions** — just write and confirm
|
|
64
|
+
- **Timestamp format**: Use local time, `YYYY-MM-DD HH:mm` (24-hour, no seconds)
|
|
65
|
+
</step>
|
|
66
|
+
|
|
67
|
+
<step name="list">
|
|
68
|
+
**Subcommand: list — show notes from both scopes.**
|
|
69
|
+
|
|
70
|
+
1. Glob `.planning/notes/*.md` (if directory exists) — project notes
|
|
71
|
+
2. Glob `C:/projects/GSD-Antigravity/.antigravity/notes/*.md` (if directory exists) — global notes
|
|
72
|
+
3. For each file, read frontmatter to get `date` and `promoted` status
|
|
73
|
+
4. Exclude files where `promoted: true` from active counts (but still show them, dimmed)
|
|
74
|
+
5. Sort by date, number all active entries sequentially starting at 1
|
|
75
|
+
6. If total active entries > 20, show only the last 10 with a note about how many were omitted
|
|
76
|
+
|
|
77
|
+
**Display format:**
|
|
78
|
+
|
|
79
|
+
```
|
|
80
|
+
Notes:
|
|
81
|
+
|
|
82
|
+
Project (.planning/notes/):
|
|
83
|
+
1. [2026-02-08 14:32] refactor the hook system to support async validators
|
|
84
|
+
2. [promoted] [2026-02-08 14:40] add rate limiting to the API endpoints
|
|
85
|
+
3. [2026-02-08 15:10] consider adding a --dry-run flag to build
|
|
86
|
+
|
|
87
|
+
Global (C:/projects/GSD-Antigravity/.antigravity/notes/):
|
|
88
|
+
4. [2026-02-08 10:00] cross-project idea about shared config
|
|
89
|
+
|
|
90
|
+
{count} active note(s). Use `/gsd:note promote <N>` to convert to a todo.
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
If a scope has no directory or no entries, show: `(no notes)`
|
|
94
|
+
</step>
|
|
95
|
+
|
|
96
|
+
<step name="promote">
|
|
97
|
+
**Subcommand: promote — convert a note into a todo.**
|
|
98
|
+
|
|
99
|
+
1. Run the **list** logic to build the numbered index (both scopes)
|
|
100
|
+
2. Find entry N from the numbered list
|
|
101
|
+
3. If N is invalid or refers to an already-promoted note, tell the user and stop
|
|
102
|
+
4. **Requires `.planning/` directory** — if it doesn't exist, warn: "Todos require a GSD project. Run `/gsd:new-project` to initialize one."
|
|
103
|
+
5. Ensure `.planning/todos/pending/` directory exists
|
|
104
|
+
6. Generate todo ID: `{NNN}-{slug}` where NNN is the next sequential number (scan both `.planning/todos/pending/` and `.planning/todos/done/` for the highest existing number, increment by 1, zero-pad to 3 digits) and slug is the first ~4 meaningful words of the note text
|
|
105
|
+
7. Extract the note text from the source file (body after frontmatter)
|
|
106
|
+
8. Create `.planning/todos/pending/{id}.md`:
|
|
107
|
+
|
|
108
|
+
```yaml
|
|
109
|
+
---
|
|
110
|
+
title: "{note text}"
|
|
111
|
+
status: pending
|
|
112
|
+
priority: P2
|
|
113
|
+
source: "promoted from /gsd:note"
|
|
114
|
+
created: {YYYY-MM-DD}
|
|
115
|
+
theme: general
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## Goal
|
|
119
|
+
|
|
120
|
+
{note text}
|
|
121
|
+
|
|
122
|
+
## Context
|
|
123
|
+
|
|
124
|
+
Promoted from quick note captured on {original date}.
|
|
125
|
+
|
|
126
|
+
## Acceptance Criteria
|
|
127
|
+
|
|
128
|
+
- [ ] {primary criterion derived from note text}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
9. Mark the source note file as promoted: update its frontmatter to `promoted: true`
|
|
132
|
+
10. Confirm: `Promoted note {N} to todo {id}: {note text}`
|
|
133
|
+
</step>
|
|
134
|
+
|
|
135
|
+
</process>
|
|
136
|
+
|
|
137
|
+
<edge_cases>
|
|
138
|
+
1. **"list" as note text**: `/gsd:note list of things` saves note "list of things" (subcommand only when `list` is the entire arg)
|
|
139
|
+
2. **No `.planning/`**: Falls back to global `C:/projects/GSD-Antigravity/.antigravity/notes/` — works in any directory
|
|
140
|
+
3. **Promote without project**: Warns that todos require `.planning/`, suggests `/gsd:new-project`
|
|
141
|
+
4. **Large files**: `list` shows last 10 when >20 active entries
|
|
142
|
+
5. **Duplicate slugs**: Append `-2`, `-3` etc. to filename if slug already used on same date
|
|
143
|
+
6. **`--global` position**: Stripped from anywhere — `--global my idea` and `my idea --global` both save "my idea" globally
|
|
144
|
+
7. **Promote already-promoted**: Tell user "Note {N} is already promoted" and stop
|
|
145
|
+
8. **Empty note text after stripping flags**: Treat as `list` subcommand
|
|
146
|
+
</edge_cases>
|
|
147
|
+
|
|
148
|
+
<success_criteria>
|
|
149
|
+
- [ ] Append: Note file written with correct frontmatter and verbatim text
|
|
150
|
+
- [ ] Append: No questions asked — instant capture
|
|
151
|
+
- [ ] List: Both scopes shown with sequential numbering
|
|
152
|
+
- [ ] List: Promoted notes shown but dimmed
|
|
153
|
+
- [ ] Promote: Todo created with correct format
|
|
154
|
+
- [ ] Promote: Source note marked as promoted
|
|
155
|
+
- [ ] Global fallback: Works when no `.planning/` exists
|
|
156
|
+
</success_criteria>
|
|
@@ -174,12 +174,33 @@ If "Run discuss-phase first": Display `/gsd:discuss-phase {X}` and exit workflow
|
|
|
174
174
|
|
|
175
175
|
## 5. Handle Research
|
|
176
176
|
|
|
177
|
-
**Skip if:** `--gaps` flag
|
|
177
|
+
**Skip if:** `--gaps` flag or `--skip-research` flag.
|
|
178
178
|
|
|
179
179
|
**If `has_research` is true (from init) AND no `--research` flag:** Use existing, skip to step 6.
|
|
180
180
|
|
|
181
181
|
**If RESEARCH.md missing OR `--research` flag:**
|
|
182
182
|
|
|
183
|
+
**If no explicit flag (`--research` or `--skip-research`) and not `--auto`:**
|
|
184
|
+
Ask the user whether to research, with a contextual recommendation based on the phase:
|
|
185
|
+
|
|
186
|
+
```
|
|
187
|
+
AskUserQuestion([
|
|
188
|
+
{
|
|
189
|
+
question: "Research before planning Phase {X}: {phase_name}?",
|
|
190
|
+
header: "Research",
|
|
191
|
+
multiSelect: false,
|
|
192
|
+
options: [
|
|
193
|
+
{ label: "Research first (Recommended)", description: "Investigate domain, patterns, and dependencies before planning. Best for new features, unfamiliar integrations, or architectural changes." },
|
|
194
|
+
{ label: "Skip research", description: "Plan directly from context and requirements. Best for bug fixes, simple refactors, or well-understood tasks." }
|
|
195
|
+
]
|
|
196
|
+
}
|
|
197
|
+
])
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
If user selects "Skip research": skip to step 6.
|
|
201
|
+
|
|
202
|
+
**If `--auto` and `research_enabled` is false:** Skip research silently (preserves automated behavior).
|
|
203
|
+
|
|
183
204
|
Display banner:
|
|
184
205
|
```
|
|
185
206
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
@@ -47,7 +47,7 @@ AskUserQuestion([
|
|
|
47
47
|
multiSelect: false,
|
|
48
48
|
options: [
|
|
49
49
|
{ label: "Quality", description: "Opus everywhere except verification (highest cost)" },
|
|
50
|
-
{ label: "Balanced (Recommended)", description: "Opus for planning, Sonnet for execution/verification" },
|
|
50
|
+
{ label: "Balanced (Recommended)", description: "Opus for planning, Sonnet for research/execution/verification" },
|
|
51
51
|
{ label: "Budget", description: "Sonnet for writing, Haiku for research/verification (lowest cost)" },
|
|
52
52
|
{ label: "Inherit", description: "Use current session model for all agents (best for OpenCode /model)" }
|
|
53
53
|
]
|
|
@@ -126,6 +126,15 @@ AskUserQuestion([
|
|
|
126
126
|
{ label: "Per Phase", description: "Create branch for each phase (gsd/phase-{N}-{name})" },
|
|
127
127
|
{ label: "Per Milestone", description: "Create branch for entire milestone (gsd/{version}-{name})" }
|
|
128
128
|
]
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
question: "Enable context window warnings? (injects advisory messages when context is getting full)",
|
|
132
|
+
header: "Ctx Warnings",
|
|
133
|
+
multiSelect: false,
|
|
134
|
+
options: [
|
|
135
|
+
{ label: "Yes (Recommended)", description: "Warn when context usage exceeds 65%. Helps avoid losing work." },
|
|
136
|
+
{ label: "No", description: "Disable warnings. Allows Antigravity to reach auto-compact naturally. Good for long unattended runs." }
|
|
137
|
+
]
|
|
129
138
|
}
|
|
130
139
|
])
|
|
131
140
|
```
|
|
@@ -149,6 +158,9 @@ Merge new settings into existing config.json:
|
|
|
149
158
|
},
|
|
150
159
|
"git": {
|
|
151
160
|
"branching_strategy": "none" | "phase" | "milestone"
|
|
161
|
+
},
|
|
162
|
+
"hooks": {
|
|
163
|
+
"context_warnings": true/false
|
|
152
164
|
}
|
|
153
165
|
}
|
|
154
166
|
```
|
|
@@ -220,6 +232,7 @@ Display:
|
|
|
220
232
|
| UI Phase | {On/Off} |
|
|
221
233
|
| UI Safety Gate | {On/Off} |
|
|
222
234
|
| Git Branching | {None/Per Phase/Per Milestone} |
|
|
235
|
+
| Context Warnings | {On/Off} |
|
|
223
236
|
| Saved as Defaults | {Yes/No} |
|
|
224
237
|
|
|
225
238
|
These settings apply to future /gsd:plan-phase and /gsd:execute-phase runs.
|
|
@@ -16,7 +16,7 @@ STATS=$(node "$GSD_TOOLS" stats json)
|
|
|
16
16
|
if [[ "$STATS" == @file:* ]]; then STATS=$(cat "${STATS#@file:}"); fi
|
|
17
17
|
```
|
|
18
18
|
|
|
19
|
-
Extract fields from JSON: `milestone_version`, `milestone_name`, `phases`, `total_plans`, `total_summaries`, `percent`, `requirements_total`, `requirements_complete`, `git_commits`, `git_first_commit_date`, `last_activity`.
|
|
19
|
+
Extract fields from JSON: `milestone_version`, `milestone_name`, `phases`, `phases_completed`, `phases_total`, `total_plans`, `total_summaries`, `percent`, `plan_percent`, `requirements_total`, `requirements_complete`, `git_commits`, `git_first_commit_date`, `last_activity`.
|
|
20
20
|
</step>
|
|
21
21
|
|
|
22
22
|
<step name="present_stats">
|
|
@@ -26,7 +26,10 @@ Present to the user with this format:
|
|
|
26
26
|
# 📊 Project Statistics — {milestone_version} {milestone_name}
|
|
27
27
|
|
|
28
28
|
## Progress
|
|
29
|
-
[████████░░] X/Y
|
|
29
|
+
[████████░░] X/Y phases (Z%)
|
|
30
|
+
|
|
31
|
+
## Plans
|
|
32
|
+
X/Y plans complete (Z%)
|
|
30
33
|
|
|
31
34
|
## Phases
|
|
32
35
|
| Phase | Name | Plans | Completed | Status |
|
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,17 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.25.1] - 2026-03-16
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- **GSD Sync 1.25.1**: Full synchronization with the latest GSD core, featuring optimized model profiles and enhanced state consistency.
|
|
12
|
+
- **Selective Inclusion Engine**: Injected `parseIncludeFlag`, `applyIncludes`, and `buildPhaseBase` into the core CLI, enabling granular context management via the `--include` flag.
|
|
13
|
+
- **Artifact Discovery**: Integrated `discoverPhaseArtifacts` for automated detection of hierarchical project files, improving context gathering automation.
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
- **Skill Optimization**: Applied advanced refactoring via `gsd-converter`, reducing script overhead through 2-space indentation and condensed headers.
|
|
17
|
+
- **Improved Portability**: Enhanced regex-based path mapping for even more robust environment isolation in Antigravity.
|
|
18
|
+
|
|
8
19
|
## [1.24.0] - 2026-03-15
|
|
9
20
|
|
|
10
21
|
### Added
|
package/README.md
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
[](https://opensource.org/licenses/MIT)
|
|
4
4
|
[](https://github.com/google-deepmind/antigravity)
|
|
5
5
|
[](https://www.npmjs.com/package/gsd-antigravity-kit)
|
|
6
|
-
[](https://github.com/dturkuler/GSD-Antigravity/releases/latest)
|
|
7
|
+
[](https://github.com/glittercowboy/get-shit-done)
|
|
8
8
|
|
|
9
9
|
**GSD-Antigravity Kit** is the official bootstrapping and management utility for the [Get Shit Done (GSD)](https://github.com/glittercowboy/get-shit-done) protocol within the Antigravity AI framework. It serves as a high-performance **Installer** and **Skill Manager** that provision, optimizes, and maintains GSD skills in your AG environment.
|
|
10
10
|
|
|
@@ -6,6 +6,17 @@ This document tracks technical Root Cause Analysis (RCA) for bug fixes in the **
|
|
|
6
6
|
|
|
7
7
|
## Technical Analysis History
|
|
8
8
|
|
|
9
|
+
### v1.25.1 (2026-03-16)
|
|
10
|
+
* **Context:** `gsd-tools.cjs` (Selective Inclusion and Artifact Discovery)
|
|
11
|
+
* **Issue:** Lack of standardized context slicing and automated artifact traversal in the core GSD engine, leading to inconsistent context gathering across different subagents.
|
|
12
|
+
* **Root Cause Analysis:**
|
|
13
|
+
- The core engine was missing a unified way to handle partial context loading, forcing agents to either load the entire state or manually parse it.
|
|
14
|
+
- Artifact discovery relied on static paths which didn't always account for deeply nested or dynamically named phase directories.
|
|
15
|
+
* **How it was fixed:**
|
|
16
|
+
- **Smart Inclusions**: Injected `parseIncludeFlag`, `applyIncludes`, and `buildPhaseBase` into `gsd-tools.cjs`. This allows the `--include` flag to dynamically filter state/roadmap data, significantly reducing token overhead for long-running workflows.
|
|
17
|
+
- **Automated Discovery**: Integrated `discoverPhaseArtifacts()` to automatically traverse the `.planning/` hierarchy, ensuring that all relevant requirements, plans, and implementation notes are available to the agent without manual specification.
|
|
18
|
+
- **Model Profile Injection**: Injected a centralized `MODEL_PROFILES` object to ensure consistent model selection (e.g., using better models for planning and cheaper ones for simple tasks) across the entire GSD toolchain.
|
|
19
|
+
|
|
9
20
|
### v1.24.0 (2026-03-15)
|
|
10
21
|
* **Context:** `gsd-tools.cjs` (Engine Modernization)
|
|
11
22
|
* **Issue:** Technical debt in the core engine; increasing complexity of the monolithic `gsd-tools.cjs` script; and lack of granular control over phase/milestone state transitions.
|