feat: expose tdd_mode in init JSON and add --tdd flag override (#2124)
* test(2123): add failing tests for TDD init JSON exposure and --tdd flag Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat(2123): expose tdd_mode in init JSON and add --tdd flag override Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
---
|
||||
name: gsd:execute-phase
|
||||
description: Execute all plans in a phase with wave-based parallelization
|
||||
argument-hint: "<phase-number> [--wave N] [--gaps-only] [--interactive]"
|
||||
argument-hint: "<phase-number> [--wave N] [--gaps-only] [--interactive] [--tdd]"
|
||||
allowed-tools:
|
||||
- Read
|
||||
- Write
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
name: gsd:plan-phase
|
||||
description: Create detailed phase plan (PLAN.md) with verification loop
|
||||
argument-hint: "[phase] [--auto] [--research] [--skip-research] [--gaps] [--skip-verify] [--prd <file>] [--reviews] [--text]"
|
||||
argument-hint: "[phase] [--auto] [--research] [--skip-research] [--gaps] [--skip-verify] [--prd <file>] [--reviews] [--text] [--tdd]"
|
||||
agent: gsd-planner
|
||||
allowed-tools:
|
||||
- Read
|
||||
|
||||
@@ -807,13 +807,13 @@ async function runCommand(command, args, cwd, raw, defaultValue) {
|
||||
const workflow = args[1];
|
||||
switch (workflow) {
|
||||
case 'execute-phase': {
|
||||
const { validate: epValidate } = parseNamedArgs(args, [], ['validate']);
|
||||
init.cmdInitExecutePhase(cwd, args[2], raw, { validate: epValidate });
|
||||
const { validate: epValidate, tdd: epTdd } = parseNamedArgs(args, [], ['validate', 'tdd']);
|
||||
init.cmdInitExecutePhase(cwd, args[2], raw, { validate: epValidate, tdd: epTdd });
|
||||
break;
|
||||
}
|
||||
case 'plan-phase': {
|
||||
const { validate: ppValidate } = parseNamedArgs(args, [], ['validate']);
|
||||
init.cmdInitPlanPhase(cwd, args[2], raw, { validate: ppValidate });
|
||||
const { validate: ppValidate, tdd: ppTdd } = parseNamedArgs(args, [], ['validate', 'tdd']);
|
||||
init.cmdInitPlanPhase(cwd, args[2], raw, { validate: ppValidate, tdd: ppTdd });
|
||||
break;
|
||||
}
|
||||
case 'new-project':
|
||||
|
||||
@@ -375,6 +375,7 @@ function loadConfig(cwd) {
|
||||
brave_search: get('brave_search') ?? defaults.brave_search,
|
||||
firecrawl: get('firecrawl') ?? defaults.firecrawl,
|
||||
exa_search: get('exa_search') ?? defaults.exa_search,
|
||||
tdd_mode: get('tdd_mode', { section: 'workflow', field: 'tdd_mode' }) ?? false,
|
||||
text_mode: get('text_mode', { section: 'workflow', field: 'text_mode' }) ?? defaults.text_mode,
|
||||
sub_repos: get('sub_repos', { section: 'planning', field: 'sub_repos' }) ?? defaults.sub_repos,
|
||||
resolve_model_ids: get('resolve_model_ids') ?? defaults.resolve_model_ids,
|
||||
|
||||
@@ -88,6 +88,7 @@ function cmdInitExecutePhase(cwd, phase, raw, options = {}) {
|
||||
verifier_model: resolveModelInternal(cwd, 'gsd-verifier'),
|
||||
|
||||
// Config flags
|
||||
tdd_mode: options.tdd || config.tdd_mode || false,
|
||||
commit_docs: config.commit_docs,
|
||||
sub_repos: config.sub_repos,
|
||||
parallelization: config.parallelization,
|
||||
@@ -211,6 +212,7 @@ function cmdInitPlanPhase(cwd, phase, raw, options = {}) {
|
||||
checker_model: resolveModelInternal(cwd, 'gsd-plan-checker'),
|
||||
|
||||
// Workflow flags
|
||||
tdd_mode: options.tdd || config.tdd_mode || false,
|
||||
research_enabled: config.research,
|
||||
plan_checker_enabled: config.plan_checker,
|
||||
nyquist_validation_enabled: config.nyquist_validation,
|
||||
|
||||
@@ -103,3 +103,111 @@ describe('workflow.tdd_mode config round-trip', () => {
|
||||
assert.strictEqual(typeof config.workflow.tdd_mode, 'boolean');
|
||||
});
|
||||
});
|
||||
|
||||
// ─── init JSON exposure ────────────────────────────────────────────────────
|
||||
|
||||
describe('tdd_mode in init plan-phase JSON output', () => {
|
||||
let tmpDir;
|
||||
|
||||
beforeEach(() => {
|
||||
tmpDir = createTempProject();
|
||||
// Create ROADMAP.md with a phase so init plan-phase can find it
|
||||
const roadmap = [
|
||||
'# Roadmap',
|
||||
'',
|
||||
'## Phase 1 — Foundation',
|
||||
'**Status:** Planned',
|
||||
'**Requirements:** [R1]',
|
||||
].join('\n');
|
||||
fs.writeFileSync(path.join(tmpDir, '.planning', 'ROADMAP.md'), roadmap);
|
||||
// Ensure config exists
|
||||
runGsdTools('config-ensure-section', tmpDir, { HOME: tmpDir });
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
cleanup(tmpDir);
|
||||
});
|
||||
|
||||
test('init plan-phase includes tdd_mode: false by default', () => {
|
||||
const result = runGsdTools('init plan-phase 1', tmpDir);
|
||||
assert.ok(result.success, `init plan-phase failed: ${result.error}`);
|
||||
const json = JSON.parse(result.output);
|
||||
assert.strictEqual(json.tdd_mode, false);
|
||||
});
|
||||
|
||||
test('init plan-phase --tdd overrides to tdd_mode: true', () => {
|
||||
const result = runGsdTools('init plan-phase 1 --tdd', tmpDir);
|
||||
assert.ok(result.success, `init plan-phase --tdd failed: ${result.error}`);
|
||||
const json = JSON.parse(result.output);
|
||||
assert.strictEqual(json.tdd_mode, true);
|
||||
});
|
||||
|
||||
test('config workflow.tdd_mode: true surfaces in init plan-phase without flag', () => {
|
||||
runGsdTools('config-set workflow.tdd_mode true', tmpDir);
|
||||
const result = runGsdTools('init plan-phase 1', tmpDir);
|
||||
assert.ok(result.success, `init plan-phase failed: ${result.error}`);
|
||||
const json = JSON.parse(result.output);
|
||||
assert.strictEqual(json.tdd_mode, true);
|
||||
});
|
||||
|
||||
test('--tdd flag overrides config value of false', () => {
|
||||
runGsdTools('config-set workflow.tdd_mode false', tmpDir);
|
||||
const result = runGsdTools('init plan-phase 1 --tdd', tmpDir);
|
||||
assert.ok(result.success, `init plan-phase --tdd failed: ${result.error}`);
|
||||
const json = JSON.parse(result.output);
|
||||
assert.strictEqual(json.tdd_mode, true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('tdd_mode in init execute-phase JSON output', () => {
|
||||
let tmpDir;
|
||||
|
||||
beforeEach(() => {
|
||||
tmpDir = createTempProject();
|
||||
// Create ROADMAP.md with a phase so init execute-phase can find it
|
||||
const roadmap = [
|
||||
'# Roadmap',
|
||||
'',
|
||||
'## Phase 1 — Foundation',
|
||||
'**Status:** Planned',
|
||||
'**Requirements:** [R1]',
|
||||
].join('\n');
|
||||
fs.writeFileSync(path.join(tmpDir, '.planning', 'ROADMAP.md'), roadmap);
|
||||
// Ensure config exists
|
||||
runGsdTools('config-ensure-section', tmpDir, { HOME: tmpDir });
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
cleanup(tmpDir);
|
||||
});
|
||||
|
||||
test('init execute-phase includes tdd_mode: false by default', () => {
|
||||
const result = runGsdTools('init execute-phase 1', tmpDir);
|
||||
assert.ok(result.success, `init execute-phase failed: ${result.error}`);
|
||||
const json = JSON.parse(result.output);
|
||||
assert.strictEqual(json.tdd_mode, false);
|
||||
});
|
||||
|
||||
test('init execute-phase --tdd overrides to tdd_mode: true', () => {
|
||||
const result = runGsdTools('init execute-phase 1 --tdd', tmpDir);
|
||||
assert.ok(result.success, `init execute-phase --tdd failed: ${result.error}`);
|
||||
const json = JSON.parse(result.output);
|
||||
assert.strictEqual(json.tdd_mode, true);
|
||||
});
|
||||
|
||||
test('config workflow.tdd_mode: true surfaces in init execute-phase without flag', () => {
|
||||
runGsdTools('config-set workflow.tdd_mode true', tmpDir);
|
||||
const result = runGsdTools('init execute-phase 1', tmpDir);
|
||||
assert.ok(result.success, `init execute-phase failed: ${result.error}`);
|
||||
const json = JSON.parse(result.output);
|
||||
assert.strictEqual(json.tdd_mode, true);
|
||||
});
|
||||
|
||||
test('--tdd flag overrides config value of false', () => {
|
||||
runGsdTools('config-set workflow.tdd_mode false', tmpDir);
|
||||
const result = runGsdTools('init execute-phase 1 --tdd', tmpDir);
|
||||
assert.ok(result.success, `init execute-phase --tdd failed: ${result.error}`);
|
||||
const json = JSON.parse(result.output);
|
||||
assert.strictEqual(json.tdd_mode, true);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user