feat(auto-advance): chain phase execution across full milestone
Wire execute-phase to invoke transition.md inline when --auto flag or workflow.auto_advance config is set, propagate --auto through transition to next phase invocations, add config-get command to gsd-tools, and fix broken "config get" calls to use hyphenated "config-get" subcommand. Closes #344 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -692,6 +692,42 @@ function cmdConfigSet(cwd, keyPath, value, raw) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function cmdConfigGet(cwd, keyPath, raw) {
|
||||||
|
const configPath = path.join(cwd, '.planning', 'config.json');
|
||||||
|
|
||||||
|
if (!keyPath) {
|
||||||
|
error('Usage: config-get <key.path>');
|
||||||
|
}
|
||||||
|
|
||||||
|
let config = {};
|
||||||
|
try {
|
||||||
|
if (fs.existsSync(configPath)) {
|
||||||
|
config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
|
||||||
|
} else {
|
||||||
|
error('No config.json found at ' + configPath);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
if (err.message.startsWith('No config.json')) throw err;
|
||||||
|
error('Failed to read config.json: ' + err.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Traverse dot-notation path (e.g., "workflow.auto_advance")
|
||||||
|
const keys = keyPath.split('.');
|
||||||
|
let current = config;
|
||||||
|
for (const key of keys) {
|
||||||
|
if (current === undefined || current === null || typeof current !== 'object') {
|
||||||
|
error(`Key not found: ${keyPath}`);
|
||||||
|
}
|
||||||
|
current = current[key];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (current === undefined) {
|
||||||
|
error(`Key not found: ${keyPath}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
output(current, raw, String(current));
|
||||||
|
}
|
||||||
|
|
||||||
function cmdHistoryDigest(cwd, raw) {
|
function cmdHistoryDigest(cwd, raw) {
|
||||||
const phasesDir = path.join(cwd, '.planning', 'phases');
|
const phasesDir = path.join(cwd, '.planning', 'phases');
|
||||||
const digest = { phases: {}, decisions: [], tech_stack: new Set() };
|
const digest = { phases: {}, decisions: [], tech_stack: new Set() };
|
||||||
@@ -4999,6 +5035,11 @@ async function main() {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 'config-get': {
|
||||||
|
cmdConfigGet(cwd, args[1], raw);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case 'history-digest': {
|
case 'history-digest': {
|
||||||
cmdHistoryDigest(cwd, raw);
|
cmdHistoryDigest(cwd, raw);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -417,7 +417,7 @@ Check for auto-advance trigger:
|
|||||||
1. Parse `--auto` flag from $ARGUMENTS
|
1. Parse `--auto` flag from $ARGUMENTS
|
||||||
2. Read `workflow.auto_advance` from config:
|
2. Read `workflow.auto_advance` from config:
|
||||||
```bash
|
```bash
|
||||||
AUTO_CFG=$(node ~/.claude/get-shit-done/bin/gsd-tools.cjs config get workflow.auto_advance 2>/dev/null || echo "false")
|
AUTO_CFG=$(node ~/.claude/get-shit-done/bin/gsd-tools.cjs config-get workflow.auto_advance 2>/dev/null || echo "false")
|
||||||
```
|
```
|
||||||
|
|
||||||
**If `--auto` flag present OR `AUTO_CFG` is true:**
|
**If `--auto` flag present OR `AUTO_CFG` is true:**
|
||||||
|
|||||||
@@ -359,11 +359,32 @@ node ~/.claude/get-shit-done/bin/gsd-tools.cjs commit "docs(phase-{X}): complete
|
|||||||
|
|
||||||
<step name="offer_next">
|
<step name="offer_next">
|
||||||
|
|
||||||
**Routing is handled by `transition.md`** — do NOT emit a separate "Next Up" block here.
|
**Exception:** If `gaps_found`, the `verify_phase_goal` step already presents the gap-closure path (`/gsd:plan-phase {X} --gaps`). No additional routing needed — skip auto-advance.
|
||||||
|
|
||||||
After `verify_phase_goal` passes (or human approves), the workflow ends. The user runs `/gsd:progress` or the transition workflow handles next-step routing.
|
**Auto-advance detection:**
|
||||||
|
|
||||||
**Exception:** If `gaps_found`, the `verify_phase_goal` step already presents the gap-closure path (`/gsd:plan-phase {X} --gaps`). No additional routing needed.
|
1. Parse `--auto` flag from $ARGUMENTS
|
||||||
|
2. Read `workflow.auto_advance` from config:
|
||||||
|
```bash
|
||||||
|
AUTO_CFG=$(node ~/.claude/get-shit-done/bin/gsd-tools.cjs config-get workflow.auto_advance 2>/dev/null || echo "false")
|
||||||
|
```
|
||||||
|
|
||||||
|
**If `--auto` flag present OR `AUTO_CFG` is true (AND verification passed with no gaps):**
|
||||||
|
|
||||||
|
```
|
||||||
|
╔══════════════════════════════════════════╗
|
||||||
|
║ AUTO-ADVANCING → TRANSITION ║
|
||||||
|
║ Phase {X} verified, continuing chain ║
|
||||||
|
╚══════════════════════════════════════════╝
|
||||||
|
```
|
||||||
|
|
||||||
|
Execute the transition workflow inline (do NOT use Task — orchestrator context is ~10-15%, transition needs phase completion data already in context):
|
||||||
|
|
||||||
|
Read and follow `~/.claude/get-shit-done/workflows/transition.md`, passing through the `--auto` flag so it propagates to the next phase invocation.
|
||||||
|
|
||||||
|
**If neither `--auto` nor `AUTO_CFG` is true:**
|
||||||
|
|
||||||
|
The workflow ends. The user runs `/gsd:progress` or invokes the transition workflow manually.
|
||||||
</step>
|
</step>
|
||||||
|
|
||||||
</process>
|
</process>
|
||||||
|
|||||||
@@ -336,7 +336,7 @@ Check for auto-advance trigger:
|
|||||||
1. Parse `--auto` flag from $ARGUMENTS
|
1. Parse `--auto` flag from $ARGUMENTS
|
||||||
2. Read `workflow.auto_advance` from config:
|
2. Read `workflow.auto_advance` from config:
|
||||||
```bash
|
```bash
|
||||||
AUTO_CFG=$(node ~/.claude/get-shit-done/bin/gsd-tools.cjs config get workflow.auto_advance 2>/dev/null || echo "false")
|
AUTO_CFG=$(node ~/.claude/get-shit-done/bin/gsd-tools.cjs config-get workflow.auto_advance 2>/dev/null || echo "false")
|
||||||
```
|
```
|
||||||
|
|
||||||
**If `--auto` flag present OR `AUTO_CFG` is true:**
|
**If `--auto` flag present OR `AUTO_CFG` is true:**
|
||||||
|
|||||||
@@ -378,7 +378,7 @@ Next: Phase [X+1] — [Name]
|
|||||||
⚡ Auto-continuing: Plan Phase [X+1] in detail
|
⚡ Auto-continuing: Plan Phase [X+1] in detail
|
||||||
```
|
```
|
||||||
|
|
||||||
Exit skill and invoke SlashCommand("/gsd:plan-phase [X+1]")
|
Exit skill and invoke SlashCommand("/gsd:plan-phase [X+1] --auto")
|
||||||
|
|
||||||
**If CONTEXT.md does NOT exist:**
|
**If CONTEXT.md does NOT exist:**
|
||||||
|
|
||||||
@@ -390,7 +390,7 @@ Next: Phase [X+1] — [Name]
|
|||||||
⚡ Auto-continuing: Discuss Phase [X+1] first
|
⚡ Auto-continuing: Discuss Phase [X+1] first
|
||||||
```
|
```
|
||||||
|
|
||||||
Exit skill and invoke SlashCommand("/gsd:discuss-phase [X+1]")
|
Exit skill and invoke SlashCommand("/gsd:discuss-phase [X+1] --auto")
|
||||||
|
|
||||||
</if>
|
</if>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user