Skip to content

Selasar Revamp: Project Rail (Phase 1) - #84

Merged
suprie merged 3 commits into
mainfrom
run/selasar-revamp-build-a-rail-component-72px-icon-strip-one-door-per-project-2-letter-plus3-17da9665fd0c
Aug 12, 2026
Merged

Selasar Revamp: Project Rail (Phase 1)#84
suprie merged 3 commits into
mainfrom
run/selasar-revamp-build-a-rail-component-72px-icon-strip-one-door-per-project-2-letter-plus3-17da9665fd0c

Conversation

@suprie

Copy link
Copy Markdown
Owner

Summary

Replaces AppShell.tsx's feature-first sidebar with a 72px project rail (Rail.tsx): one door per registered project (2-letter initials, last-active-first), each door's glow tied to that project's RunState plus a placeholder night-run badge, a right-click pin/unpin affordance with pinned-only+overflow rail logic past 5 projects, and the Settings entry point moved to a gear icon at the rail's foot. Covers prd-rail-corridor-shell Phase 1 in full (4 queued loops, run as one combined overnight batch).

What changed

  • New src/components/layout/Rail.tsx — 72px door strip, right-click pin/unpin context menu, overflow door, settings gear at the foot
  • New src/lib/rail.ts — pure door-selection logic (doorInitials, sortByLastActive, selectRailDoors, hasActiveOrQueuedRun), covered by tests/frontend/rail.test.mjs
  • New src/hooks/useNightRunStatuses.ts — polls getRunStatus per visible door every 5s for the night-run badge
  • src-tauri/src/config.rs + commands/project.rs + lib.rs — new pinned: bool on ProjectEntry + set_project_pinned command, mirroring the existing autonomous flag
  • src/components/layout/AppShell.tsx — sidebar replaced with <Rail />; brand mark + "Local only vX" footer dropped, version badge moved into the shared header
  • src/router.tsx — removed the now-dead onNavClick/handleNavClick plumbing (its only branch, /import, had no live nav link left after the earlier Dashboard redesign)
  • docs/epics/selasar-revamp/prd-rail-corridor-shell.md — Phase 1 checklist checked, Design section's open questions resolved
  • .loopdeck/loops.md, .loopdeck/decisions.md — session bookkeeping

PRD

docs/epics/selasar-revamp/prd-rail-corridor-shell.md (Phase 1 — Project rail)

Decisions

  • 2026-08-12 — Rail pin state is a plain per-machine bool; night-run badge is a run-plan-derived placeholder (accepted): pin/unpin is a right-click context menu backed by a plain bool field mirroring autonomous; the night-run badge derives from an active/queued .loopdeck/run-plan.yaml, an explicit placeholder pending prd-detail-drawer's spike.
  • 2026-08-04 — Run-queue reliability: verdict marker must survive to the final message; branch names are now descriptive (accepted): the final chat message must restate **Verdict:** PASS/WARN/BLOCK even if already stated earlier in the turn.
  • 2026-08-04 — prd-assign-loop-id complete: real-file round-trip test added, frontend e2e stays an honest gap (accepted): round-trips against this repo's own real PRD file; frontend click-through stays unverifiable without a DOM test harness this repo doesn't have.

Test plan

  • cargo fmt --check — clean
  • cargo clippy --lib -- -D warnings — clean
  • cargo test --lib — 596 passed, 0 failed, 8 ignored (unchanged; no new Rust tests, matching the untested set_project_autonomous precedent for set_project_pinned)
  • npx tsc --noEmit — clean
  • npm run build — clean
  • npm run test:frontend — 8 passed (1 pre-existing + 7 new in tests/frontend/rail.test.mjs)
  • Manual: npm run tauri dev and confirm the rail renders one door per project, right-click opens pin/unpin, and crossing 5 projects collapses to pinned+overflow — no _electron/Playwright driver exists in this repo, so this wasn't verified live (same documented gap as every prior UI-only loop in .loopdeck/loops.md)

Verify Verdict

PRD Verification — docs/epics/selasar-revamp/prd-rail-corridor-shell.md

