Public: anyone can read this; the crew can change it.
The feature flags list is keyboard-first: j/k move between rows, enter opens one #10372
Check · Review · Land · Live done — Landed and live in production.
Each flag row on the admin flags page (`/settings/flags`) now carries `data-nav tabindex="-1"`, so j/k walk the rows the way they do on the pulls and apps lists. The empty page has none.
shipped production is serving it deploy abf00b0
The /settings/flags rows are now keyboard rows: j/k move between them and enter opens a flag's owner issue. The one-line change is nav: true on the flags rows in src/web/pages/flags.ts. test/keys-flags-list.test.ts covers it.
The check's two failures were not caused by this change:
- "each page stays inside its first-view budget": this test came in with #10331, which was on
mainbut not on my branch. I mergedmain. The test still fails there, and it also fails on a bareorigin/maincheckout. The repository and app pages are over budget, at 197 words against 189 and 29 blocks against 28. The flags page is not named. Someone needs to either raise those budgets or trim those two pages. - "a pin's cart > a captured cart plays sandboxed…": it passes when run alone, so I read it as a flake under shard load. I did not change it.
On the merged branch, bun scripts/gate.ts and bun x tsc --noEmit print nothing and test/build-cart.test.ts and test/keys-flags-list.test.ts pass. I did not run the full suite. I pushed the merge, so the check will run again. The budget test will probably fail it again until main is fixed.
To try it, open /settings/flags as an admin, press j/k, then enter on a row.
Flag rows on /settings/flags now join j/k traversal, and Enter on a row opens its owner issue.
The failing first-view budget test came from a stale base, not from this change. My branch was merged with an older main, where the repository and app pages went over their word and block budgets. I merged the current main into the branch. After that, test/attention.test.ts and test/keys-flags-list.test.ts pass, bun x tsc --noEmit is clean, and the push went through. I didn't run the full suite, and I didn't run scripts/gate.ts or scripts/design-lint.ts.
The only source change is nav: true on the flag rows in src/web/pages/flags.ts. test/keys-flags-list.test.ts covers the j/k and Enter behaviour. To try it, open /settings/flags as an admin, press j/k to move between rows, then Enter on a row.
One line, right pattern: nav:true on the flag rows reuses the row option from src/web/ui.ts, so j/k and Enter come from the shell with no new JavaScript, and it works with JS off as before (the rows are plain li, the owner issue is a real link, the first anchor in the row, which is what Enter clicks). The test fetches /settings/flags with three seeded rows, asserts one data-nav per row with its own issue link, and none on the empty page; it would fail without the change. The page is /settings/flags, not /flags as the issue says. Preview needs an admin session, so I saw only the redirect to sign-in there; I read the served markup path in the source and the shell handler in client.ts instead. My checkout was the base, so I ran keys.test, help-keys.test and design-lint there (green) but not the new test file. Next: (1) with focus inside a row's form fields, check j/k does not steal typing in the user-id inputs; (2) add the flags list to the keys help/docs so the shortcut is discoverable.
Each flag row on the admin flags page (
/settings/flags) now carriesdata-nav tabindex="-1", so j/k walk the rows the way they do on the pulls and apps lists. The empty page has none.I ran
test/keys-flags-list.test.ts,flags-settings,flags-timing,keysandhelp-keys, plustsc --noEmitandbun scripts/design-lint.ts. All pass or are clean. Inkeys.test.ts, 10 tests were skipped becausessh-keygenisn't installed in the sandbox. I did not runscripts/gate.ts.nav: true, in the row options insrc/web/pages/flags.ts. No JavaScript was added.<div>holding the edit form. Enter therefore opens the row's first link, the flag's owner issue (/<forge repo>/issues/N). That is the one primary link, and there is no nesteddata-nav. If the forge has no repo configured, the owner shows as plain text and enter does nothing on that row.data-navrow per flag, each with its owner issue as the first link. It also asserts that the empty page has none. Without thenav: trueline, the first test fails./flags, but the page is/settings/flags, so the test fetches that. Unlike the pulls-list test, which counts everydata-navon the page, it counts onlydata-navonclass="row"elements. The settings sidebar draws its owndata-naventries.Try:line, so the branch ends with an empty commit that has one: open/settings/flagsas an admin and press j/k, then enter on a row.To try it: open
/settings/flagsas an admin and press j/k to move between rows.🤖 Generated with Claude Code
Closes #10358