valent-pipeline 0.5.5 → 0.5.6
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/package.json +1 -1
- package/src/board/public/app.js +8 -1
- package/src/board/public/styles.css +5 -0
- package/src/lib/board.js +45 -2
package/package.json
CHANGED
package/src/board/public/app.js
CHANGED
|
@@ -90,9 +90,16 @@ function statusKind(status, column) {
|
|
|
90
90
|
/* ---------- Chips ----------------------------------------------------------------------- */
|
|
91
91
|
function statusChip(story) {
|
|
92
92
|
const k = statusKind(story.status, story.column);
|
|
93
|
-
|
|
93
|
+
// When the status was inferred from on-disk artifacts (backlog status lags an in-flight groom),
|
|
94
|
+
// mark it so the board reads honestly: a dotted chip + a title explaining the real backlog state.
|
|
95
|
+
const inferred = story.status_source === 'artifacts';
|
|
96
|
+
const title = inferred
|
|
97
|
+
? `status: ${k.label} (inferred from artifacts — backlog still says ${story.backlog_status || 'pending'})`
|
|
98
|
+
: `status: ${k.label}`;
|
|
99
|
+
return h('span', { class: `chip chip--status ${k.cls}${inferred ? ' chip--inferred' : ''}`, title },
|
|
94
100
|
h('span', { class: 'chip__icon', 'aria-hidden': 'true' }, k.icon),
|
|
95
101
|
k.label,
|
|
102
|
+
inferred ? h('span', { class: 'chip__inferred-mark', 'aria-hidden': 'true', title: 'inferred' }, '~') : null,
|
|
96
103
|
);
|
|
97
104
|
}
|
|
98
105
|
|
|
@@ -457,6 +457,11 @@ body {
|
|
|
457
457
|
.chip--status.is-idle { color: var(--ink-muted); background: var(--idle-soft); border-color: transparent; }
|
|
458
458
|
.chip--status.is-warn { color: var(--warn); background: var(--warn-soft); border-color: transparent; }
|
|
459
459
|
|
|
460
|
+
/* Inferred status — derived from on-disk artifacts because the backlog status lags an active
|
|
461
|
+
groom. Dashed outline + a faint "~" mark signals "best-effort, not yet persisted". */
|
|
462
|
+
.chip--status.chip--inferred { border: 1px dashed currentColor; }
|
|
463
|
+
.chip__inferred-mark { opacity: 0.6; font-weight: 600; margin-left: 1px; }
|
|
464
|
+
|
|
460
465
|
/* ---------- Backlog list ---------------------------------------------------------------- */
|
|
461
466
|
.backlog {
|
|
462
467
|
max-width: 1100px;
|
package/src/lib/board.js
CHANGED
|
@@ -60,6 +60,30 @@ export function columnForStatus(status) {
|
|
|
60
60
|
return STATUS_TO_COLUMN.get(status) || 'other'
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
+
/**
|
|
64
|
+
* Grooming artifacts, most-advanced phase first. Their presence means a story is mid-groom even
|
|
65
|
+
* when the backlog `status` still says `pending` — the Workflow path (plan.workflow.js) grooms
|
|
66
|
+
* the batch in-memory and only persists `status: groomed` at the very end, so the backlog status
|
|
67
|
+
* lags reality during a live groom (and there is often no pipeline-state.json at all). The board
|
|
68
|
+
* is a projection, so it infers the grooming phase from the artifacts the groom agents have
|
|
69
|
+
* already written, exactly as it overlays the live current_story over a lagging backlog.
|
|
70
|
+
*/
|
|
71
|
+
const GROOMING_ARTIFACT_STATUS = [
|
|
72
|
+
['readiness-review.md', 'readiness-review'],
|
|
73
|
+
['qa-test-spec.md', 'test-case-development'],
|
|
74
|
+
['uxa-spec.md', 'ux-spec'],
|
|
75
|
+
['reqs-brief.md', 'requirements-spec'],
|
|
76
|
+
]
|
|
77
|
+
|
|
78
|
+
/** The most-advanced grooming status implied by present artifacts, or null if none. */
|
|
79
|
+
export function inferGroomingStatus(artifacts) {
|
|
80
|
+
if (!Array.isArray(artifacts)) return null
|
|
81
|
+
for (const [file, status] of GROOMING_ARTIFACT_STATUS) {
|
|
82
|
+
if (artifacts.includes(file)) return status
|
|
83
|
+
}
|
|
84
|
+
return null
|
|
85
|
+
}
|
|
86
|
+
|
|
63
87
|
/** Story points, tolerating either field name (matches sprint.js `pointsOf`). */
|
|
64
88
|
function pointsOf(item) {
|
|
65
89
|
const p = item.points ?? item.story_points
|
|
@@ -74,10 +98,29 @@ function depsOf(item) {
|
|
|
74
98
|
/** Normalize one backlog item into a board story (stable shape regardless of input quirks). */
|
|
75
99
|
function normalizeStory(item, artifactsByStory) {
|
|
76
100
|
const id = item.id
|
|
77
|
-
const
|
|
101
|
+
const backlogStatus = item.status || 'pending'
|
|
102
|
+
const artifacts = (artifactsByStory && artifactsByStory[id]) || []
|
|
103
|
+
|
|
104
|
+
// Reflect an in-flight groom the backlog status hasn't caught up to: if a story still reads
|
|
105
|
+
// `pending` (its column would be Backlog) but grooming artifacts already exist on disk, surface
|
|
106
|
+
// the inferred grooming phase so it shows in Grooming instead of sitting in Backlog. An explicit
|
|
107
|
+
// forward status (groomed/sprint-planned/development/…/shipped) always wins — only `pending` is
|
|
108
|
+
// upgraded, and `status_source` records that the status was derived, not read from the backlog.
|
|
109
|
+
let status = backlogStatus
|
|
110
|
+
let statusSource = 'backlog'
|
|
111
|
+
if (columnForStatus(backlogStatus) === 'backlog') {
|
|
112
|
+
const inferred = inferGroomingStatus(artifacts)
|
|
113
|
+
if (inferred) {
|
|
114
|
+
status = inferred
|
|
115
|
+
statusSource = 'artifacts'
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
78
119
|
return {
|
|
79
120
|
id,
|
|
80
121
|
status,
|
|
122
|
+
backlog_status: backlogStatus,
|
|
123
|
+
status_source: statusSource,
|
|
81
124
|
column: columnForStatus(status),
|
|
82
125
|
depends_on: depsOf(item),
|
|
83
126
|
points: pointsOf(item),
|
|
@@ -88,7 +131,7 @@ function normalizeStory(item, artifactsByStory) {
|
|
|
88
131
|
active: false, // set true below if it matches current_story
|
|
89
132
|
phase: null, // overlaid from current_story when active
|
|
90
133
|
branch: null,
|
|
91
|
-
artifacts
|
|
134
|
+
artifacts,
|
|
92
135
|
cost: null, // { tokens, agent_ms, invocations, roles:[...] } when an audit report is supplied
|
|
93
136
|
}
|
|
94
137
|
}
|