Commit 33436ba
fix(deploy): existing-persona lookup uses /deployments list (not phantom /agents) (#120)
* fix(deploy): existing-persona lookup uses /deployments list (not phantom /agents)
`findExistingAgent` was calling
`GET /workspaces/{ws}/agents?persona_slug=<slug>`. That route is a
dashboard proxy to an external gateway: it requires session-cookie auth
and 403s for the `cli:auth` Bearer tokens the CLI uses. The actual list
of deployed personas — the `agents` table reader added in cloud#580 —
lives at `GET /workspaces/{ws}/deployments`, accepts `cli:auth`, and
returns `{agents:[{agentId, personaId, deployedName, status, ...}]}`.
Why no `?personaId=` server-side filter: `agents.personaId` on the
cloud schema is a UUID FK to `personas.id`. The CLI only knows the
persona's slug (the local persona JSON's `id` field). Sending the slug
as `personaId=` makes cloud's drizzle predicate throw on the UUID cast
→ 500. The list is workspace-scoped (dozens of rows, not thousands),
so the right tradeoff is fetching unfiltered and matching client-side
against `deployedName` (which cloud derives from
`persona.slug || persona.name || persona.id`), `personaSlug`, or
`personaId` as a fallback.
Changes:
* `findExistingAgent` → call `/deployments` (no query string).
* `parseAgentLike` accepts both `{agentId}` (new) and `{id}` (legacy
preview shape). When `expectedPersonaId` is supplied, match it
against any persona-identifying field on the row (deployedName,
personaSlug, personaId). Rows with NO persona info at all (legacy
preview shape that pre-filtered server-side) still pass through.
* Treat `status === 'destroyed'` as "not present" so a re-deploy with
the same slug doesn't trip on-exists against a tombstone.
* Rewrite test mocks to disambiguate the listing GET from the deploy
POST via `init.method` (both now share the same URL).
* Added two new tests: full /deployments shape parsing (with
tombstone + wrong-persona rows skipped), and ordering guarantee
(listing GET fires before deploy POST).
Smoke against production cloud with the user's actual Anthropic-
connected workspace: no more 403 on the existing-persona check, no
more 500 on the personaId filter. Bundle upload now reaches cloud's
deploy handler. (Next failure: cloud Lambda missing
`@parcel/watcher-linux-x64-glibc` native binary — server packaging
issue, separate PR.)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* review fixes: tighten persona-match + prefer newest active row
Addressing review findings on PR #120:
* Workspace-scoped list rows without persona-identifying fields are no
longer treated as matches. The "no persona fields → pass through"
fallback was justified by legacy `{agent: {...}}` envelopes where the
URL path implied persona-scoping, but cloud's new `/deployments` list
is workspace-scoped — a row missing `deployedName`/`personaSlug`/
`personaId` could belong to any persona in the workspace, and acting
on it would let on-exists destroy the wrong agent. The legacy envelope
keeps its back-compat via a `requirePersonaMatch: false` opt-in;
every array element from the new endpoint sets `requirePersonaMatch: true`.
* When multiple rows match (destroy+redeploy race window, soft-delete
windows), prefer the newest `active` row instead of whichever cloud
returns first. Sort by status tier (active first) then `createdAt`
descending. Previously the first parsed match won, which on most SQL
backends meant insertion order — the opposite of what users expect.
Tests:
* `workspace-scoped list rows without persona-identifying fields are
NOT matched` — proves the tightened filter ignores ambiguous rows.
* `multiple active rows for the same persona — newest wins` — proves
the newest-active tiebreaker.
* `active row wins over an older active and over inactive rows` —
proves status tier outranks createdAt.
* `malformed array entries (null/empty) are skipped without throwing` —
defensive parser regression guard.
101/101 deploy tests pass.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* test(deploy): use deployments list in cancel fixture
---------
Co-authored-by: Ricky Schema Cascade <ricky@agent-relay.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>1 parent 97a800b commit 33436ba
3 files changed
Lines changed: 398 additions & 42 deletions
0 commit comments