feat(api): GET /api/agent/proposals/{id} — read a proposed agent write #343
No reviewers
Labels
No labels
area:auth
area:ci
area:db
area:infra
area:native
area:pwa
area:service
epic
feature
foundation
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
james/carol!343
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "342-proposal-read-endpoint"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Write tools never mutate — they persist a
ProposedChange(summary + structured diff + safe/destructive classification) as anagent_proposalsrow, and the conversation'sawaiting_confirmationpause carries only theproposalId. There was no way to read that proposal back, so a client couldn't render what's about to change before committing/rejecting it. This adds the read side; commit/reject (#51) already exist.What's in it
GET /api/agent/proposals/{id}→ProposalDto:proposalId,action(safe_create|safe_update|destructive_update|destructive_delete),tool,entity{type,id},summary,diff,status,createdAt,expiresAt. The original toolinputstays server-side (apply-time replay detail).pendingproposal past its expiry reads asexpired, computed without mutating (the commit path keeps its lazyexpiredpersist; a GET must not write).lib/dto/proposal.ts), RFC 7807 errors, registered in the generated OpenAPI spec (committedopenapi.json).Verification (run locally on this branch)
typecheck✓ ·lint✓testagainst both engines (ephemeral Postgres viaTEST_POSTGRES_URL): 1211 passed (+5 GET tests: 401, owner-read, cross-user 404, missing 404, pending-past-expiry →expired+ asserts the row stayspending)openapi:check✓ up to date ·openapi:coverage116 → 117 pairsOut of scope
@carol/api-clienthook for this endpoint (lands with the conversation hooks).Part of epic #47; unblocks the chat-UI confirmation flow.
Closes #342
🤖 Generated with Claude Code
📊 Test coverage
Patch coverage: no testable lines changed.
Overall (
app/,lib/,db/, excluding UI per ADR-0019):Soft thresholds per ADR-0019. Coverage is informational and does not block merge.
The committed @carol/api-client generated client tracks openapi.json; adding GET /api/agent/proposals/{id} drifted it. Regenerate so the `check` gate passes and the new path + ProposalDto are typed for the upcoming conversation hooks. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>