Public: anyone can read this; the crew can change it.

The packs list is keyboard-first: j/k move between rows, enter opens one #10425

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

The `/packs` list now joins the shell's j/k row traversal, so j/k move between packs and enter opens the highlighted one.

shipped production is serving it deploy abf00b0

opened this

The /packs list now joins the shell's j/k row traversal, so j/k move between packs and enter opens the highlighted one.

  • Change: src/web/pages/packs.ts adds nav: true to each row in the /packs list. The whole title of each row is its link, so enter opens the pack.
  • Left alone: the rows on a pack's own page. They are external links and a crew list with no links, so they have no nav.
  • Test: the new test/keys-packs.test.ts asserts one data-nav row per catalog pack, that each row's first link is /packs/<name>, and that a pack's own page has none. It fails without the packs.ts change and passes with it.
  • No empty-list test: I did not write one. The catalog always ships packs, so /packs has no empty state to render.
  • Checks: the new test passes, bun scripts/design-lint.ts is clean, and bun x tsc --noEmit is clean. I did not run any other tests.
  • Try it: open /packs, press j then k, then enter.
  • Push: the pre-push hook demanded a "Try:" commit, so I added an empty one with the same try line.

Closes #10404

commented

The /packs list now joins the shell's j/k row traversal, so j/k move between packs and enter opens the highlighted one.

  • Change: src/web/pages/packs.ts adds nav: true to each row in the /packs list. The whole title of each row is its link, so enter opens the pack.
  • Left alone: the rows on a pack's own page. They are external links and a crew list with no links, so they have no nav.
  • Test: the new test/keys-packs.test.ts asserts one data-nav row per catalog pack, that each row's first link is /packs/<name>, and that a pack's own page has none. It fails without the packs.ts change and passes with it.
  • No empty-list test: I did not write one. The catalog always ships packs, so /packs has no empty state to render.
  • Checks: the new test passes, bun scripts/design-lint.ts is clean, and bun x tsc --noEmit is clean. I did not run any other tests.
  • Try it: open /packs, press j then k, then enter.
  • Push: the pre-push hook demanded a "Try:" commit, so I added an empty one with the same try line.
Changes requested — before the latest push

The change is correct and works in the preview: /packs renders one data-nav row per pack, and the rows on a pack page have none. No security or design-system findings. One miss: the issue's box 2 asks for an assertion that the empty page carries no data-nav, and the test does not have it.

Fix: add the empty-page test. Make the catalog empty, or render the list with no packs, then assert the page has no class="row"[^>]*data-nav tabindex="-1" match, as test/keys-flags-list.test.ts does at line 64. "The catalog always ships packs" is the reason a test is wanted: it pins the behaviour if the catalog ever empties. Note also that packs.ts has no empty-state branch, so if rendering it empty is impractical, say so in the pull and ask the issue to drop that clause.

commented

The packs list is now keyboard-first: /packs renders each pack as one data-nav row, so j/k move between packs and enter opens the first link in the row. A pack's own page keeps its rows out of the traversal.

Review fix: I added the empty-page test that box 2 asked for. test/keys-packs.test.ts now renders the list with no packs and asserts no class="row"[^>]*data-nav tabindex="-1" match, the same pattern as test/keys-flags-list.test.ts.

One small refactor: the catalog is read once per process, so I couldn't empty it for the test. I pulled the list markup out of packsPage into an exported packsList(packs) in src/web/pages/packs.ts. packsPage calls it, so the markup and the page's behaviour are unchanged, and the test calls it with [].

Not done: packs.ts has no empty-state branch (no "no packs yet" message), and I didn't add one. The issue doesn't ask for it.

Checks: tsc --noEmit is clean, bun test test/keys-packs.test.ts passes (3 tests), and design-lint is clean. I did not run scripts/gate.ts, and I did not run the full suite; the forge's check runs that on the push.

Try it: open /packs, press j then k to move between packs, and enter to open one.

🤖 Generated with Claude Code

commented

The packs list now joins the shell's j/k traversal. /packs marks each pack row as a stop, so j and k move between packs and Enter opens the focused one.

Why the check failed: my change didn't cause it. src/kernel/why_now.ts was left importing nothing under src/ when the gate retired the "why does this go ahead of the pipeline" question (54dacba00). That tripped "every module under src/ is imported by another, or allowed". The failure only showed once the branch was merged with current main.

The fix: I merged main into this branch and deleted src/kernel/why_now.ts and test/why-now.test.ts. The test was the file's only importer, and nothing else references the module. I preferred deleting it to adding it to scripts/unreached-allow.json, because that list is meant only to shrink.

What changed in the packs list:

  • src/web/pages/packs.ts has the list as a packsList function, and each row is built with nav: true.
  • test/keys-packs.test.ts checks that the rows are j/k stops, and that an empty list draws no data-nav row.

Not done: nothing beyond the issue. I didn't touch other lists.

Checks run locally: bun x tsc --noEmit is clean, and test/unreached.test.ts and test/keys-packs.test.ts pass. I didn't run the full suite, since the forge runs it on push.

To try it: open /packs on the preview, press j then k, then Enter.

🤖 Generated with Claude Code

Approved

Earlier ask (empty-page test for box 2) is met: packsList([]) is asserted to draw no data-nav row. The new lines are clean: packsList is a small exported function, each row carries nav: true, and the pack page keeps none. The preview serves /packs with 200 and data-nav rows. Deleting the unreached why_now.ts and its test is what the unreached check needs, and nothing else imports it. Non-blocking: scripts/unreached-allow.json lists src/kernel/why_now.ts in my clone of main. If the head still lists it, the stale-entry test in test/unreached.test.ts will name it once the file is gone, so remove the line if so.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs