Skip to content

feat(status + dashboard): "ready/iterating" + 4 UX polish items#52

Merged
fstamatelopoulos merged 2 commits into
mainfrom
iteration-7/status-iterating
May 19, 2026
Merged

feat(status + dashboard): "ready/iterating" + 4 UX polish items#52
fstamatelopoulos merged 2 commits into
mainfrom
iteration-7/status-iterating

Conversation

@fstamatelopoulos
Copy link
Copy Markdown
Owner

@fstamatelopoulos fstamatelopoulos commented May 19, 2026

Summary

Two-themed PR bundling related dashboard UX work.

Part 1: "ready/iterating" status (the original PR scope)

Multi-loop projects (PA + SA driving the workspace through several sequential milestone loops, like the gmbot run) had a misleading "COMPLETED" badge between loops — the project wasn't done, it was iterating.

Fix: one new explicit transition + one label rename.

  • Transition: {completed, failed, stopped} + cfcf review (standalone)idle. Triggered at the top of startReview(). Narrow trigger by design — only SA (scope work). Not reflect (retrospection), document (finalizing), or spec (PA, independent surface with its own chip from PR feat(ui): interactive-agent surfacing — History section + workspace card 'PA active' chip #51).
  • Paused stays paused — preserves resume mechanics + refine_plan action.
  • In-loop architect (runReviewSync) doesn't flip — it transitions through running already.
  • failed and stopped stay distinct internally for audit-trail preservation.
  • Label rename: idle\"ready/iterating\" in both StatusBadge.tsx (web) and cfcf status CLI. Internal value stays idle — zero state-machine churn.

Part 2: 4 UX polish items (added during dogfood review)

1. History tab section headers: (N)(active: A | total: T). Surfaces "is something running RIGHT NOW" at a glance.

2. Status tab PhaseIndicator subtitle: \"Iteration 24\"\"Iteration 24 (max: 28)\". The ceiling sits next to the live timer.

3. Status tab Loop State block trimmed: iteration count + max moved to PhaseIndicator (above). Pause-every lives in Config tab already. Block replaced with conditional "Stall warning" — only renders when consecutiveStalled > 0.

4. Workspace card three changes:

  • Live elapsed timer for running loop. New workspace.loopStartedAt field (server-enriched from loopState.startedAt when activeAgent === \"loop\"), rendered inside the loop chip via the existing useElapsed hook.
  • Chips moved BELOW title+badge row. With loop + PA chips both possible, single-row header was tight; two-row layout gives each chip room. Conditional rendering — no chips, no row.
  • Agents row adds Reflect. PA NOT added (global config — identical on every card). Architect + Documenter omitted to keep row scannable; can add later if dogfood demands.

Test plan

  • bun run test — 1079 tests pass (+8 new for Part 1; Part 2 is pure presentation, no new tests)
  • bun run typecheck — clean
  • Part 1: 8 new tests in architect-runner.test.ts covering TERMINAL_LOOP_STATUSES exhaustiveness; flips from completed/failed/stopped; does NOT flip paused (load-bearing — preserves resume mechanics); does NOT flip running/idle; defensive undefined-status handling
  • Manual smoke (post-merge):
    • On gmbot (currently "completed"), run cfcf review → dashboard badge flips to "ready/iterating" + cfcf status shows the new label
    • Start a loop, watch the workspace card's chip show \"● loop running · 12s\" ticking live; PA chip appears in a second row when PA is active
    • History tab section headers show \"Interactive sessions (active: 1 | total: 3)\" correctly
    • Status tab top-bar shows \"Iteration N (max: M) · 15m 00s\"; "Loop State" block is gone unless consecutiveStalled > 0

Versioning

Pairs naturally with PR #51 (also in [Unreleased]). Recommend bundling both into v0.24.5 when tagging. The CHANGELOG already has both entries side by side.

🤖 Generated with Claude Code

fstamatelopoulos and others added 2 commits May 18, 2026 18:52
Multi-loop projects (PA + SA driving the workspace through
several sequential milestone loops) had a misleading "COMPLETED"
badge between loops — the project wasn't done, it was iterating.

Fix: one new explicit transition + one label rename.

Transition: {completed, failed, stopped} + cfcf review
(standalone) -> idle. Triggered at the top of architect-runner's
startReview() path, BEFORE the SA spawn. Narrow trigger by
design — only SA (scope work). Not reflect (retrospection),
document (finalizing), or spec (PA, independent surface with
its own chip from v0.24.5).

Paused stays paused — preserves resume mechanics + refine_plan
action. In-loop architect (runReviewSync) doesn't flip — it
transitions through "running" already. failed and stopped stay
distinct internally for audit-trail preservation.

Label rename: idle -> "ready/iterating" in StatusBadge.tsx
(web) and a new formatStatus() helper in cfcf status CLI. The
slashed label covers both intents (fresh workspace = "ready",
post-terminal + SA run = "iterating") without derive-from-
history complexity. Internal value stays "idle" — zero
state-machine churn.

Implementation: TERMINAL_LOOP_STATUSES constant +
flipTerminalStatusToIdle(workspace) helper (returns bool for
testability + best-effort error handling). startReview() calls
it before ensureWorkspaceLogDir.

Test coverage: 8 new tests covering all status transitions
(completed/failed/stopped flip; paused/running/idle don't flip;
undefined status defensive case; TERMINAL_LOOP_STATUSES set
exhaustiveness). All 1079 tests pass; typecheck clean.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Four small dogfood-driven UX polish items bundled together:

1. History tab section headers: split count into "(active: N |
   total: M)" instead of just "(N)". Surfaces "is something
   running RIGHT NOW" without scanning rows.

2. Status tab PhaseIndicator subtitle: "Iteration 24 (max: 28)"
   instead of just "Iteration 24". Ceiling visible next to the
   live timer without a click into Config.

3. Status tab Loop State block: trimmed. Iteration/max now in
   PhaseIndicator above; pause-every is in Config tab. Block
   replaced with conditional "Stall warning" that only renders
   when consecutiveStalled > 0.

4. Workspace card three changes:
   - Live elapsed timer for running loop. New
     workspace.loopStartedAt field (server-enriched from
     loopState.startedAt when activeAgent === "loop"), rendered
     inside the loop chip via useElapsed hook.
   - Chips moved BELOW title+badge row (was crowded when loop +
     PA both active). Two-row layout, conditional rendering —
     no chips = no row.
   - Agents row adds Reflect (per-workspace). PA intentionally
     NOT added (global config = same on every card). Architect
     + Documenter omitted to keep row scannable.

Server enrichment: /api/workspaces gets loopStartedAt populated
from loopState.startedAt when active. One getLoopState() call
per running workspace, in-memory cached.

No new tests — pure presentation. All 1079 tests still pass.
Typecheck clean.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@fstamatelopoulos fstamatelopoulos changed the title feat(status): "ready/iterating" label + flip on standalone SA feat(status + dashboard): "ready/iterating" + 4 UX polish items May 19, 2026
@fstamatelopoulos fstamatelopoulos merged commit b40fd49 into main May 19, 2026
3 checks passed
@fstamatelopoulos fstamatelopoulos deleted the iteration-7/status-iterating branch May 19, 2026 02:13
fstamatelopoulos added a commit that referenced this pull request May 19, 2026
…polish

Bumps version 0.24.4 -> 0.24.5 and consolidates [Unreleased] into a
[0.24.5] release entry. Shipped via PR #51 + PR #52.

Net-new since v0.24.4:
- PR #51: History tab partition (Interactive sessions + Loop
  history sections) + workspace card "PA active" chip + Status
  tab tag; server-side PA PID liveness check
- PR #52: ready/iterating status semantics (cfcf review flips
  terminal status to idle) + 4 dashboard polish items (history
  active counts, in-page iteration max, card timer, card layout)

Test coverage: 1079 tests pass (+22 new). Typecheck clean.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant