@satoramoto/scruple
v0.0.2
Published
A wrapper around coding agents that captures API calls, token usage, and git activity for review.
Downloads
40
Readme
scruple
A wrapper around coding agents (claude, codex, aider, and any other
OpenAI-compatible CLI) that observes everything that happens during a session
— API calls, token usage, the conversation payload, and any git activity
inside the session — and ships it to a scruple ingest server for review in
the web app.
The agent itself runs untouched: scruple sets the agent's API base URL
(ANTHROPIC_BASE_URL for Claude, OPENAI_BASE_URL and OPENAI_API_BASE for
OpenAI-style agents) to a local proxy and prepends a transparent git shim
to PATH. Both are removed when the session ends.
Install
From npm:
npm install -g @satoramoto/scrupleFrom source:
bun install
bun link # exposes `scruple` on your PATHRequires Bun ≥ 1.3.
Authorize
scruple loginRuns an OAuth device-code flow against the ingest server (default
http://localhost:7000, override with SCRUPLE_INGEST_URL). The token is
written to ~/.scruple/config.json with mode 0600. Without a token,
sessions still run locally — events are logged to ~/.scruple/ but nothing
is sent upstream.
Use
scruple <tag> <agent> [args...]<tag>— a label that gets attached to every event from this session. Pass-to use the current git branch name (re-read on every request, so it tracks branch switches mid-session). A bare issue number like42(orpr/42, or#42if you quote it) is expanded toorg/repo#42using the current repo'soriginremote (errors if no remote is configured). Trade-off: a tag literally named42is no longer possible — name it something descriptive instead.<agent>— the agent command to launch. Recognized:claude,codex,aider,gpt. The OpenAI-style agents will pick upOPENAI_BASE_URL/OPENAI_API_BASEfrom your environment as the upstream, so you can point them at OpenRouter, Groq, Fireworks, Together, vLLM, Ollama, etc. without any code changes — just export the var before running scruple.- Remaining args are forwarded to the agent.
Examples:
scruple feature-x claude # tag everything as "feature-x"
scruple 42 claude # expands to satoramoto/scruple-cli#42
scruple - claude # tag with current branch, live
scruple - claude --resume # forwards --resume to claude
scruple feature-x codex # OpenAI Codex CLI through the proxy
OPENAI_BASE_URL=https://openrouter.ai/api/v1 scruple feature-x aiderWhat gets captured
- API calls — every
/v1/messages(Anthropic),/v1/chat/completions(OpenAI), and/v1/responses(OpenAI) request: model, token counts (input, output, cache read, cache creation), latency, request ID, status, the request payload, and the streamed response blocks. OpenAI'stool_callsand reasoning summaries are normalized to the sametool_use/thinkingshape that Anthropic uses, so the ingest server doesn't care which provider the event came from. - Git events —
commit,switch,checkout,push,pull,rebase,merge,reset,stash. For commits we also capture the message, author, parents, and shortstat. The shim is fire-and-forget and never blocks or fails the underlyinggitcommand.
Local artifacts:
~/.scruple/events.jsonl— one JSON line per API call.~/.scruple/sessions/<timestamp>-<pid>.log— debug log for the session. Inside tmux, this is auto-tailed in a split pane.~/.scruple/config.json— auth token and ingest URL.
Layout
src/
wrapper/ cli entry, agent detection, git shim, tmux pane, login
proxy/ local Bun.serve() proxy that forwards to the chosen provider
lib/ config, logging, ingest client, SSE sniffers (Anthropic + OpenAI), typesDevelop
bun test
bun src/wrapper/cli.ts <tag> claude # run from source without linking