Skip to content

TUI Epic 3: Library screen (replaces Plans) - #159

Merged
TraderSamwise merged 4 commits into
masterfrom
chore/tui-next-14
Jun 17, 2026
Merged

TUI Epic 3: Library screen (replaces Plans)#159
TraderSamwise merged 4 commits into
masterfrom
chore/tui-next-14

Conversation

@TraderSamwise

@TraderSamwise TraderSamwise commented Jun 17, 2026

Copy link
Copy Markdown
Owner

Third epic of the TUI IA redesign. Replaces the per-session Plans tab with a Library screen — a browsable view of the project's documents and real plans, matching the project's direction (the app/HTTP /library surfaces project docs).

What changed

Phase 1 — Library loader. New pure-ish src/library.ts: loadLibraryEntries({repoRoot, plansDir, resolveLabel}) returns allowlisted project docs (AGENTS/CLAUDE/CODEX/README.md, mirroring metadata-server's library allowlist) plus session plans from .aimux/plansskipping untouched TBD stubs and falling back to file mtime when a plan lacks a frontmatter updatedAt. Pure isStubPlan helper. Unit-tested via temp dir.

Phase 2 — Library screen (key l). Browsable list of docs + plans with a content preview pane and editor-open (e/Enter). Direct cutover from Plans: removed the plans screen/controller/renderer, repointed the DashboardScreen union / statusline tab / nav cycle / dispatch from plans/plibrary/l, and migrate any persisted plans screen → library.

Fixes the carried-forward Plans bugs (empty TBD-stub walls, no mtime sort fallback) and frames docs as first-class library content.

Verification

  • yarn typecheck, yarn lint, yarn build clean
  • yarn vitest run — 1389 tests pass (6 new loader tests)

Dashboard and Graveyard untouched.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added a Library dashboard screen showing documents and plans with metadata, timestamps, and a preview/details pane.
    • Added keyboard browsing with an optional details sidebar, plus opening selected entries in an external editor.
  • Tests
    • Added coverage for library loading and stub-plan detection.
    • Updated dashboard/tmux statusline rendering tests for the new library screen.
  • Documentation / UX
    • Replaced “plans” with “library” across dashboard tabs, help overlays, and keyboard shortcuts.
    • Migrated persisted dashboard view values from the old plans option to library.

test and others added 2 commits June 17, 2026 13:39
loadLibraryEntries reads the allowlisted project docs (AGENTS/CLAUDE/
CODEX/README.md, matching the app/metadata-server library surface) plus
session plans from .aimux/plans, skipping untouched TBD stubs and
falling back to file mtime when a plan lacks a frontmatter updatedAt.
Backs the upcoming Library screen that replaces Plans.

Epic 3 (Library) phase 1 of 2.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The Plans tab showed per-session .aimux/plans stubs (mostly "TBD").
Replace it with a Library screen (key l) that browses the project's
documents (AGENTS/CLAUDE/CODEX/README.md, matching the app/HTTP library
surface) alongside real, non-stub plans, with a content preview pane and
editor open (e/Enter). Direct cutover: remove the plans screen + its
controller/renderer, repoint the union/statusline/nav/dispatch from
'plans'/'p' to 'library'/'l', and migrate any persisted 'plans' screen
to 'library'.

Epic 3 (Library) phase 2 of 2.

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

vercel Bot commented Jun 17, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
app Ready Ready Preview, Comment Jun 17, 2026 6:14am

@TraderSamwise

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 17, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 2cdcd752-c66b-4fcc-9b93-623b13b530df

📥 Commits

Reviewing files that changed from the base of the PR and between 10fda00 and e080898.

📒 Files selected for processing (3)
  • src/library.test.ts
  • src/library.ts
  • src/multiplexer/library.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/library.ts
  • src/multiplexer/library.ts

📝 Walkthrough

Walkthrough

The PR replaces the "plans" dashboard screen with a new "library" screen. A new src/library.ts module loads doc and plan markdown files from the filesystem into LibraryEntry objects, with optional frontmatter parsing and stub detection. A new multiplexer controller in src/multiplexer/library.ts handles show/render/key input including terminal mode toggling and editor spawning. TUI rendering is added via renderLibraryScreen and renderLibraryDetails. All plans-related exports are removed from archives.ts, screen type contracts are updated, and the p key binding is remapped to show library instead of plans throughout control flow, routing, and help text.

Changes

Library Screen Replaces Plans Screen

Layer / File(s) Summary
Library data model and loader
src/library.ts, src/library.test.ts
Defines LibraryEntryKind, LibraryEntry, LibraryLoadOptions, isStubPlan, frontmatterUpdatedAt, and loadLibraryEntries. Tests cover stub detection, allowlist/exclusion rules, label resolution, frontmatter stripping, newest-first sorting, mtime fallback, CRLF handling, malformed frontmatter, and empty-repo cases.
Screen type and state contracts
src/dashboard/state.ts, src/dashboard/ui-state-store.ts, src/statusline-model.ts, src/multiplexer/index.ts, src/multiplexer/dashboard-tail-methods.ts
Replaces "plans" with "library" in DashboardScreen union, VALID_SCREENS, persisted screen migration mapping, StatuslineData.dashboardScreen, and DASHBOARD_SCREEN_TABS. Swaps planEntries/planIndex for libraryEntries/libraryIndex in Multiplexer state. Updates DashboardTailMethods interface to add showLibrary, renderLibrary, handleLibraryKey and remove eight plan-related methods, with corresponding wiring in dashboardTailMethods implementation.
Library multiplexer controller
src/multiplexer/library.ts
Implements refreshLibrary (loads/bounds-checks entries), showLibrary (clears/refreshes/switches/renders), renderLibrary (lazy-refresh wrapper), openEntryInEditor (editor spawning with raw/alternate terminal mode management), and handleLibraryKey (parses key events for tab/quit/navigate/select/refresh/open, including j/k/numeric keys and wrapping).
Library TUI screen renderers
src/tui/screens/subscreen-renderers.ts
Adds LIBRARY_KIND_TONE styling map, renderLibraryScreen (renders selectable entry list with empty-state, per-entry metadata, optional details sidebar), and renderLibraryDetails (renders title/kind/sessionId/updated/path and preview with line wrapping and width-aware truncation).
Plans removal and screen routing
src/multiplexer/archives.ts, src/multiplexer/runtime-state.ts, src/multiplexer/session-launch.ts, src/multiplexer/dashboard-control.ts, src/multiplexer/dashboard-interaction.ts, src/multiplexer/navigation.ts
Removes eight plan exports and plan hydration logic from archives.ts. Updates screen dispatch in runtime-state.ts to call host.renderLibrary() for "library" screen. Reroutes "library" screen input to host.handleLibraryKey(data) in session-launch.ts dispatcher. Changes p key binding from showPlans() to showLibrary() across dashboard control/interaction/navigation handlers.
Help text, keycap hints, and statusline test
src/tui/screens/dashboard-renderers.ts, src/tui/screens/overlay-renderers.ts, src/tmux/statusline.test.ts
Updates [p] keycap label from plans to library in five dashboard buildHelpLine() branches (no-sessions, worktrees+sessions, worktrees, sessions-present, default). Replaces p plans with p library in help overlay text. Updates statusline test to set dashboardScreen: "library" and assert the corresponding highlight segment.

Sequence Diagram

sequenceDiagram
  participant User
  participant handleDashboardKey
  participant showLibrary
  participant loadLibraryEntries
  participant renderLibraryScreen
  participant handleLibraryKey
  participant openEntryInEditor

  User->>handleDashboardKey: press "p"
  handleDashboardKey->>showLibrary: showLibrary(host)
  showLibrary->>loadLibraryEntries: load docs + plans from fs
  loadLibraryEntries-->>showLibrary: LibraryEntry[]
  showLibrary->>renderLibraryScreen: render list + frame
  User->>handleLibraryKey: press "e" or enter
  handleLibraryKey->>openEntryInEditor: openEntryInEditor(host, path)
  openEntryInEditor->>openEntryInEditor: exit raw mode, spawnSync $EDITOR
  openEntryInEditor->>loadLibraryEntries: refresh after editor exits
  openEntryInEditor->>renderLibraryScreen: re-render library
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • TraderSamwise/aimux#157: Both PRs modify dashboard screen identifiers and persisted-screen normalization logic in src/dashboard/state.ts and src/dashboard/ui-state-store.ts, impacting the same routing and state restoration pathways.
  • TraderSamwise/aimux#158: Both PRs update dashboard screen integration points like src/multiplexer/runtime-state.ts routing and StatuslineData/help+navigation wiring to add a new dashboard view (library vs. project).

Poem

🐇 Hop hop, the plans have gone away,
A library blooms in their place today!
With p I leap to docs and plans so fine,
Frontmatter stripped, entries sorted by time.
The stub is skipped, the real ones shine—
This bunny's shelf is now divine! 📚✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 9.09% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'TUI Epic 3: Library screen (replaces Plans)' directly and clearly summarizes the main change: replacing the Plans screen with a new Library screen.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/tui-next-14

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai

coderabbitai Bot commented Jun 17, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

'l' is the vim-style worktree drill-in key (alongside enter/right) on the
main dashboard, so binding it to Library shadowed drilling into a
worktree. Use 'p' instead — the freed Plans key, of which Library is the
successor — which only shadows the redundant worktree 'p'=up (k/up still
work), exactly as the old 'p'=plans did. Also drop the now-unreachable
"plans" literal from the StatuslineData union.

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/library.ts`:
- Line 95: The updatedAt field assignment needs to validate that the frontmatter
timestamp from frontmatterUpdatedAt(content) is actually a valid date string
before using it. Currently, malformed timestamps pass through and cause
Date.parse() to return NaN at the sorting logic later. Modify the updatedAt
assignment to validate the frontmatter value by attempting to parse it, and only
use it if the result is a valid number (not NaN); otherwise, fall back to the
mtime value from statSync(path).mtime.toISOString().
- Around line 22-23: The FRONTMATTER regex pattern only matches LF newlines,
which causes frontmatter parsing to fail silently on CRLF-authored markdown
files, affecting both updatedAt extraction and preview stripping. Update the
FRONTMATTER regex to be CRLF-tolerant by modifying all newline matches to accept
both LF and CRLF line endings. Replace hardcoded newline characters in the
pattern with a pattern that matches either carriage return plus line feed or
just line feed.

In `@src/multiplexer/library.ts`:
- Around line 41-48: The terminal mode restoration code in the spawnSync editor
invocation is not protected against exceptions. Wrap the spawnSync call in a
try/finally block to ensure terminal modes are always restored, even if the
spawn operation throws an error. Move the host.terminalHost.exitRawMode() and
host.terminalHost.exitAlternateScreen() calls into the try block before
spawnSync, then move the host.terminalHost.enterRawMode() and
host.terminalHost.enterAlternateScreen(true) calls into a finally block so they
execute unconditionally after the spawn attempt completes or fails.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ad47c34f-2782-4d12-97bd-a06fa08733ea

📥 Commits

Reviewing files that changed from the base of the PR and between f3cff8e and b9e6754.

📒 Files selected for processing (18)
  • src/dashboard/state.ts
  • src/dashboard/ui-state-store.ts
  • src/library.test.ts
  • src/library.ts
  • src/multiplexer/archives.ts
  • src/multiplexer/dashboard-control.ts
  • src/multiplexer/dashboard-interaction.ts
  • src/multiplexer/dashboard-tail-methods.ts
  • src/multiplexer/index.ts
  • src/multiplexer/library.ts
  • src/multiplexer/navigation.ts
  • src/multiplexer/runtime-state.ts
  • src/multiplexer/session-launch.ts
  • src/statusline-model.ts
  • src/tmux/statusline.test.ts
  • src/tui/screens/dashboard-renderers.ts
  • src/tui/screens/overlay-renderers.ts
  • src/tui/screens/subscreen-renderers.ts

Comment thread src/library.ts Outdated
Comment thread src/library.ts
Comment thread src/multiplexer/library.ts
@TraderSamwise

Copy link
Copy Markdown
Owner Author

Sub-agent review pass. One real defect, fixed:

  • l key collision (high): l is the vim-style worktree drill-in key on the main dashboard (with enter/right), so binding Library to l shadowed drilling into a worktree. Switched Library to p — the freed Plans key (Library is Plans' successor), which only shadows the redundant worktree p=up (k/up still work), matching the old p=plans behavior. (10fda00)
  • Stale union literal (low): dropped the unreachable "plans" from the StatuslineData.dashboardScreen union (migrated to library on read). (10fda00)

Loader (isStubPlan, mtime fallback, sort, error isolation), controller (index clamp, render purity, editor terminal-state restore), and the rest of the cutover reviewed clean.

…ditor try/finally

- Make the library frontmatter regex and updatedAt scan CRLF-tolerant so
  CRLF-authored plans/docs parse correctly.
- Ignore a malformed frontmatter updatedAt (falls back to mtime) so it
  can't degrade the recency sort.
- Restore terminal raw/alternate modes via try/finally around the editor
  spawn so a throw can't leave the terminal broken.
- Add CRLF + malformed-timestamp regression tests.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@TraderSamwise
TraderSamwise merged commit 8d20205 into master Jun 17, 2026
3 checks passed
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