api: catch the CLI up to the current routes, and stop failing silently - #107
Conversation
Most commands were 404ing against prod: the backend renamed routes under
/integrations, /agents, /secrets, and /files, and every CLI path was a
hand-maintained copy that drifted. Worse, the failures were invisible in the
sessions UI, because the composer's pickers swallowed their errors and rendered
an empty list.
Repoints every drifted path and bumps @ellipsis-dev/sdk to 0.6.0. Error output
now reads the server's {error: {code, message}} envelope, so a failure shows
what went wrong instead of a bare status line; FastAPI's own {detail}
rejections are still read, since validation and auth answer in that shape.
Renames the asset command tree to file, following the server. The old spelling
stays as a hidden alias.
Drops the review surface the server deleted: pull_request_number is required
now, so reviewing your working tree cannot work, and the /reviews/defaults
ladder was replaced by resolving a pipeline from its committed location. That
also fixes review init, which defaulted to agents/code_review.yaml and so wrote
a file the sync rejects outright; the only paths that run are code_review.yaml
and .ellipsis/code_review.yaml.
There was a problem hiding this comment.
Caution
Changes requested ❌ — 2 issues
Reviewed d5f1b78 in 10 minutes, 29 seconds.
- Reviewed
1commit with1163lines of code in25files - Ran
1review agent producing2comments where2were posted - This pipeline runs no gatekeeper, so findings are posted as written.
- View full details on ellipsis.dev
This review was created by . You can tag
@ellipsis in this pull request.
| setPolledOnce(true) | ||
| } catch { | ||
| // Transient poll failure — keep the previous list; the next tick retries. | ||
| setApiError(null) |
There was a problem hiding this comment.
The sessions poll wipes every reported API error on success, so a composer picker failure is erased within one 5s tick and never comes back — clear only the poll's own error.
poll() runs on mount and every SIDEBAR_POLL_MS (5000) while the nav is shown, and each success calls setApiError(null). The pickers fetch once (pickersLoading.current is never reset), so the failure cannot be re-reported. Verified against prod from this checkout: GET /agents/configs returns 422 while GET /sessions succeeds, so agent shows x agent configs: 422 … for under five seconds and then silently renders an empty config picker — the exact failure this change was written to stop.
| setApiError(null) | |
| // Only the poll's own failure is known to be over; a picker's is not. | |
| setApiError((prev) => (prev?.startsWith('sessions: ') ? null : prev)) |
| // Block-and-stream, then re-read: the findings are collected from the | ||
| // sandbox at teardown, so they only exist once the review finalizes. | ||
| // Same two-step `agent asset get` uses. | ||
| // Same two-step `agent file get` uses. |
There was a problem hiding this comment.
The default agent review <n> path is dead as written: line 96 streams started.id (a crun_…) against /sessions/{id}, which 404s, so the command errors out after creating a real billable review and never prints findings.
Confirmed live against prod: GET /sessions/crun_5Dzhd… → 404 Agent session crun_5Dzhd… not found. watchSessionStreaming either throws StreamAuthError or degrades to watchSession(), which polls the same 404 and throws — either way api.getReview(started.id) on line 97 is never reached. The PR body defers this as pre-existing, but the effect is that the flagship command exits nonzero on every invocation without --no-wait; the fix is to stream a stage session id from Review.stages[].session_id.
Summary
Most CLI commands were 404ing against prod. The backend renamed routes under
/integrations,/agents,/secrets, and/files, and every path in the CLI was a hand-maintained copy that drifted.agent github repos,agent config list,agent variable list,agent asset list, andagent loginwere all broken.Two failures made this worse than it had to be:
{"error": {"code", "message"}}, and we only read{"detail"}, so every failure printed a bare404 Not Foundwith the server's actual explanation discarded..catch(() => []), so a broken route rendered an empty list with no indication anything had failed. That is how this was found.What changed
Routes. Every drifted path repointed, and
@ellipsis-dev/sdkbumped to 0.6.0./github/*,/slack/*,/linear/teams,/sentry/organizations/integrations/…/configs,/defaults,/templates/agents/…/variables/secrets/assets/files/cli-auth/*/auth/cli/*Errors.
parseErrorResponsereads the{error: {message}}envelope, and still reads{detail}because FastAPI's own validation and auth rejections answer in that shape.The footer. Background API failures now show as a red line in the nav hint row. The hints are recoverable from muscle memory; a swallowed error is not.
assettofile. Follows the server, including the response keys ({asset:…}to{file:…},{assets:[…]}to{files:[…]}).agent assetstill works as a hidden alias.Removed review surface the server deleted (#6108, #6109):
pull_request_numberis required now, so reviewing your working tree cannot work at all, and the/reviews/defaultsladder was replaced by resolving a pipeline from its committed location. Gone: the local-tree path and its sidecar-branch push,--branch/--config/--model/--budget, and theagent review defaultgroup.Fixed
agent review init, which defaulted toagents/code_review.yamland wrote a file the sync rejects outright. Onlycode_review.yamland.ellipsis/code_review.yamlrun. It now refuses an illegal path rather than writing a file that looks fine and never executes, and the scaffold dropspull_requests.repositories(a sync error outside the.ellipsisrepo) andinclude_default_reviewers(deleted from a schema that forbids unknown keys).Test plan
bun run typecheckclean,bun run test436 passinggithub repos,file list,integration,slack channels,linear teams,sentry orgs,variable list,session list,me,model listGET /sessions/… failed: 404 Agent session … not found.with a request id, where it previously read404 Not Foundx repositories: …when a picker failsreview initverified in a scratch repo: writes both legal paths, refusesagents/code_review.yamlCodeReviewConfig.assert_valid_for_locationat both legal locations, and confirmed the old default is rejectedPOST /reviewsandagent session startare untested here, since exercising them creates real state in prod.Note
agent config list,agent template list, andagent config default liststill return 422 on prod. The public/agents/*routes are shadowed by the legacy dashboardAgentsRouter, which mounts at the same prefix with header auth and is registered first. Not fixable from the CLI; @hbrooks is fixing it backend-side. The paths in this PR are correct and those three commands start working once the shadowing is resolved.Two pre-existing bugs found while working, left for a follow-up:
agent review's stream call passes thecrun_…review id to a session endpoint (stage session ids live instages[]), and prod now serves/fileswhile the published SDK 0.6.0 spec still says/assets, so the SDK needs a republish to match.Important
Realigns CLI routes with backend refactoring, fixes silent error handling, and removes deprecated review functionality.
Routes updated: Most CLI commands were 404ing because the backend reorganized route namespaces; routes repointed to
/integrations/…(GitHub, Slack, Linear, Sentry),/agents/…(configs, defaults, templates),/secrets(variables),/files(assets), and/auth/cli/…(login).@ellipsis-dev/sdkbumped to 0.6.0.Error reporting improved:
parseErrorResponsenow reads the new{error: {code, message}}envelope from the server while still supporting{detail}for FastAPI's own validation and auth rejections. Error details are no longer discarded — the server's actual message now appears instead of a bare404 Not Found.API failures now visible: The sessions UI's background calls (configs, repos, models pickers) replace the nav hint row with a red error line (e.g.,
✗ repositories: 404 Agent session … not found) instead of silently.catch(() => [])into empty lists, making broken routes and expired tokens discoverable.Asset → File: Response keys renamed (
asset→file,assets→files,/assets→/files). The oldagent assetcommand still works as an alias.Review functionality removed: The backend deleted support for reviewing uncommitted working trees (which required a sidecar branch push). Removed
--branch,--config,--model,--budgetoptions fromagent review start;pull-requestis now required (no longer optional). Removed theagent review defaultsubcommand.agent review inithardened: Now refuses paths outside ofcode_review.yamland.ellipsis/code_review.yaml(the only two paths the server reads), preventing configs that look correct but never execute. Scaffold updated to remove sync-error fields (pull_requests.repositories,include_default_reviewers).This description was created by
for d5f1b78. It will automatically update as commits are pushed.