feat(api): GET /runs — list runs filtered by status + initial_input#78
Merged
viktor-shcherb merged 3 commits intomainfrom Apr 30, 2026
Merged
feat(api): GET /runs — list runs filtered by status + initial_input#78viktor-shcherb merged 3 commits intomainfrom
viktor-shcherb merged 3 commits intomainfrom
Conversation
11 tasks
Member
Author
Review: APPROVE(Posted as a comment because GitHub blocks self-approval via All issue verification items met (each has a passing test in
CI: green (quality pass; build skipped). Local gates also green: Process: claim ✓, sketch posted before first commit ✓ (sketch 11:52:53Z, first commit 11:54:42Z), interfaces → tests → impl ordering preserved across the three commits. Security checks
Backward compat
Nits (non-blocking, address if you'd like)
LGTM. Orchestrator: ready to merge. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds
GET /runsto the publisher API: a list endpoint that filters bystatus,pipeline_id, and arbitraryinitial_input.<field>=<value>predicates against the JSON blob, paginated by
limit/offset. Mountsinside
createPublisherAppso it inherits the bearer-auth middlewarealongside the existing
GET /runs/{id}route. Lets an agent resolve anatural-language request (e.g. "add Stripe to jobseek") into a
concrete
run_idwithout the user pasting it.Related issue
Closes #76
Files changed
src/api/publisher/runs.ts— newmountRunListRoute+RunListItem/RunListViewtypes + filter/pagination logic. The existingmountRunRoutescalls into it soindex.tsis unchanged in spirit.src/api/publisher/runs.test.ts— 11 vitest cases covering every "Verification" bullet from the issue plus the server-side limit clamp and field-name SQL-injection guard.docs/contracts.md— new §8GET /runs— list runs with request/response shapes and error tokens; §2.2 publisher route list updated.Verification (from the issue)
?status=runningreturns only running runs ordered bycreated_at DESC.?pipeline_id=jobseek-add-company&status=runningAND-combines.?initial_input.company_name=Stripematches byJSON_EXTRACT($.company_name).?limit=5&offset=10paginates.limit=abc,offset=-1,initial_input.bad-field=x).{runs: []}(NOT 404).limitclamped server-side at 100 even when the caller asks for more.Manual checks run locally
pnpm typecheckcleanpnpm lintcleanpnpm test299 root tests + 34 contracts tests pass; coverage on the new module 97.88%pnpm grep:allall four gates greenSQL-injection note
initial_input.<field>interpolates the field name into aJSON_EXTRACT(initial_input_json, '$.<field>')clause. The value sidestays bound. Field names are gated against
^[A-Za-z0-9_]+$beforeinterpolation; anything else returns 400
initial_input_field_invalid:<field>.Notes for reviewer
PATCH /runs/{id}(separate murmur#77), per-userauthz (post-demo).
runs.created_atis sufficient. A(created_at DESC)index could come later if list traffic grows.data-dependent — at demo scale the prepare cost is negligible.