Skip to content

feat: add planner dashboard TUI (/planner-dashboard)#21

Merged
m62624 merged 14 commits into
mainfrom
feat/planner-tui-dashboard
Jun 15, 2026
Merged

feat: add planner dashboard TUI (/planner-dashboard)#21
m62624 merged 14 commits into
mainfrom
feat/planner-tui-dashboard

Conversation

@m62624

@m62624 m62624 commented Jun 15, 2026

Copy link
Copy Markdown
Owner

No description provided.

m62624 and others added 14 commits June 15, 2026 07:49
Full-screen, theme-aware, adaptive dashboard for the planner:
- Segmented stage progress ribbon with per-stage theme colors and
  in-segment labels, filling left-to-right as stages complete
- Marquee ticker (route, active task, branch) scrollable with ←→
- Scrollable task list with status icons and selection follow
- Detail panel with current step, branch, and per-stage timings
  derived from the timer checkpoints
- Live refresh from disk while open; adapts to terminal resize;
  compact single-column layout on narrow terminals
- Pure model + renderers in dashboard-model.ts (unit tested with an
  identity palette); interactive shell in dashboard.ts
- Footer/widget hint pointing at /planner-dashboard
- Add @earendil-works/pi-tui dependency for TUI primitives

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Reserve a blank cell on each side of each stage label and render the
label with a readable treatment (bold/text/muted) instead of the stage
fill color, so "INIT", "DISCOVERY", etc. stay legible against the
▰/░ progress fill.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Rebuild /planner-dashboard as a full-screen workspace (Option 3):
- Top band: stage ribbon + status + marquee ticker
- Middle: live model conversation rendered from session entries
  (projectSessionEntries + renderTranscript), planner tool calls and
  results collapsed to one line by default, expandable
- Bottom: our own input line that sends to the model via
  pi.sendUserMessage, plus focus tabs (input / chat / tasks)
- Tab cycles panes; tasks pane expands the task list + stage timings;
  chat pane scrolls and toggles expand-all; live refresh while open
- Pure transcript module (chat-view.ts) unit tested with identity palette

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Auto-open the workspace once per session for planner-worktree
  sessions via a session_start hook (covers create/resume/improve
  without touching the fragile session-switch handoff). Reopen with
  /planner-dashboard; close to fall back to the plain chat.
- Remove /planner-preview (the workspace replaces it).
- README: document /planner-dashboard, drop /planner-preview.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Fixes the footer overlap and mouse-wheel-into-scrollback issues, and
makes the TUI configurable:

- Render the workspace as a fixed top overlay (overlay: true) instead of
  an inline scrollback component, so the mouse wheel no longer drags it
  off-screen and the native footer stays visible below it.
- Size the overlay to terminal rows minus a configurable footer reserve.
- Add a `workspace` settings group: enabled, autoOpen, footerReserveRows
  (schema, defaults, manager merge/normalize, /planner-helper docs).
- openPlannerWorkspace loads settings; auto-open respects autoOpen and
  the master enabled switch; footer reserve is tunable if the footer
  overlaps or leaves a gap.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Stream assistant output live: subscribe to message_update/message_end
  and append the in-flight assistant message to the transcript, so tokens
  appear as they are generated instead of only after the turn commits.
- Replace the glyph-fill stage ribbon with a clean bracket style
  (INIT › INTAKE › [DISCOVERY] › …): active stage bracketed + bold in its
  theme colour, completed stages coloured, pending dimmed. Adapts to width.
- Redraw only when something visible changed (content, clock second,
  coarse marquee step, focus/input) instead of every tick — removes the
  choppy repaint and steadies the ticker.
- Document the workspace keys, settings, and Pi keybindings.json in the
  /planner-helper report and SETTINGS.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
