Miro Pipeline Dashboard (Codex)
Creates or updates a pipeline dashboard on the Miro board with:
- Current pipeline status (which step is active)
- Recently completed tasks with durations
- Pipeline metrics (averages, skip rate)
When to use / When to skip
Use when:
- The project has
MIRO_BOARD_URLconfigured inAGENTS.md - A pipeline cycle just completed — update the board with the new result
- The user asked: "update Miro dashboard"
- Start of a session — display current pipeline state on the board
Skip when:
- No Miro board is configured for the project (no
MIRO_BOARD_URL) - The Miro MCP server is not connected or authenticated
- The pipeline hasn't moved since the last update — the board would show the same state
Prerequisite
- Miro MCP server registered in
.codex/config.toml(HTTP transport:https://mcp.miro.com) - MCP authentication completed (Codex prompts on first call)
MIRO_BOARD_URLdefined inAGENTS.md
Procedure
1. Gather data
Pull pipeline state and historical metrics through MCP tools:
apd:apd_pipeline_state() # current step + step timings
apd:apd_pipeline_metrics() # historical runs (timestamp, phase ts, status, adversarial T/A/D, agent counts)
Compute averages and skip rate from the runs list returned by apd:apd_pipeline_metrics(). Pass limit=N to cap the most recent N runs (0 = all, max 200).
2. Create dashboard table on the board
Use Miro MCP create_table to create the dashboard:
Table 1: Pipeline Status
| Step | Status | Time |
|---|---|---|
| Spec | ✅ / ⏳ / — | timestamp |
| Builder | ✅ / ⏳ / — | timestamp |
| Reviewer | ✅ / ⏳ / — | timestamp |
| Verifier | ✅ / ⏳ / — | timestamp |
- ✅ = completed (green sticky note)
- ⏳ = in progress (yellow sticky note)
- — = not started (gray sticky note)
3. Create metrics section
Use Miro MCP create_document for a markdown document:
# APD Pipeline Metrics
**Total tasks:** {count}
**Average duration:** {time}
**Fastest task:** {time}
**Slowest task:** {time}
**Skip rate:** {percentage}
## Average per step
- spec→builder: {time}
- builder→reviewer: {time}
- reviewer→verifier: {time}
4. Create recent tasks
Use Miro MCP create_table for a table of the last 5 tasks:
| Task | Duration | Status |
|---|---|---|
| {name} | {time} | ✅ / ⚠️ skip / partial |
5. Organize on the board
Position elements in a frame named "APD Pipeline Dashboard":
- Pipeline Status table — top left
- Metrics document — top right
- Recent tasks — bottom
6. Updating an existing dashboard
If the frame "APD Pipeline Dashboard" already exists on the board:
- Delete existing elements in the frame
- Create new ones with updated data
- Do NOT create a new frame — reuse the existing one
Anti-patterns
- Don't create a new "APD Pipeline Dashboard" frame on every update → Do reuse the existing frame and replace its contents
- Don't push status to the board mid-step (transitions are fast) → Do push only after a step completes (state is stable)
- Don't assume the user wants a board update on every commit → Do check for
MIRO_BOARD_URLin AGENTS.md before invoking - Don't copy raw
apd:apd_pipeline_state()output onto the board → Do transform it into the table/sticky shapes the dashboard uses
Examples
Example 1 — First dashboard on a fresh board.
Input: MIRO_BOARD_URL configured but the board has no "APD Pipeline Dashboard" frame yet. apd:apd_pipeline_state() reports spec=DONE, builder=ACTIVE, no metrics history.
Output: Create the frame and seed it with the current state:
Pipeline Status table:
| Spec | ✅ | 14:02 |
| Builder | ⏳ | 14:08 |
| Reviewer | — | |
| Verifier | — | |
Metrics document: "No completed cycles yet"
Recent tasks: empty
Return the board URL.
Example 2 — Mid-cycle update preserves the frame.
Input: Frame already exists from a previous run; pipeline just transitioned builder → reviewer. Old table shows builder=⏳, reviewer=—.
Output: Reuse the frame — delete old shapes, write new ones in place:
Before:
| Spec | ✅ | 14:02 |
| Builder | ⏳ | 14:08 |
| Reviewer | — | |
After:
| Spec | ✅ | 14:02 |
| Builder | ✅ | 14:23 |
| Reviewer | ⏳ | 14:23 |
Do NOT create a second frame — find_frame_by_name("APD Pipeline Dashboard") first.
Example 3 — Cycle complete updates Recent tasks.
Input: Pipeline cycle finished (commit abc1234, total 11m 32s). Old "Recent tasks" table had 4 rows; latest task should slot in at the top.
Output: All status cells flip to ✅, Metrics document refreshes averages, Recent tasks gets a new top row:
Recent tasks (after):
| Add /orders/refund | 11m 32s | ✅ | ← new
| Migrate webhook auth | 9m 14s | ✅ |
| Fix payment 5xx | 3m 02s | ⚠️ skip |
| Email template refactor| 7m 48s | ✅ |
| OAuth callback fix | 5m 21s | ✅ |
Cap at 5 rows; trim oldest if needed.
Exit criteria
You're done when:
- The "APD Pipeline Dashboard" frame exists on the board (created or reused)
- Pipeline Status table reflects the current step state (✅/⏳/—)
- Metrics document has the latest numbers from
apd:apd_pipeline_metrics() - Recent tasks table shows the last 5 tasks with durations
- The board URL has been returned to the user
Hand-off
- This skill is idempotent — repeated invocations update the same frame
- After a pipeline cycle completes → may be invoked from
apd-finishif the user opts to push the dashboard before push/PR - If MCP authentication fails → escalate to user; do NOT silently skip
Source: zstevovich/claude-apd — distributed by TomeVault.