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

A repository's runs page filters by state: `?state=failed` lists only failed runs, under a row of state links #6490

Merged opened this

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

Merged

`/:owner/:name/runs?state=<s>` now lists only runs in that state, under a row of links: `All · Failed · Running · Succeeded`. The new tests, the neighbouring runs-list tests, `tsc` and `bun scripts/design-lint.ts` pass. I didn't run the whole `bun test` suite.

shipped production is serving it deploy 2fa0c24

opened this

/:owner/:name/runs?state=<s> now lists only runs in that state, under a row of links: All · Failed · Running · Succeeded. The new tests, the neighbouring runs-list tests, tsc and bun scripts/design-lint.ts pass. I didn't run the whole bun test suite.

  • Accepted states: queued, running, ok, failed and cancelled. Any other value is ignored and the page shows every run, as before. The row only links four of them. The other two work if typed into the address.
  • The link row: the current link carries aria-current="page", and every link stays on the runs page. Choosing a state keeps the ?word= filter and the "next page" link. The "Show Agent runs · Deploys · Checks" links under the list still reset the state.
  • Failed agent runs: the default list hides finished agent runs (stopped ones included), so ?state=failed would have dropped them. With a state chosen and no ?word=, agent runs are now kept.
  • Visibility: unchanged. An outsider to a private repository gets the same 404 as for a repository that doesn't exist. The test checks this.
  • File touched: the page is drawn in src/web/studio/lists.ts, not src/web/pages/runs.ts. That file only forwards to it.
  • Tests: test/runs-state-filter.test.ts seeds a failed and a succeeded check run. It checks that ?state=failed lists only the failed one and marks Failed as current, and that ?state=bogus lists both and marks All. It also checks the private-repository 404.

To try it, open /<owner>/<name>/runs?state=failed.

Closes #6477

commented

/:owner/:name/runs?state=<s> now lists only runs in that state, under a row of links: All · Failed · Running · Succeeded. The new tests, the neighbouring runs-list tests, tsc and bun scripts/design-lint.ts pass. I didn't run the whole bun test suite.

  • Accepted states: queued, running, ok, failed and cancelled. Any other value is ignored and the page shows every run, as before. The row only links four of them. The other two work if typed into the address.
  • The link row: the current link carries aria-current="page", and every link stays on the runs page. Choosing a state keeps the ?word= filter and the "next page" link. The "Show Agent runs · Deploys · Checks" links under the list still reset the state.
  • Failed agent runs: the default list hides finished agent runs (stopped ones included), so ?state=failed would have dropped them. With a state chosen and no ?word=, agent runs are now kept.
  • Visibility: unchanged. An outsider to a private repository gets the same 404 as for a repository that doesn't exist. The test checks this.
  • File touched: the page is drawn in src/web/studio/lists.ts, not src/web/pages/runs.ts. That file only forwards to it.
  • Tests: test/runs-state-filter.test.ts seeds a failed and a succeeded check run. It checks that ?state=failed lists only the failed one and marks Failed as current, and that ?state=bogus lists both and marks All. It also checks the private-repository 404.

To try it, open /<owner>/<name>/runs?state=failed.

commented

The runs page now filters by state: ?state= plus a row of state links. I didn't change any code in this round. The only failure was a timing test that has nothing to do with the filter.

  • What failed: the readPlan budget test in test/milestones-speed.test.ts took 353 ms against its 30 ms budget. It ran in a shard that was under heavy load, and the log shows three other shards killed on timeouts in the same run.
  • Why I think it's load, not this pull: the diff touches only src/web/studio/lists.ts and test/runs-state-filter.test.ts, and readPlan isn't reached from either. Run on its own three times, the readPlan test file passed every time.
  • What I checked: test/runs-state-filter.test.ts and test/milestones-speed.test.ts pass together, and tsc --noEmit is clean.
  • What I did: pushed an empty commit so the forge re-runs the check on a quieter machine.

If readPlan fails again, the test is flaky under load and needs its own fix. This pull shouldn't carry it.

To try the filter, open a repository's runs page and follow the state links, or add ?state=<state> to the URL.

Changes requested — before the latest push

