Public: anyone can read this; the crew can change it.
The API's runs list names its Server-Timing phases: session, runs, render #4909
Check · Review · Land · Live done — Landed and live in production.
`GET /api/v1/repos/:owner/:name/runs` now answers a `Server-Timing` header naming `session`, `runs` and `render`, as the branches list does. The new test passes. The type check only reports that it can't find the `bun` type definitions, so I couldn't confirm the change type-checks. I didn't run the rest of the test suite.
shipped production is serving it deploy 2e641a3
GET /api/v1/repos/:owner/:name/runs now answers a Server-Timing header naming session, runs and render, as the branches list does. The new test passes. The type check only reports that it can't find the bun type definitions, so I couldn't confirm the change type-checks. I didn't run the rest of the test suite.
- Handler: in
src/http/api.ts, the runs-list handler notessessionwithtakeSessionTime. It wraps thelistRepoRunsread in arunsphase and the JSON response in arenderphase. The response body and status codes are unchanged, and no other handler was touched. - Test:
test/api-runs-timing.test.tsfollowstest/api-branches-timing.test.ts. It asserts the phase names["session", "runs", "render"]in order on a 200, and that a missing repo answers 404 naming onlysession. Dropping a phase fails it. - Not done: nothing beyond the issue.
To try it, send an authenticated request to /api/v1/repos/<owner>/<name>/runs and read the server-timing header.
🤖 Generated with Claude Code
Clean. The runs-list handler follows the same pattern as the branches list: session is noted before loadRepo, listRepoRuns is wrapped in runs, and the JSON goes through render. Status codes, body and the per-reader filtering are unchanged. The handler is read-only, so the change opens no new write path, no new input and no new output to escape. The phase names are fixed strings, so the header carries no user data.
Checked: at head 60e6dd63, bun test ./test/api-runs-timing.test.ts ./test/api-branches-timing.test.ts gives 4 pass, 0 fail. The tests would fail if a phase were dropped or reordered. The preview has no public repositories to list, so I could only try the 404 door there. Both /api/v1/repos/trevato/forge/runs and /api/v1/repos/x/nope/runs answer 404 with server-timing: app;dur=…, session;dur=0.1, which matches the second test. The 200 path is covered by the test.
The pull only adds timing to a JSON endpoint, so the terminal and README have nothing to mirror. The mcp/secrets lines in the base-to-head diff come from the branch being older than #4802; they are not part of this change.
GET /api/v1/repos/:owner/:name/runsnow answers aServer-Timingheader namingsession,runsandrender, as the branches list does. The new test passes. The type check only reports that it can't find thebuntype definitions, so I couldn't confirm the change type-checks. I didn't run the rest of the test suite.src/http/api.ts, the runs-list handler notessessionwithtakeSessionTime. It wraps thelistRepoRunsread in arunsphase and the JSON response in arenderphase. The response body and status codes are unchanged, and no other handler was touched.test/api-runs-timing.test.tsfollowstest/api-branches-timing.test.ts. It asserts the phase names["session", "runs", "render"]in order on a 200, and that a missing repo answers 404 naming onlysession. Dropping a phase fails it.To try it, send an authenticated request to
/api/v1/repos/<owner>/<name>/runsand read theserver-timingheader.🤖 Generated with Claude Code
Closes #4893