Scaffold backend: Hono + Rivet Kit + per-user Docker stack
Backend that provisions per-user OpenCode + Gitea Docker pair via
dockerode and exposes the Grow Agent / sub-agent Rivet Kit actors
described in the PRD. Sub-agent workflows route through the parent
Grow Agent's OpenCode Docker.
- src/docker/manager.ts spawns growqr-gitea-<userId> and growqr-opencode-<userId>
- src/actors/{grow-agent,sub-agent,registry}.ts: Rivet Kit actors
- src/routes/{actors,opencode,git}.ts: PRD section 5.2-5.4 HTTP API
- docker-compose.yml runs rivet-engine + backend (mounts host Docker socket)
- PRD updated to lock in per-user OpenCode/Gitea Docker topology
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
101
README.md
Normal file
101
README.md
Normal file
@@ -0,0 +1,101 @@
|
||||
# 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-<userId> (one per user, spawned on demand)
|
||||
└─ growqr-opencode-<userId> (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-<id>/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.
|
||||
Reference in New Issue
Block a user