mirror of
https://github.com/glittercowboy/get-shit-done
synced 2026-04-25 17:25:23 +02:00
When a phase completes, the offer_next step now checks whether CONTEXT.md already exists for the next phase before presenting options. - If CONTEXT.md is absent: /gsd-discuss-phase is the recommended first step - If CONTEXT.md exists: /gsd-plan-phase is the recommended first step Adds regression test asserting conditional routing is present. Closes #2002 Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
87 lines
3.7 KiB
JavaScript
87 lines
3.7 KiB
JavaScript
/**
|
|
* Regression tests for bug #2002
|
|
*
|
|
* offer_next in execute-phase.md must present conditional next steps
|
|
* based on whether CONTEXT.md already exists for the next phase.
|
|
* The previous flat list offered all options equally with no primary
|
|
* recommendation, leaving agents without guidance on the correct first step.
|
|
*
|
|
* Fixed: offer_next now checks for {next}-CONTEXT.md in the phase directory.
|
|
* - If CONTEXT.md is missing: primary suggestion is /gsd-discuss-phase
|
|
* - If CONTEXT.md exists: primary suggestion is /gsd-plan-phase
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
const { describe, test } = require('node:test');
|
|
const assert = require('node:assert/strict');
|
|
const fs = require('node:fs');
|
|
const path = require('node:path');
|
|
|
|
const workflowPath = path.resolve(
|
|
__dirname, '..', 'get-shit-done', 'workflows', 'execute-phase.md'
|
|
);
|
|
|
|
describe('bug #2002: offer_next checks CONTEXT.md before suggesting next step', () => {
|
|
let content;
|
|
|
|
// Read once — all tests share the same file content
|
|
test('setup: workflow file is readable', () => {
|
|
content = fs.readFileSync(workflowPath, 'utf-8');
|
|
assert.ok(content.length > 0, 'execute-phase.md must not be empty');
|
|
});
|
|
|
|
test('offer_next section checks for CONTEXT.md existence', () => {
|
|
content = content || fs.readFileSync(workflowPath, 'utf-8');
|
|
// The workflow must check for CONTEXT.md in the next phase directory
|
|
assert.ok(
|
|
content.includes('CONTEXT.md'),
|
|
'offer_next must reference CONTEXT.md to determine primary next step'
|
|
);
|
|
});
|
|
|
|
test('offer_next presents /gsd-discuss-phase when CONTEXT.md does not exist', () => {
|
|
content = content || fs.readFileSync(workflowPath, 'utf-8');
|
|
// Must have a conditional path where discuss-phase is the primary step
|
|
// when CONTEXT.md is missing — look for proximity of "not exist"/"missing"/
|
|
// "does not exist" and "gsd-discuss-phase" in the offer_next step
|
|
const offerNextIdx = content.indexOf('offer_next');
|
|
assert.ok(offerNextIdx !== -1, 'offer_next step must exist');
|
|
|
|
// Use 5000-char window — the step is ~60 lines of prose before the conditionals
|
|
const offerNextSection = content.slice(offerNextIdx, offerNextIdx + 5000);
|
|
assert.ok(
|
|
/CONTEXT\.md.*does not exist|CONTEXT\.md.*not.*exist|If CONTEXT\.md does/i.test(offerNextSection) ||
|
|
/gsd-discuss-phase.*recommended|recommended.*gsd-discuss-phase/i.test(offerNextSection),
|
|
'offer_next must present /gsd-discuss-phase as primary when CONTEXT.md does not exist'
|
|
);
|
|
});
|
|
|
|
test('offer_next presents /gsd-plan-phase when CONTEXT.md exists', () => {
|
|
content = content || fs.readFileSync(workflowPath, 'utf-8');
|
|
const offerNextIdx = content.indexOf('offer_next');
|
|
assert.ok(offerNextIdx !== -1, 'offer_next step must exist');
|
|
|
|
const offerNextSection = content.slice(offerNextIdx, offerNextIdx + 5000);
|
|
assert.ok(
|
|
/CONTEXT\.md.*exists|exists.*CONTEXT\.md|If CONTEXT\.md/i.test(offerNextSection),
|
|
'offer_next must present /gsd-plan-phase as primary when CONTEXT.md exists'
|
|
);
|
|
});
|
|
|
|
test('offer_next section contains at least one conditional guard before listing commands', () => {
|
|
content = content || fs.readFileSync(workflowPath, 'utf-8');
|
|
const offerNextIdx = content.indexOf('offer_next');
|
|
assert.ok(offerNextIdx !== -1, 'offer_next step must exist');
|
|
|
|
const offerNextSection = content.slice(offerNextIdx, offerNextIdx + 5000);
|
|
|
|
// The fixed version must contain at least one "If CONTEXT.md" conditional
|
|
// guard before presenting command options. The old flat list had no guard.
|
|
assert.ok(
|
|
/If CONTEXT\.md/i.test(offerNextSection),
|
|
'offer_next must contain at least one "If CONTEXT.md" conditional guard'
|
|
);
|
|
});
|
|
});
|