Skip to content

feat: display round number alongside workflow phase in dashboard slot tiles#99

Merged
lukstafi merged 3 commits intomainfrom
ludics/task-837eab5f-s4/root
Mar 28, 2026
Merged

feat: display round number alongside workflow phase in dashboard slot tiles#99
lukstafi merged 3 commits intomainfrom
ludics/task-837eab5f-s4/root

Conversation

@lukstafi
Copy link
Copy Markdown
Owner

Summary

  • Adds round: number | null field to the SlotJson interface in src/dashboard.ts
  • Extracts orchState.round alongside orchState.phase in generateSlots(), reusing the existing readOrchestrationState() call
  • Renders round as part of the phase text in templates/dashboard/dashboard.js (e.g. "work (round 3)")

Test plan

  • Build compiles: bun run typecheck passes
  • Slot tiles with an active orchestration state show "phase (round N)" instead of just "phase"
  • Slot tiles with no orchestration state or round = 0 still show phase text without a round suffix
  • Empty slots still render correctly (round is null)

🤖 Generated with Claude Code

lukstafi and others added 3 commits March 28, 2026 18:38
Full task spec on round 1, brief reference on round 2+ to save context window tokens.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… tiles

Show "work (round 3)" style phase text in slot tiles by propagating
OrchestrationState.round through SlotJson and rendering it in dashboard.js.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@lukstafi lukstafi merged commit a27c023 into main Mar 28, 2026
1 check passed
@lukstafi
Copy link
Copy Markdown
Owner Author

Refactor Notes — task-837eab5f (Coder)

What I'd do differently next time

1. Read OrchestrationState once, share the result

generateSlots() currently calls readOrchestrationState(num) twice per slot:

  • once in the phase/round block (~line 200)
  • once inside lookupSlotOrchestrationLinks() (~line 220)

Both reads are synchronous file I/O on the same path. A simple refactor would pass the already-read orchState into lookupSlotOrchestrationLinks as an argument, eliminating the second read. For small deployments this is a micro-optimisation, but it makes the data flow explicit and removes a potential TOCTOU inconsistency if the file changes between the two reads.

// Pass orchState in rather than re-reading inside the helper
const orchLinks = empty ? { prUrl: null, t3codeThreadLinks: null }
  : lookupSlotOrchestrationLinks(num, t3codeWebUrl, taskId, orchState ?? undefined);

2. Consider exposing planMergeRound / mergeRound as a tooltip

The implementation plan notes these fields exist but are "less useful for at-a-glance display." However, showing the merge/plan-merge round as a tooltip on the phase pill (e.g. title="merge round 2") costs nothing visually and could help debugging stalled merges. Worth a one-liner addition in dashboard.js if the reviewer agrees.

3. Guard against round === 0 semantics being context-dependent

The JS check slot.round > 0 correctly suppresses display when round is 0. But the TypeScript side emits round: orchState.round ?? null, which passes through 0 if that's the stored value. It might be cleaner to mirror the guard on the TS side too:

round: empty ? null : (round != null && round > 0 ? round : null),

This keeps the JSON clean (no "round": 0 entries) and makes the contract explicit.

4. Centralise the "orchState matches current task" predicate

The condition !taskId || orchState.taskId === taskId || orchState.feature === taskId appears twice in generateSlots(). Extracting it into a small inline helper or a named variable avoids drift if the matching logic ever changes.

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