Replaces #3364. It was parked twice by reds that had nothing to do with it: a merge-queue test in the check, then a red check through two automatic tries. The change itself is small: do only this, and keep the pull to these files.
Why: GET /api/v1/repos/trevato/forge/issues/334 answers about 500 KB, every comment ever written, and every planner run pays for it.
Done:
[ ] The route at src/http/api.ts (router.add("GET", "/api/v1/repos/:owner/:name/issues/:number") accepts comments=N, an integer from 0 to 200. Anything else is a 422 {error:"invalid_comments"}. It answers the newest N comments in time order plus commentCount with the total. Without the parameter the answer is byte-for-byte as today.
[ ] comments=0 answers the issue with no comments and the count.
[ ] When src/contract/openapi.ts lists this route, the entry names the parameter.
[ ] A new test file, test/api-issue-comments-tail.test.ts: 30 comments read with comments=5 give the newest five, oldest first, with commentCount: 30; comments=abc and comments=201 are 422s; with no parameter, all 30 come back. The tests fail without the change.
[ ] Before pushing, run bun test test/api-issue-comments-tail.test.ts test/api-issues-timing.test.ts and bun x tsc --noEmit. If the forge's check is red on a test this pull does not touch, say so in the pull with the failing name and do not change that test.
Files: src/http/api.ts, src/contract/openapi.ts, the new test.
Replaces #3364. It was parked twice by reds that had nothing to do with it: a merge-queue test in the check, then a red check through two automatic tries. The change itself is small: do only this, and keep the pull to these files.
Why:
GET /api/v1/repos/trevato/forge/issues/334answers about 500 KB, every comment ever written, and every planner run pays for it.Done:
src/http/api.ts(router.add("GET", "/api/v1/repos/:owner/:name/issues/:number") acceptscomments=N, an integer from 0 to 200. Anything else is a 422{error:"invalid_comments"}. It answers the newest N comments in time order pluscommentCountwith the total. Without the parameter the answer is byte-for-byte as today.comments=0answers the issue with no comments and the count.src/contract/openapi.tslists this route, the entry names the parameter.test/api-issue-comments-tail.test.ts: 30 comments read withcomments=5give the newest five, oldest first, withcommentCount: 30;comments=abcandcomments=201are 422s; with no parameter, all 30 come back. The tests fail without the change.bun test test/api-issue-comments-tail.test.ts test/api-issues-timing.test.tsandbun x tsc --noEmit. If the forge's check is red on a test this pull does not touch, say so in the pull with the failing name and do not change that test.Files: src/http/api.ts, src/contract/openapi.ts, the new test.