From f758b53336c678b963b1867fd76f0fb263c2f5ca Mon Sep 17 00:00:00 2001 From: Michael Freno Date: Sun, 9 Aug 2026 22:29:24 -0400 Subject: [PATCH] drop tasks dir --- tasks/yazi-remake/01-rearchitect-nav-model.md | 54 ---------- .../02-build-three-pane-layout-primitive.md | 56 ----------- .../03-convert-list-tabs-to-primitive.md | 58 ----------- .../04-fit-search-and-player-panes.md | 52 ---------- tasks/yazi-remake/05-rebuild-shell-chrome.md | 56 ----------- tasks/yazi-remake/06-rewire-keybinds.md | 56 ----------- .../07-blocker-task-04-player-search.md | 98 ------------------- tasks/yazi-remake/07-verify-remake.md | 61 ------------ tasks/yazi-remake/README.md | 40 -------- 9 files changed, 531 deletions(-) delete mode 100644 tasks/yazi-remake/01-rearchitect-nav-model.md delete mode 100644 tasks/yazi-remake/02-build-three-pane-layout-primitive.md delete mode 100644 tasks/yazi-remake/03-convert-list-tabs-to-primitive.md delete mode 100644 tasks/yazi-remake/04-fit-search-and-player-panes.md delete mode 100644 tasks/yazi-remake/05-rebuild-shell-chrome.md delete mode 100644 tasks/yazi-remake/06-rewire-keybinds.md delete mode 100644 tasks/yazi-remake/07-blocker-task-04-player-search.md delete mode 100644 tasks/yazi-remake/07-verify-remake.md delete mode 100644 tasks/yazi-remake/README.md diff --git a/tasks/yazi-remake/01-rearchitect-nav-model.md b/tasks/yazi-remake/01-rearchitect-nav-model.md deleted file mode 100644 index 2c70a33..0000000 --- a/tasks/yazi-remake/01-rearchitect-nav-model.md +++ /dev/null @@ -1,54 +0,0 @@ -# 01. Rearchitect nav model — remove the sidebar pane - -meta: - id: yazi-remake-01 - feature: yazi-remake - priority: P1 - depends_on: [] - tags: [implementation, nav-model, tests-required] - -objective: - -- Remove the always-on `SIDEBAR_PANE` concept from the navigation context so `activeTab` is plain tab state (not a pane), establishing clean parent|current|preview semantics for the yazi remake. - -deliverables: - -- `src/context/NavigationContext.tsx` — delete `SIDEBAR_PANE` constant and all references; `activeTab` is no longer a pane -- `src/utils/navigation.ts` — update `TabPaneCount` semantics; depth-tabs = 1 focusable pane (current), the 3 visible columns are a render concern not 3 panes -- Updated header/comment block describing the parent|current|preview model -- `swipe()` / `popDepth()` reworked: depth-tabs `l`=drill (`open`), `h`=pop (noop at depth 0); fixed-pane tabs `h/l` move between parent/current/preview -- Tab-enter resets focus to `DEPTH_CENTER_PANE` (current pane), not a sidebar - -steps: - -- Audit every reference to `SIDEBAR_PANE` across the codebase (grep) -- In `NavigationContext.tsx`: delete the `SIDEBAR_PANE = -1` export and the `focusedIndex`/`setFocusedIndex` SIDEBAR_PANE branch added previously -- Set the initial `activePane` signal and the tab-switch createEffect to reset to `DEPTH_CENTER_PANE` (the current pane), not `SIDEBAR_PANE` -- Rework `swipe()` to clamp to `[0, paneCount-1]` for fixed-pane tabs (the sidebar is no longer in the chain); depth-tabs don't use `swipe` for drill/pop (that lives in Shell dispatch) -- In `utils/navigation.ts`: confirm `TabPaneCount` reflects focusable content panes only (depth-tabs = 1, Search = 3, Player = 1); update `PANE_RATIO` leave-behind note (ratio change happens in task 02) -- Update the file header comment block to describe parent|current|preview -- Run `lens_diagnostics` on the two files - -tests: - -- Unit: `focusedIndex(DEPTH_CENTER_PANE)` on a depth-tab returns the top frame's focus; `setFocusedIndex` writes to the top frame (Arrange a tab with a 2-frame stack, Act by calling setFocusedIndex, Assert topFrame.focus updated) -- Integration: tab-switch effect sets `activePane` to `DEPTH_CENTER_PANE` (not -1); `swipe(-1, 3)` on a fixed tab clamps to 0 not -1 -- e2e (harness): app boots with `nav.state.pane === 0` (current), not -1 - -acceptance_criteria: - -- No symbol `SIDEBAR_PANE` exists anywhere in `src/` -- Initial `activePane` === `DEPTH_CENTER_PANE` (0) -- Tab-enter sets `activePane` to `DEPTH_CENTER_PANE` -- `swipe()` lower bound is 0 (no `-1`) - -validation: - -- `grep -rn "SIDEBAR_PANE" src/` returns nothing -- `bun run build` passes -- `lens_diagnostics` paths=[`src/context/NavigationContext.tsx`,`src/utils/navigation.ts`] severity=error → 0 findings - -notes: - -- This task unblocks 03/04/05/06. It must not delete `DEPTH_CENTER_PANE` — that constant is generalised to "the current pane" and retained -- `SIDEBAR_ACTIONS` (added in Shell in a prior turn) is removed in task 06 (the keybind rewrite), not here — but Shell will temporarily fail to compile after this task until 05/06 land; that's expected and the build command ignores type errors, so gate success on grep + targeted diagnostics, not the full build diff --git a/tasks/yazi-remake/02-build-three-pane-layout-primitive.md b/tasks/yazi-remake/02-build-three-pane-layout-primitive.md deleted file mode 100644 index d5fe2e7..0000000 --- a/tasks/yazi-remake/02-build-three-pane-layout-primitive.md +++ /dev/null @@ -1,56 +0,0 @@ -# 02. Build the reusable 3-pane layout primitive (1:3:3 ratio, stable parent slot) - -meta: - id: yazi-remake-02 - feature: yazi-remake - priority: P1 - depends_on: [] - tags: [implementation, layout, tests-required] - -objective: - -- Create one reusable `` primitive that renders three bordered columns (parent | current | preview) at a 1:3:3 grow ratio with a stable 1/7 parent slot even when blank, so every list tab shares an identical, layout-stable shell. - -deliverables: - -- `src/components/YaziPaneRow.tsx` — new component: props `parent`, `current`, `preview` (Solid JSX/accessors), `parentLabel`, `currentLabel`, `previewLabel`, `focused` (boolean, defaults to current) -- `src/utils/navigation.ts` — `PANE_RATIO` updated to `{ parent: 1, current: 3, preview: 3 }` (was `{ parent: 1, current: 4, preview: 3 }`) -- Each pane: bordered `scrollbox` + slim header label row (height=1) -- Parent pane keeps its 1/7 `flexGrow` slot even when empty (renders a muted placeholder, never `width:0`) -- Focus ring (border color = accent on current; muted `border` on parent & preview) - -steps: - -- Set `PANE_RATIO = { parent: 1, current: 3, preview: 3 }` in `utils/navigation.ts` -- Create `YaziPaneRow.tsx` exporting a component that lays out three `` columns in a row -- Each column: a height-1 header `` with the label text, then a `` rendering the passed children -- Thread a `theme` via `useTheme()` inside the primitive (don't require callers to pass colors) -- `focused` prop controls which column gets the accent border — default current; parent & preview always muted -- Ensure the parent column renders a muted placeholder box (e.g. a single `` or empty) when its children are null, but critically keeps `flexGrow={PANE_RATIO.parent}` so width never collapses -- Add a JSDoc header describing the yazi 1:3:3 contract -- Run diagnostics on the new file - -tests: - -- Unit: the primitive renders three boxes with flexGrow 1/3/3 regardless of null children (Arrange null parent, render, Assert three columns present with correct flexGrow) -- Integration: toggling `focused` swaps the accent border onto the requested column -- e2e (harness): a page using the primitive shows three equal-ratio columns with the parent column visibly non-zero width even when blank - -acceptance_criteria: - -- `PANE_RATIO` is `{ parent: 1, current: 3, preview: 3 }` -- `YaziPaneRow` accepts parent/current/preview children + labels + focused -- Parent column width never collapses to 0 (stable 1/7 slot) -- Only the focused column shows the accent border - -validation: - -- `grep -n "PANE_RATIO" src/utils/navigation.ts` shows the new 1:3:3 values -- `lens_diagnostics` paths=[`src/components/YaziPaneRow.tsx`,`src/utils/navigation.ts`] severity=error → 0 findings -- Harness: render a throwaway page using ``; confirm 3 columns at 1:3:3 via the frame - -notes: - -- Independent of task 01 (no nav-state dependency) — can be built in parallel -- Callers (tasks 03/04) pass their own parent/current/preview JSX; the primitive is purely structural -- opentui scrollbox: use `focused` only on the current pane so scroll focus follows the cursor diff --git a/tasks/yazi-remake/03-convert-list-tabs-to-primitive.md b/tasks/yazi-remake/03-convert-list-tabs-to-primitive.md deleted file mode 100644 index 686f9eb..0000000 --- a/tasks/yazi-remake/03-convert-list-tabs-to-primitive.md +++ /dev/null @@ -1,58 +0,0 @@ -# 03. Convert Feed/MyShows/Discover/Settings to the shared parent|current|preview primitive - -meta: - id: yazi-remake-03 - feature: yazi-remake - priority: P2 - depends_on: [yazi-remake-01, yazi-remake-02] - tags: [implementation, pages, tests-required] - -objective: - -- Rewrite the four depth-stack list tabs to render through ``, with the previous-depth list now visible in the parent pane (blank at depth 0), the current-depth list in current, and the hovered item in preview — eliminating per-page bespoke 3-column JSX. - -deliverables: - -- `src/pages/Feed/FeedPage.tsx` — rewritten to use ``; parent = previous-depth list, current = current-depth list, preview = hovered item detail -- `src/pages/MyShows/MyShowsPage.tsx` — same conversion -- `src/pages/Discover/DiscoverPage.tsx` — same conversion -- `src/pages/Settings/SettingsPage.tsx` — same conversion (sections → items → editor) -- Each page's `nav.action` handler retained but only acts on the current pane -- All per-page bespoke row/flexbox 3-column JSX removed - -steps: - -- For each of the four pages, read the current implementation to extract the parent/current/preview content builders -- Wrap the page body in `` -- Parent pane: render the previous-depth frame's list (depth-1). At depth 0 the parent receives null/placeholder (the primitive keeps the slot) -- Current pane: the current-depth list, focusable, with `onMouseDown` row handlers calling `nav.setActivePane(DEPTH_CENTER_PANE)` + `nav.setDepthFocus(i, depth)` -- Preview pane: hovered-item detail derived from `focusedIndex(DEPTH_CENTER_PANE)` (unchanged logic, just relocated into the preview slot) -- Keep `pushDepth`/`popDepth` calls in the `open` action (drill) — behaviour unchanged, only layout changes -- Remove the old inline `` columns in favour of the primitive -- Verify each page's `nav.action` handler guards on `data.pane === DEPTH_CENTER_PANE && nav.activePane() === DEPTH_CENTER_PANE` - -tests: - -- Unit: each page's `open` action pushes a frame and the parent pane switches from blank to the previous list (Arrange depth 0, Act open, Assert stack length 2 and parent renders the old list) -- Integration: `h` (pop) returns parent to blank at depth 0; `l` (drill) populates parent with the previous list -- e2e (harness): Feed depth 0→1→2 shows parent blank → previous feeds list → previous episodes list; Settings sections→items→editor shows the chain in the parent pane - -acceptance_criteria: - -- All four pages render via `` (no bespoke 3-column JSX remains) -- Parent pane is blank at depth 0, populated at depth ≥ 1 -- Drilling (l/Enter) populates the parent with the previous-depth list -- Popping (h) empties the parent back to blank at depth 0 -- j/k move focus only within the current pane - -validation: - -- `grep -rn "YaziPaneRow" src/pages/` returns 4 files -- `lens_diagnostics` paths over the four page files severity=error → 0 findings -- Harness walk: `init` → navigate Feed → `l` (drill) → `l` (drill) → `h` (pop) → `h` (pop); confirm parent slot transitions blank→list→list→blank - -notes: - -- Depends on 01 (pane model) and 02 (the primitive) being merged -- The already-working `{(item) => (… item() …)}` accessor pattern for opentui `` callbacks must be preserved in preview panes -- Keep `LoadingIndicator` usages where they exist diff --git a/tasks/yazi-remake/04-fit-search-and-player-panes.md b/tasks/yazi-remake/04-fit-search-and-player-panes.md deleted file mode 100644 index af55a15..0000000 --- a/tasks/yazi-remake/04-fit-search-and-player-panes.md +++ /dev/null @@ -1,52 +0,0 @@ -# 04. Fit Search and Player into the 3-pane (1:3:3) model - -meta: - id: yazi-remake-04 - feature: yazi-remake - priority: P2 - depends_on: [yazi-remake-01, yazi-remake-02] - tags: [implementation, pages, tests-required] - -objective: - -- Bring the two fixed-layout tabs (Search, Player) into the same 1:3:3 parent|current|preview shell, deciding per-page whether to adopt the depth-stack or stay fixed-3-pane, while applying the new ratios throughout. - -deliverables: - -- `src/pages/Search/SearchPage.tsx` — rendered through ``; parent = query input + recent-search history, current = results list, preview = focused-result detail -- `src/pages/Player/PlayerPage.tsx` — rendered through ``; current = now-playing transport, preview = episode description/notes, parent = blank placeholder (or compact episode list if available) -- Decision recorded in each file's header comment: depth-stack vs fixed-3-pane - -steps: - -- Read both pages to understand their current pane semantics -- Search: map INPUT→parent, RESULTS→current, DETAIL→preview inside ``. If the 1/7 parent slot is too narrow for the input box, widen parent for Search only by passing an override ratio OR move the query into current and results into parent — pick the option that keeps the input usable and document it -- Search: keep the `inputFocused` effect (Shell yields keys to `` when current-pane focus is on the query) — adapt to whichever pane the input lives in -- Player: single content pane; parent = blank/placeholder (1/7), current = transport + progress + controls (3/7), preview = episode art/description/notes (3/7). If no preview data, render a muted placeholder but keep the slot -- Confirm fixed-pane tab swipe (h/l between parent/current/preview) still routes correctly for Search -- Run diagnostics - -tests: - -- Unit: Search's `handleSubmit` swipes to the results pane and sets focus index 0 (Arrange empty results, Act submit, Assert activePane === results pane & focusedIndex 0) -- Integration: Player renders with parent blank and the transport in current -- e2e (harness): Search shows query | results | detail at 1:3:3; Player shows blank | transport | notes at 1:3:3 - -acceptance_criteria: - -- Both pages render via `` at 1:3:3 -- Search input remains typeable (Shell yields keys when the query pane is focused) -- Player's transport is in the current pane with focus -- No layout collapse: parent & preview keep their slots even if blank - -validation: - -- `grep -rn "YaziPaneRow" src/pages/Search src/pages/Player` returns 2 files -- `lens_diagnostics` paths over both files severity=error → 0 findings -- Harness: navigate to Search, type a query, press Enter, see results in current + detail in preview; navigate to Player, see transport + notes - -notes: - -- Depends on 01 (pane model — though Search is fixed-pane, the model cleanup affects `swipe` bounds) and 02 (the primitive) -- If Search input at 1/7 is genuinely too tight (~14 cols at 100w), prefer moving the query into the current pane for Search only and the results into parent — but confirm width with the harness before committing -- Player is single-content; the 1:3:3 with blanks is mostly cosmetic but keeps the layout globally consistent diff --git a/tasks/yazi-remake/05-rebuild-shell-chrome.md b/tasks/yazi-remake/05-rebuild-shell-chrome.md deleted file mode 100644 index 0399d4e..0000000 --- a/tasks/yazi-remake/05-rebuild-shell-chrome.md +++ /dev/null @@ -1,56 +0,0 @@ -# 05. Rebuild Shell chrome — drop sidebar, add yazi bottom status/tab bar - -meta: - id: yazi-remake-05 - feature: yazi-remake - priority: P1 - depends_on: [yazi-remake-01] - tags: [implementation, shell-chrome, tests-required] - -objective: - -- Remove the always-on left tab sidebar entirely and replace it with a full-width page area above a slim yazi-style bottom bar that surfaces the active tab, depth/counts, selection, now-playing, and a discoverable tab strip. - -deliverables: - -- `src/components/Shell.tsx` — sidebar JSX deleted; render `LayerGraph[tab]()` full-width + a rebuilt bottom status/command bar -- Bottom bar (normal mode): mode label, `TAB_LABEL[tab] · depth N · i/len` (or `pane i/n` for fixed tabs), selection count `●N`, now-playing `♪ title`, pending-keybind hint, and a compact tab strip `[1]Feed [2]MyShows …` with the active tab marked -- Bottom bar (command mode): `:` prompt + buffer + error (unchanged, just relocated if needed) -- Help overlay kept; now-playing relocated from the old sidebar footer into the status bar - -steps: - -- Read `Shell.tsx` and delete the entire left tab sidebar `…` block -- Replace the middle row with a single full-width `{LayerGraph[nav.activeTab()]()}` -- Rebuild the bottom bar: a height-1 `` with the fragments described above -- Tab strip: render `Object.values(TABS)` filtered to numbers; for each tab show `[N] Label` with the active tab inverted/highlighted (accent bg or `≡` marker) -- Status fragment: `nav.activePane() === DEPTH_CENTER_PANE ? (isDepthTab ? \`depth ${currentDepth()}\` : \`pane ${activePane()+1}/${count}\`) : 'tabs'` — but since the sidebar is gone, default to the depth/pane string (focus starts on current) -- Relocate `nowPlaying()` text from the sidebar footer into the bottom bar -- Keep `runCommand`, `handleCommandKey`, the help overlay, and `playEpisodeAndSwitch` untouched -- Run diagnostics - -tests: - -- Unit: `nowPlaying()` formats `♪ ` (Arrange a current episode, Assert the string) -- Integration: switching tabs updates the tab strip's active marker and the status tab label -- e2e (harness): `init` shows no left sidebar, a full-width page, and a bottom bar containing the tab strip + `Feed · depth 0`; cycling tabs moves the strip's active marker - -acceptance_criteria: - -- No `width={14}` sidebar `` remains in `Shell.tsx` -- The active page fills the full content width -- The bottom bar shows the active tab, depth, counts, selection, now-playing, and the tab strip -- The active tab is visually marked in the strip - -validation: - -- `grep -n "width={14}" src/components/Shell.tsx` returns nothing -- `grep -n "LayerGraph" src/components/Shell.tsx` shows the full-width render -- `lens_diagnostics` paths=[`src/components/Shell.tsx`] severity=error → 0 findings -- Harness: `init` frame has no sidebar column and shows the tab strip in the last row - -notes: - -- Depends on 01 (the pane model: focus starts on current, so the status fragment no longer needs the `SIDEBAR_PANE` branch) -- Task 06 rewrites the dispatch keybinds in this same file; do the chrome here and leave the dispatch `SIDEBAR_ACTIONS` branch for 06 to remove (or remove it here if 01 already deleted the constant — coordinate with 01) -- `playEpisodeAndSwitch` and the command bar must keep working diff --git a/tasks/yazi-remake/06-rewire-keybinds.md b/tasks/yazi-remake/06-rewire-keybinds.md deleted file mode 100644 index 5281595..0000000 --- a/tasks/yazi-remake/06-rewire-keybinds.md +++ /dev/null @@ -1,56 +0,0 @@ -# 06. Rewire keybinds — h/l drill+pop, digits switch tabs, focus starts on current - -meta: - id: yazi-remake-06 - feature: yazi-remake - priority: P1 - depends_on: [yazi-remake-01, yazi-remake-05] - tags: [implementation, keybinds, tests-required] - -objective: - -- Rewire the Shell dispatch so the sidebar's special-cased j/k branch is gone, h/l drill/pop on depth-tabs and swipe on fixed tabs, digit keys + `[ ]` are the sole tab switcher, and app focus starts on the current pane. - -deliverables: - -- `src/components/Shell.tsx` (dispatch) — `SIDEBAR_ACTIONS` set + the `if (nav.activePane() === SIDEBAR_PANE)` branch deleted -- `h`/`l` unified: depth-tabs `l`=current-drills (`open` emit), `h`=current-pops (noop at depth 0); fixed-pane tabs `h/l`=`swipe(∓1, count)` -- `1`-`6` / `tab-goto-*`, `tab-next`/`tab-prev` (`[`/`]`) — the only tab switchers -- Initial focus + tab-enter land on `DEPTH_CENTER_PANE` -- `keybinds.jsonc` reviewed (update labels/help only if needed) - -steps: - -- Read the current `dispatch()` (post task 01 it references a deleted `SIDEBAR_PANE` — fix the compile here) -- Remove the `SIDEBAR_ACTIONS` constant and its branch -- In the `default` case, implement: digit/tab-goto → `setActiveTab`; `swipe-prev` → (depth-tab & current & depth>0) `popDepth` else (depth-tab & current & depth==0) noop else `swipe(-1, count)`; `swipe-next` → (depth-tab & current) emit `open` else `swipe(1, count)` -- Move/list actions (`move-down/up`, `jump-*`, `page-*`, `goto-top/bottom`) flow to `PAGE_ACTIONS` → `emit("nav.action")` for the current pane only -- Confirm `escape`/`command`/`visual-mode`/`toggle-select`/audio/global branches unchanged -- Verify the app boot path sets focus to current (task 01 set the signal; confirm dispatch doesn't override) -- Run diagnostics + harness key sequence - -tests: - -- Unit: `dispatch("move-down")` on a depth-tab current pane emits `nav.action {action:"move-down"}` (Arrange current pane, Act, Assert emit) -- Integration: `dispatch("swipe-next")` on a depth-tab at depth 0 emits `open` (drill); `dispatch("swipe-prev")` at depth 1 pops to depth 0; at depth 0 `swipe-prev` is a noop -- e2e (harness): `l` drills (depth 0→1, parent populates), `h` pops (1→0, parent blanks), `1`/`2`/`3` switch tabs, `j`/`k` move the current list cursor without changing depth - -acceptance_criteria: - -- No `SIDEBAR_PANE` or `SIDEBAR_ACTIONS` references in `Shell.tsx` -- `h` at depth 0 is a noop (does not error, does not change pane) -- `l` at current on a depth-tab drills (depth+1) -- Digit keys switch tabs; focus lands on current pane -- `j`/`k` move within current only - -validation: - -- `grep -n "SIDEBAR" src/components/Shell.tsx` returns nothing -- `lens_diagnostics` paths=[`src/components/Shell.tsx`] severity=error → 0 findings -- Harness: `init` (focus on current) → `l` (depth 1, parent filled) → `l` (depth 2) → `h` (depth 1) → `h` (depth 0, parent blank) → `3` (Discover tab, focus on current) → `j`/`k` move - -notes: - -- Depends on 01 (pane model: `swipe` bounds, no SIDEBAR) and 05 (dispatch lives in the rebuilt Shell) -- If `keybinds.jsonc` has a `tab-next`/`tab-prev` mapping conflict, resolve here -- The noop `h` at depth 0 should feel inert (yazi: at root, `h` does nothing) diff --git a/tasks/yazi-remake/07-blocker-task-04-player-search.md b/tasks/yazi-remake/07-blocker-task-04-player-search.md deleted file mode 100644 index 83faf17..0000000 --- a/tasks/yazi-remake/07-blocker-task-04-player-search.md +++ /dev/null @@ -1,98 +0,0 @@ -# 07-blocker — Task 04 (Search + Player) never converted to YaziPaneRow - -meta: - id: yazi-remake-07-blocker - feature: yazi-remake - priority: P0 - blocks: [yazi-remake-07] - blocked_by: [yazi-remake-04] - tags: [blocker, verification, tasks-required] - -## Problem - -Task 04 (`04-fit-search-and-player-panes.md`) is marked complete, but its -core deliverable was never implemented: - -> - `src/pages/Player/PlayerPage.tsx` — rendered through `` -> - `src/pages/Search/SearchPage.tsx` — rendered through `` - -`grep -rn "YaziPaneRow" src/pages/Search src/pages/Player` → **0 files**. - -## Evidence (from task 07 harness walk-through, 100×30) - -### Player ❌ - -`src/pages/Player/PlayerPage.tsx` renders a single full-width -`` (now-playing transport + controls). No parent pane, no preview -pane. Frame `.harness/player-current.txt`: - -``` -│ Now Playing 0:00 / 0:00 (0%) │ -... -│ │ │[Prev]│ │[Play]│ │[Next]│ Vol 70% Speed 1x ... │ │ -``` - -Expected (task 04 + feature exit criteria): `blank | transport | notes` at -1/7 : 3/7 : 3/7. - -### Search ⚠️ ratio wrong - -`src/pages/Search/SearchPage.tsx` renders three custom `` columns but **omits `flexBasis={0}`**, so Yoga distributes -space by natural content width (the input box is `width={28}`). Measured -column widths at 100 cols: **31 / 32 / 31** (equal thirds), NOT the target -**~14 / 43 / 43** (1:3:3). - -`` exists precisely to set `flexBasis={0}` per column and force -the exact 1:3:3 ratio regardless of content (see its header comment). Routing -Search through it fixes the ratio for free. - -## Why not patched in task 07 - -Task 07 is explicitly the verification gate. Its notes: - -> - This is the gate for the whole feature — do not mark done if any criterion -> fails; open a blocker task instead -> - If the harness reveals a visual regression (e.g. parent collapses, ratios -> off), file it against the responsible task (02 or 03) rather than -> patching here - -This is a missing implementation in task 04, not a regression in 02/03, so the -responsible task is 04. Patches belong there. - -## Failing exit criteria - -- "All tabs render three stable columns at 1/7 : 3/7 : 3/7" — Player fails - (not 3 columns); Search fails (wrong ratio). -- "`5` → Player: blank|transport|notes at 1:3:3" — fails. -- "`4` → Search: query|results|detail at 1:3:3" — 3 columns yes, ratio wrong. - -## Fix plan (task 04 do-over) - -1. `src/pages/Player/PlayerPage.tsx` — wrap the existing transport JSX in a - ``. - Parent should fall through to the primitive's muted `—` placeholder (it - already keeps its 1/7 slot when blank). Preview = episode description / - waveform (currently inline under "Now Playing"). Keep `PlayerPaneCount=1` - (the visible columns are a render concern; only current=0 is focusable). -2. `src/pages/Search/SearchPage.tsx` — replace the three custom `` columns with a single ``. Keep the - `inputFocused` effect so the Shell yields keys to the native `` - when the query pane is focused — note `inputFocused` is a Search-owned - signal; YaziPaneRow's `focused` prop only drives the accent ring + scroll - focus, which for Search can stay on the current (results) column. -3. Remove the now-dead custom ratio code from both files after the swap. -4. Re-run: `grep -rn YaziPaneRow src/pages/Search src/pages/Player` → 2 files; - `bun run build`; `bun test`; harness walk-through: Player shows 3 cols, - Search cols measure ~14/43/43. - -## Verification gates (re-run task 07 after fix) - -- `bun run build` → "Build complete" -- `bun test` → 0 fail -- harness: - - Player frame has 3 bordered columns (parent `—`, current transport, - preview notes/placeholder) at 1:3:3 - - Search frame columns measure ~14/43/43 diff --git a/tasks/yazi-remake/07-verify-remake.md b/tasks/yazi-remake/07-verify-remake.md deleted file mode 100644 index b1fdcac..0000000 --- a/tasks/yazi-remake/07-verify-remake.md +++ /dev/null @@ -1,61 +0,0 @@ -# 07. Verify the remake — build + diagnostics + harness walk-through - -meta: - id: yazi-remake-07 - feature: yazi-remake - priority: P1 - depends_on: [yazi-remake-03, yazi-remake-04, yazi-remake-05, yazi-remake-06] - tags: [verification, tests-required] - status: BLOCKED # see .harness/verification-07.md + tasks/yazi-remake/07-blocker-task-04-player-search.md - -objective: - -- Confirm the yazi remake meets every exit criterion via a clean build, zero diagnostics, and a full harness walk-through of every tab and depth. - -deliverables: - -- A passing `bun run build` -- `lens_diagnostics mode=all` with zero errors across edited files -- Harness frames + state proving the parent|current|preview 1:3:3 layout, drill/pop behaviour, tab switching, and status bar across all six tabs - -steps: - -- Run `bun run build` — expect "Build complete" -- Run `lens_diagnostics mode=all severity=error` — expect 0 findings across all session-edited files -- Run the drive harness (`scripts/tui-harness.tsx`) walk-through: - - `init` → confirm no sidebar, 3 columns at 1:3:3, focus on current, bottom tab strip visible - - Feed: `l` (depth 0→1, parent fills) → `l` (1→2) → `h` (2→1) → `h` (1→0, parent blanks) ; `j`/`k` move current - - `2` → MyShows: drill show→episodes, parent reflects - - `3` → Discover: category→results, parent shows categories - - `6` → Settings: sections→items→editor, parent shows the previous list at each depth - - `4` → Search: query|results|detail at 1:3:3; type + Enter works - - `5` → Player: blank|transport|notes at 1:3:3 -- Capture the status bar content (active tab + depth + counts + now-playing + tab strip) from a representative frame - -tests: - -- Build: `bun run build` exits 0 with "Build complete" -- Diagnostics: `lens_diagnostics` mode=all → 0 errors -- Harness (integration/e2e): the walk-through above produces the expected frames & state (parent blank at depth 0, populates on drill, blanks on pop; digits switch tabs; h noop at depth 0) - -acceptance_criteria: - -- `bun run build` passes -- `lens_diagnostics` mode=all reports zero errors -- All six tabs render 3 stable columns at 1:3:3 -- Parent pane is blank at depth 0; drill fills it with the previous-depth list; pop empties it -- `h` is a noop at depth 0; `l` drills; `1-6`/`[`/`]` switch tabs; `j/k` move current only -- No sidebar; focus starts on current; bottom bar shows active tab + depth + counts + tab strip - -validation: - -- `bun run build 2>&1 | tail -3` → "Build complete" -- `lens_diagnostics` mode=all severity=error → "No error issues…" -- Harness `state nav` after `init` shows `pane === 0` (current), not -1 -- Harness frames for Feed depth 0/1/2 show the parent slot transition blank→list→list - -notes: - -- This is the gate for the whole feature — do not mark done if any criterion fails; open a blocker task instead -- If the harness reveals a visual regression (e.g. parent collapses, ratios off), file it against the responsible task (02 or 03) rather than patching here -- Save a representative `.harness/last-frame.txt` snapshot if a visual reference is useful for future sessions diff --git a/tasks/yazi-remake/README.md b/tasks/yazi-remake/README.md deleted file mode 100644 index de0899a..0000000 --- a/tasks/yazi-remake/README.md +++ /dev/null @@ -1,40 +0,0 @@ -# Yazi UI Remake - -Objective: Remake the PodTUI shell into a yazi-pure parent|current|preview 3-pane layout (1:3:3 ratio) with a bottom tab strip and no always-on sidebar. - -Status legend: [ ] todo, [~] in-progress, [x] done - -## Tasks - -- [x] 01 — rearchitect-nav-model → `01-rearchitect-nav-model.md` -- [x] 02 — build-three-pane-layout-primitive → `02-build-three-pane-layout-primitive.md` -- [x] 03 — convert-list-tabs-to-primitive → `03-convert-list-tabs-to-primitive.md` -- [x] 04 — fit-search-and-player-panes → `04-fit-search-and-player-panes.md` -- [x] 05 — rebuild-shell-chrome → `05-rebuild-shell-chrome.md` -- [x] 06 — rewire-keybinds → `06-rewire-keybinds.md` -- [x] 07 — verify-remake → `07-verify-remake.md` - -## Dependencies - -- 03 depends on 01 -- 03 depends on 02 -- 04 depends on 01 -- 04 depends on 02 -- 05 depends on 01 -- 06 depends on 01 -- 06 depends on 05 -- 07 depends on 03 -- 07 depends on 04 -- 07 depends on 05 -- 07 depends on 06 - -## Exit criteria - -- The feature is complete when the left tab sidebar is gone; tabs switch only via digit keys `1-6` / `[ ]` and a bottom tab strip -- All tabs render three stable columns at 1/7 : 3/7 : 3/7 (parent | current | preview) -- The parent pane renders the previous-depth list and is blank (but keeps its 1/7 slot) at depth 0 -- `h`/`l` drill (push) and pop depths on list tabs; `h` is a noop at depth 0 -- `j`/`k` move within the current pane only; focus starts on the current pane -- Feed depth 0→1→2, MyShows, Discover, Settings (sections→items→editor), Search, and Player all render correctly via the drive harness -- `bun run build` passes and `lens_diagnostics` (mode=all) reports zero errors -- The bottom status bar shows active tab + depth + counts, selection count, now-playing, and the tab strip