@ai-codebot/daemon
v0.2.0
Published
slock local-runner daemon — dials the cloud relay over outbound WSS and brokers a local coding-agent CLI through a 127.0.0.1 capability proxy.
Maintainers
Readme
@ai-codebot/daemon
The slock local-runner daemon (PR4). Dials the cloud relay (/daemon/connect)
over an outbound WSS tunnel, speaks the PR2 frame protocol, and on a Launch runs a
local coding-agent in cwd=repo — brokering the model credential through a
127.0.0.1 per-launch proxy so the real LLM key never reaches the agent.
npx @ai-codebot/daemon connect \
--server-url wss://<your-relay-host>/daemon/connect \
--api-key ck_machine_… \
[--repo <path>] [--model-url <url>] [--cli claude|codex|auto] [--once]The machine key may also be supplied via CODEBOT_MACHINE_KEY. The key is never
logged.
Architecture
src/frames.ts— TS + zod mirror of the server'sdaemon_frames.py(snake_case,MAX_FRAME_BYTES = 256 KiB). Inbound frames are zod-validated at the boundary.src/tunnel.ts—wsclient. Bearer in theAuthorizationheader (never the query), Hello/HelloAck handshake, Pong-on-Ping, exp-backoff + full-jitter reconnect. Close codes: 4401 unauth / 4409 superseded → no reconnect.src/broker/— the127.0.0.1capability broker (C4). A per-launchcrypto.randomBytes(32)token is handed to the child asANTHROPIC_API_KEY; the broker stream-pipes requests to the real model endpoint, injecting the real key. The real key + theck_machine_machine key are stripped from the child env.src/spawn/— PRIMARY = real CLI (fail-fast until the OQ-3 flag contract is verified); FALLBACK = the N2 local tool-loop (read/write/replace/run-tests/finish).disallowed-tools.tsis the single source of truth for the blacklist.
Security invariants (Tier-A)
- The real model key never reaches the agent (env/argv/token-file/logs).
- Per-launch token isolation: wrong token → 401, non-model path → 403, broker dies with the launch.
- The
ck_machine_key is confined to the tunnel layer. - Disallowed tools stripped before spawn; deadline kills child+broker; SIGINT tears
down all launches (no orphans /
0600token files). - No silent fallback: model unreachable / no model / no CLI+no N2 → loud
failed. - Exactly one
Resultper launch (零静默).
Tests
pnpm --filter @ai-codebot/daemon test # automated tsx --test suite (CI)
node verify-daemon.mjs --server-url ws://127.0.0.1:8001/daemon/connect … # MANUAL E2E (NOT CI)Real CLIs + a real local model cannot run in CI; verify-daemon.mjs documents the
owner-run E2E against a SECOND agent-service on :8001 (never :8000).
OQ-3 (PRIMARY CLI flags — unverified)
The exact headless / JSON-output / disallowed-tools flag NAMES for the shipped
Claude Code / Codex CLIs are unverified. They live behind the CLI_FLAG_CONTRACT
constant in src/spawn/cli-runner.ts with verified: false; the runner fails
fast (CliContractUnverifiedError) rather than emit a possibly-wrong invocation,
and the launch falls back to the fully-tested N2 path. To enable a CLI: verify the
real flags, flip verified: true, and add an integration proof in verify-daemon.mjs.
