Spaces:
Running
Running
| # Puck daemon | |
| `gradio.Server` (Gradio 6 server mode) that doubles as the **HF Space backend** and the **local daemon**. It is dumb pipes by design: validate wire events against [`/schema/event.schema.json`](../schema/event.schema.json), queue them, serve the built frontend. All policy lives in the TS engine (`frontend/src/engine`) β keeping it that way is what makes the eventual Tauri/Rust swap ~150 lines instead of a rewrite. | |
| ## Run | |
| ```bash | |
| cd server | |
| uv run app.py # http://127.0.0.1:7777 | |
| ``` | |
| - Serves `frontend/dist` at `/` if built (`cd frontend && bun run build`). | |
| - In dev, run `bun dev` in `frontend/` instead β vite proxies `/api` to `:7777`. | |
| ## API | |
| | Route | Purpose | | |
| |---|---| | |
| | `POST /api/events` | Ingest a wire event. 202 on accept, **422 with details** on schema violation | | |
| | `GET /api/events/pending` | Drain the queue (each event delivered once; frontend polls every 3s) | | |
| | `GET /api/health` | Liveness | | |
| Try it: | |
| ```bash | |
| curl -X POST http://127.0.0.1:7777/api/events \ | |
| -H 'Content-Type: application/json' \ | |
| -d '{"source":"claude","type":"task_completed","title":"Refactor memory garden"}' | |
| ``` | |
| Puck flies over and comments within ~3s. | |
| ## Claude Code hook | |
| `claude-hooks/puck-event.sh` turns Claude Code lifecycle events into Puck events. Register in `~/.claude/settings.json`: | |
| ```json | |
| { | |
| "hooks": { | |
| "Stop": [ | |
| { "hooks": [{ "type": "command", "command": "/Users/vuln/code/puck/server/claude-hooks/puck-event.sh" }] } | |
| ], | |
| "Notification": [ | |
| { "hooks": [{ "type": "command", "command": "/Users/vuln/code/puck/server/claude-hooks/puck-event.sh" }] } | |
| ] | |
| } | |
| } | |
| ``` | |
| Fire-and-forget: if the daemon is down, the hook exits 0 in β€2s and Claude Code never notices. | |
| ## Adding a new watcher | |
| Write anything that POSTs the wire shape to `/api/events` β language doesn't matter, the schema is the contract. Give the engine a scoring template for your `(source, type)` pair in `frontend/src/engine/wire.ts` (`TEMPLATES`), or accept the middling fallback scores. | |