In the discovery-first /planner-improve flow, discovery runs before the
goal is drafted. But planner_goal_decide(approve) always routed to
discovery/scan_project_structure (the create-flow assumption), so improve
plans re-ran the whole discovery stage after approval (re-scan, "questions
already submitted", second compact).

Now approval routes creationMethod=improve plans straight to
planning/read_context, and the state machine allows
intake/await_goal_approval → planning/read_context for improve. Create
plans are unchanged (goal first, then discovery).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…auses

- Sanitize transcript text (expand tabs, strip ANSI/control bytes) so the
  expand (x) view no longer breaks the frame on tool output that contains
  tabs or escape codes.
- Dashboard clock + stage timings now show live elapsed time (activeMs plus
  time since last disk sync) instead of the rarely-synced persisted value,
  so they tick in real time. Timer sync interval is threaded from settings.
- Restore a smooth one-cell-per-tick marquee when the ticker overflows;
  keep the calm render-on-change behaviour when it fits.
- Timer pauses only while waiting on the user (goal approval, discovery
  questions, result acceptance, user decisions). It now counts intake
  drafting and compaction for honest active timing.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…row ribbon

- Streaming now redraws per message_update event (token by token) instead
  of on the poll tick, so the chat fills in smoothly like Pi's own chat.
- Clock + stage timings recompute live in-memory each draw (applyLiveTiming)
  and disk reload drops to ~3s, so the terminal shows full-time elapsed
  without per-second disk reads (persisted timer still syncs every 10 min).
- Inherit Pi keybindings: app.thinking.toggle (Ctrl+T) hides/shows thinking
  rows; app.tools.expand (Ctrl+O) expands/collapses tool output.
- Stage ribbon falls back to a compact [ACTIVE] n/total indicator when the
  terminal is too narrow for the full ribbon, so the active stage is always
  visible.
- Detail-panel note now word-wraps and ellipsises instead of hard-clipping.
- Docs: workspace keys + inherited bindings in /planner-helper and SETTINGS.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Header clock now uses the live-recomputed model instead of the value
  from the last disk reload, so it ticks every second (was stepping in
  ~3s reload increments).
- Chat pane: End jumps back to the live tail (newest output), Home to the
  top — so after scrolling up you can return to the streaming view.
- Input accepts pasted text (bracketed paste handled, ANSI/control bytes
  stripped, newlines folded to spaces). Image paste is not supported in
  the workspace (Pi's image paste targets its built-in editor); documented.
- Docs: paste + End/Home keys in /planner-helper and SETTINGS.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- The transcript now anchors to an absolute top line while scrolled up, so
  newly streamed/committed output appends below without yanking the view to
  the bottom. End re-follows the live tail; Home jumps to the top.
- Project only a trailing window of session entries (HISTORY_WINDOW=400) and
  cache the projection, rebuilding only when the windowed slice changes
  instead of every 180ms tick. Scrolling to the top loads the next older
  chunk, so long sessions never project the whole conversation at once and
  the per-tick CPU/alloc cost stays bounded.
- renderTranscript switches from scroll-from-bottom to atBottom + absolute
  topLine and returns the resolved top line for the caller to track.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
At a disabled compact boundary (task compaction is off by default),
compact_task wants finish_step, not request_compact. The guidance never
named the target step, so the model called finish_step with the current
step as the target and hit invalid_next_step, then thrashed
fail/retry/start before recovering.

- Lifecycle: the disabled-compact and generic finish_step messages now
  state the exact target via getAllowedNextPlannerPositions, and the
  disabled-compact message explicitly says not to call request_compact.
- Orchestrator: blocked-tool reasons now include the lifecycle guidance
  (with the target), so the model sees the right next step on the block.
- status: compact_task rule explains both paths (enabled -> request/complete
  compact; disabled -> finish_step to execution/select_next_task).
- Test: state machine advances compact_task -> select_next_task and rejects
  finishing into the same step.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- The auto-scrolling ticker forced a full repaint every ~180ms, which is
  what drove the dashboard to ~40% CPU. Replace it with a static, clipped
  context line (active task / branch / blocking note) — no per-tick repaint.
  Idle now redraws ~once/second (clock only); when nothing changes the tick
  is a cheap no-op.
- Throttle streaming-driven redraws to ~12fps so a fast token stream cannot
  drive an unbounded repaint rate.
- Make the workspace keys configurable via settings workspace.keys
  (focusNext/up/down/pageUp/pageDown/jumpBottom/jumpTop/expand/submit/exit),
  matched through matchesKey; Ctrl+C always exits. Pi's keybindings.json only
  accepts Pi action ids, so our keys live in planner settings.
- Docs updated.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
When final checks revealed a needed code edit (e.g. a biome import-order
error in a new test file), the model was stuck: run_final_tests cannot edit
project files, and fail_step/retry_step only re-run the same step. There was
no path back to an editing step, so the model thrashed.

- State machine: execution/run_final_tests now branches to
  {capture_skill (forward), implement_task (back to fix)}.
- status: run_final_tests rule explains to finish_step into implement_task
  for fixes (not fail_step), and that this step cannot edit project files.
- Test: run_final_tests allows the implement_task branch.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actions github-actions Bot added the feat label Jun 15, 2026
@m62624 m62624 merged commit 451a9a1 into main Jun 15, 2026
2 checks passed
@m62624 m62624 deleted the feat/planner-tui-dashboard branch June 15, 2026 09:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant