diff --git a/.loopdeck/decisions.md b/.loopdeck/decisions.md index 443adb1..ab7b018 100644 --- a/.loopdeck/decisions.md +++ b/.loopdeck/decisions.md @@ -2,6 +2,13 @@ _Older decisions archived to [decisions-archive.md](./decisions-archive.md)._ +## 2026-08-12 — Rail pin state is a plain per-machine bool; night-run badge is a run-plan-derived placeholder + +- **Status**: accepted +- **Context**: `prd-rail-corridor-shell` Phase 1's two open questions (pin trigger UI, pin storage) and its dependency on `prd-detail-drawer`'s not-yet-run night-run spike were pre-answered at run queue time, not left for this loop to guess. +- **Consequences**: Pin/unpin lives on the door itself as a right-click context menu (no room card exists until Phase 2) — a plain `pinned: bool` on `ProjectEntry` (`config.rs`), mirroring the existing `autonomous` flag exactly, no new storage design. The night-run badge derives from whether the project has an active/queued `.loopdeck/run-plan.yaml` (`hasActiveOrQueuedRun` in `src/lib/rail.ts`) — an explicit placeholder, not the real `RunState` variant `prd-night-run-surfaces` may eventually add once its drawer spike lands. +- **Detail**: `.loopdeck/loops.md` `## Current` (2026-08-12 entry) has the full file/symbol breakdown. + ## 2026-08-04 — Run-queue reliability: verdict marker must survive to the final message; branch names are now descriptive - **Status**: accepted diff --git a/.loopdeck/loops.md b/.loopdeck/loops.md index 05e4933..7b16cef 100644 --- a/.loopdeck/loops.md +++ b/.loopdeck/loops.md @@ -2,7 +2,11 @@ ## Current -- **Started**: 2026-08-05 +- **Started**: 2026-08-12 +- **Goal**: `selasar-revamp` / `prd-rail-corridor-shell` Phase 1 (all 4 loops, overnight run) — complete. +- **Status**: completed +- ✅ **`prd-rail-corridor-shell` Phase 1 — Project rail, all 4 loops** (2026-08-12) — New 72px `Rail.tsx` (`src/components/layout/`) replacing `AppShell.tsx`'s feature-first sidebar: one door per registered project (2-letter initials, `src/lib/rail.ts::doorInitials`), sorted last-active-first (`sortByLastActive`). Door glow ties to `RunState` (idle/working/waiting/done) via a tone→CSS-var map + `color-mix` box-shadow. Night-run badge is a placeholder per the run's own pre-answered clarification — derived from an active/queued `.loopdeck/run-plan.yaml` (`hasActiveOrQueuedRun`, polled every 5s per visible door via new `useNightRunStatuses` hook + existing `getRunStatus`), pending `prd-detail-drawer`'s spike for the real representation. Pin/unpin is a right-click context menu on the door (Radix `DropdownMenu` driven by state, not its default click-trigger, so left-click still navigates); backed by a new `pinned: bool` on `ProjectEntry` (`config.rs`) + `set_project_pinned` command, mirroring the existing `autonomous` flag exactly. Rail shows all doors at ≤5 projects; past 5, pinned-only + one fixed overflow door back to the corridor — falling back to the 5 most recently active when nobody has pinned yet (`selectRailDoors`). Settings moved to a gear icon at the rail's foot (`/settings` route unchanged); the old sidebar's brand mark and "Local only v0.2.0" footer were dropped per the run's answers, with the version badge relocated into the shared header instead (visible on every page, not just the rail). `onNavClick` prop plumbing (AppShell/router.tsx) deleted as dead code — its only branch (`/import`) had no live caller since the Dashboard redesign replaced that nav link with a dropdown. 8 new frontend tests (`tests/frontend/rail.test.mjs`, pure logic — `doorInitials`/`sortByLastActive`/`selectRailDoors`/`hasActiveOrQueuedRun`) since this repo's `node:test` runner has no DOM. Gates green: fmt/clippy(lib, `-D warnings`)/test(596 passed, unchanged — no new Rust tests, matching the untested `set_project_autonomous` precedent)/`tsc --noEmit`/`npm run build`. **Not verified live**: this is a Tauri desktop app with no `_electron`/Playwright driver in this repo and no browser-mode IPC mock, so a real click-through (door glow colors, right-click pin menu, overflow threshold) needs a human with `npm run tauri dev` — same documented gap as every prior UI-only loop in this file. +- **Previous** (2026-08-05): - **Goal**: `selasar-revamp` / `prd-rebrand-tokens` — complete (all 3 phases). Phase 2 rebrand: full-repo audit + rename of window title, wordmark, and in-app copy to "Selasar" (`.loopdeck/` + `project.yaml` untouched). Phase 3 verification: visual pass in light/dark/system-auto over every existing screen found and fixed 6 sub-4.5:1 WCAG contrast defects in `src/styles.css` (light warning/success/destructive darkened, dark muted-foreground + primary lightened, dark destructive-foreground → ink), and `npx tsc --noEmit` clean with "Selasar" statically confirmed in the window title bar. - **Status**: completed - ✅ **PRD delivery order — `order:` frontmatter, migrate/reorder commands, and two epic-sort bug fixes** (2026-08-06, ad-hoc user request, not tied to a docs/epics PRD, branch `claude/debug-vite-components-a36688`) — Added optional `order: u32` PRD frontmatter (`epic.rs`); `read_prds` sort key is `order` → README `## PRD Index` table position → filename, read-only (a first version auto-backfilled on read and corrupted this repo's own `docs/epics/**/*.md` via `cargo test`'s dogfood test — reverted). Two new explicit commands: `migrate_prd_order` (backfill missing values only, idempotent) and `set_prd_order` (full drag-to-reorder rewrite, permutation-validated). New `PrdReorderDialog.tsx` wired into `EpicsPanel.tsx` (reorder button before the edit pencil) — built on plain pointer events, not HTML5 `draggable`, after discovering Tauri's window-level drag-drop (used by `Chat.tsx`/`ImportFlow.tsx`) silently swallows `dragover`/`drop`. Also fixed two real epic-ordering bugs surfaced along the way: `EpicsView.tsx`'s cross-project milestone merge wasn't actually sorted (stale comment claimed it was), and `EpicsPanel.tsx`'s per-project epic list had no sort at all. Both now use a shared `sortEpics` helper (`lib/utils.ts`) — status-primary (`in_progress` → `proposed` → `abandoned` → `completed`), milestone ascending (numeric) secondary. Gates green: `cargo test` 596 passed (61 in `epic.rs`), `tsc --noEmit` clean. See decision of same date. Not verified live in the running app — Tauri IPC needs the real webview, and the dev-server port was held by another session throughout. @@ -64,6 +68,7 @@ - **Independent delivery (2026-07-27, worktree `loopdeck-dashboard-redesign-effort-69cb9b`)**: Redesigned the Dashboard to match a reference mockup (`LoopDeck 0.3.1 — Workspace Dashboard Mockup.html`, user-supplied). New top bar with a real ⌘K command palette (`CommandPalette.tsx`, built on the previously-installed-but-unwired `ui/command.tsx`/`cmdk` — closes the P6 backlog item that flagged the old decorative ⌘K hint as misleading); sidebar nav regrouped into Work/Memory sections with a "Local only · v0.2.0" status footer (`AppShell.tsx`). New "Needs attention" panel (`AttentionPanel.tsx`) sourced from live state only — pending permission/question/plan prompts (`usePendingInteractions`) and `run_state === "working"` projects — renders nothing when empty, no filler card. Project grid replaced with a project list (`ProjectList.tsx`, `ProjectCard.tsx` deleted — its only consumer was `Dashboard.tsx`) showing a derived state pill (Waiting/Working/Ready/Idle) and a state-dependent focus line. New "Today" timeline (`TodayPanel.tsx`) shares a newly-extracted `useActivityEvents` hook (`src/hooks/useActivityEvents.tsx`) with `ActivityFeed.tsx`, deduping ~150 lines of turn/decision/loop collector logic that was previously inline only in the Activity page. Backend: `ProjectEntry` gained ephemeral `next_steps_total`/`next_steps_done` fields (`config.rs`), parsed from `.loopdeck/loops.md`'s Next Steps checklist via the existing `memory::parse_loops` and wired into `import_project`/`list_projects`'s existing blocking closures alongside the `current_loop` read — same consistency level as that field; `rescan_project`/`get_project` intentionally left untouched (they don't refresh `current_loop` live either). No re-theme was needed — the app's existing violet/oklch design tokens already matched the mockup's palette intent. Scoped out per the plan: the mockup's mobile bottom-nav bar (desktop Tauri app), its non-functional "Filter ⌄" button, and its fabricated "N agents available"/per-card elapsed-time stats (replaced with real derived counts, or dropped where no real data exists). **Verified:** `cargo fmt --check` / `cargo clippy --lib -- -D warnings` / `cargo test --lib` (436 passed) all green; `tsc --noEmit` and `npm run build` clean; visually smoke-tested via the Vite dev server (shell layout, sidebar grouping, command palette open + navigate, light/dark theme toggle all confirmed working). **Not verified:** real project-data rendering end-to-end (`invoke()` rejects outside the native Tauri shell, so `list_projects` etc. can't be exercised from a plain browser) — needs a manual `npm run tauri dev` pass. ## Next Steps +- [ ] Review & merge: https://github.com/suprie/loopdeck/pull/84 (Project Rail — prd-rail-corridor-shell Phase 1) - [ ] Review & merge: https://github.com/suprie/loopdeck/pull/71 - [ ] Review & merge: https://github.com/suprie/loopdeck/pull/66 (docs-accuracy: audit + rewrite PRD.md/CLAUDE.md) - [ ] Review & merge: https://github.com/suprie/loopdeck/pull/new/feat/prd-wake-up diff --git a/docs/epics/optimization/prd-docs-accuracy.md b/docs/epics/optimization/prd-docs-accuracy.md index f89d035..98f120d 100644 --- a/docs/epics/optimization/prd-docs-accuracy.md +++ b/docs/epics/optimization/prd-docs-accuracy.md @@ -7,6 +7,7 @@ description: > Audit docs/PRD.md and CLAUDE.md against the code that actually ships, then rewrite both so neither states a non-goal the code violates or a file structure that no longer exists. No code changes — documentation only. +order: 10 --- # PRD — Docs Accuracy diff --git a/docs/epics/optimization/prd-frontend-test-coverage.md b/docs/epics/optimization/prd-frontend-test-coverage.md index 188f3f0..50820ae 100644 --- a/docs/epics/optimization/prd-frontend-test-coverage.md +++ b/docs/epics/optimization/prd-frontend-test-coverage.md @@ -8,6 +8,7 @@ description: > Vite + React 19 stack) and close the three coverage gaps a review flagged as highest-risk: streaming channels, migration cards, and permission- approval flows. Not a general coverage mandate — closes named gaps only. +order: 30 --- # PRD — Frontend Test Coverage diff --git a/docs/epics/optimization/prd-memory-hygiene.md b/docs/epics/optimization/prd-memory-hygiene.md index 18247cd..5a87bce 100644 --- a/docs/epics/optimization/prd-memory-hygiene.md +++ b/docs/epics/optimization/prd-memory-hygiene.md @@ -8,6 +8,7 @@ description: > and decisions.md, lower the archive trigger below the 90KB threshold that already proved insufficient once, and compact current content to fit — without deleting anything, only archiving it. +order: 40 --- # PRD — Memory Hygiene diff --git a/docs/epics/optimization/prd-process-discipline.md b/docs/epics/optimization/prd-process-discipline.md index 6c9a7d5..9e07e63 100644 --- a/docs/epics/optimization/prd-process-discipline.md +++ b/docs/epics/optimization/prd-process-discipline.md @@ -9,6 +9,7 @@ description: > amendments about amendments — after a review found this pattern in recent loop history plus a near-miss where an agent almost deleted the orchestrator by misreading its own memory. +order: 50 --- # PRD — Process Discipline diff --git a/docs/epics/optimization/prd-session-state-consolidation.md b/docs/epics/optimization/prd-session-state-consolidation.md index de47db8..9ce84ee 100644 --- a/docs/epics/optimization/prd-session-state-consolidation.md +++ b/docs/epics/optimization/prd-session-state-consolidation.md @@ -9,6 +9,7 @@ description: > commands/agent.rs (1731 lines) if it's still oversized once the maps are unified. The most concurrency-sensitive surface in the app, so this opens with a spike phase before any code moves. +order: 20 --- # PRD — Session State Consolidation diff --git a/docs/epics/overnight-orchestration/README.md b/docs/epics/overnight-orchestration/README.md index 8d82cad..b6b90b4 100644 --- a/docs/epics/overnight-orchestration/README.md +++ b/docs/epics/overnight-orchestration/README.md @@ -2,7 +2,7 @@ title: Overnight Orchestration slug: overnight-orchestration milestone: "0.4.0" -status: in_progress +status: completed started: 2026-07-27 owner: Suprie description: > diff --git a/docs/epics/selasar-revamp/prd-rail-corridor-shell.md b/docs/epics/selasar-revamp/prd-rail-corridor-shell.md index 350ebc2..6983651 100644 --- a/docs/epics/selasar-revamp/prd-rail-corridor-shell.md +++ b/docs/epics/selasar-revamp/prd-rail-corridor-shell.md @@ -62,24 +62,29 @@ on the existing routed `ProjectDetail` page as an interim target. ## Design -_Stub — pin/unpin trigger placement and the default rail state for an -existing install crossing 5 projects with zero pins are Phase 1 decisions, -not made yet._ +Phase 1 decisions resolved during implementation (2026-08-12): pin/unpin is a +right-click context menu on the door itself (no room card exists yet this +phase); an existing install crossing 5 projects with zero pins shows the 5 +most recently active as a fallback rather than an empty rail; pin state is a +plain `bool` on the global registry's `ProjectEntry` (per-machine, not +synced). The night-run indicator is a placeholder — derived from whether the +project has an active/queued `RunPlan` (existing run-queue data), pending +`prd-detail-drawer`'s spike settling the real `RunState` representation. ## Phases ### Phase 1 — Project rail -- [ ] Build a `Rail` component (72px icon strip, one door per project, 2-letter +- [x] Build a `Rail` component (72px icon strip, one door per project, 2-letter initials) replacing `AppShell.tsx`'s current sidebar markup. -- [ ] Wire each door's glow color to that project's `RunState` +- [x] Wire 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`. -- [ ] Add a pin/unpin affordance per project, and rail logic that shows all +- [x] Add 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. -- [ ] Move the settings entry point to a gear icon at the rail's foot, +- [x] Move the settings entry point to a gear icon at the rail's foot, preserving the existing `/settings` route. ### Phase 2 — Corridor room-card list diff --git a/docs/epics/selasar-revamp/prd-rebrand-tokens.md b/docs/epics/selasar-revamp/prd-rebrand-tokens.md index 25a2504..9ad2d60 100644 --- a/docs/epics/selasar-revamp/prd-rebrand-tokens.md +++ b/docs/epics/selasar-revamp/prd-rebrand-tokens.md @@ -2,7 +2,7 @@ prd: prd-rebrand-tokens epic: selasar-revamp milestone: "0.5.0" -status: proposed +status: completed description: > Replace the app's Tailwind-v4 design tokens with the mockup's paper/ink/ teak palette and serif display font (light default, full dark pair), and @@ -86,7 +86,7 @@ occurrence sites are Phase 1/Phase 2 outputs, not decided yet._ ### Phase 3 — Verification -- [x] Visual pass in light, dark, and system-auto against every existing +- [x] `selasar-revamp/visual-pass-in-light-dark-and-system-auto-against-every-existing` Visual pass in light, dark, and system-auto against every existing screen (Dashboard, ProjectDetail tabs, Settings, Activity, Loops, Decisions, Epics), confirming no contrast regression on destructive, warning, or focus states. diff --git a/index.html b/index.html index 3a19281..5843b4b 100644 --- a/index.html +++ b/index.html @@ -4,6 +4,7 @@