# growqr-backend Backend for the Grow Agent Platform (see [`docs/PRD.md`](docs/PRD.md)). Per the PRD, every user gets: - A **Grow Agent** (Rivet Kit actor) that orchestrates **sub-agent actors**. - A **dedicated OpenCode Docker** container — every sub-agent workflow executes through it. - A **dedicated Gitea Docker** container — backs the agent's memory and project repos. - A frontend (Next.js, separate repo) that pulls the Rivet Kit React SDK and talks to the Grow Agent over the actor connection. ## Architecture ``` Frontend (Next.js + Rivet Kit React SDK) │ ▼ Backend (Hono + Rivet Kit client + dockerode) │ ├─▶ rivet-engine (compose service) → Grow Agent + Sub-Agent actors │ └─▶ Docker daemon (host) ├─ growqr-gitea- (one per user, spawned on demand) └─ growqr-opencode- (one per user, spawned on demand) ``` The backend mounts the host Docker socket so it can spawn the per-user container pair via `dockerode` on `POST /actors/provision`. ## Layout ``` src/ config.ts env config log.ts pino logger index.ts Hono app entrypoint docker/manager.ts dockerode wrapper — spawns Gitea + OpenCode per user actors/ grow-agent.ts Rivet Kit master actor (one per user) sub-agent.ts Rivet Kit worker actor (workflows → OpenCode Docker) registry.ts Rivet Kit actor registry setup routes/ actors.ts PRD §5.2 — actor registry HTTP API opencode.ts PRD §5.3 — OpenCode Docker management git.ts PRD §5.4 — Gitea Docker management ``` ## Local setup Prereqs: Node 22+, Docker, `docker compose`. ```bash cp .env.example .env npm install docker compose up -d rivet-engine # start Rivet engine npm run dev # start backend on :4000 ``` The backend pulls the Gitea + OpenCode images on first user provision (no need to pre-pull). ## Smoke test ```bash # Provision a Grow Agent + spawn its OpenCode + Gitea Docker curl -X POST localhost:4000/actors/provision \ -H 'content-type: application/json' \ -d '{"userId":"u_alice"}' # Send a message curl -X POST localhost:4000/actors/u_alice/message \ -H 'content-type: application/json' \ -d '{"text":"hello"}' # Spawn a sub-agent curl -X POST localhost:4000/actors/u_alice/sub-agents \ -H 'content-type: application/json' \ -d '{"type":"coding","channelId":"ch-coding-1"}' # Run a workflow through OpenCode Docker curl -X POST localhost:4000/actors/u_alice/sub-agents/coding-/run \ -H 'content-type: application/json' \ -d '{"prompt":"scaffold a Hello World"}' # Stop the user's stack curl -X POST localhost:4000/actors/u_alice/stop ``` `docker ps` should show `growqr-gitea-u_alice` and `growqr-opencode-u_alice` after provision. ## What's stubbed These are wired structurally but not yet talking to real upstream APIs: - OpenCode HTTP/SSE session API (the `routes/opencode.ts` forwarder is a stub). - Gitea repo/commit calls (the `routes/git.ts` handlers are stubs). - Auth (PRD §5.1) and payments (PRD §5.5). - Persistent registry — currently in-memory; replace with a real DB. ## Frontend The Next.js frontend lives at `../growqr-frontend` (currently cloned as a nested dir at `./growqr-frontend` — git-ignored from this repo). It will install `@rivetkit/react` and connect to the Grow Agent actor for chat + streaming events.