Verdict: PASS

No ## Acceptance Criteria section in this PRD; verified against Phase 1's own checklist items verbatim (the exact scope this run's 4 loops targeted). No commits existed yet on this branch at verify time, so the changed-file set was the working-tree diff, not a committed diff.

#CriterionStatusEvidence
1Build a Rail component (72px icon strip, one door per project, 2-letter initials) replacing AppShell.tsx's current sidebar markup.PASSsrc/components/layout/Rail.tsx:133w-[72px]; :82doorInitials(project.name) (src/lib/rail.ts:7, first 2 chars uppercased); src/components/layout/AppShell.tsx:58<Rail /> replacing the old <aside> sidebar
2Wire each door's glow color to that project's RunState (working/waiting/done/idle) plus a distinct night-run indicator, reusing the state derivation already in AttentionPanel.tsx / useAttentionItems.PASSRail.tsx:19-24,34-39 — tone/text maps keyed by RunState; :54,77 — reads project.run_state directly off the same ProjectEntry.run_state field AttentionPanel.tsx:78 already reads (no duplicate derivation added); :86-94 — distinct Moon-badge night-run indicator
3Add a pin/unpin affordance per project, and rail logic that shows all projects at 5 or fewer, or pinned-only plus one overflow door (back to the corridor) past 5.PASSRail.tsx:70-73 — right-click onContextMenu opens the menu; :98-108 — Pin/Unpin item calling setPinned; src/lib/rail.ts:29-42selectRailDoors (≤5 shows all / pinned-only+overflow / fallback to 5-most-recent past 5 with no pins), covered by 5 assertions in tests/frontend/rail.test.mjs
4Move the settings entry point to a gear icon at the rail's foot, preserving the existing /settings route.PASSRail.tsx:155-166 — gear Settings icon Link at the rail's foot; src/router.tsx:150/settings route untouched

Non-goals audit

  • No scope creep detected. Doors still route to the existing ProjectDetail page (no overlay drawer added); pin persistence stayed a single bool field; the night-run indicator stayed a badge, not the full drawer experience prd-night-run-surfaces owns.

Roll-up: PASS — 0 FAIL, 0 PARTIAL, 4 PASS.

Run metadata

  • Phases:
    • selasar-revamp/build-a-rail-component-72px-icon-strip-one-door-per-project-2-letter — "Build a Rail component (72px icon strip, one door per project, 2-letter" (selasar-revamp / prd-rail-corridor-shell / Phase 1 — Project rail)
    • selasar-revamp/wire-each-door-s-glow-color-to-that-project-s-runstate — "Wire each door's glow color to that project's RunState" (selasar-revamp / prd-rail-corridor-shell / Phase 1 — Project rail)
    • selasar-revamp/add-a-pin-unpin-affordance-per-project-and-rail-logic-that-shows-all — "Add a pin/unpin affordance per project, and rail logic that shows all" (selasar-revamp / prd-rail-corridor-shell / Phase 1 — Project rail)
    • selasar-revamp/move-the-settings-entry-point-to-a-gear-icon-at-the-rail-s-foot — "Move the settings entry point to a gear icon at the rail's foot," (selasar-revamp / prd-rail-corridor-shell / Phase 1 — Project rail)
  • Budgets: 2000000 tokens total · 21600s wall-clock cap for this turn · 28800s total-run wall-clock cap

Replaces AppShell.tsx's feature-first sidebar with a 72px project rail (Rail.tsx): one door per registered project (2-letter initials, last-active-first), each door's glow tied to that project's RunState plus a placeholder night-run badge, a right-click pin/unpin affordance with pinned-only+overflow rail logic past 5 projects, and the Settings entry point moved to a gear icon at the rail's foot. Covers prd-rail-corridor-shell Phase 1 in full (4 queued loops, run as one combined overnight batch).
@suprie
suprie marked this pull request as ready for review August 12, 2026 03:28
@suprie
suprie merged commit 73ddf77 into mainAug 12, 2026
2 checks passed
Sign up for freeto 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

@suprie