All commands support --json for machine-readable output. Commands that query alerts use exit code 1 if active (unacknowledged, unsuppressed) alerts exist.
--config PATH Override config file path
--db PATH Override database path
--agent ID Filter to a specific agent
--json Output in JSON format
--no-color Disable color output
-v, --verbose Verbose output
Guided setup wizard. Creates config file, generates ingest secret, optionally installs background daemon.
tj init is the primary name, the one every other developer tool uses for "set this up here."
tj onboard is the same command under its original name: one command object registered twice, so
the options, the prompts and the config it writes are identical and cannot drift.
tj onboard # interactive setup
tj onboard --claude-code # configure Claude Code telemetry
tj onboard --no-daemon # skip daemon installation
tj onboard --budget 5.00 # set daily budget during setup
tj onboard --force # overwrite existing config
tj onboard --verify # poll for the first span after setup and report confirmed/not-confirmed
tj onboard --verify-only # skip setup; just re-poll an existing install (post-restart re-check)
tj init --cloud <key> --org <org> # forward spans, sessions and commits to TokenJam Cloud (asks first; --yes skips)
tj init --cloud off # stop forwarding, keep the key
tj init --add-project # register another repo against a setup you already have
tj init --claude-code --reconfigure # re-prompt for plan tier and budget (needs --claude-code or --codex)
tj init --hooks # install the prepare-commit-msg hook in this repo
tj init --notes # also install the post-commit git-notes hook (implies --hooks)
tj init --enforce # turn on the enforcement proxy in suggest modeKey flags for non-interactive setup: --plan, --budget, --no-daemon skip every prompt; use these to run onboarding unattended (CI, Docker, a script). The project/dashboard-namespace name is never prompted for — it's always derived from the repo (git remote) or folder name. --verify is separate: it opts into the post-setup telemetry poll instead of the interactive "verify now?" confirm.
--cloud <key> --org <org> connects this machine to a TokenJam Cloud organization (tj init is the same command). It writes [cloud] into the config, prints exactly what leaves the machine (token counts, model names, cost, timestamps, tool names, file paths, session / repo / branch / commit identifiers, hashed developer id, git author email) and what never does by default (prompt text, completions, tool outputs, file contents, diffs, secrets), asks for a yes, then pushes the history already on disk; the daemon forwards new sessions every five minutes from then on. Both values are on Cloud's Connect screen; the key alone does not identify the organization. --cloud-endpoint points at a different API; --cloud off turns forwarding off in place. See configuration.md.
--hooks and --notes are the per-repo half of the same stamping. --hooks installs a
prepare-commit-msg hook so a commit you make from a plain shell mid-session carries a
TokenJam-Session: trailer, which joins it to the session at deterministic confidence. --notes
adds a post-commit hook that writes the session's measured cost to refs/notes/tokenjam, and
implies --hooks. Both write inside a managed block, keep a hook you already have, refuse a
core.hooksPath inside the worktree, and are idempotent. Off by default. See
docs/ledger/hooks-and-notes.md.
--enforce turns on the enforcement proxy in suggest mode (tj proxy enable) and prints
what it does and does not touch. Suggest mode forwards every request unmodified and records what a
policy would have done; nothing is blocked or rewritten until you approve it. Subscription-plan
traffic is never intercepted and subscription OAuth credentials are never proxied or forwarded.
Composes with --hooks. See docs/proxy/overview.md.
--add-project registers the current repo under a project namespace in an existing global
config, without re-running the wizard: no plan or budget prompt, no backfill, no daemon restart. It
needs tj init to have run once somewhere first.
--reconfigure re-prompts for plan tier and budget against a config that already exists,
skipping agent-runtime re-detection. It must be paired with --claude-code or --codex:
tj init --claude-code --reconfigure
tj init --codex --reconfigurePlan tier is per provider and lives in [budget.<provider>], which only the provider-specific flows
write, so a bare tj init --reconfigure against an existing config exits 1 with
--reconfigure has no effect without --claude-code or --codex rather than silently doing nothing.
Scope flags. --plan sets the plan tier non-interactively, --analysis-span 30d|90d|all sets
how far back the analyzers look (storage retention is derived from it, and all disables deletion
entirely, so history the analyzers use cannot be deleted underneath them), and
--backfill-days N / --backfill-all set the history scope without the interactive prompt.
--verify-only is the lightweight post-restart re-check: it skips the whole wizard (no config rewrite, no summary, no restart banner) and only polls an already-configured install for its first live span. Use it after you've restarted Claude Code / Codex; tj onboard --claude-code --verify-only (or --codex, or bare for an SDK install) reads that persona's existing config and reports confirmed / not-confirmed. Backfilled history doesn't count here; the poll waits for a new live span.
--verify and --no-daemon: verification polls for the first span through whichever read path is available. With the daemon running it reads over HTTP; with --no-daemon, the poller opens the DuckDB file directly; the same file the SDK would need to write to. If nothing else is writing yet (the pre-first-run case) this works; if something else holds the write lock, verification reports "start tj serve" rather than confirming, even though onboarding itself succeeded. Run tj ping instead to prove interception without touching the DB lock at all, or start tj serve temporarily to get a live confirmation.
Emit one clearly-labeled test span through the real SDK export path to prove instrumentation is wired up, without needing a whole agent. Reports whether the span was intercepted and where it was delivered (running daemon over HTTP, or local DuckDB directly).
tj ping
tj ping --agent my-agent
tj ping --jsonExit codes: 0 = intercepted and delivered, 1 = interception or delivery failed.
Health check; validates config, database connectivity, ingest secret, and alert channel reachability.
tj doctorExit codes: 0 = healthy, 1 = warnings, 2 = errors.
Current agent state: session info, cost, token counts, active alerts.
tj status
tj status --agent my-agentTrace listing with span waterfall view.
tj traces
tj traces --since 1h
tj trace <trace-id> # full span waterfall for a single traceCost breakdown by agent, model, day, or tool.
tj cost
tj cost --since 7d
tj cost --group-by model # group by model
tj cost --group-by day # group by day
tj cost --group-by agent # group by agent
tj cost --group-by tool # group by toolDiagnose where your Claude Code quota goes: what share of tokens is re-reading prior context (conversation history, CLAUDE.md, tool output) vs. net-new work, plus recurring inclusions (capture-gated) and /compact candidates. Subscription plans see a token-share/quota headline; API plans see dollars as a secondary line. Needs a direct DB connection or a running tj serve (computed server-side when the daemon holds the write lock).
tj context
tj context --since 7d --agent my-agent
tj context --jsonKey flags: --since, --agent, --json.
Turn-by-turn reconstruction of how a Claude Code session attempted its task; its ordered moves (delegate / dead_end / verify / act), and for every subagent delegation, that subagent's mandate plus a factual tool-category tally (reads/edits/searches/commands) and its own recursively-rendered method spine. With no --session, auto-selects the most recent session with real activity. Reads the on-disk transcript, falling back to a persisted snapshot when the transcript was pruned; needs a direct DB connection or a running tj serve (the daemon does the reconstruction+fallback server-side when it holds the write lock).
tj session-story
tj session-story --session <session-id>
tj session-story --jsonKey flags: --session, --last (default when --session is omitted), --json.
Retroactive audit of your premium (Opus/Fable/Mythos) quota: which past premium-tier sessions were structurally Sonnet-shaped (small input/output, few tool calls)? Covers Fable and Mythos (the tiers above Opus) as well as Opus. Reports the percent of premium quota that went to Sonnet-shaped sessions (a retrospective behaviour mirror; those tokens are already spent, so it is misallocated, not "reclaimable"), example sessions to spot-check, and an optional tuned routing-config export. Subscription users see a habit nudge; API-billed users additionally see the already-billed dollar counterfactual. Quota-share framing, never a dollar "saving" claim. The JSON field is percent_quota_misallocated. Needs a direct DB connection (can't run against a live tj serve).
tj quota-audit
tj quota-audit --since 30d --agent my-agent
tj quota-audit --export-config claude-code
tj quota-audit --jsonKey flags: --since, --agent, --export-config, --json.
Alert history with severity and type filtering.
tj alerts
tj alerts --severity critical
tj alerts --type sensitive_action
tj alerts --since 1h
tj alerts --unread # only unacknowledged alertsView and set daily/session cost limits.
tj budget # view all budgets
tj budget --agent my-agent --daily 5.00 # set daily limit
tj budget --agent my-agent --session 1.00 # set session limitBehavioral drift report: baseline vs latest session Z-scores.
tj drift
tj drift --agent my-agentExit code 1 if any agent has drifted (useful for CI gating).
Close the loop on a run: annotate it, promote it into an expectation, and track whether later runs pass or regress. Local-first; pass/regress is your recorded verdict, not an automated score. Also available as the Lens "Loop" tab on a session's detail page.
# Annotate a run with a human note + optional verdict (good/bad/mixed/unknown)
tj loop annotate <session_id> --verdict bad --note "retried the same tool 5x"
tj loop annotations <session_id>
# Promote a run into a stored expectation, then record reruns against it
tj loop expect <session_id> --name "no retry loop" --desc "must not retry >3x"
tj loop expectations
tj loop record <expectation_id> <session_id> --outcome pass --note "fixed it"
tj loop history <expectation_id>Tool call summary: call counts, average duration, error rates.
tj tools
tj tools --since 1hExport spans in multiple formats.
tj export --format json
tj export --format csv --output spans.csv
tj export --format otlp
tj export --format openevals --output traces.jsonAnalyze recent usage for cost-saving candidates, cache opportunities, prompt trimming, workflow reuse, recurring failures, and budget exposure.
tj optimize # run all analyzers
tj optimize downsize cache reuse # run selected analyzers
tj optimize relearn # recurring failures an agent re-hits
tj optimize --since 7d --agent my-agent # scope the analysis window
tj optimize --compare last-7d # compare against a prior window
tj optimize --export-config claude-code # write advisory routing recommendations
tj optimize --json # machine-readable reportAnalyzer names: downsize, cache, cache-recommend, resend, trim, reuse, script,
subagent, summarize, verbosity, deadweight, relearn, stream-usage, budget-projection,
shipped.
shipped is the odd one out: it reports what your sessions left behind rather than what they could
have cost less. It carries no savings figure and sits outside the recoverable-waste rollup. See
docs/optimize/shipped.md and docs/ledger/overview.md.
relearn finds failure signatures that recur across three or more sessions, the blockers an agent silently re-hits. Act on what it finds with tj relearn.
Key flags: --since, --agent, --budget, --budget-usd, --compare, --expand, --export-config, --export-templates, --json.
Review and apply fixes for the recurring failures tj optimize relearn detects. The same proposals the Lens Review inbox shows, from the terminal. The detector runs on a schedule inside tj serve, so list is empty until a pass has completed.
tj relearn list # stored proposals, with their IDs
tj relearn apply <proposal_id> # preview the exact diff (dry run)
tj relearn apply <proposal_id> --go # write it, with a backup and a commit
tj relearn enable <fix_id> --yes # wire an applied enforcement fix live
tj relearn revert <fix_id> # undo an applied fix
tj relearn eval-case <proposal_id> # the evidence as JSON, for your own eval toolingThe human gate is unconditional: apply is a dry run unless you pass --go, enable refuses without --yes because a hook starts intercepting tool calls once it is wired in, and every write is reversible with revert. eval-case is read-only.
Subcommands: list, apply, enable, revert, eval-case.
Key flags: apply: --go, --target, --scope, --force; enable: --yes; eval-case: --out.
Compile advisory router configs from downsize findings. Exports are written under the TokenJam config directory for manual review and are not applied automatically.
tj route export --target ccr
tj route export --target litellm --since 7d
tj route export --check
tj route export --target ccr --jsonKey flags on tj route export: --target ccr|litellm, --check, --agent, --since, --json.
Show a shareable spend-tier summary for the selected usage window, paired with the downsize savings figure.
tj tokenmaxx
tj tokenmaxx --since 7d
tj tokenmaxx --jsonKey flags: --since, --json.
Read-only inspection of the resolved model pricing table; one row per (provider, model) with input/output/cache-read/cache-write rates in USD per million tokens, plus a source column (override vs. packaged).
tj pricing list
tj pricing list --model claude-opus
tj pricing list --jsonKey flags: --model, --json.
Ingest historical telemetry from local Claude Code logs or external observability exports.
tj backfill claude-code
tj backfill claude-code --since 30d --quiet
tj backfill langfuse --source-file observations.json
tj backfill helicone --source-url https://api.helicone.ai --api-key <key>
tj backfill otlp --source-file spans.ndjsonSubcommands: claude-code, codex, langfuse, helicone, otlp, status.
tj backfill status shows which on-disk Claude Code sessions are not yet in the database.
Claude Code prunes its own transcripts after roughly 30 days, so a session that never made it in is
on a clock. Sessions are compared by the transcript's internal sessionId rather than by filename,
because roughly half the .jsonl files under the projects root sit in nested subagents/ folders
and carry their parent's id, which makes a filename count wildly over-report the gap.
tj backfill status # the gap, with the ten largest missing sessions
tj backfill status --since 30d # scope the comparison window
tj backfill status --jsonKey flags: --since on all sources; --root, --since-days, and --quiet for claude-code; --source-url, --source-file, and --api-key for Langfuse and Helicone; --source-url and --source-file for OTLP.
Generate standalone HTML reports for analyzer findings. Reuse reports can also write Markdown skeleton sidecars.
tj report --trim
tj report --trim my-agent --since 7d
tj report --reuse
tj report --reuse my-agent --no-openKey flags: --trim [agent_id], --reuse [agent_id], --since, --no-open.
Structure-aware prompt summarization (advisory). list scans for prompt files worth summarizing and estimates the per-call token saving (read-only). prep wraps a prompt's structure behind verbatim markers and emits it for a model to rewrite; --via claude-p or --via api runs the rewrite for you in one shot. check verifies a rewrite preserved every structure block (a hard gate) and stages it. apply writes a staged rewrite back to the file (default dry-run; --go writes, with a backup); undo restores from that backup.
tj summarize list
tj summarize list --recursive --json
tj summarize prep path/to/prompt.md
tj summarize prep path/to/prompt.md --via claude-p
tj summarize check path/to/prompt.md --summary rewrite.md --prepped-hash <hash>
tj summarize apply path/to/prompt.md
tj summarize apply --go
tj summarize undo path/to/prompt.md --goSubcommands: list, prep, check, apply, undo.
Key flags: list: --recursive, --repo, --no-global, --ext, --min-prose, --json; prep: --via claude-p|api, --ratio, --json; check: --summary, --prepped-hash, --json; apply/undo: --go, --dry-run, --json.
Inspect policy-adjacent configuration and recent suggest-mode policy decisions.
tj policy list
tj policy list --json
tj policy decisions
tj policy decisions --since 7d --limit 50
tj policy decisions --jsonSubcommands: list, decisions.
Key flags: --json for both subcommands; --limit and --since for decisions.
Manage the optional suggest-mode proxy and its provider base-URL wiring.
tj proxy status
tj proxy enable
tj proxy disable
tj proxy killswitch
tj proxy killswitch --offSubcommands: enable, disable, status, killswitch.
Key flag: --off on killswitch releases pass-through mode.
These are wired by tj onboard --claude-code and invoked by Claude Code itself (via hooks / the statusline / the shell wrapper), not typically run by hand; documented here for completeness and troubleshooting.
Zero-model-token status line for Claude Code. Reads the session payload JSON Claude Code pipes on stdin and prints one line: model, session token total, and the re-read share (cache-read ÷ total tokens), with a /compact nudge once re-reading dominates. Runs out-of-band after each turn; never enters the model's context, so it costs no quota. Wired into ~/.claude/settings.json's statusLine by tj onboard --claude-code.
tj statusline # reads payload JSON on stdin; not meant to be typed interactivelyIt also writes the active-session record (~/.tj/active_sessions.json) the commit hook reads, which
is how a commit made from a terminal Claude Code did not spawn still gets a session trailer.
Attaches a commit's session cost to refs/notes/tokenjam as a JSON note. Called by the post-commit
hook tj init --notes installs, for a commit whose message carries a TokenJam-Session: trailer.
Run it by hand on any trailered commit if you want.
tj commit-note # HEAD
tj commit-note <sha>
tj --json commit-note # machine-readable outcomeIt never fails the commit it runs from: every outcome exits 0, and tj -v commit-note says what it
did or why it did nothing. The only git write is the note on our own ref; the commit message is never touched
here. See docs/ledger/hooks-and-notes.md.
Hands a resuming (or post-compaction) session a compact brief of its prior method (task, progress, dead ends, working files) instead of re-investigating. Deterministic, no LLM, zero in-loop token cost. tj onboard --claude-code wires --from-hook into a SessionStart hook automatically.
tj resume-brief --from-hook # SessionStart-hook mode: reads session_id/transcript_path from stdin
tj resume-brief --session <id>
tj resume-brief --transcript <path>
tj resume-brief --last # manual: most recently active session by mtimeKey flags: --from-hook, --session, --transcript, --last (exactly one is expected).
Prints this project's OTel resource attributes (service.name=claude-code-<repo>[,service.namespace=<project>]) on one bare line. Called by the claude shell wrapper (installed by tj onboard --claude-code) to build each terminal's OTEL_RESOURCE_ATTRIBUTES, appending a per-terminal service.instance.id.
tj otel-resource-attrsReports a terminal's Claude Code session(s) as closed, so the dashboard archives that tile immediately (Claude Code emits no close event of its own). Called best-effort by the claude shell wrapper on exit/interrupt; talks to the running daemon over HTTP and never touches the DB directly. Always exits 0; a failure here must never break the user's shell.
tj session-end --instance <terminal-id>
tj session-end --session <session_id>
tj session-end -v --instance <terminal-id> # -v surfaces what happened on failureKey flags: --instance, --session (at least one required).
Run reproducible Agent Incident Library scenarios without API keys or external services.
tj demo # list available scenarios
tj demo retry-loop # run one scenario
tj demo retry-loop --json # machine-readable scenario outputKey flag: --json.
Start the MCP server (stdio transport, for SDK / API integrations). tj onboard --claude-code / --codex do not register it; an in-loop MCP is a per-turn token tax on subscription users (+36% measured); wire it manually with claude mcp add tj --scope user -- tj mcp only if you're building an SDK / API integration.
tj mcpStart the local REST API server with web UI and Prometheus metrics.
tj serve # foreground
tj serve & # background
tj serve --host 0.0.0.0 # bind to all interfaces
tj serve --port 8080 # custom port
tj serve --reload # auto-reload for developmentWeb UI: http://127.0.0.1:7391/
API docs: http://127.0.0.1:7391/docs
Metrics: http://127.0.0.1:7391/metrics
Stop the background daemon or tj serve process.
PID-file discovery requires a matching command line from /proc or ps. If
neither can establish the process identity, TokenJam leaves that PID alone;
a live PID by itself is not proof that it still belongs to the daemon.
tj stopFull removal: all TokenJam data, config, daemon, MCP registration, and env vars; AND the tokenjam
package itself (pipx/uv-tool installs are removed automatically; a plain pip/venv install gets the
exact pip uninstall command printed instead of a guess). The symmetric counterpart to tj onboard.
tj uninstall # interactive confirmation
tj uninstall --yes # skip confirmationConfig-only teardown; the same wiring/config cleanup as tj uninstall above, but leaves the
tokenjam package installed so tj onboard works again without reinstalling. Use this to reconfigure
or pause TokenJam.
tj reset # interactive confirmation
tj reset --yes # skip confirmation