mirror of
https://github.com/glittercowboy/get-shit-done
synced 2026-04-25 17:25:23 +02:00
Merge pull request #1385 from gsd-build/fix/autonomous-ui-phase-1375
fix: add ui-phase and ui-review to autonomous workflow
This commit is contained in:
@@ -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.
|
||||
|
||||
</step>
|
||||
|
||||
<step name="smart_discuss">
|
||||
@@ -789,7 +860,7 @@ When any phase operation fails or a blocker is detected, present 3 options via A
|
||||
</process>
|
||||
|
||||
<success_criteria>
|
||||
- [ ] 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
|
||||
</success_criteria>
|
||||
|
||||
143
tests/autonomous-ui-steps.test.cjs
Normal file
143
tests/autonomous-ui-steps.test.cjs
Normal file
@@ -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('<success_criteria>'));
|
||||
assert.ok(
|
||||
criteriaSection.includes('advisory') || criteriaSection.includes('non-blocking'),
|
||||
'success criteria should note UI review is advisory/non-blocking'
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user