Summary
blueprint-pocketbase-react is the only runnable blueprint without the app→agent direction. Its PocketBase hooks adapter (pb/pb_hooks/_a2app.pb.js + _a2app_impl.js) serves identity, describe, and the record create/update/delete guards. It has no:
- operations endpoint: there is no
/api/ops/{name} route, so operations declared in operations.json (the starter's archive-done, for one) are listed by describe but cannot be invoked.
- task queue: no
/api/_a2app/tasks routes, so nothing can be queued for an agent and agent-app <dir> bridge has nothing to deliver.
- events: no
/api/_a2app/events.
reference/blueprint.md currently tells authors to record this as a known limitation, or pick another blueprint. Every other runtime blueprint (react-node, go-react, rust-react, rails-vue, python-fastapi) carries the queue.
Proposal
- Operations:
- Endpoint:
POST /api/ops/{name}.
- App-owned code: a seam where the app's own operation code lives, with
trigger available beside the store.
- Access: same-origin View calls allowed on single-user apps, the agent token required otherwise.
- Approval: destructive operations need approval (
428 + approval key), matching the other adapters.
- Task queue and events, matching the other adapters' wire format:
- Endpoints:
GET /api/_a2app/tasks[?status=], GET /tasks/{id}, and POST …/claim | progress | complete | cancel.
- Events:
GET /api/_a2app/events.
- Lifecycle:
trigger(type, payload, capability) refuses undeclared event types. The same occurrence dedupes to one task. A claim lapses without a heartbeat and the task is redelivered, failing as redelivery_exhausted after the delivery limit.
- Storage: tasks and events persist across restarts in the app's data directory.
- Discovery: identity advertises the queue so
agent-app <dir> bridge finds it.
- Runtime constraints: hooks run in PocketBase's Goja runtime, not Node. Handlers can't close over file scope (each one
require()s the impl), and storage goes through $app/$os. The pure rules (dedup key, lifecycle transitions, sweep) go in _a2app_rules.js, so node … --selftest in the gate covers them.
- Starter and View:
- Docs: replace the "no app→agent queue in v0.1" section of
reference/blueprint.md with how to declare events, fire trigger, and show the work.
Acceptance
- Bidirectional conformance: a pocketbase-react app passes the Class C (bidi) conformance suite: task poll, claim, claim contention (
409 task_not_claimable), progress, completion.
- Real run: clicking "Ask an agent" in the starter queues a task that
agent-app <dir> bridge start delivers to a real harness. The View shows it waiting, working and done (or failed, with "Ask again") without a reload.
- Gate: the blueprint's gate self-test covers the new rules, and a fresh scaffold passes
validate's "agent work shown in the View" step.
- Version: verified against PocketBase v0.26.6, the only version the adapter supports.
Summary
blueprint-pocketbase-reactis the only runnable blueprint without the app→agent direction. Its PocketBase hooks adapter (pb/pb_hooks/_a2app.pb.js+_a2app_impl.js) serves identity, describe, and the record create/update/delete guards. It has no:/api/ops/{name}route, so operations declared inoperations.json(the starter'sarchive-done, for one) are listed by describe but cannot be invoked./api/_a2app/tasksroutes, so nothing can be queued for an agent andagent-app <dir> bridgehas nothing to deliver./api/_a2app/events.reference/blueprint.mdcurrently tells authors to record this as a known limitation, or pick another blueprint. Every other runtime blueprint (react-node, go-react, rust-react, rails-vue, python-fastapi) carries the queue.Proposal
POST /api/ops/{name}.triggeravailable beside the store.428+ approval key), matching the other adapters.GET /api/_a2app/tasks[?status=],GET /tasks/{id}, andPOST …/claim | progress | complete | cancel.GET /api/_a2app/events.trigger(type, payload, capability)refuses undeclared event types. The same occurrence dedupes to one task. A claim lapses without a heartbeat and the task is redelivered, failing asredelivery_exhaustedafter the delivery limit.agent-app <dir> bridgefinds it.require()s the impl), and storage goes through$app/$os. The pure rules (dedup key, lifecycle transitions, sweep) go in_a2app_rules.js, sonode … --selftestin the gate covers them.request-triageoperation that queues work, anagentTaskfield ontasks, and the previous task id in the payload so asking again queues new work.ui/src, matching the other React blueprints, so the starter passes the "agent work shown in the View" validate step (Enforce agent-state UX for app→agent features (live task status, readable results) #13).reference/blueprint.mdwith how to declare events, firetrigger, and show the work.Acceptance
409 task_not_claimable), progress, completion.agent-app <dir> bridge startdelivers to a real harness. The View shows it waiting, working and done (or failed, with "Ask again") without a reload.validate's "agent work shown in the View" step.