AGENTS.md — relay
relay is an open-source harness that lets one person's coding-agent subscriptions (Claude, Codex, Grok) work as one system: GitHub issues are the task bus, self-hosted runners on the user's own machines execute steps with the vendor CLIs under the machine's own login, a Postgres database holds shared memory and an append-only event feed, and a small web app shows it all. Credentials never leave the machine they were created on.
Layout
packages/core— TypeScript library:db/(Postgres schema + migrations + typed queries; PGlite locally, Neon in production),brief/(the brief compiler andrelay.mdrenderer),memory/(transcript capture: parse, gate, extract decisions with the Sonnet lane),onboard/(official-vendor-docs ingestion gate),lanes/(headless adapters forclaude -p,fx,codex exec,grok -p),ledger/(step.usage writer and price table),assets/(Blob or local store, versions, review),rules/(owned-section installer forAGENTS.md/CLAUDE.md),hooks/(per-CLI hook installers and the brief cache),state/(project registration and file digests).packages/cli— therelaycommand.src/commands/holds one file per command group (setup,link,brief,recall,decide,prefer,capture,memory,assets,token),hooks/*.mjsare the dependency-free scripts the CLIs' hooks point at,templates/the caller workflowsrelay linkinstalls.relay onboard <model>ingests vendor guidance;relay feed,relay usage,relay doctor;relay token createmints scoped bearer tokens for the web app (hash stored, shown once).packages/mcp— the relay MCP server@relay/mcp:bin/relay-mcp.mjs(stdio for the CLIs),createMcpHandler(Streamable HTTP for the web app), one tool set for both: public read tools (relay_get_*), memory tools (relay_recall,relay_brief,relay_guidance,relay_feed,relay_project,relay_decide,relay_prefer) and asset tools (relay_asset_*), gated by the scopes a token carries (TOOL_SCOPESinsrc/server.ts).apps/web— Next.js app: event feed, projects, usage meters, workers, asset library with review (/assets), info and docs pages, webhook ingest (GitHub, Vercel), the public read API and the asset API under/api/v1, the MCP server at/mcp, the retention cron, and the agent-readiness files (/.well-known/*,/openapi.json,/llms.txt). Data goes throughapps/web/lib/data.ts:RELAY_DATA=dbor anyDATABASE_URLselectslib/data-db.tsover@relay/core(PGlite whenDATABASE_URLis unset, one handle per instance inlib/db.ts); otherwiselib/data-mock.tsserveslib/mock.ts. Bearer tokens are checked inlib/auth.ts(tokenstable, thenRELAY_API_TOKENS, thenRELAY_MEMORY_TOKEN).DESIGN.mdthere holds the UX brief and tokens.skills/relay/SKILL.md— the agent skill for installing relay, served at/.well-known/agent-skills/index.json..github/workflows— reusable runner workflows that repos call with a thin caller.docs/—ARCHITECTURE.mdis the source of truth for design;AGENT-READINESS.mdis the contract for the hosted site;VERSIONING.mdis the API deprecation policy;research/holds dated surveys.
Commands
pnpm install # Node 24+ required (.node-version); bin/relay finds one itself
pnpm -r typecheck
pnpm -r test # vitest; DB tests run on PGlite, no server needed
pnpm relay --help
pnpm relay setup # plan hooks + MCP server for the CLIs on this machine; --yes writes
pnpm relay link # in a repo (bin/relay link from elsewhere): digests, summary, relay.md, owned sections, workflows, labels; idempotent
pnpm relay brief 42 # the memory envelope a lane would get for issue 42
pnpm --filter @relay/web dev # mock data
RELAY_DATA=db pnpm --filter @relay/web dev # the CLI's PGlite file (stop the CLI first; PGlite is single-process)
pnpm --filter @relay/web build && pnpm --filter @relay/web typecheck
pnpm relay token create --name ci --scopes feed:read,assets:write # bearer token for /api/v1 and /mcp, shown once
RELAY_PUBLIC_URL=https://relay.kyro.house pnpm --filter @relay/web check:agentic # is-agentic score gate, after deploy
Memory commands (docs/MEMORY.md): relay brief, relay recall, relay decide, relay prefer, relay capture, relay memory history. Hooks call the CLI through the repo's own tsx, so the checkout must stay where relay setup ran (re-run it after moving).
Conventions
- TypeScript strict, ESM,
.tsimports with extensions. No default exports except Next.js pages/routes. - Plain SQL migrations in
packages/core/src/db/migrations/NNN_*.sql; never edit a shipped migration. - Every model call goes through a lane adapter and writes a
step.usageevent. Nothing calls a model directly. - Official vendor sources only for model guidance (
onboard/registry.tsallowlists domains). Do not add community prompt guides. - Secrets live in environment variables, never in files or examples.
.env.examplelists names only. - Keep
AGENTS.md,llms.txt, andREADME.mdaccurate when you change commands or layout; CI checks that README commands exist. - Commit messages: imperative, one topic each. Do not commit generated output, databases, or anything under
.harness/.
Installing relay for a user (agent instructions)
If a user asks you to set up relay, do these steps and stop at anything that needs their browser:
git clone <repo> && cd relay && pnpm installpnpm relay doctor— reports which CLIs are installed and logged in (claude,codexorfx,grok,gh), Node version, and database reachability. Tell the user what is missing; logins are theirs to do.pnpm relay setup— prints every file it would touch in~/.claude,~/.codex,~/.grok(hooks and the memory MCP server) and writes nothing; runpnpm relay setup --yesonly if the user said so. Run it throughpnpmso the hooks record the pinned Node 24.- In each repo they want managed:
cd <repo> && <relay checkout>/bin/relay link. This is the only per-repo step and runs the whole pipeline: registers the project and hashes its files, digests the changed files and writes the project summary (Sonnet lane, needs theclaudelogin;--no-digestskips it,--max-filescaps it at 400 by default), writesrelay.mdfrom that summary, adds the owned section toAGENTS.md/CLAUDE.md, the GitHub labels (gh), and the caller workflows. It prints every stage and ends with one cost line. Re-running is safe and makes no model calls unless files changed;--refreshrewrites the summary. Do not runrelay project digestorrelay project summarizeby hand. - Optional, for runners: follow
docs/RUNNERS.mdto register a self-hosted GitHub Actions runner on a machine that holds the logins. - Optional, for a model the user will prompt (image/video models):
pnpm relay onboard <provider/model>.
Never move or copy a login, token, or auth.json between machines. Never run with permission checks disabled on a machine that holds the user's logins.