#!/usr/bin/env node /** * Dev body wrapper: prints the developer card, then runs `podman compose up * --build` attached (Ctrl+C stops the body). See compose.yaml for the shape. */ import { spawn } from 'node:child_process' const card = ` ┌──────────────────────────── dev body ────────────────────────────┐ │ web UI (live timeline) http://localhost:3000 │ │ service health curl localhost:3000/healthz │ │ agent readiness curl localhost:33081/readyz │ │ │ │ pod-local service API (dev: published on host 33001) │ │ status: curl localhost:33001/v1/status │ │ ingest chat: curl localhost:33001/v1/chat/ingest \\ │ │ -H 'content-type: application/json' \\ │ │ -d '{"messages":[{...ChatMessageIn...}]}' │ │ ingest audit: curl localhost:33001/v1/audit/ingest ... │ │ recall: curl localhost:33001/v1/recall -d '{"kind":...}' │ │ │ │ fake telegram (echoes sends back as mention wakes) │ │ curl -X POST localhost:38080/bot-dev-token/sendMessage \\ │ │ -H 'content-type: application/json' \\ │ │ -d '{"chat_id":-100,"text":"hello will"}' │ │ │ │ storage thresholds dev: warn 10% / stop 5% (host fs is ~84% full) │ │ model session: fake without a key; ZAI_API_KEY=... mise run dev │ │ makes will real (force fake: WILL_SESSION_MODE=fake) │ │ genome: will lives in ./.dev/work (clone of ./.dev/origin/will.git │ │ seeded from your commits + dev-sync overlay of your dirty files).│ │ will edits/commits/pushes ONLY there. Inspect: cd .dev/work │ │ your real workspace is never mounted into the agent │ │ │ │ state: ./.dev/{origin.git,work,agent,service-data} on your host │ │ reset: rm -rf .dev && podman compose up -d │ │ logs: podman compose logs -f service | agent │ │ shell: podman compose exec agent bash │ │ podman compose exec service bash │ └──────────────────────────────────────────────────────────────────┘ ` console.log(card) const child = spawn('podman', ['compose', 'up', '--build'], { stdio: 'inherit' }) child.on('exit', (code, signal) => { process.exit(code ?? (signal === 'SIGINT' ? 0 : 1)) }) for (const sig of ['SIGINT', 'SIGTERM']) { process.on(sig, () => { // child is in the same foreground group; it already got the signal child.kill(sig) }) }