diff --git a/get-shit-done/workflows/autonomous.md b/get-shit-done/workflows/autonomous.md index 390298ad..b6e1f644 100644 --- a/get-shit-done/workflows/autonomous.md +++ b/get-shit-done/workflows/autonomous.md @@ -219,6 +219,45 @@ PHASE_STATE=$(node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" init phase-op Check `has_context`. If false → go to handle_blocker: "Smart discuss for phase ${PHASE_NUM} did not produce CONTEXT.md." +**3a.5. UI Design Contract (Frontend Phases)** + +Check if this phase has frontend indicators and whether a UI-SPEC already exists: + +```bash +PHASE_SECTION=$(node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" roadmap get-phase ${PHASE_NUM} 2>/dev/null) +echo "$PHASE_SECTION" | grep -iE "UI|interface|frontend|component|layout|page|screen|view|form|dashboard|widget" > /dev/null 2>&1 +HAS_UI=$? +UI_SPEC_FILE=$(ls "${PHASE_DIR}"/*-UI-SPEC.md 2>/dev/null | head -1) +``` + +Check if UI phase workflow is enabled: + +```bash +UI_PHASE_CFG=$(node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" config-get workflow.ui_phase 2>/dev/null || echo "true") +``` + +**If `HAS_UI` is 0 (frontend indicators found) AND `UI_SPEC_FILE` is empty (no UI-SPEC exists) AND `UI_PHASE_CFG` is not `false`:** + +Display: + +``` +Phase ${PHASE_NUM}: Frontend phase detected — generating UI design contract... +``` + +``` +Skill(skill="gsd:ui-phase", args="${PHASE_NUM}") +``` + +Verify UI-SPEC was created: + +```bash +UI_SPEC_FILE=$(ls "${PHASE_DIR}"/*-UI-SPEC.md 2>/dev/null | head -1) +``` + +**If `UI_SPEC_FILE` is still empty after ui-phase:** Display warning `Phase ${PHASE_NUM}: UI-SPEC generation did not produce output — continuing without design contract.` and proceed to 3b. + +**If `HAS_UI` is 1 (no frontend indicators) OR `UI_SPEC_FILE` is not empty (UI-SPEC already exists) OR `UI_PHASE_CFG` is `false`:** Skip silently to 3b. + **3b. Plan** ``` @@ -325,6 +364,38 @@ On **"Continue without fixing"**: Display `Phase ${PHASE_NUM} ⏭ Gaps deferred` On **"Stop autonomous mode"**: Go to handle_blocker with "User stopped — gaps remain in phase ${PHASE_NUM}". +**3d.5. UI Review (Frontend Phases)** + +> Run after any successful execution routing (passed, human_needed accepted, or gaps deferred/accepted) — before proceeding to the iterate step. + +Check if this phase had a UI-SPEC (created in step 3a.5 or pre-existing): + +```bash +UI_SPEC_FILE=$(ls "${PHASE_DIR}"/*-UI-SPEC.md 2>/dev/null | head -1) +``` + +Check if UI review is enabled: + +```bash +UI_REVIEW_CFG=$(node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" config-get workflow.ui_review 2>/dev/null || echo "true") +``` + +**If `UI_SPEC_FILE` is not empty AND `UI_REVIEW_CFG` is not `false`:** + +Display: + +``` +Phase ${PHASE_NUM}: Frontend phase with UI-SPEC — running UI review audit... +``` + +``` +Skill(skill="gsd:ui-review", args="${PHASE_NUM}") +``` + +Display the review result summary (score from UI-REVIEW.md if produced). Continue to iterate step regardless of score — UI review is advisory, not blocking. + +**If `UI_SPEC_FILE` is empty OR `UI_REVIEW_CFG` is `false`:** Skip silently to iterate step. + @@ -789,7 +860,7 @@ When any phase operation fails or a blocker is detected, present 3 options via A -- [ ] All incomplete phases executed in order (smart discuss → plan → execute each) +- [ ] All incomplete phases executed in order (smart discuss → ui-phase → plan → execute → ui-review each) - [ ] Smart discuss proposes grey area answers in tables, user accepts or overrides per area - [ ] Progress banners displayed between phases - [ ] Execute-phase invoked with --no-transition (autonomous manages transitions) @@ -813,4 +884,8 @@ When any phase operation fails or a blocker is detected, present 3 options via A - [ ] Final completion banner displayed after lifecycle - [ ] Progress bar uses phase number / total milestone phases (not position among incomplete) - [ ] Smart discuss documents relationship to discuss-phase with CTRL-03 note +- [ ] Frontend phases get UI-SPEC generated before planning (step 3a.5) if not already present +- [ ] Frontend phases get UI review audit after successful execution (step 3d.5) if UI-SPEC exists +- [ ] UI phase and UI review respect workflow.ui_phase and workflow.ui_review config toggles +- [ ] UI review is advisory (non-blocking) — phase proceeds to iterate regardless of score diff --git a/tests/autonomous-ui-steps.test.cjs b/tests/autonomous-ui-steps.test.cjs new file mode 100644 index 00000000..c32cf907 --- /dev/null +++ b/tests/autonomous-ui-steps.test.cjs @@ -0,0 +1,143 @@ +/** + * Tests that autonomous.md includes ui-phase and ui-review steps for frontend phases. + * + * Issue #1375: autonomous workflow skips ui-phase and ui-review for frontend phases. + * The per-phase execution loop should be: discuss -> ui-phase -> plan -> execute -> verify -> ui-review + * for phases with frontend indicators. + */ + +const { describe, it, test, beforeEach } = require('node:test'); +const assert = require('node:assert/strict'); +const fs = require('fs'); +const path = require('path'); + +const WORKFLOW_PATH = path.join(__dirname, '..', 'get-shit-done', 'workflows', 'autonomous.md'); + +describe('autonomous workflow ui-phase and ui-review integration (#1375)', () => { + let content; + + beforeEach(() => { + assert.ok(fs.existsSync(WORKFLOW_PATH), 'workflows/autonomous.md should exist'); + content = fs.readFileSync(WORKFLOW_PATH, 'utf-8'); + }); + + describe('step 3a.5 — UI design contract before planning', () => { + test('autonomous.md contains a UI design contract step between discuss and plan', () => { + assert.ok( + content.includes('3a.5'), + 'should have step 3a.5 for UI design contract' + ); + }); + + test('UI design contract step detects frontend indicators via grep pattern', () => { + // Same grep pattern as plan-phase step 5.6 + assert.ok( + content.includes('grep -iE "UI|interface|frontend|component|layout|page|screen|view|form|dashboard|widget"'), + 'should use the same frontend detection grep pattern as plan-phase step 5.6' + ); + }); + + test('UI design contract step checks for existing UI-SPEC.md', () => { + assert.ok( + content.includes('UI-SPEC.md'), + 'should check for existing UI-SPEC.md' + ); + }); + + test('UI design contract step respects workflow.ui_phase config toggle', () => { + assert.ok( + content.includes('workflow.ui_phase'), + 'should respect workflow.ui_phase config toggle' + ); + }); + + test('UI design contract step invokes gsd:ui-phase skill', () => { + assert.ok( + content.includes('skill="gsd:ui-phase"'), + 'should invoke gsd:ui-phase via Skill()' + ); + }); + + test('UI design contract step appears before plan step (3b)', () => { + const uiPhasePos = content.indexOf('3a.5'); + const planPos = content.indexOf('**3b. Plan**'); + assert.ok( + uiPhasePos < planPos, + 'step 3a.5 (UI design contract) should appear before step 3b (plan)' + ); + }); + }); + + describe('step 3d.5 — UI review after execution', () => { + test('autonomous.md contains a UI review step after execution', () => { + assert.ok( + content.includes('3d.5'), + 'should have step 3d.5 for UI review' + ); + }); + + test('UI review step checks for UI-SPEC existence before running', () => { + // The UI review should only run if a UI-SPEC was created/exists + const reviewSection = content.slice(content.indexOf('3d.5')); + assert.ok( + reviewSection.includes('UI_SPEC_FILE'), + 'UI review step should check for UI-SPEC file existence' + ); + }); + + test('UI review step respects workflow.ui_review config toggle', () => { + assert.ok( + content.includes('workflow.ui_review'), + 'should respect workflow.ui_review config toggle' + ); + }); + + test('UI review step invokes gsd:ui-review skill', () => { + assert.ok( + content.includes('skill="gsd:ui-review"'), + 'should invoke gsd:ui-review via Skill()' + ); + }); + + test('UI review is advisory (non-blocking)', () => { + const reviewSection = content.slice(content.indexOf('3d.5')); + assert.ok( + reviewSection.includes('advisory') || reviewSection.includes('non-blocking') || reviewSection.includes('regardless of score'), + 'UI review should be advisory and not block phase progression' + ); + }); + + test('UI review step appears after execution routing (3d)', () => { + const executeRouting = content.indexOf('**3d. Post-Execution Routing**'); + const uiReviewPos = content.indexOf('3d.5'); + assert.ok( + uiReviewPos > executeRouting, + 'step 3d.5 (UI review) should appear after step 3d (post-execution routing)' + ); + }); + }); + + describe('success criteria updated', () => { + test('success criteria includes UI-aware flow', () => { + assert.ok( + content.includes('ui-phase') && content.includes('ui-review'), + 'success criteria should reference ui-phase and ui-review' + ); + }); + + test('success criteria mentions frontend phases get UI-SPEC before planning', () => { + assert.ok( + content.includes('Frontend phases') || content.includes('frontend phases'), + 'success criteria should mention frontend phases' + ); + }); + + test('success criteria notes UI review is advisory', () => { + const criteriaSection = content.slice(content.indexOf('')); + assert.ok( + criteriaSection.includes('advisory') || criteriaSection.includes('non-blocking'), + 'success criteria should note UI review is advisory/non-blocking' + ); + }); + }); +});