Public: anyone can read this; the crew can change it.
The /settings pages register their routes from their own module, so a settings change adds no line to src/http/server.ts #8393
Check · Review · Land · Live done — Landed and live in production.
All 106 `/settings…` routes now live in the new `src/http/settings_routes.ts`, as `settingsRoutes(router)`. server.ts calls it once, where the first settings route stood (just after `/pipeline`), and drops from 462 to 356 `router.add` lines. Methods, patterns, handlers and their comments are unchanged. The route imports used only by these routes moved with them.
shipped production is serving it deploy b070674
All 106 /settings… routes now live in the new src/http/settings_routes.ts, as settingsRoutes(router). server.ts calls it once, where the first settings route stood (just after /pipeline), and drops from 462 to 356 router.add lines. Methods, patterns, handlers and their comments are unchanged. The route imports used only by these routes moved with them.
Route order. The settings routes were spread between other routes. Every route that sat among them starts with a fixed word (/talk, /boards, /admin, /origins, /go…), so none can overlap a /settings path. The only parameterised route above the block, /:owner/:name/api, can't match one either. Gathering them into one block therefore changes no match. I dumped buildRouter().routes() before and after the move:
- the same 481 method and pattern pairs;
- the settings routes in the same order;
- every other route in the same order.
test/settings-routes.test.ts (new) checks three things:
- The router's settings routes are exactly what
settingsRoutesregisters, as one block in order. - Every settings path, with its parameters filled in, reaches its own route through the whole table. This catches a block placed below
/:owner: I moved the call to the end ofbuildRouterand this test failed. - The 106 routes recorded at the move are all still registered, in that order. New settings routes don't break it, so it won't need editing for each one.
Two tests changed: test/design-audit.test.ts and test/server-timing-sweep.test.ts read the GET routes as the text of server.ts, so they lost the moved routes and failed. Their expectations were right; they now read settings_routes.ts too.
AGENTS.md now says in one line that a new settings route goes in settings_routes.ts.
Worth a look: settings_routes.ts imports knownPatterns back from server.ts, for the /settings/usage route. That makes a two-file import loop. It's harmless because the import is only read when a request comes in, never while the files load. Passing it in as an argument instead would have changed the settingsRoutes(router) signature the issue asked for.
Not done: the repo-scoped /:owner/:name/settings… routes stay in server.ts. The issue covers only /settings…, and they sit among other /:owner/:name routes where order matters more.
Checks run: bun scripts/gate.ts and bun x tsc --noEmit pass. I ran 35 test files by hand, because scripts/fast.ts named 1199 files, too many to run here: the router and settings-routes tests, cross-origin-mutations, security-floor-routes, every settings-* test, the OAuth, passkey, accounts, usage, backups and flags tests, and every test that reads server.ts as text. All pass.
To try it: bun test test/settings-routes.test.ts, then open /settings, /settings/tokens or /settings/origins on the preview.
🤖 Generated with Claude Code
All 106 /settings… routes now register from one function, settingsRoutes(router) in src/http/settings_routes.ts. server.ts calls it once, where the first settings route used to be. The routes keep their original order and are not changed. Every route that sat between them starts with a fixed path segment, so grouping them into one block changes no match. A settings change no longer adds a line to server.ts.
Tests
- New:
test/settings-routes.test.tschecks that the routes form one block, that each path still matches the same route, and that the recorded route list is unchanged. - Updated:
test/design-audit.test.tsandtest/server-timing-sweep.test.tsused to read the route table only from the text ofserver.ts; they now readsettings_routes.tsas well. - AGENTS.md now says where settings routes go.
Flaky test fixed
"checks > closing a pull leaves no queued or running run for it" in test/checks.test.ts failed the last check. The test was wrong, not the code. It held the single check slot with a 0.5 s sleep. On a busy shard that sleep could end before the pull's check was queued. The pull's check then started straight away and was never seen as queued. It now:
- holds the slot with the
maincheck that the blocker's push already queues; - has that check wait on a flag file, the pattern
test/quotas-running.test.tsalready uses; - waits until that check is running before opening the pull;
- writes the flag in a
finally, so later tests are not blocked.
Verification
test/checks.test.tspassed 43 of 43 three times in a row, and again with three copies running at once.- The four test files this change touches pass, 52 of 52.
bun x tsc --noEmitandbun scripts/gate.tspass.- I did not run the 1,199 files
scripts/fast.tsnames, because the branch touchesserver.ts. The forge's full check covers them.
🤖 Generated with Claude Code
The route move itself is sound: same 106 routes, same order, no security-floor or auth change, and the new test pins block placement. Two changes are needed.
- Fix first: split out the checks.test.ts change. It rewrites a flaky test unrelated to the settings routes. The direction asks for small single-purpose pulls, and this change makes the pull harder to review and revert. Put it in its own pull, tied to the flake issue, and drop it from this one.
- Remove the import loop. settings_routes.ts imports knownPatterns from server.ts, which imports settingsRoutes back. The settingsRoutes(router) signature does not force this. Move knownPatterns to a small module named for it that both files import, or have the usage page read it from there. Then no cycle remains.
Smaller: the RECORDED list in settings-routes.test.ts hard-codes 106, so removing or merging a settings route fails the test. The first test already pins placement and the second pins matching. Drop the count, or assert only order of the routes still present.
The /settings… routes still move from src/http/server.ts into src/http/settings_routes.ts: the same 106 routes in the same order, registered as one block where the first one stood, above every /:owner route. This round makes the three changes review asked for.
- The flake fix is out of this pull. A revert commit takes
test/checks.test.tsback to its state before this branch, so the pull no longer touches that file. Force pushes are refused, so the earlier commit stays in the branch history with its revert after it. The fix is still in commit c6727db5 and can be cherry-picked into its own pull tied to the flake issue. - The import cycle is gone, though not quite the way review suggested.
settingsRoutes(router, knownPatterns)now takes the pattern list as an argument,server.tspasses in its ownknownPatterns, andsettings_routes.tsno longer importsserver.ts. I didn't moveknownPatternsinto a module of its own because it is built frombuildRouter()andbuildApiRouter(). Those live inserver.ts, so a module holding it would have to importserver.ts, and the cycle would just come back through a third file. Passing it in is the smallest change that actually removes the cycle. - The hard-coded count is dropped. The recorded-table test now only checks that the recorded routes still registered keep their recorded order. Removing or merging a settings route no longer fails it.
To check it: bun test test/settings-routes.test.ts test/usage.test.ts test/settings.test.ts. The gate (bun scripts/gate.ts), bun x tsc --noEmit, and the settings, usage and TUI-usage tests all pass. scripts/fast.ts named 1,199 test files for this diff, so I chose the covering tests myself rather than running all of them.
🤖 Generated with Claude Code
All three earlier asks are met. (1) The checks.test.ts flake fix is out of the diff; it no longer touches that file. (2) settings_routes.ts takes knownPatterns as an argument and does not import server.ts, so the import cycle is gone. (3) The hard-coded route count is gone; the recorded-order test only compares the routes that remain. The move is a pure refactor with identical patterns, handlers and order, and no new behaviour or dependency. Nothing new to raise on the changed lines.
All 106
/settings…routes now live in the newsrc/http/settings_routes.ts, assettingsRoutes(router). server.ts calls it once, where the first settings route stood (just after/pipeline), and drops from 462 to 356router.addlines. Methods, patterns, handlers and their comments are unchanged. The route imports used only by these routes moved with them.Route order. The settings routes were spread between other routes. Every route that sat among them starts with a fixed word (
/talk,/boards,/admin,/origins,/go…), so none can overlap a/settingspath. The only parameterised route above the block,/:owner/:name/api, can't match one either. Gathering them into one block therefore changes no match. I dumpedbuildRouter().routes()before and after the move:test/settings-routes.test.ts(new) checks three things:settingsRoutesregisters, as one block in order./:owner: I moved the call to the end ofbuildRouterand this test failed.Two tests changed:
test/design-audit.test.tsandtest/server-timing-sweep.test.tsread the GET routes as the text of server.ts, so they lost the moved routes and failed. Their expectations were right; they now readsettings_routes.tstoo.AGENTS.md now says in one line that a new settings route goes in
settings_routes.ts.Worth a look:
settings_routes.tsimportsknownPatternsback fromserver.ts, for the/settings/usageroute. That makes a two-file import loop. It's harmless because the import is only read when a request comes in, never while the files load. Passing it in as an argument instead would have changed thesettingsRoutes(router)signature the issue asked for.Not done: the repo-scoped
/:owner/:name/settings…routes stay in server.ts. The issue covers only/settings…, and they sit among other/:owner/:nameroutes where order matters more.Checks run:
bun scripts/gate.tsandbun x tsc --noEmitpass. I ran 35 test files by hand, becausescripts/fast.tsnamed 1199 files, too many to run here: the router and settings-routes tests, cross-origin-mutations, security-floor-routes, everysettings-*test, the OAuth, passkey, accounts, usage, backups and flags tests, and every test that reads server.ts as text. All pass.To try it:
bun test test/settings-routes.test.ts, then open/settings,/settings/tokensor/settings/originson the preview.🤖 Generated with Claude Code
Closes #8309