@hanzlaa/rcode 4.10.6 → 4.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +1 -1
- package/CLAUDE.md +1 -1
- package/CONTRIBUTING.md +3 -0
- package/cli/install.js +160 -0
- package/dist/rcode.js +254 -234
- package/package.json +1 -1
- package/rcode/agents/rcode-project-researcher.md +1 -1
- package/rcode/agents/rcode-ux-designer.md +1 -0
- package/rcode/agents/rcode-verifier.md +2 -2
- package/rcode/agents/rules/planner/common-patterns.md +2 -1
- package/rcode/agents/rules/planner/goal-backward-thinking.md +33 -0
- package/rcode/agents/rules/planner/sprint-verification.md +1 -0
- package/rcode/agents/rules/planner/task-templates.md +20 -1
- package/rcode/agents/rules/project-researcher/detailed-guide.md +10 -0
- package/rcode/agents/rules/sprint-checker/dimensions.md +74 -0
- package/rcode/agents/rules/sprint-checker/process.md +12 -0
- package/rcode/agents/rules/verifier/behavioral-spot-checks.md +5 -1
- package/rcode/agents/rules/verifier/gap-output.md +5 -0
- package/rcode/agents/rules/verifier/reachability-check.md +69 -0
- package/rcode/bin/rcode-tools.cjs +39 -3
- package/rcode/commands/ui-phase.md +1 -1
- package/rcode/references/design-library/LICENSE +21 -0
- package/rcode/references/design-library/README.md +37 -0
- package/rcode/references/design-library/charts.csv +26 -0
- package/rcode/references/design-library/colors.csv +97 -0
- package/rcode/references/design-library/icons.csv +101 -0
- package/rcode/references/design-library/styles.csv +68 -0
- package/rcode/references/design-library/typography.csv +58 -0
- package/rcode/references/design-library/ui-reasoning.csv +101 -0
- package/rcode/references/design-library/ux-guidelines.csv +100 -0
- package/rcode/references/design-library/web-interface.csv +31 -0
- package/rcode/references/domain-probes.md +8 -0
- package/rcode/references/project-types.yaml +29 -0
- package/rcode/references/questioning.md +3 -0
- package/rcode/references/roadmapper-playbook.md +90 -0
- package/rcode/references/sprint-checker-playbook.md +14 -0
- package/rcode/references/verifier-playbook.md +20 -7
- package/rcode/workflows/autonomous.md +26 -3
- package/rcode/workflows/complete-milestone.md +1 -1
- package/rcode/workflows/council.md +51 -6
- package/rcode/workflows/discuss-phase.md +9 -2
- package/rcode/workflows/execute-sprint.md +35 -7
- package/rcode/workflows/execute-waves.md +2 -2
- package/rcode/workflows/execute.md +21 -6
- package/rcode/workflows/help.md +1 -1
- package/rcode/workflows/plan-research-validation.md +1 -1
- package/rcode/workflows/plan.md +31 -0
- package/rcode/workflows/ship.md +22 -0
- package/rcode/workflows/ui-phase.md +104 -22
- package/rcode/workflows/ui-review.md +9 -1
- package/rcode/workflows/verify-work.md +1 -1
- package/server/lib/scanner.js +25 -4
package/rcode/workflows/ship.md
CHANGED
|
@@ -121,6 +121,17 @@ Verify the work is ready to ship:
|
|
|
121
121
|
Check for `status: passed` or `status: human_needed` (with human approval).
|
|
122
122
|
If no VERIFICATION.md or status is `gaps_found`: warn and ask user to confirm.
|
|
123
123
|
|
|
124
|
+
**If proceeding with anything other than a clean `status: passed`** (i.e.
|
|
125
|
+
`human_needed` or a user-confirmed `gaps_found`): the generated PR body
|
|
126
|
+
(step below) MUST include a `## Known Gaps` section listing every
|
|
127
|
+
unresolved human-verification item or gap from VERIFICATION.md — mirroring
|
|
128
|
+
`complete-milestone.md`'s `### Known Gaps` pattern. This is not optional
|
|
129
|
+
cosmetic detail: a PR shipped on `human_needed`/`gaps_found` without this
|
|
130
|
+
section reads to a reviewer as fully verified when it isn't. Do not rely on
|
|
131
|
+
the `## Verification` section's item list alone (below) to carry this —
|
|
132
|
+
that section is easy to skim past; `## Known Gaps` must be its own
|
|
133
|
+
clearly-labeled heading.
|
|
134
|
+
|
|
124
135
|
2. **Clean working tree?**
|
|
125
136
|
```bash
|
|
126
137
|
git status --short
|
|
@@ -215,6 +226,17 @@ For each SUMMARY.md in the phase directory:
|
|
|
215
226
|
- {human verification items from VERIFICATION.md, if any}
|
|
216
227
|
```
|
|
217
228
|
|
|
229
|
+
**5b. Known Gaps section (only when VERIFICATION.md status is not a clean `passed`):**
|
|
230
|
+
```markdown
|
|
231
|
+
## Known Gaps
|
|
232
|
+
|
|
233
|
+
This PR ships with `status: {human_needed|gaps_found}` per VERIFICATION.md, confirmed by the user in preflight.
|
|
234
|
+
|
|
235
|
+
- {gap/human-verification item 1 — file/truth + what's unconfirmed}
|
|
236
|
+
- {gap/human-verification item 2}
|
|
237
|
+
```
|
|
238
|
+
Omit this section entirely when VERIFICATION.md status is a clean `passed` with zero open items.
|
|
239
|
+
|
|
218
240
|
**6. Decisions section:**
|
|
219
241
|
```markdown
|
|
220
242
|
## Key Decisions
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
# Workflow: rcode-ui-phase
|
|
2
2
|
|
|
3
3
|
<purpose>
|
|
4
|
-
Produce UI-SPEC.md
|
|
4
|
+
Produce two artifacts before any UI code gets written: UI-SPEC.md (formalized design contract — color tokens, typography, component inventory, interaction states, accessibility requirements) and WIREFRAMES.md (per-role screen inventory — what exists, who sees it, loading/empty/error states for each). Grounds design choices in `rcode/references/design-library/` (vendored style/palette/typography/UX-rules data — see that directory's README) instead of an agent inventing tokens from nothing. Detects frontend keywords (React, Next.js, Vue, Tailwind, CSS, UI) and suggests this workflow early if UI-SPEC.md is absent.
|
|
5
5
|
</purpose>
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
## Step
|
|
8
|
+
## Step 0a — Usage check
|
|
9
9
|
|
|
10
10
|
If `$ARGUMENTS` is empty or contains only `--help` or `-h`:
|
|
11
11
|
|
|
@@ -25,7 +25,7 @@ STOP — do not proceed.
|
|
|
25
25
|
- `rcode-ux-designer` — UI specification generator
|
|
26
26
|
</available_agent_types>
|
|
27
27
|
|
|
28
|
-
## Step
|
|
28
|
+
## Step 0b — Initialize
|
|
29
29
|
|
|
30
30
|
```bash
|
|
31
31
|
INIT=$(node .rcode/bin/rcode-tools.cjs init ui-phase "$ARGUMENTS" 2>/dev/null)
|
|
@@ -41,6 +41,7 @@ Parse:
|
|
|
41
41
|
- `flags.existing_ui` — path to existing design system or Figma export
|
|
42
42
|
- `flags.design_system` — path to design tokens file
|
|
43
43
|
- `ui_spec_path` — `.rcode/UI-SPEC.md` (output location)
|
|
44
|
+
- `wireframes_path` — `.rcode/WIREFRAMES.md` (output location)
|
|
44
45
|
|
|
45
46
|
## Step 1 — Detect Existing UI Assets
|
|
46
47
|
|
|
@@ -49,12 +50,33 @@ If `flags.existing_ui` or `flags.design_system` provided:
|
|
|
49
50
|
EXISTING=$(node .rcode/bin/rcode-tools.cjs find-files --type=design-tokens)
|
|
50
51
|
```
|
|
51
52
|
|
|
52
|
-
Load existing design system, extract:
|
|
53
|
+
Load existing design system, extract into `EXISTING_DESIGN_SYSTEM_DATA` (a text block passed verbatim into Step 2's prompt):
|
|
53
54
|
- Color palette (hex, variable names)
|
|
54
55
|
- Typography scales (font family, sizes, weights, line heights)
|
|
55
56
|
- Component list (buttons, forms, layouts, modals, etc.)
|
|
56
57
|
- Interaction patterns (hover, focus, active, disabled states)
|
|
57
58
|
|
|
59
|
+
If `$EXISTING` is empty or extraction finds nothing usable, treat this the
|
|
60
|
+
same as "no existing system found" and fall through to Step 1b — don't leave
|
|
61
|
+
`EXISTING_DESIGN_SYSTEM_DATA` half-populated.
|
|
62
|
+
|
|
63
|
+
If an existing design system was found and `EXISTING_DESIGN_SYSTEM_DATA` is populated, skip Step 1b (don't override what's already decided) and go straight to Step 2.
|
|
64
|
+
|
|
65
|
+
## Step 1b — Ground the design in the reference library (no existing system found)
|
|
66
|
+
|
|
67
|
+
Don't let the agent invent a palette/style from nothing. If PROJECT.md and
|
|
68
|
+
ROADMAP.md are both missing, stop here and say so: "No PROJECT.md/ROADMAP.md
|
|
69
|
+
found — run `/rcode-new-project-research` or `/rcode-new-project-roadmap`
|
|
70
|
+
first so there's a project category to ground the design in." Otherwise look up:
|
|
71
|
+
|
|
72
|
+
1. **Category match** — grep the project's category (from PROJECT.md/ROADMAP.md — e.g. "B2B SaaS Enterprise", "Analytics Dashboard", "Fintech (Banking)") against `rcode/references/design-library/ui-reasoning.csv`'s `UI_Category` column. This returns a recommended style/color-mood/typography-mood and explicit anti-patterns to avoid — read the row, don't guess a category if none matches closely; fall back to the closest match and say so. Capture the result as `CATEGORY_MATCH`.
|
|
73
|
+
2. **Style detail** — take the recommended style name from step 1 and look it up in `styles.csv` for concrete hex values, effects, accessibility rating, and an implementation checklist. Capture as `STYLE_DETAIL`.
|
|
74
|
+
3. **UX rules** — grep `ux-guidelines.csv` for the categories relevant to this project's screens (Navigation, Forms, etc.) for concrete do/don't rules with code examples. Capture as `UX_RULES`.
|
|
75
|
+
|
|
76
|
+
`CATEGORY_MATCH` + `STYLE_DETAIL` + `UX_RULES` together are what Step 2's
|
|
77
|
+
prompt calls `DESIGN_LOOKUP_RESULT` below — assemble them into one text block
|
|
78
|
+
before spawning the agent.
|
|
79
|
+
|
|
58
80
|
## Step 2 — Spawn UI Designer
|
|
59
81
|
|
|
60
82
|
Spawn `rcode-ux-designer` subagent:
|
|
@@ -62,34 +84,80 @@ Spawn `rcode-ux-designer` subagent:
|
|
|
62
84
|
```
|
|
63
85
|
Task tool call:
|
|
64
86
|
subagent_type: "rcode-ux-designer"
|
|
65
|
-
description: "Generate UI-SPEC.md"
|
|
87
|
+
description: "Generate UI-SPEC.md and WIREFRAMES.md"
|
|
66
88
|
prompt: |
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
89
|
+
Ground every choice below in {EXISTING_DESIGN_SYSTEM_DATA if Step 1 found one, else DESIGN_LOOKUP_RESULT from Step 1b} —
|
|
90
|
+
do not invent a palette/style from nothing when reference data or an existing system exists.
|
|
91
|
+
|
|
92
|
+
Write UI-SPEC.md with:
|
|
93
|
+
1. **Design Direction** — which style/category this follows (from the reference library lookup) and why, one paragraph
|
|
94
|
+
2. **Color Tokens** — semantic variable names, hex values, accessibility contrast ratios
|
|
95
|
+
3. **Typography** — font family, scales (12px, 14px, 16px, 18px, 20px, 24px, etc.), weights, line heights
|
|
96
|
+
4. **Component Inventory** — list of UI components with property variants (size, color, state, disabled)
|
|
97
|
+
5. **Interaction States** — hover, focus, active, disabled, loading for interactive elements
|
|
98
|
+
6. **Accessibility** — WCAG 2.1 AA compliance checklist, color contrast requirements, keyboard navigation rules
|
|
99
|
+
7. **Responsive Breakpoints** — mobile, tablet, desktop breakpoints and stacking rules
|
|
100
|
+
|
|
78
101
|
Write to: {ui_spec_path}
|
|
79
102
|
```
|
|
80
103
|
|
|
104
|
+
## Step 2b — Spawn Wireframes (per-role screen inventory)
|
|
105
|
+
|
|
106
|
+
Read REQUIREMENTS.md/PROJECT.md for the project's user roles (if any) and the
|
|
107
|
+
IA decision — `roadmapper-playbook.md`'s Information Architecture step (Workflow
|
|
108
|
+
step 3b) says this is persisted as either a standalone `.planning/IA.md` or a
|
|
109
|
+
`## Information Architecture` section in ROADMAP.md, so check both locations,
|
|
110
|
+
not just ROADMAP.md. If neither has an IA decision, this step cannot produce a
|
|
111
|
+
real result — stop and say so: "No Information Architecture decision found in
|
|
112
|
+
ROADMAP.md or IA.md — the roadmapper needs to produce one first
|
|
113
|
+
(`/rcode-new-project-roadmap` for a brand-new project, `/rcode-new-milestone`
|
|
114
|
+
to regenerate the roadmap for an existing one — both invoke rcode-roadmapper,
|
|
115
|
+
which owns the IA step)."
|
|
116
|
+
|
|
117
|
+
Spawn `rcode-ux-designer` subagent (same agent, second artifact):
|
|
118
|
+
|
|
119
|
+
```
|
|
120
|
+
Task tool call:
|
|
121
|
+
subagent_type: "rcode-ux-designer"
|
|
122
|
+
description: "Generate WIREFRAMES.md"
|
|
123
|
+
prompt: |
|
|
124
|
+
For each top-level IA section and each screen it contains, write one entry:
|
|
125
|
+
|
|
126
|
+
### {Screen name} — {route/path}
|
|
127
|
+
**Roles that see it:** {role list, or "all authenticated users"}
|
|
128
|
+
**Purpose:** {one line — what the user accomplishes here}
|
|
129
|
+
**Layout:** {ASCII or textual wireframe — header/nav placement, primary content
|
|
130
|
+
area, key actions, not a pixel-perfect mockup}
|
|
131
|
+
**Required states** (do not omit any that apply):
|
|
132
|
+
- Loading: {what renders while data is fetching}
|
|
133
|
+
- Empty: {what renders when there's no data yet — never a blank screen}
|
|
134
|
+
- Error: {what renders on fetch/action failure — never a silent failure}
|
|
135
|
+
- Success/populated: {the normal case}
|
|
136
|
+
**Primary actions:** {buttons/links a user takes from here, and where they go}
|
|
137
|
+
|
|
138
|
+
Cover EVERY screen implied by the roadmap's phases, not just Phase 1's.
|
|
139
|
+
A screen with no role that can see it, or with only a "populated" state and
|
|
140
|
+
no loading/empty/error state defined, is an incomplete entry — fix it before
|
|
141
|
+
writing, don't ship the gap.
|
|
142
|
+
|
|
143
|
+
Write to: {wireframes_path}
|
|
144
|
+
```
|
|
145
|
+
|
|
81
146
|
## Step 3 — Store Reference in State
|
|
82
147
|
|
|
83
|
-
Update state with
|
|
148
|
+
Update state with both artifact locations:
|
|
84
149
|
```bash
|
|
85
150
|
node .rcode/bin/rcode-tools.cjs state set --ui-spec-path ".rcode/UI-SPEC.md"
|
|
151
|
+
node .rcode/bin/rcode-tools.cjs state set --wireframes-path ".rcode/WIREFRAMES.md"
|
|
86
152
|
```
|
|
87
153
|
|
|
88
154
|
Print:
|
|
89
155
|
```
|
|
90
156
|
✓ UI-SPEC.md generated: {ui_spec_path}
|
|
157
|
+
✓ WIREFRAMES.md generated: {wireframes_path}
|
|
91
158
|
|
|
92
|
-
|
|
159
|
+
UI-SPEC.md contains:
|
|
160
|
+
• Design Direction (grounded in design-library lookup, not invented)
|
|
93
161
|
• Color Tokens
|
|
94
162
|
• Typography System
|
|
95
163
|
• Component Inventory
|
|
@@ -97,10 +165,22 @@ Contains:
|
|
|
97
165
|
• Accessibility Checklist
|
|
98
166
|
• Responsive Breakpoints
|
|
99
167
|
|
|
100
|
-
|
|
168
|
+
WIREFRAMES.md contains:
|
|
169
|
+
• Every screen from the roadmap's IA, with role visibility
|
|
170
|
+
• Loading/empty/error/success state for each screen — no screen ships
|
|
171
|
+
without all four defined
|
|
172
|
+
|
|
173
|
+
These specs guide component development, design consistency, and give
|
|
174
|
+
sprint-checker something concrete to verify state-completeness against.
|
|
101
175
|
```
|
|
102
176
|
|
|
103
|
-
## Step 4 — Modify plan.md Detection (
|
|
177
|
+
## Step 4 — Modify plan.md Detection (one-time setup, not per-invocation)
|
|
178
|
+
|
|
179
|
+
This step is setup documentation for `plan.md`, not part of `/rcode-ui-phase`'s
|
|
180
|
+
own run sequence — it does not re-run every time `/rcode-ui-phase` is
|
|
181
|
+
invoked. Before applying it, check whether `plan.md` already has this
|
|
182
|
+
detection step (grep for "ui_safety_gate" or "Detect frontend keywords");
|
|
183
|
+
skip if present.
|
|
104
184
|
|
|
105
185
|
In plan.md workflow, add Step 0.6 — **Detect frontend keywords and suggest UI safety gate**
|
|
106
186
|
|
|
@@ -141,17 +221,19 @@ Run /rcode-ui-phase, then return to /rcode-plan
|
|
|
141
221
|
|
|
142
222
|
## Success Criteria
|
|
143
223
|
|
|
144
|
-
- UI-SPEC.md created with all
|
|
224
|
+
- UI-SPEC.md created with all 7 sections, design direction grounded in `design-library/` lookup (or an existing design system), not invented
|
|
145
225
|
- Color tokens documented with contrast ratios
|
|
146
226
|
- Component inventory complete with variants
|
|
147
227
|
- Accessibility checklist included
|
|
148
|
-
-
|
|
228
|
+
- WIREFRAMES.md created covering every screen implied by the roadmap's IA, each with role visibility and all four states (loading/empty/error/success) defined
|
|
229
|
+
- State updated with both UI-SPEC.md and WIREFRAMES.md paths
|
|
149
230
|
|
|
150
231
|
## On Error
|
|
151
232
|
|
|
152
233
|
- If subagent fails: provide template UI-SPEC.md
|
|
153
234
|
- If frontend detection fails: skip suggestion
|
|
154
235
|
- If config.yaml missing ui_safety_gate: default to true (suggest)
|
|
236
|
+
- If no IA decision exists in ROADMAP.md or IA.md yet: WIREFRAMES.md cannot be produced meaningfully — stop Step 2b and say so rather than writing a screen list with no basis
|
|
155
237
|
|
|
156
238
|
## Next Up
|
|
157
239
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Workflow: rcode-ui-review
|
|
2
2
|
|
|
3
3
|
<purpose>
|
|
4
|
-
Retroactively audit completed UI work against the UI-SPEC.md contract. Validates across 6 pillars: color consistency, typography compliance, component inventory coverage, accessibility requirements, responsive behavior, and design coherence. Produces audit report with pass/fail per pillar.
|
|
4
|
+
Retroactively audit completed UI work against the UI-SPEC.md contract (and WIREFRAMES.md, when present, for per-screen state coverage). Validates across 6 pillars: color consistency, typography compliance, component inventory coverage, accessibility requirements, responsive behavior, and design coherence. Produces audit report with pass/fail per pillar.
|
|
5
5
|
</purpose>
|
|
6
6
|
|
|
7
7
|
|
|
@@ -41,6 +41,7 @@ Parse:
|
|
|
41
41
|
- `flags.phase` — audit specific phase (optional, default: all completed phases)
|
|
42
42
|
- `flags.detailed` — include detailed findings per component
|
|
43
43
|
- `spec_path` — load UI-SPEC.md if exists
|
|
44
|
+
- `wireframes_path` — load WIREFRAMES.md if exists (optional; used for per-screen state coverage)
|
|
44
45
|
- `phase_name` — phase to audit
|
|
45
46
|
|
|
46
47
|
## Step 1 — Validate UI-SPEC.md Exists
|
|
@@ -65,6 +66,10 @@ Read UI-SPEC.md for:
|
|
|
65
66
|
- Accessibility requirements
|
|
66
67
|
- Responsive breakpoints
|
|
67
68
|
|
|
69
|
+
If `.rcode/WIREFRAMES.md` exists, also read it for the per-role screen inventory and
|
|
70
|
+
required states (loading/empty/error/success) — missing states become findings under
|
|
71
|
+
Component Inventory or Design Coherence.
|
|
72
|
+
|
|
68
73
|
Scan phase/codebase for:
|
|
69
74
|
- Component files (*.tsx, *.jsx, *.vue)
|
|
70
75
|
- CSS/styling files (*.css, *.module.css, tailwind.config.js, etc.)
|
|
@@ -85,6 +90,9 @@ Task tool call:
|
|
|
85
90
|
**UI-SPEC.md Reference:**
|
|
86
91
|
{contents_of_ui_spec_md}
|
|
87
92
|
|
|
93
|
+
**WIREFRAMES.md Reference (if present):**
|
|
94
|
+
{contents_of_wireframes_md}
|
|
95
|
+
|
|
88
96
|
**Codebase to Audit:**
|
|
89
97
|
{component_files_list}
|
|
90
98
|
{styling_rules}
|
|
@@ -117,7 +117,7 @@ UI_SPEC_FILE=$(ls "${PHASE_DIR}"/*-UI-SPEC.md 2>/dev/null | head -1)
|
|
|
117
117
|
**If Playwright-MCP tools are available in this session (`mcp__playwright__*` tools
|
|
118
118
|
respond to tool calls) AND (`UI_PHASE_FLAG` is `true` OR `UI_SPEC_FILE` is non-empty):**
|
|
119
119
|
|
|
120
|
-
For each UI checkpoint listed in the phase's UI-SPEC.md (or inferred from SUMMARY.md
|
|
120
|
+
For each UI checkpoint listed in the phase's UI-SPEC.md and WIREFRAMES.md (screen states — loading/empty/error/success), or inferred from SUMMARY.md if neither exists:
|
|
121
121
|
|
|
122
122
|
1. Use `mcp__playwright__navigate` (or equivalent) to open the component's URL.
|
|
123
123
|
2. Use `mcp__playwright__screenshot` to capture a screenshot.
|
package/server/lib/scanner.js
CHANGED
|
@@ -133,6 +133,16 @@ function buildPhaseTree(projectDir, rawPhases, listCached, overrides) {
|
|
|
133
133
|
if (!sprintFiles.length) return p;
|
|
134
134
|
|
|
135
135
|
const phaseComplete = /complete|done/i.test(p.status || '');
|
|
136
|
+
// Story status must not cascade blindly from the phase's self-reported
|
|
137
|
+
// status (#gap: dashboard-truthfulness). A phase marked 'complete' in
|
|
138
|
+
// state.json is unverified until its own VERIFICATION.md says so — only
|
|
139
|
+
// then do we let stories inherit 'done'. Otherwise stories stay 'todo'
|
|
140
|
+
// even if the phase claims completion, so the board never shows a green
|
|
141
|
+
// checkmark with zero independent evidence behind it.
|
|
142
|
+
const verificationFile = files.find(f => /-VERIFICATION\.md$/i.test(f));
|
|
143
|
+
const verificationText = verificationFile ? (safeReadText(path.join(phasesDir, dir.name, verificationFile)) || '') : '';
|
|
144
|
+
const phaseVerified = phaseComplete && /status:\s*passed/i.test(verificationText);
|
|
145
|
+
const storyStatus = phaseVerified ? 'done' : 'todo';
|
|
136
146
|
const sprints = sprintFiles.map(f => {
|
|
137
147
|
const m = f.match(/^(\d+)-(\d+)-SPRINT\.md$/i);
|
|
138
148
|
const num = m ? parseInt(m[2], 10) : 0;
|
|
@@ -163,7 +173,7 @@ function buildPhaseTree(projectDir, rawPhases, listCached, overrides) {
|
|
|
163
173
|
const story = {
|
|
164
174
|
id: idM ? idM[1] : `${sid}-task-${stories.length + 1}`,
|
|
165
175
|
title: (titleAttrM && titleAttrM[1].trim()) || (titleTagM && titleTagM[1].trim()) || `Task ${stories.length + 1}`,
|
|
166
|
-
status:
|
|
176
|
+
status: storyStatus,
|
|
167
177
|
};
|
|
168
178
|
if (ov[story.id]) story.status = ov[story.id].status;
|
|
169
179
|
if (acM && acM[1].trim()) story.acceptance = acM[1].trim();
|
|
@@ -187,7 +197,7 @@ function buildPhaseTree(projectDir, rawPhases, listCached, overrides) {
|
|
|
187
197
|
stories.push({
|
|
188
198
|
id: hId,
|
|
189
199
|
title: hm[2].trim(),
|
|
190
|
-
status: ov[hId] ? ov[hId].status :
|
|
200
|
+
status: ov[hId] ? ov[hId].status : storyStatus,
|
|
191
201
|
});
|
|
192
202
|
}
|
|
193
203
|
}
|
|
@@ -217,7 +227,11 @@ function buildPhaseTree(projectDir, rawPhases, listCached, overrides) {
|
|
|
217
227
|
}).filter(depId => depId !== null && depId !== intId)
|
|
218
228
|
)];
|
|
219
229
|
|
|
220
|
-
|
|
230
|
+
// Surface the same verification check at the phase level so consumers of
|
|
231
|
+
// the tree (phases list, progress %, currentPhase, milestones) can also
|
|
232
|
+
// avoid trusting a self-reported 'complete' status blindly — not just the
|
|
233
|
+
// per-story cascade above. null when the phase doesn't claim completion.
|
|
234
|
+
return { ...p, sprints, dependsOn: phaseDependsOn, verified: phaseComplete ? phaseVerified : null };
|
|
221
235
|
});
|
|
222
236
|
}
|
|
223
237
|
|
|
@@ -278,7 +292,14 @@ function buildDashboard(state) {
|
|
|
278
292
|
const range = started || completed
|
|
279
293
|
? [fmtShort(started), fmtShort(completed)].filter(Boolean).join(' – ')
|
|
280
294
|
: '';
|
|
281
|
-
|
|
295
|
+
// A phase self-reporting 'complete' without a passing *-VERIFICATION.md
|
|
296
|
+
// (p.verified === false, set by buildPhaseTree) is downgraded to 'active'
|
|
297
|
+
// rather than shown as 'done' — the dashboard must not render a green
|
|
298
|
+
// checkmark, fill the progress bar, or skip a phase as currentPhase on
|
|
299
|
+
// an unconfirmed status alone (same drift class as the sprint-level check).
|
|
300
|
+
let phaseState = toState(p.status);
|
|
301
|
+
if (phaseState === 'done' && p.verified === false) phaseState = 'active';
|
|
302
|
+
return { ...p, name: p.name || p.slug || String(p.id || ''), range, state: phaseState };
|
|
282
303
|
}).sort((a, b) => (parseFloat(a.id ?? a.number) || 0) - (parseFloat(b.id ?? b.number) || 0));
|
|
283
304
|
|
|
284
305
|
// ---- progress (prefer story counts; fall back to phase-level counts) ----
|