get-shit-done-cc 1.6.3 → 1.7.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 +26 -0
- package/agents/gsd-phase-researcher.md +4 -4
- package/agents/gsd-project-researcher.md +5 -5
- package/bin/install.js +167 -8
- package/commands/gsd/discuss-phase.md +7 -1
- package/commands/gsd/help.md +15 -0
- package/commands/gsd/quick.md +286 -0
- package/commands/gsd/research-phase.md +1 -1
- package/get-shit-done/workflows/discovery-phase.md +5 -9
- package/get-shit-done/workflows/execute-plan.md +3 -1
- package/get-shit-done/workflows/resume-project.md +4 -0
- package/get-shit-done/workflows/verify-phase.md +2 -3
- package/hooks/gsd-check-update.js +4 -4
- package/hooks/statusline.js +1 -1
- package/package.json +5 -1
package/README.md
CHANGED
|
@@ -297,6 +297,31 @@ Then `/gsd:new-milestone` starts the next version — same flow as `new-project`
|
|
|
297
297
|
|
|
298
298
|
---
|
|
299
299
|
|
|
300
|
+
### Quick Mode
|
|
301
|
+
|
|
302
|
+
```
|
|
303
|
+
/gsd:quick
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
**For ad-hoc tasks that don't need full planning.**
|
|
307
|
+
|
|
308
|
+
Quick mode gives you GSD guarantees (atomic commits, state tracking) with a faster path:
|
|
309
|
+
|
|
310
|
+
- **Same agents** — Planner + executor, same quality
|
|
311
|
+
- **Skips optional steps** — No research, no plan checker, no verifier
|
|
312
|
+
- **Separate tracking** — Lives in `.planning/quick/`, not phases
|
|
313
|
+
|
|
314
|
+
Use for: bug fixes, small features, config changes, one-off tasks.
|
|
315
|
+
|
|
316
|
+
```
|
|
317
|
+
/gsd:quick
|
|
318
|
+
> What do you want to do? "Add dark mode toggle to settings"
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
**Creates:** `.planning/quick/001-add-dark-mode-toggle/PLAN.md`, `SUMMARY.md`
|
|
322
|
+
|
|
323
|
+
---
|
|
324
|
+
|
|
300
325
|
## Why It Works
|
|
301
326
|
|
|
302
327
|
### Context Engineering
|
|
@@ -429,6 +454,7 @@ You're never locked in. The system adapts.
|
|
|
429
454
|
| `/gsd:add-todo [desc]` | Capture idea for later |
|
|
430
455
|
| `/gsd:check-todos` | List pending todos |
|
|
431
456
|
| `/gsd:debug [desc]` | Systematic debugging with persistent state |
|
|
457
|
+
| `/gsd:quick` | Execute ad-hoc task with GSD guarantees |
|
|
432
458
|
|
|
433
459
|
<sup>¹ Contributed by reddit user OracleGreyBeard</sup>
|
|
434
460
|
|
|
@@ -157,11 +157,11 @@ For finding what exists, community patterns, real-world usage.
|
|
|
157
157
|
- "How do people solve Y?"
|
|
158
158
|
- "Common mistakes with Z"
|
|
159
159
|
|
|
160
|
-
**Query templates
|
|
160
|
+
**Query templates:**
|
|
161
161
|
```
|
|
162
162
|
Stack discovery:
|
|
163
|
-
- "[technology] best practices
|
|
164
|
-
- "[technology] recommended libraries
|
|
163
|
+
- "[technology] best practices [current year]"
|
|
164
|
+
- "[technology] recommended libraries [current year]"
|
|
165
165
|
|
|
166
166
|
Pattern discovery:
|
|
167
167
|
- "how to build [type of thing] with [technology]"
|
|
@@ -173,7 +173,7 @@ Problem discovery:
|
|
|
173
173
|
```
|
|
174
174
|
|
|
175
175
|
**Best practices:**
|
|
176
|
-
-
|
|
176
|
+
- Always include the current year (check today's date) for freshness
|
|
177
177
|
- Use multiple query variations
|
|
178
178
|
- Cross-verify findings with authoritative sources
|
|
179
179
|
- Mark WebSearch-only findings as LOW confidence
|
|
@@ -200,12 +200,12 @@ For finding what exists, community patterns, real-world usage.
|
|
|
200
200
|
- "Common mistakes with Z"
|
|
201
201
|
- Ecosystem surveys
|
|
202
202
|
|
|
203
|
-
**Query templates
|
|
203
|
+
**Query templates:**
|
|
204
204
|
```
|
|
205
205
|
Ecosystem discovery:
|
|
206
|
-
- "[technology] best practices
|
|
207
|
-
- "[technology] recommended libraries
|
|
208
|
-
- "[technology] vs [alternative]
|
|
206
|
+
- "[technology] best practices [current year]"
|
|
207
|
+
- "[technology] recommended libraries [current year]"
|
|
208
|
+
- "[technology] vs [alternative] [current year]"
|
|
209
209
|
|
|
210
210
|
Pattern discovery:
|
|
211
211
|
- "how to build [type of thing] with [technology]"
|
|
@@ -219,7 +219,7 @@ Problem discovery:
|
|
|
219
219
|
```
|
|
220
220
|
|
|
221
221
|
**Best practices:**
|
|
222
|
-
-
|
|
222
|
+
- Always include the current year (check today's date) for freshness
|
|
223
223
|
- Use multiple query variations
|
|
224
224
|
- Cross-verify findings with authoritative sources
|
|
225
225
|
- Mark WebSearch-only findings as LOW confidence
|
package/bin/install.js
CHANGED
|
@@ -48,7 +48,12 @@ function parseConfigDirArg() {
|
|
|
48
48
|
// Also handle --config-dir=value format
|
|
49
49
|
const configDirArg = args.find(arg => arg.startsWith('--config-dir=') || arg.startsWith('-c='));
|
|
50
50
|
if (configDirArg) {
|
|
51
|
-
|
|
51
|
+
const value = configDirArg.split('=')[1];
|
|
52
|
+
if (!value) {
|
|
53
|
+
console.error(` ${yellow}--config-dir requires a non-empty path${reset}`);
|
|
54
|
+
process.exit(1);
|
|
55
|
+
}
|
|
56
|
+
return value;
|
|
52
57
|
}
|
|
53
58
|
return null;
|
|
54
59
|
}
|
|
@@ -151,6 +156,96 @@ function copyWithPathReplacement(srcDir, destDir, pathPrefix) {
|
|
|
151
156
|
}
|
|
152
157
|
}
|
|
153
158
|
|
|
159
|
+
/**
|
|
160
|
+
* Clean up orphaned files from previous GSD versions
|
|
161
|
+
*/
|
|
162
|
+
function cleanupOrphanedFiles(claudeDir) {
|
|
163
|
+
const orphanedFiles = [
|
|
164
|
+
'hooks/gsd-notify.sh', // Removed in v1.6.x
|
|
165
|
+
];
|
|
166
|
+
|
|
167
|
+
for (const relPath of orphanedFiles) {
|
|
168
|
+
const fullPath = path.join(claudeDir, relPath);
|
|
169
|
+
if (fs.existsSync(fullPath)) {
|
|
170
|
+
fs.unlinkSync(fullPath);
|
|
171
|
+
console.log(` ${green}✓${reset} Removed orphaned ${relPath}`);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Clean up orphaned hook registrations from settings.json
|
|
178
|
+
*/
|
|
179
|
+
function cleanupOrphanedHooks(settings) {
|
|
180
|
+
const orphanedHookPatterns = [
|
|
181
|
+
'gsd-notify.sh', // Removed in v1.6.x
|
|
182
|
+
];
|
|
183
|
+
|
|
184
|
+
let cleaned = false;
|
|
185
|
+
|
|
186
|
+
// Check all hook event types (Stop, SessionStart, etc.)
|
|
187
|
+
if (settings.hooks) {
|
|
188
|
+
for (const eventType of Object.keys(settings.hooks)) {
|
|
189
|
+
const hookEntries = settings.hooks[eventType];
|
|
190
|
+
if (Array.isArray(hookEntries)) {
|
|
191
|
+
// Filter out entries that contain orphaned hooks
|
|
192
|
+
const filtered = hookEntries.filter(entry => {
|
|
193
|
+
if (entry.hooks && Array.isArray(entry.hooks)) {
|
|
194
|
+
// Check if any hook in this entry matches orphaned patterns
|
|
195
|
+
const hasOrphaned = entry.hooks.some(h =>
|
|
196
|
+
h.command && orphanedHookPatterns.some(pattern => h.command.includes(pattern))
|
|
197
|
+
);
|
|
198
|
+
if (hasOrphaned) {
|
|
199
|
+
cleaned = true;
|
|
200
|
+
return false; // Remove this entry
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
return true; // Keep this entry
|
|
204
|
+
});
|
|
205
|
+
settings.hooks[eventType] = filtered;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
if (cleaned) {
|
|
211
|
+
console.log(` ${green}✓${reset} Removed orphaned hook registrations`);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
return settings;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Verify a directory exists and contains files
|
|
219
|
+
*/
|
|
220
|
+
function verifyInstalled(dirPath, description) {
|
|
221
|
+
if (!fs.existsSync(dirPath)) {
|
|
222
|
+
console.error(` ${yellow}✗${reset} Failed to install ${description}: directory not created`);
|
|
223
|
+
return false;
|
|
224
|
+
}
|
|
225
|
+
try {
|
|
226
|
+
const entries = fs.readdirSync(dirPath);
|
|
227
|
+
if (entries.length === 0) {
|
|
228
|
+
console.error(` ${yellow}✗${reset} Failed to install ${description}: directory is empty`);
|
|
229
|
+
return false;
|
|
230
|
+
}
|
|
231
|
+
} catch (e) {
|
|
232
|
+
console.error(` ${yellow}✗${reset} Failed to install ${description}: ${e.message}`);
|
|
233
|
+
return false;
|
|
234
|
+
}
|
|
235
|
+
return true;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Verify a file exists
|
|
240
|
+
*/
|
|
241
|
+
function verifyFileInstalled(filePath, description) {
|
|
242
|
+
if (!fs.existsSync(filePath)) {
|
|
243
|
+
console.error(` ${yellow}✗${reset} Failed to install ${description}: file not created`);
|
|
244
|
+
return false;
|
|
245
|
+
}
|
|
246
|
+
return true;
|
|
247
|
+
}
|
|
248
|
+
|
|
154
249
|
/**
|
|
155
250
|
* Install to the specified directory
|
|
156
251
|
*/
|
|
@@ -175,6 +270,12 @@ function install(isGlobal) {
|
|
|
175
270
|
|
|
176
271
|
console.log(` Installing to ${cyan}${locationLabel}${reset}\n`);
|
|
177
272
|
|
|
273
|
+
// Track installation failures
|
|
274
|
+
const failures = [];
|
|
275
|
+
|
|
276
|
+
// Clean up orphaned files from previous versions
|
|
277
|
+
cleanupOrphanedFiles(claudeDir);
|
|
278
|
+
|
|
178
279
|
// Create commands directory
|
|
179
280
|
const commandsDir = path.join(claudeDir, 'commands');
|
|
180
281
|
fs.mkdirSync(commandsDir, { recursive: true });
|
|
@@ -183,13 +284,21 @@ function install(isGlobal) {
|
|
|
183
284
|
const gsdSrc = path.join(src, 'commands', 'gsd');
|
|
184
285
|
const gsdDest = path.join(commandsDir, 'gsd');
|
|
185
286
|
copyWithPathReplacement(gsdSrc, gsdDest, pathPrefix);
|
|
186
|
-
|
|
287
|
+
if (verifyInstalled(gsdDest, 'commands/gsd')) {
|
|
288
|
+
console.log(` ${green}✓${reset} Installed commands/gsd`);
|
|
289
|
+
} else {
|
|
290
|
+
failures.push('commands/gsd');
|
|
291
|
+
}
|
|
187
292
|
|
|
188
293
|
// Copy get-shit-done skill with path replacement
|
|
189
294
|
const skillSrc = path.join(src, 'get-shit-done');
|
|
190
295
|
const skillDest = path.join(claudeDir, 'get-shit-done');
|
|
191
296
|
copyWithPathReplacement(skillSrc, skillDest, pathPrefix);
|
|
192
|
-
|
|
297
|
+
if (verifyInstalled(skillDest, 'get-shit-done')) {
|
|
298
|
+
console.log(` ${green}✓${reset} Installed get-shit-done`);
|
|
299
|
+
} else {
|
|
300
|
+
failures.push('get-shit-done');
|
|
301
|
+
}
|
|
193
302
|
|
|
194
303
|
// Copy agents to ~/.claude/agents (subagents must be at root level)
|
|
195
304
|
// Only delete gsd-*.md files to preserve user's custom agents
|
|
@@ -216,7 +325,11 @@ function install(isGlobal) {
|
|
|
216
325
|
fs.writeFileSync(path.join(agentsDest, entry.name), content);
|
|
217
326
|
}
|
|
218
327
|
}
|
|
219
|
-
|
|
328
|
+
if (verifyInstalled(agentsDest, 'agents')) {
|
|
329
|
+
console.log(` ${green}✓${reset} Installed agents`);
|
|
330
|
+
} else {
|
|
331
|
+
failures.push('agents');
|
|
332
|
+
}
|
|
220
333
|
}
|
|
221
334
|
|
|
222
335
|
// Copy CHANGELOG.md
|
|
@@ -224,13 +337,21 @@ function install(isGlobal) {
|
|
|
224
337
|
const changelogDest = path.join(claudeDir, 'get-shit-done', 'CHANGELOG.md');
|
|
225
338
|
if (fs.existsSync(changelogSrc)) {
|
|
226
339
|
fs.copyFileSync(changelogSrc, changelogDest);
|
|
227
|
-
|
|
340
|
+
if (verifyFileInstalled(changelogDest, 'CHANGELOG.md')) {
|
|
341
|
+
console.log(` ${green}✓${reset} Installed CHANGELOG.md`);
|
|
342
|
+
} else {
|
|
343
|
+
failures.push('CHANGELOG.md');
|
|
344
|
+
}
|
|
228
345
|
}
|
|
229
346
|
|
|
230
347
|
// Write VERSION file for whats-new command
|
|
231
348
|
const versionDest = path.join(claudeDir, 'get-shit-done', 'VERSION');
|
|
232
349
|
fs.writeFileSync(versionDest, pkg.version);
|
|
233
|
-
|
|
350
|
+
if (verifyFileInstalled(versionDest, 'VERSION')) {
|
|
351
|
+
console.log(` ${green}✓${reset} Wrote VERSION (${pkg.version})`);
|
|
352
|
+
} else {
|
|
353
|
+
failures.push('VERSION');
|
|
354
|
+
}
|
|
234
355
|
|
|
235
356
|
// Copy hooks
|
|
236
357
|
const hooksSrc = path.join(src, 'hooks');
|
|
@@ -243,12 +364,23 @@ function install(isGlobal) {
|
|
|
243
364
|
const destFile = path.join(hooksDest, entry);
|
|
244
365
|
fs.copyFileSync(srcFile, destFile);
|
|
245
366
|
}
|
|
246
|
-
|
|
367
|
+
if (verifyInstalled(hooksDest, 'hooks')) {
|
|
368
|
+
console.log(` ${green}✓${reset} Installed hooks`);
|
|
369
|
+
} else {
|
|
370
|
+
failures.push('hooks');
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
// If critical components failed, exit with error
|
|
375
|
+
if (failures.length > 0) {
|
|
376
|
+
console.error(`\n ${yellow}Installation incomplete!${reset} Failed: ${failures.join(', ')}`);
|
|
377
|
+
console.error(` Try running directly: node ~/.npm/_npx/*/node_modules/get-shit-done-cc/bin/install.js --global\n`);
|
|
378
|
+
process.exit(1);
|
|
247
379
|
}
|
|
248
380
|
|
|
249
381
|
// Configure statusline and hooks in settings.json
|
|
250
382
|
const settingsPath = path.join(claudeDir, 'settings.json');
|
|
251
|
-
const settings = readSettings(settingsPath);
|
|
383
|
+
const settings = cleanupOrphanedHooks(readSettings(settingsPath));
|
|
252
384
|
const statuslineCommand = isGlobal
|
|
253
385
|
? 'node "$HOME/.claude/hooks/statusline.js"'
|
|
254
386
|
: 'node .claude/hooks/statusline.js';
|
|
@@ -364,11 +496,37 @@ function handleStatusline(settings, isInteractive, callback) {
|
|
|
364
496
|
* Prompt for install location
|
|
365
497
|
*/
|
|
366
498
|
function promptLocation() {
|
|
499
|
+
// Check if stdin is a TTY - if not, fall back to global install
|
|
500
|
+
// This handles npx execution in environments like WSL2 where stdin may not be properly connected
|
|
501
|
+
if (!process.stdin.isTTY) {
|
|
502
|
+
console.log(` ${yellow}Non-interactive terminal detected, defaulting to global install${reset}\n`);
|
|
503
|
+
const { settingsPath, settings, statuslineCommand } = install(true);
|
|
504
|
+
handleStatusline(settings, false, (shouldInstallStatusline) => {
|
|
505
|
+
finishInstall(settingsPath, settings, statuslineCommand, shouldInstallStatusline);
|
|
506
|
+
});
|
|
507
|
+
return;
|
|
508
|
+
}
|
|
509
|
+
|
|
367
510
|
const rl = readline.createInterface({
|
|
368
511
|
input: process.stdin,
|
|
369
512
|
output: process.stdout
|
|
370
513
|
});
|
|
371
514
|
|
|
515
|
+
// Track whether we've processed the answer to prevent double-execution
|
|
516
|
+
let answered = false;
|
|
517
|
+
|
|
518
|
+
// Handle readline close event to detect premature stdin closure
|
|
519
|
+
rl.on('close', () => {
|
|
520
|
+
if (!answered) {
|
|
521
|
+
answered = true;
|
|
522
|
+
console.log(`\n ${yellow}Input stream closed, defaulting to global install${reset}\n`);
|
|
523
|
+
const { settingsPath, settings, statuslineCommand } = install(true);
|
|
524
|
+
handleStatusline(settings, false, (shouldInstallStatusline) => {
|
|
525
|
+
finishInstall(settingsPath, settings, statuslineCommand, shouldInstallStatusline);
|
|
526
|
+
});
|
|
527
|
+
}
|
|
528
|
+
});
|
|
529
|
+
|
|
372
530
|
const configDir = expandTilde(explicitConfigDir) || expandTilde(process.env.CLAUDE_CONFIG_DIR);
|
|
373
531
|
const globalPath = configDir || path.join(os.homedir(), '.claude');
|
|
374
532
|
const globalLabel = globalPath.replace(os.homedir(), '~');
|
|
@@ -380,6 +538,7 @@ function promptLocation() {
|
|
|
380
538
|
`);
|
|
381
539
|
|
|
382
540
|
rl.question(` Choice ${dim}[1]${reset}: `, (answer) => {
|
|
541
|
+
answered = true;
|
|
383
542
|
rl.close();
|
|
384
543
|
const choice = answer.trim() || '1';
|
|
385
544
|
const isGlobal = choice !== '2';
|
|
@@ -2,7 +2,13 @@
|
|
|
2
2
|
name: gsd:discuss-phase
|
|
3
3
|
description: Gather phase context through adaptive questioning before planning
|
|
4
4
|
argument-hint: "<phase>"
|
|
5
|
-
allowed-tools:
|
|
5
|
+
allowed-tools:
|
|
6
|
+
- Read
|
|
7
|
+
- Write
|
|
8
|
+
- Bash
|
|
9
|
+
- Glob
|
|
10
|
+
- Grep
|
|
11
|
+
- AskUserQuestion
|
|
6
12
|
---
|
|
7
13
|
|
|
8
14
|
<objective>
|
package/commands/gsd/help.md
CHANGED
|
@@ -129,6 +129,21 @@ Execute all plans in a phase.
|
|
|
129
129
|
|
|
130
130
|
Usage: `/gsd:execute-phase 5`
|
|
131
131
|
|
|
132
|
+
### Quick Mode
|
|
133
|
+
|
|
134
|
+
**`/gsd:quick`**
|
|
135
|
+
Execute small, ad-hoc tasks with GSD guarantees but skip optional agents.
|
|
136
|
+
|
|
137
|
+
Quick mode uses the same system with a shorter path:
|
|
138
|
+
- Spawns planner + executor (skips researcher, checker, verifier)
|
|
139
|
+
- Quick tasks live in `.planning/quick/` separate from planned phases
|
|
140
|
+
- Updates STATE.md tracking (not ROADMAP.md)
|
|
141
|
+
|
|
142
|
+
Use when you know exactly what to do and the task is small enough to not need research or verification.
|
|
143
|
+
|
|
144
|
+
Usage: `/gsd:quick`
|
|
145
|
+
Result: Creates `.planning/quick/NNN-slug/PLAN.md`, `.planning/quick/NNN-slug/SUMMARY.md`
|
|
146
|
+
|
|
132
147
|
### Roadmap Management
|
|
133
148
|
|
|
134
149
|
**`/gsd:add-phase <description>`**
|
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gsd:quick
|
|
3
|
+
description: Execute a quick task with GSD guarantees (atomic commits, state tracking) but skip optional agents
|
|
4
|
+
argument-hint: ""
|
|
5
|
+
allowed-tools:
|
|
6
|
+
- Read
|
|
7
|
+
- Write
|
|
8
|
+
- Edit
|
|
9
|
+
- Glob
|
|
10
|
+
- Grep
|
|
11
|
+
- Bash
|
|
12
|
+
- Task
|
|
13
|
+
- AskUserQuestion
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
<objective>
|
|
17
|
+
Execute small, ad-hoc tasks with GSD guarantees (atomic commits, STATE.md tracking) while skipping optional agents (research, plan-checker, verifier).
|
|
18
|
+
|
|
19
|
+
Quick mode is the same system with a shorter path:
|
|
20
|
+
- Spawns gsd-planner (quick mode) + gsd-executor(s)
|
|
21
|
+
- Skips gsd-phase-researcher, gsd-plan-checker, gsd-verifier
|
|
22
|
+
- Quick tasks live in `.planning/quick/` separate from planned phases
|
|
23
|
+
- Updates STATE.md "Quick Tasks Completed" table (NOT ROADMAP.md)
|
|
24
|
+
|
|
25
|
+
Use when: You know exactly what to do and the task is small enough to not need research or verification.
|
|
26
|
+
</objective>
|
|
27
|
+
|
|
28
|
+
<execution_context>
|
|
29
|
+
Orchestration is inline - no separate workflow file. Quick mode is deliberately simpler than full GSD.
|
|
30
|
+
</execution_context>
|
|
31
|
+
|
|
32
|
+
<context>
|
|
33
|
+
@.planning/STATE.md
|
|
34
|
+
</context>
|
|
35
|
+
|
|
36
|
+
<process>
|
|
37
|
+
**Step 1: Pre-flight validation**
|
|
38
|
+
|
|
39
|
+
Check that an active GSD project exists:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
if [ ! -f .planning/ROADMAP.md ]; then
|
|
43
|
+
echo "Quick mode requires an active project with ROADMAP.md."
|
|
44
|
+
echo "Run /gsd:new-project first."
|
|
45
|
+
exit 1
|
|
46
|
+
fi
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
If validation fails, stop immediately with the error message.
|
|
50
|
+
|
|
51
|
+
Quick tasks can run mid-phase - validation only checks ROADMAP.md exists, not phase status.
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
**Step 2: Get task description**
|
|
56
|
+
|
|
57
|
+
Prompt user interactively for the task description:
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
AskUserQuestion(
|
|
61
|
+
header: "Quick Task",
|
|
62
|
+
question: "What do you want to do?",
|
|
63
|
+
followUp: null
|
|
64
|
+
)
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Store response as `$DESCRIPTION`.
|
|
68
|
+
|
|
69
|
+
If empty, re-prompt: "Please provide a task description."
|
|
70
|
+
|
|
71
|
+
Generate slug from description:
|
|
72
|
+
```bash
|
|
73
|
+
slug=$(echo "$DESCRIPTION" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9]/-/g' | sed 's/--*/-/g' | sed 's/^-//;s/-$//' | cut -c1-40)
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
**Step 3: Calculate next quick task number**
|
|
79
|
+
|
|
80
|
+
Ensure `.planning/quick/` directory exists and find the next sequential number:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
# Ensure .planning/quick/ exists
|
|
84
|
+
mkdir -p .planning/quick
|
|
85
|
+
|
|
86
|
+
# Find highest existing number and increment
|
|
87
|
+
last=$(ls -1d .planning/quick/[0-9][0-9][0-9]-* 2>/dev/null | sort -r | head -1 | xargs -I{} basename {} | grep -oE '^[0-9]+')
|
|
88
|
+
|
|
89
|
+
if [ -z "$last" ]; then
|
|
90
|
+
next_num="001"
|
|
91
|
+
else
|
|
92
|
+
next_num=$(printf "%03d" $((10#$last + 1)))
|
|
93
|
+
fi
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
**Step 4: Create quick task directory**
|
|
99
|
+
|
|
100
|
+
Create the directory for this quick task:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
QUICK_DIR=".planning/quick/${next_num}-${slug}"
|
|
104
|
+
mkdir -p "$QUICK_DIR"
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Report to user:
|
|
108
|
+
```
|
|
109
|
+
Creating quick task ${next_num}: ${DESCRIPTION}
|
|
110
|
+
Directory: ${QUICK_DIR}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Store `$QUICK_DIR` for use in orchestration.
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
**Step 5: Spawn planner (quick mode)**
|
|
118
|
+
|
|
119
|
+
Spawn gsd-planner with quick mode context:
|
|
120
|
+
|
|
121
|
+
```
|
|
122
|
+
Task(
|
|
123
|
+
prompt="
|
|
124
|
+
<planning_context>
|
|
125
|
+
|
|
126
|
+
**Mode:** quick
|
|
127
|
+
**Directory:** ${QUICK_DIR}
|
|
128
|
+
**Description:** ${DESCRIPTION}
|
|
129
|
+
|
|
130
|
+
**Project State:**
|
|
131
|
+
@.planning/STATE.md
|
|
132
|
+
|
|
133
|
+
</planning_context>
|
|
134
|
+
|
|
135
|
+
<constraints>
|
|
136
|
+
- Create a SINGLE plan with 1-3 focused tasks
|
|
137
|
+
- Quick tasks should be atomic and self-contained
|
|
138
|
+
- No research phase, no checker phase
|
|
139
|
+
- Target ~30% context usage (simple, focused)
|
|
140
|
+
</constraints>
|
|
141
|
+
|
|
142
|
+
<output>
|
|
143
|
+
Write PLAN.md to: ${QUICK_DIR}/PLAN.md
|
|
144
|
+
Return: ## PLANNING COMPLETE with plan path
|
|
145
|
+
</output>
|
|
146
|
+
",
|
|
147
|
+
subagent_type="gsd-planner",
|
|
148
|
+
description="Quick plan: ${DESCRIPTION}"
|
|
149
|
+
)
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
After planner returns:
|
|
153
|
+
1. Verify PLAN.md exists at `${QUICK_DIR}/PLAN.md`
|
|
154
|
+
2. Extract plan count (typically 1 for quick tasks)
|
|
155
|
+
3. Report: "Plan created: ${QUICK_DIR}/PLAN.md"
|
|
156
|
+
|
|
157
|
+
If PLAN.md not found, error: "Planner failed to create PLAN.md"
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
**Step 6: Spawn executor**
|
|
162
|
+
|
|
163
|
+
Spawn gsd-executor with plan reference:
|
|
164
|
+
|
|
165
|
+
```
|
|
166
|
+
Task(
|
|
167
|
+
prompt="
|
|
168
|
+
Execute quick task ${next_num}.
|
|
169
|
+
|
|
170
|
+
Plan: @${QUICK_DIR}/PLAN.md
|
|
171
|
+
Project state: @.planning/STATE.md
|
|
172
|
+
|
|
173
|
+
<constraints>
|
|
174
|
+
- Execute all tasks in the plan
|
|
175
|
+
- Commit each task atomically
|
|
176
|
+
- Create SUMMARY.md in the quick task directory
|
|
177
|
+
- Do NOT update ROADMAP.md (quick tasks are separate from planned phases)
|
|
178
|
+
</constraints>
|
|
179
|
+
",
|
|
180
|
+
subagent_type="gsd-executor",
|
|
181
|
+
description="Execute: ${DESCRIPTION}"
|
|
182
|
+
)
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
After executor returns:
|
|
186
|
+
1. Verify SUMMARY.md exists at `${QUICK_DIR}/SUMMARY.md`
|
|
187
|
+
2. Extract commit hash from executor output
|
|
188
|
+
3. Report completion status
|
|
189
|
+
|
|
190
|
+
If SUMMARY.md not found, error: "Executor failed to create SUMMARY.md"
|
|
191
|
+
|
|
192
|
+
Note: For quick tasks producing multiple plans (rare), spawn executors in parallel waves per execute-phase patterns.
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
**Step 7: Update STATE.md**
|
|
197
|
+
|
|
198
|
+
Update STATE.md with quick task completion record.
|
|
199
|
+
|
|
200
|
+
**7a. Check if "Quick Tasks Completed" section exists:**
|
|
201
|
+
|
|
202
|
+
Read STATE.md and check for `### Quick Tasks Completed` section.
|
|
203
|
+
|
|
204
|
+
**7b. If section doesn't exist, create it:**
|
|
205
|
+
|
|
206
|
+
Insert after `### Blockers/Concerns` section:
|
|
207
|
+
|
|
208
|
+
```markdown
|
|
209
|
+
### Quick Tasks Completed
|
|
210
|
+
|
|
211
|
+
| # | Description | Date | Commit | Directory |
|
|
212
|
+
|---|-------------|------|--------|-----------|
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
**7c. Append new row to table:**
|
|
216
|
+
|
|
217
|
+
```markdown
|
|
218
|
+
| ${next_num} | ${DESCRIPTION} | $(date +%Y-%m-%d) | ${commit_hash} | [${next_num}-${slug}](./quick/${next_num}-${slug}/) |
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
**7d. Update "Last activity" line:**
|
|
222
|
+
|
|
223
|
+
Find and update the line:
|
|
224
|
+
```
|
|
225
|
+
Last activity: $(date +%Y-%m-%d) - Completed quick task ${next_num}: ${DESCRIPTION}
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
Use Edit tool to make these changes atomically
|
|
229
|
+
|
|
230
|
+
---
|
|
231
|
+
|
|
232
|
+
**Step 8: Final commit and completion**
|
|
233
|
+
|
|
234
|
+
Stage and commit quick task artifacts:
|
|
235
|
+
|
|
236
|
+
```bash
|
|
237
|
+
# Stage quick task artifacts
|
|
238
|
+
git add ${QUICK_DIR}/PLAN.md
|
|
239
|
+
git add ${QUICK_DIR}/SUMMARY.md
|
|
240
|
+
git add .planning/STATE.md
|
|
241
|
+
|
|
242
|
+
# Commit with quick task format
|
|
243
|
+
git commit -m "$(cat <<'EOF'
|
|
244
|
+
docs(quick-${next_num}): ${DESCRIPTION}
|
|
245
|
+
|
|
246
|
+
Quick task completed.
|
|
247
|
+
|
|
248
|
+
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
|
249
|
+
EOF
|
|
250
|
+
)"
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
Get final commit hash:
|
|
254
|
+
```bash
|
|
255
|
+
commit_hash=$(git rev-parse --short HEAD)
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
Display completion output:
|
|
259
|
+
```
|
|
260
|
+
---
|
|
261
|
+
|
|
262
|
+
GSD > QUICK TASK COMPLETE
|
|
263
|
+
|
|
264
|
+
Quick Task ${next_num}: ${DESCRIPTION}
|
|
265
|
+
|
|
266
|
+
Summary: ${QUICK_DIR}/SUMMARY.md
|
|
267
|
+
Commit: ${commit_hash}
|
|
268
|
+
|
|
269
|
+
---
|
|
270
|
+
|
|
271
|
+
Ready for next task: /gsd:quick
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
</process>
|
|
275
|
+
|
|
276
|
+
<success_criteria>
|
|
277
|
+
- [ ] ROADMAP.md validation passes
|
|
278
|
+
- [ ] User provides task description
|
|
279
|
+
- [ ] Slug generated (lowercase, hyphens, max 40 chars)
|
|
280
|
+
- [ ] Next number calculated (001, 002, 003...)
|
|
281
|
+
- [ ] Directory created at `.planning/quick/NNN-slug/`
|
|
282
|
+
- [ ] PLAN.md created by planner
|
|
283
|
+
- [ ] SUMMARY.md created by executor
|
|
284
|
+
- [ ] STATE.md updated with quick task row
|
|
285
|
+
- [ ] Artifacts committed
|
|
286
|
+
</success_criteria>
|
|
@@ -69,7 +69,7 @@ grep -A30 "### Decisions Made" .planning/STATE.md 2>/dev/null
|
|
|
69
69
|
|
|
70
70
|
Present summary with phase description, requirements, prior decisions.
|
|
71
71
|
|
|
72
|
-
## 4. Spawn gsd-researcher Agent
|
|
72
|
+
## 4. Spawn gsd-phase-researcher Agent
|
|
73
73
|
|
|
74
74
|
Research modes: ecosystem (default), feasibility, implementation, comparison.
|
|
75
75
|
|
|
@@ -107,16 +107,14 @@ For: Choosing between options, new external integration.
|
|
|
107
107
|
|
|
108
108
|
5. **Cross-verify:** Any WebSearch finding → confirm with Context7/official docs.
|
|
109
109
|
|
|
110
|
-
6. **
|
|
111
|
-
|
|
112
|
-
7. **Create DISCOVERY.md** using ~/.claude/get-shit-done/templates/discovery.md structure:
|
|
110
|
+
6. **Create DISCOVERY.md** using ~/.claude/get-shit-done/templates/discovery.md structure:
|
|
113
111
|
|
|
114
112
|
- Summary with recommendation
|
|
115
113
|
- Key findings per option
|
|
116
114
|
- Code examples from Context7
|
|
117
115
|
- Confidence level (should be MEDIUM-HIGH for Level 2)
|
|
118
116
|
|
|
119
|
-
|
|
117
|
+
7. Return to plan-phase.md.
|
|
120
118
|
|
|
121
119
|
**Output:** `.planning/phases/XX-name/DISCOVERY.md`
|
|
122
120
|
</step>
|
|
@@ -160,18 +158,16 @@ For: Architectural decisions, novel problems, high-risk choices.
|
|
|
160
158
|
- Mark what's verified vs assumed
|
|
161
159
|
- Flag contradictions
|
|
162
160
|
|
|
163
|
-
6. **
|
|
164
|
-
|
|
165
|
-
7. **Create comprehensive DISCOVERY.md:**
|
|
161
|
+
6. **Create comprehensive DISCOVERY.md:**
|
|
166
162
|
|
|
167
163
|
- Full structure from ~/.claude/get-shit-done/templates/discovery.md
|
|
168
164
|
- Quality report with source attribution
|
|
169
165
|
- Confidence by finding
|
|
170
166
|
- If LOW confidence on any critical finding → add validation checkpoints
|
|
171
167
|
|
|
172
|
-
|
|
168
|
+
7. **Confidence gate:** If overall confidence is LOW, present options before proceeding.
|
|
173
169
|
|
|
174
|
-
|
|
170
|
+
8. Return to plan-phase.md.
|
|
175
171
|
|
|
176
172
|
**Output:** `.planning/phases/XX-name/DISCOVERY.md` (comprehensive)
|
|
177
173
|
</step>
|
|
@@ -4,6 +4,8 @@ Execute a phase prompt (PLAN.md) and create the outcome summary (SUMMARY.md).
|
|
|
4
4
|
|
|
5
5
|
<required_reading>
|
|
6
6
|
Read STATE.md before any operation to load project context.
|
|
7
|
+
|
|
8
|
+
@~/.claude/get-shit-done/references/git-integration.md
|
|
7
9
|
</required_reading>
|
|
8
10
|
|
|
9
11
|
<process>
|
|
@@ -1574,7 +1576,7 @@ lmn012o feat(08-02): create user registration endpoint
|
|
|
1574
1576
|
|
|
1575
1577
|
Each task has its own commit, followed by one metadata commit documenting plan completion.
|
|
1576
1578
|
|
|
1577
|
-
|
|
1579
|
+
See `git-integration.md` (loaded via required_reading) for commit message conventions.
|
|
1578
1580
|
</step>
|
|
1579
1581
|
|
|
1580
1582
|
<step name="update_codebase_map">
|
|
@@ -13,6 +13,10 @@ Enables seamless session continuity for fully autonomous workflows.
|
|
|
13
13
|
"Where were we?" should have an immediate, complete answer.
|
|
14
14
|
</purpose>
|
|
15
15
|
|
|
16
|
+
<required_reading>
|
|
17
|
+
@~/.claude/get-shit-done/references/continuation-format.md
|
|
18
|
+
</required_reading>
|
|
19
|
+
|
|
16
20
|
<process>
|
|
17
21
|
|
|
18
22
|
<step name="detect_existing_project">
|
|
@@ -18,9 +18,8 @@ Then verify each level against the actual codebase.
|
|
|
18
18
|
</core_principle>
|
|
19
19
|
|
|
20
20
|
<required_reading>
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
- ~/.claude/get-shit-done/templates/verification-report.md (output format)
|
|
21
|
+
@~/.claude/get-shit-done/references/verification-patterns.md
|
|
22
|
+
@~/.claude/get-shit-done/templates/verification-report.md
|
|
24
23
|
</required_reading>
|
|
25
24
|
|
|
26
25
|
<process>
|
|
@@ -17,7 +17,7 @@ if (!fs.existsSync(cacheDir)) {
|
|
|
17
17
|
fs.mkdirSync(cacheDir, { recursive: true });
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
// Run check in background (spawn
|
|
20
|
+
// Run check in background (spawn background process, windowsHide prevents console flash)
|
|
21
21
|
const child = spawn(process.execPath, ['-e', `
|
|
22
22
|
const fs = require('fs');
|
|
23
23
|
const { execSync } = require('child_process');
|
|
@@ -32,7 +32,7 @@ const child = spawn(process.execPath, ['-e', `
|
|
|
32
32
|
|
|
33
33
|
let latest = null;
|
|
34
34
|
try {
|
|
35
|
-
latest = execSync('npm view get-shit-done-cc version', { encoding: 'utf8', timeout: 10000 }).trim();
|
|
35
|
+
latest = execSync('npm view get-shit-done-cc version', { encoding: 'utf8', timeout: 10000, windowsHide: true }).trim();
|
|
36
36
|
} catch (e) {}
|
|
37
37
|
|
|
38
38
|
const result = {
|
|
@@ -44,8 +44,8 @@ const child = spawn(process.execPath, ['-e', `
|
|
|
44
44
|
|
|
45
45
|
fs.writeFileSync(cacheFile, JSON.stringify(result));
|
|
46
46
|
`], {
|
|
47
|
-
|
|
48
|
-
|
|
47
|
+
stdio: 'ignore',
|
|
48
|
+
windowsHide: true
|
|
49
49
|
});
|
|
50
50
|
|
|
51
51
|
child.unref();
|
package/hooks/statusline.js
CHANGED
|
@@ -22,7 +22,7 @@ process.stdin.on('end', () => {
|
|
|
22
22
|
let ctx = '';
|
|
23
23
|
if (remaining != null) {
|
|
24
24
|
const rem = Math.round(remaining);
|
|
25
|
-
const used = 100 - rem;
|
|
25
|
+
const used = Math.max(0, Math.min(100, 100 - rem));
|
|
26
26
|
|
|
27
27
|
// Build progress bar (10 segments)
|
|
28
28
|
const filled = Math.floor(used / 10);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "get-shit-done-cc",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.0",
|
|
4
4
|
"description": "A meta-prompting, context engineering and spec-driven development system for Claude Code by TÂCHES.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"get-shit-done-cc": "bin/install.js"
|
|
@@ -26,6 +26,10 @@
|
|
|
26
26
|
"type": "git",
|
|
27
27
|
"url": "git+https://github.com/glittercowboy/get-shit-done.git"
|
|
28
28
|
},
|
|
29
|
+
"homepage": "https://github.com/glittercowboy/get-shit-done",
|
|
30
|
+
"bugs": {
|
|
31
|
+
"url": "https://github.com/glittercowboy/get-shit-done/issues"
|
|
32
|
+
},
|
|
29
33
|
"engines": {
|
|
30
34
|
"node": ">=16.7.0"
|
|
31
35
|
}
|