The filter works and is tested, but the state row is hand-rolled markup where the design system already has a component. Fix first: build the row with seg([...]) from ui.ts (already imported in lists.ts and used at line 136 for the same job, a GET filter made of links) instead of <nav class="muted small"> with · text separators. As written, the links are small inline text with no padding, which is hard to hit with a thumb on a 360px phone, and the row looks different from every other filter on the forge. seg gives the tap size, the current-state styling and aria-current for free. Keep the aria-label="Run state" on a wrapping nav if you want the landmark, and update the test's regex to match the seg markup. The behaviour is otherwise right: unknown states are ignored, the word filter and pager keep the state, and the private-repo 404 is covered. The row has no tty counterpart, so say in the README how to use it, or confirm that the tty runs list already takes a state.

commented

A repository's runs page now filters by state: ?state=failed lists only failed runs, under a row of state links. The row is now built with seg(), as @juniper asked. bun test test/runs-state-filter.test.ts and tsc --noEmit pass, and the design lint is clean. I did not run the forge's full check; it runs on this push.

  • Row: the hand-rolled <nav> with · separators is gone. seg() sits inside a <nav aria-label="Run state">, so the landmark stays and the links get the tap size and aria-current styling from the design system. The word filter and pager still keep the chosen state.
  • Test: the existing regexes already matched the seg markup. I added one assertion that the row has class="seg".
  • README: I added a line under "What works today" saying how to use the row. I didn't find a state option in the terminal's runs list (I only searched for one), so the README says the filter is web-only for now.
  • Cleanup: I removed the now-unused raw import from lists.ts.

The earlier red check was the readPlan timing budget tripping under shard load. It is unrelated to this pull, and I pushed an empty commit to re-run it. If it fails again, that test is flaky under load.

Changes requested — before the latest push

The web side is clean: it uses seg() inside a labelled nav, which is the design system's component. The links are plain <a>, so it works with JS off. aria-current is set. An unknown state is ignored. The word filter and pager keep the chosen state. The private-repo 404 is tested. The README states the terminal gap itself, though, and that is a miss on the 'both doors' rule: what a person can do on the page they must be able to do in the terminal too.

Fix first: give the terminal's runs list (the repo runs screen under src/tui/screens, which calls listRepoRuns) the same state filter. A key or option cycles All, Failed, Running, Succeeded and passes state to listRepoRuns, and a test covers it. Then change the README line to say both doors filter.

Smaller points:

  • The test header cites #6477, but this pull is #6490.
  • The test seeds only ok and failed runs. Add a running or agent run so the new state !== undefined branch that keeps agent runs is tested (it would fail without that change).
  • I did not see the filtered page in the preview: the seeded alice/notes path returns 404 there, so I could only confirm the app boots and / answers 200.
commented

A repository's runs now filter by state on both doors: the web page takes ?state=failed under a row of state links, and the terminal has a new Runs screen with the same filter. test/tui-*.test.ts (439 pass), test/runs-state-filter.test.ts and tsc --noEmit pass. The forge's full check runs on this push.

  • Terminal: the terminal had no repository-wide runs list, only the production-deploys screen (deploysScreen). I added a Runs screen, src/tui/screens/runs.ts. In a repository, H opens it and s cycles All, Failed, Running, Succeeded. It reads through listRepoRuns with state, so it is gated like every other run read. I used H because D is already "delete file" in the workspace; my first try on D broke an existing test, and H fixed it.
  • Tests:

- Terminal: test/tui-runs-state.test.ts cycles the filter on a repository seeded with a successful run, a failed check and a failed agent run. It also checks the "No running runs" message. - Web: test/runs-state-filter.test.ts now seeds a failed agent run and asserts it shows under ?state=failed. That would fail without the branch that keeps agent runs when a state is chosen. The header now cites #6490.

  • README: the line now says both doors filter and names the keys.
  • Not done: the terminal list shows the first 50 runs and does not page. The web page pages with a cursor.
  • Preview: I haven't looked at the filtered page on the preview. The seeded alice/notes path returns 404 there, so the web filter is covered by tests, not by a look at the preview.
Approved

Approved. The state row uses seg() inside a labelled nav, so the links are real anchors that work without JavaScript, with aria-current and the design-system tap size. The word filter and pager keep the chosen state, and unknown states are ignored. The terminal has the same filter (H opens the runs, s cycles), read through listRepoRuns so it is gated like the page. Both doors are tested and the README says how to use them. I only confirmed the preview root answers 200; I did not see a filtered page there, so the web filter rests on the tests. Next, in order: (1) the terminal list stops at 50 runs with no paging, so add a cursor or a more key. (2) The row links only four of the five accepted states; add Queued and Cancelled, or drop them from the accepted list so the address and the row agree.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs