CLI
Reference for the tailrace binary - create, init, scan, install-hooks, and the Claude Code hook handler.
@tailrace/cli ships the tailrace binary. Runtime: Node >= 20. Depends on @tailrace/core only.
Install
pnpm add -D @tailrace/cli
# or one-shot:
npx @tailrace/cli create next my-agentCommands
| Command | Description |
|---|---|
tailrace create <target> [dir] | Scaffold a governed agent app (next | cloudflare | openai) |
tailrace init [--force] | Detect stack; write tailrace.config.ts + .tailrace/config.json |
tailrace scan <path|-> [--json] | Tier 0 scan; exit 1 on any block-class hit |
tailrace install-hooks [--scope project|user] | Merge hooks into Claude Code settings (backup first) |
tailrace hook | Claude Code PreToolUse / PostToolUse handler (stdin → stdout) |
create
Scaffold a new project from a bundled template (no git clone of Tailrace). Distinct from init, which adds config to an existing repo.
tailrace create next my-agent
tailrace create cloudflare my-agent
tailrace create openai my-agent| Target | Stack | Tailrace packages |
|---|---|---|
next | Next.js App Router + AI SDK | @tailrace/core, @tailrace/ai-sdk |
cloudflare | Cloudflare Worker + AI SDK Compose | @tailrace/core, @tailrace/cloudflare-agents |
openai | @openai/agents Node entrypoint | @tailrace/core, @tailrace/openai-agents |
| Flag | Effect |
|---|---|
--force | Allow a non-empty destination directory |
--install | Run the detected package manager install after writing files |
Defaults: destination my-agent when [dir] is omitted. Pins @tailrace/* dependencies to the CLI package version. Writes .env.example and a README with install / verify / deploy steps. Prints host-specific curl (or npm run verify) hints on success.
Refuses a non-empty directory unless --force.
For adding Tailrace to an existing app, use init instead.
init
Detects next → ai → hono → generic Node from nearest package.json. Refuses to overwrite tailrace.config.ts unless --force. Prints a short integration snippet for the detected stack.
scan
Walks files (skips node_modules, .git, build dirs, binaries) or reads stdin when path is -. Exit 1 if any span resolves to block. Human output: path + entity + rule (never raw values). --json emits a machine-readable array of hits.
install-hooks
| Flag | Default | Effect |
|---|---|---|
--scope project | yes | $CLAUDE_PROJECT_DIR/.claude/settings.json (or cwd) |
--scope user | ~/.claude/settings.json |
Appends matcher "*" PreToolUse + PostToolUse command hooks with command: "tailrace hook" only if not already present. Ensures .tailrace/config.json exists.
hook
JSON path exclusively for policy decisions (always exit 0). Process errors exit 1.
| Case | Stdout |
|---|---|
| Clean PreToolUse | empty |
| Tokenize / mask | permissionDecision: "allow" + full updatedInput |
| Block | permissionDecision: "deny" + reason (entity + rule) |
| PostToolUse | empty (audit-only in v0.1) |
Config: .tailrace/config.json only (no TS transpile on the hot path). Identity agent default "claude-code"; workflowId = Claude Code session_id.
Perf budget: spawn-to-exit p50 < 150ms (CI gate).
Compiled config
{
"version": 1,
"agent": "claude-code",
"vaultKey": "<hex>",
"policy": {}
}Omit policy for the default (secrets → block, common PII → tokenize). Prefer TAILRACE_VAULT_KEY over committing vaultKey in prod.