llmstatus
v1.2.1
Published
Local LLM Status CLI: current code ownership by AI tool and model, repository token usage, and a README badge
Maintainers
Readme
LLM Status
See where your code came from.
Current code by tool/model · Repository token usage · README badges
Quick start · Integrations · Models · Commands · Troubleshooting · Support
LLM Status tracks supported AI edits in your Git repository and reports who owns the lines that remain today. View the mix in your terminal, open an offline HTML report, or add a badge to your README. It works with Claude Code, Codex, Cursor, Gemini CLI, Kimi Code CLI, and DeepSeek Harness.
Everything runs on your machine. The CLI makes no network calls, collects no telemetry, and needs no LLM Status account. Install and authenticate your coding tools separately.
| Understand your code | Keep the evidence local | Share a clear summary | | ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ | | Current lines by tool/model, with Human, Mixed, Unknown and Unmeasured kept visible. | Structured hooks record metadata and fingerprints. No LLM Status account or API key. | An offline report for you; aggregate badges and summaries for your repository. |
Quick start
Requirements: Node.js 20+ (22 or 24 LTS recommended; Node 20 is past end of life), Git 2.45+, and an existing Git repository.
1. Install
npm install -g llmstatus@latest
cd your-repositoryUse a global installation before enabling integrations so the hook executable has a stable path.
For a one-off scan: npx llmstatus scan.
2. Initialize and connect your coding tool
llmstatus init
llmstatus integrate codexReplace codex with claude, cursor, gemini, kimi, or deepseek. Follow the printed
activation instructions and use a fresh trusted coding session. You can enable several tools in the
same repository.
3. Verify capture, then explore
Check your tool's event count, make a supported structured edit to an existing Git-tracked file in the fresh session, and check the count again. For Codex:
llmstatus integrations codex --status
llmstatus ledger --tool codexReplace codex with your tool (claude-code is the ledger ID for claude). An increased count
confirms recorded activity; it does not establish complete coverage. Stage new files in Git before
expecting them in current-line totals. Then:
llmstatus scan
llmstatus report
llmstatus badge --writellmstatus alone also runs a scan. Paste the badge command's Markdown into your README and commit
.llmstatus/public/. Private tracking files stay ignored.
An initial scan may show Unmeasured lines because no evidence covers them yet. See how to read the numbers and troubleshooting.
Keep tracking as you code
LLM Status works best when installed and connected during normal development. A one-time scan shows the evidence available now; it cannot reconstruct every past edit or missing model ID. Keep the integrations enabled, follow their activation instructions, and use fresh trusted sessions.
# Upgrade the stable installation, then verify your enabled tool
npm install -g llmstatus@latest
llmstatus --version
llmstatus integrations codex --status
# Optional: refresh supported repository token usage when viewing reports
llmstatus usage auto enable
llmstatus scan
llmstatus reportUse your tool in place of codex. If setup reports inactive capture, rerun its integrate command
and follow the restart/plugin instructions. Keep the ignored private .llmstatus/ history when
upgrading; do not delete it to clear Unknown model. There is no background daemon, and a one-off
npx installation is unsuitable as a long-lived hook target.
When you switch models: an edit that replaces lines records the model supplied for that edit,
and untouched lines keep their earlier model. For example, if model A owns 100 lines and a Codex
edit with model B replaces 20 of them, the surviving ownership shows 80 for A and 20 for B. Hook
edits and record --operation create replace lines. A record --operation modify declaration
merges instead: the same tool with a different model shows Unknown model, and a different tool
shows Mixed. Retiring or renaming a model does not relabel its old lines, and LLM Status does not
infer a model from a default setting.
Why Unknown model remains: the tool may be known while its edit did not identify a model (Claude Code tool hooks and the native Gemini, Kimi and DeepSeek events never do), or overlapping evidence may be ambiguous. This differs from Unknown or Unmeasured code origin. Untouched historical unknowns remain unknown, and a model seen in token usage cannot backfill missing edit evidence.
A clearer view in your terminal
Color, compact sections and ownership bars make the summary easy to scan. Small terminals use a
simpler layout; redirected output is plain text. Set NO_COLOR=1 to disable color.
LLM Status / scan
acme / nebula
────────────────────────────────────────────────────────────────────
Current Branch main
Commit 6ab2fe1
Tracked Files 48
Last scan 2026-09-06T10:00:00.000Z
Current ownership
AI Contribution ━━━━━━━━━━━━━━────── 67.5% 675 lines
Measured Human ━━━───────────────── 15.0% 150 lines
Mixed ━─────────────────── 5.0% 50 lines
Unknown ━─────────────────── 2.5% 25 lines
Unmeasured ━━────────────────── 10.0% 100 lines
Tracked lines 1000
Attribution Confidence 89.0%
Primary AI Tool Codex
Unmeasured = no captured attribution; it is not measured Human.
By tool / current lines
Codex ━━━━━━━━──────────── 42.0% 420 lines
Gemini CLI ━━━━━─────────────── 25.5% 255 linesIllustrative fixture, not a measurement of this package or your repository. Bars show the share of current tracked lines; the actual CLI also includes Git, language and repository details.
Integrations
Run llmstatus init before setup. Install the coding tool separately and make its executable
available on PATH. These adapters capture supported structured file edits; running a tool
without its hooks does not establish authorship.
Supported tools and surfaces
Tool means the application that edits a file; model means the model identified on that specific edit. LLM Status tracks these separately.
| Editing tool | Type / surface | Automatic file capture | Per-edit model identity |
| ---------------------------- | -------------------------------------- | ---------------------------------------------------------- | -------------------------------------------------- |
| Claude Code | CLI / VS Code extension | Write / Edit hooks | Not included in Claude Code tool hooks (Unknown). |
| Codex | CLI and local desktop; IDE conditional | Structured apply_patch hooks | When the file hook supplies it. |
| Cursor | IDE | Agent Chat / Cmd+K and Tab edit hooks | Explicit model_id or model from the file hook. |
| Gemini CLI | CLI / VS Code Companion | write_file / replace hooks | Not included in the hook (Unknown). |
| Kimi Code CLI | CLI / IDE via ACP | Write / Edit plugin callbacks | Not included in the callback (Unknown). |
| DeepSeek Harness (dsh) | CLI, local web, IDE via ACP | Native write, edit, str_replace_editor plugin events | Not included in the native event (Unknown). |
Run a supported CLI in any IDE's terminal to use its CLI integration; this does not instrument the
IDE's own extensions. The Claude, Gemini and Kimi IDE routes are detailed below: their local hook
contracts are supported, but end-to-end authenticated IDE delivery remains unverified. Codex IDE
capture requires the same trusted project hooks as its CLI; CLI and fresh local desktop tasks have
been verified, and its hook does not distinguish them. DeepSeek IDE capture requires an IDE that
launches local dsh through ACP with the generated overlay.
Copilot, Windsurf and arbitrary editor extensions have no automatic adapter. Other local workflows can use manual declarations, including explicit tool, provider and model IDs. Those declarations are user-supplied evidence.
Model and provider recognition
These are identifier recognition examples, not a list of models offered by every tool. When a Codex or Cursor file hook, or a manual declaration, supplies an explicit model, LLM Status keeps the full ID and records the provider when it recognizes the family:
| Model family | Example hook identifiers | Provider recorded |
| ---------------------------------------- | ----------------------------------------------------------- | ------------------------------------------------ |
| GPT / OpenAI reasoning | gpt-5, gpt-3.5-turbo, o3 | OpenAI |
| Claude Opus / Sonnet / Haiku / Fable | claude-opus-4, claude-fable-5 | Anthropic |
| Gemini / Gemma / LearnLM | gemini-2.5-pro, gemma-3-27b-it | Google |
| DeepSeek | deepseek-chat, deepseek-ai/DeepSeek-R1 | DeepSeek |
| Qwen / QwQ | qwen3.6-plus, Qwen/QwQ-32B | Alibaba |
| Grok | grok-4.6, x-ai/grok-code-fast-1 | xAI |
| Kimi | kimi-k2.7-code, moonshotai/Kimi-K2-Instruct | Moonshot AI |
| GLM | glm-5.3, zai-org/GLM-5 | Z.AI |
| Llama / Muse Spark | meta-llama/Llama-3.3-70B-Instruct, muse-spark-1.3-xhigh | Meta |
| MiniMax M series | MiniMax-M3 | MiniMax |
| Nemotron | nvidia/Llama-3.1-Nemotron-70B-Instruct | NVIDIA |
| Inkling | inkling-xhigh | Thinking Machines |
| Smaug / Dracarys | smaug-agentic, abacusai/Dracarys2-72B-Instruct | Abacus.AI |
| Mistral / Mixtral / Devstral / Mathstral | mistral-large-2411, devstral-2512 | Mistral AI |
| Command A / R | command-r-plus | Cohere |
| Nova Micro / Lite / Pro / Premier | amazon.nova-pro-v1:0 | Amazon |
| Phi | microsoft/Phi-4 | Microsoft |
| Sonar | perplexity/sonar-pro | Perplexity |
| Hunyuan | hunyuan-turbos-20250313 | Tencent |
| MiMo | mimo-v2-pro | Xiaomi |
| OLMo | allenai/OLMo-2-1124-13B-Instruct | Ai2 / AllenAI |
| Step | step-2-16k | StepFun |
| Trinity | arcee-ai/trinity-large-preview | Arcee |
| AzeroGPT | azerogpt | SoundAI |
| Other / stealth / conflicting IDs | custom-model, ox-alpha-max, openai/grok-4 | Unknown unless supplied by a manual declaration. |
Recognized namespaces must agree with the model family. One optional OpenRouter wrapper is supported:
openrouter/qwen/qwen3.6-plus:free records Alibaba while keeping the full model ID and editing tool.
Custom namespaces such as acme/gpt-5 remain unknown. Recognition does not resolve model aliases
or prove which serving endpoint was used. An unrecognized but valid model ID is kept; its provider
is not guessed. Missing IDs and auto / default / unknown routing labels stay unknown, and a
session-start model is never assigned to later edits.
Connect a tool
| Tool | Connect | Qualified version / activation |
| -------------------- | ------------------------------ | ---------------------------------------------------------------------- |
| Claude Code | llmstatus integrate claude | 2.1.139+; trusted project hooks. |
| Codex | llmstatus integrate codex | Setup checks standalone Codex CLI 0.124.0+; trusted project hooks. |
| Cursor | llmstatus integrate cursor | 1.7.0+; trusted workspace hooks. |
| Gemini CLI | llmstatus integrate gemini | Stable 0.58.0+ within 0.x; trusted project hooks. |
| Kimi Code CLI | llmstatus integrate kimi | Stable 0.41.0+ within 0.x; install/reload the plugin below. |
| DeepSeek Harness | llmstatus integrate deepseek | dsh 0.1.2-rc.1 preview only; activate the launch overlay below. |
Check setup and captured activity:
llmstatus integrations
llmstatus integrations codex --status
llmstatus doctorUse claude, cursor, gemini, kimi, or deepseek in the status command to inspect that
integration. Enabled/configured does not prove that an edit was captured. Check event counts;
Gemini, Kimi and DeepSeek also report recent hook observation and activation requirements in their
detailed status.
Requirements, updates and removal
- Integrations are repository-local and qualified for main Git worktrees on macOS/Linux. Linked worktrees are rejected. The CLI package supports Windows, but live Windows hook qualification is incomplete.
- Trust the workspace, allow hooks, and start a fresh session after setup. Shell, MCP and cloud-agent file writes are outside capture coverage.
initmaintains ignore rules for private.llmstatus/files and local Claude, Codex, Cursor and Gemini hook configuration (Kimi and DeepSeek artifacts live under.llmstatus/). Setup preserves unrelated settings and refuses tracked or symlinked private state; re-runinitif the ignore rules need updating. The rules include.gemini/settings.json; a repository that commits a shared Gemini settings file keeps it tracked, but the Gemini integration refuses to install there.- Remove only LLM Status-owned hooks with
llmstatus integrate <tool> --remove. Historical ledger events remain. Re-run setup after moving the repository or changing the CLI installation path.
Claude, Gemini and Kimi in an IDE
Claude Code for VS Code. Run llmstatus integrate claude from the main checkout, open that
folder in VS Code and start a fresh trusted Claude Code extension session. Permit project hooks.
The extension must load .claude/settings.local.json and support the same exec-form hook contract
(Claude Code 2.1.139+). Setup detects the standalone CLI; a bundled extension runtime is not
versioned by that check. The official extension guide
documents shared hook settings.
Gemini CLI Companion for VS Code. Run llmstatus integrate gemini, then start gemini in the
IDE terminal from this checkout. Inside Gemini:
/ide install
/ide enableUse a trusted workspace and permit the installed project hooks. This route adds IDE context/diffs to the regular Gemini CLI session. See the official Companion guide. Gemini CLI 0.58.0 ACP is unsupported by this adapter because its tool path bypasses the required hooks. Standalone Gemini Code Assist extension edits also have no llmstatus adapter.
Kimi through ACP. Run llmstatus integrate kimi, then install/reload the generated plugin
as described below. In an ACP-compatible IDE such as Zed or JetBrains, configure a custom agent:
| Field | Value |
| ----------- | ------------------------------------------------------------------------- |
| Executable | Absolute path to the same compatible kimi used for plugin installation. |
| Arguments | ["acp"] |
| Project | This repository's main local Git checkout. |
| Plugin home | Same Kimi home/user as the CLI session that installed the plugin. |
Start a fresh IDE agent process. See the official Kimi IDE guide for editor-specific configuration. The IDE must persist file writes before the post hook: unsaved buffers and remote-only files are not captured, and saving later does not reconstruct the edit. Kimi's standalone VS Code extension/bundled runtime has not been qualified by this setup; use the documented ACP route or a supported CLI in its terminal.
For all three routes, make a supported file edit and check llmstatus integrations <tool> --status
for recorded events, replacing <tool> with claude, gemini or kimi. A configured hook or
connected IDE alone does not prove capture, and these hooks do not identify the editor surface.
Kimi activation
After llmstatus integrate kimi, use Kimi's own interactive commands:
/plugins install <directory printed by llmstatus>
/plugins reloadGenerate a supported file edit, then check llmstatus integrations kimi --status. The old Python
kimi-cli package is not supported; this adapter expects Kimi Code CLI's plugin contract. Global
credential-bearing Kimi configuration is not read or modified. On removal, also follow the printed
command to remove the inactive plugin copy.
DeepSeek CLI and IDEs
Install/configure the official DeepSeek Harness
separately. With dsh 0.1.2-rc.1 on PATH, from the main checkout on macOS/Linux:
llmstatus integrate deepseek
dsh --profile headless --patch .llmstatus/integrations/deepseek.patch.json
# An IDE that launches local dsh through ACP can use:
dsh --profile acp --patch .llmstatus/integrations/deepseek.patch.jsonUse the absolute overlay path printed by setup if the IDE starts elsewhere. Keep the IDE's existing
arguments and add --patch before profile application arguments. Restart after setup, make a native
file edit, then run llmstatus integrations deepseek --status and llmstatus ledger --tool deepseek.
The official dsh web --patch <path> profile can use the same capture plugin; it is distinct from
hosted DeepSeek chat.
The harness is a developer preview: unqualified versions are rejected. The native plugin captures exact successful built-in writes/edits, adds local subprocess latency, and reports recent hook observation separately from setup. No home/profile YAML or credentials are read or changed.
Using a DeepSeek model inside Codex or Cursor? Enable that tool's adapter. When its file hook
supplies an explicit model such as deepseek-chat or deepseek-ai/DeepSeek-R1, the report records
provider DeepSeek while keeping the editing tool. Claude Code tool hooks do not include a model,
so DeepSeek models used through Claude Code show Unknown model. An IDE without a supported adapter
can use manual declarations.
Remove capture with llmstatus integrate deepseek --remove, remove the --patch launch argument,
and restart. Existing ledger history and user-customized files are preserved; loaded/copied plugins
become inactive. Live authenticated DeepSeek/IDE delivery has not been verified.
Code contribution by model
llmstatus scan, ownership, status, and the offline report show current AI-owned lines by
tool and model. Example for a repository with 1,000 tracked lines (illustrative figures):
| Tool | Model | Current lines | % of repository | | ------ | --------------- | ------------: | --------------: | | Codex | gpt-5 | 200 | 20.0% | | Cursor | claude-sonnet-4 | 150 | 15.0% | | Gemini | Unknown model | 50 | 5.0% |
Identifiable models: 350 of 400 AI-owned lines (87.5%). The remaining 600 repository lines belong to the existing Human, Mixed, Unknown-origin or Unmeasured categories.
- Rows count code that still exists, grouped by tool and the full recorded model ID. Deletions reduce the count; moves keep the source model. The same model used in different tools has separate rows. Rows sort by descending lines, then tool/model ID.
- Percentages use all current tracked lines, including lines with no model evidence. Model rows reconcile to the AI total; missing model evidence is not removed from the denominator.
- Unknown model means missing or ambiguous model evidence on AI-owned lines. It differs from unknown code ownership. Two models ambiguously overlaying the same tool-owned line do not yield a guessed last-model author.
- Codex and Cursor contribute model identity when their edit events supply it. Claude Code tool hooks and native Gemini, Kimi and DeepSeek events produce Unknown model rows; recognizing a name is not capture.
- Git history evidence (AI co-author trailers such as Claude Code's default
Co-Authored-By, and known bot authors) only fills lines that have no captured evidence. Committing a captured edit keeps its recorded tool and model. The trade-off: if a later bot or agent commit that was not captured rewrites lines that were captured earlier, the earlier captured owner remains. scan --jsonaddscurrentOwnership.byModelandcurrentOwnership.modelCoverage. Historical model/provider event counts remain separately labeled in the report. Model IDs stay in private local output; the public badge and the export bundle show no model details.
Current contribution describes a snapshot, not a model-quality ranking. Costs and productivity scoring are not included.
Repository transfer recovery
If your repository was renamed, transferred, or moved before it had a hosted remote, old captured records may have a different repository identity. Diagnose and link them explicitly:
llmstatus repository
llmstatus repository link --from https://github.com/previous-owner/previous-name.git
llmstatus scanOnly link identities you confirm belong to this repository. The old identity must exist in your
local ledger and have a recorded commit in current HEAD's history. For a local-only repository,
use the exact previous repo_… id printed by llmstatus repository instead of a remote URL. No
network request is made. The original ledger stays unchanged; the private link is saved in
.llmstatus/repository-links.json.
Undo with llmstatus repository unlink --from <previous remote or repo id>, then scan again. Links
apply only to the confirmed destination; repeat for each historical identity after another
transfer. All three repository commands support --json, and scan/status/replay JSON includes
repositoryIdentity diagnostics. Check llmstatus integrations after a transfer and reinstall any
stale integration.
Keep the ledger and links together in private backups. A fresh clone or npm installation has no access to another machine's ignored ledger. Without original evidence, exact models remain Unknown model.
Repository token usage
Track all observed repository activity, including planning, debugging and reviews that never edit a file. Token usage is separate from surviving code contribution and always shows partial coverage or unavailable data.
llmstatus usage auto enable
llmstatus usage
llmstatus usage auto # inspect this checkout
llmstatus usage --since 2026-09-01T00:00:00Z --until 2026-10-01T00:00:00Z --json
llmstatus report --no-openRun llmstatus init first. Automatic collection is off by default. Enable it once per checkout
with llmstatus usage auto enable; usage, scan, status and report then refresh supported
local sessions before displaying totals, at most once per 60 seconds. No background service runs.
--no-sync skips refresh for one command, and CI environments always skip automatic collection.
usage auto disable keeps stored totals; usage sync refreshes explicitly even during cooldown.
If stored usage cannot be read, scan, status and report still show ownership and mark usage
unavailable with a warning.
Input includes cache; output includes reasoning. Breakdown counters are never added twice, missing
counters stay Unavailable, and repeated, growing or forked-session copies of a response are
counted once. usage shows Tool / Model / Input / Output / Total / Code % now. Code percentage
uses all current tracked lines; usage covers the selected history, so their ratio is not a
productivity score.
| Tool / surface | Token collection | Model evidence |
| --------------------------------------------------- | ------------------------------------------------------ | ----------------------------------------------------------------------------- |
| Codex CLI / desktop / IDE with local rollout files | usage auto enable or usage sync --tool codex | Recorded per-turn selection; underlying routing is not verified |
| Claude Code CLI / IDE with project session files | usage auto enable or usage sync --tool claude-code | Response message model |
| Gemini CLI / IDE with project chat files | usage auto enable or usage sync --tool gemini | Message model when present |
| Kimi Code CLI / IDE with wire 1.5 journals | usage auto enable or usage sync --tool kimi | Full model from a uniquely matched request; unresolved aliases remain unknown |
| DeepSeek Harness CLI / IDE with session formats 0–3 | usage auto enable or usage sync --tool deepseek | Response message model; failed attempts can remain unknown |
| Cursor and other tools | Normalized usage import from an external producer | Reported model or Unknown model; no native token collector |
An IDE qualifies only when it writes the supported local session format; file-edit hooks do not
imply token support. Only sessions whose recorded project matches this checkout are counted. All
usage stays in ignored private .llmstatus/usage.json: counts, model IDs, timestamps and hashed
request IDs only — no prompts, responses, raw transcripts or credentials. Public badges and export
bundles omit usage. Costs are not implemented.
Session sources. Sync reads Codex's ~/.codex/sessions and archived_sessions, Claude's
~/.claude/projects/<encoded-root>, and Gemini's project chat folders under ~/.gemini/tmp
(current per-project folders found through their .project_root marker and the older hash-named
folders, including subagent chats). Custom Codex and Claude homes
respect CODEX_HOME and CLAUDE_CONFIG_DIR. Kimi searches $KIMI_CODE_HOME/sessions/<workdir-key>
(default ~/.kimi-code) including subagent wire 1.5 journals; legacy Python Kimi logs are
unsupported, and an all-zero fallback stays unavailable. DeepSeek searches $DSH_HOME/sessions
(default ~/.dsh) for session JSONL formats 0–3, selects the newest retained format, excludes
inherited fork history and deduplicates retry settlements. Compressed .jsonl.zstd logs require
Node with built-in Zstandard support (22.15+ or 23.8+); otherwise a diagnostic is shown. Cursor's
documented local hooks expose no request-token usage, so Cursor remains import-based.
Explicit native import. Import one native file with
llmstatus usage import --format codex --file /absolute/path/session.jsonl (also claude-code,
gemini, kimi or deepseek). A Kimi import needs the original <session>/agents/<agent>/wire.jsonl
path with adjacent <session>/state.json. Keep one source mode per tool and linked repository: sync
preserves imports and skips the overlapping native collector; explicit imports that mix modes are
rejected before writing.
Normalized import. An external producer must supply real repository-scoped usage. Get the
current ID from llmstatus repository --json, save a file like this under ignored
.llmstatus/usage-input.json, and run
llmstatus usage import --format llmstatus --file .llmstatus/usage-input.json:
{
"schemaVersion": "0.1",
"repositoryId": "repo_00000000000000000000000000000000",
"observations": [
{
"id": "stable-producer-request-id",
"tool": "cursor",
"model": "recorded-full-model-id",
"timestamp": "2026-09-08T10:00:00Z",
"tokens": {
"input": 1000,
"output": 200,
"cachedInput": 600,
"cacheWriteInput": null,
"reasoningOutput": null,
"total": 1200
}
}
]
}Use stable IDs for the same request on every import. All fields are required; use null for
missing models/counters. Counts must be nonnegative safe integers; known input + output must equal
total, and cache/reasoning subsets cannot exceed input/output. Unknown fields and foreign repository
IDs are rejected. Tool IDs use lowercase letters/digits/dot/underscore/hyphen (up to 64 characters);
model and request IDs are kept up to 256 characters; auto/default/unknown become null. Do not
export account-wide billing or prompts into this format. Hashing request IDs does not encrypt the
private state.
Limits. Normalized input 32 MiB; native input 128 MiB compressed/decoded (100,000 Zstandard
frames); native JSONL record 8 MiB; sync discovery per tool: 20,000 directory entries, eight levels,
2,000 matching files and 512 MiB, newest sessions first; stored usage 64 MiB / 100,000 revisions. Unsafe, changing and malformed native inputs are
skipped with diagnostics. Date bounds must be full UTC timestamps; --since is inclusive and
--until exclusive. Filters only change reports, not which records are imported.
Forked Codex sessions. Copied parent history in a forked session is excluded. A fork whose
parent cannot be read is skipped and reported rather than double counted. Totals stored by 1.2.0
can still include copies from forked sessions; to rebuild them, move .llmstatus/usage.json aside,
run llmstatus usage sync, then re-import any normalized files.
Diagnostics. Collection reports skipped inputs, cumulative gaps and discovery limits; absent or
deleted sessions, other checkout paths and unsupported formats remain coverage gaps. JSON exposes
nativeBlockedByImport, excludedNativeObservations and collection blockedTools /
compressedFilesUnavailable. usage, scan and status JSON expose
repositoryUsage.automaticCollection; report --json exposes automaticCollection. Private
.llmstatus/usage-auto.json stores consent bound to this checkout and repository plus refresh times
and count-only diagnostics; a copied/moved checkout or changed remote needs re-enablement.
Troubleshooting
Start with llmstatus doctor and llmstatus integrations <tool> --status, replacing <tool> with
the name used for setup. Run these from the same main Git checkout as your coding session.
| What you see | What to check |
| ----------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Tool not detected or incompatible | Install the vendor tool separately, make its executable available on PATH, and compare its version with the qualified versions. A newer unqualified version may be rejected. |
| Configured, but no new events | Restart a trusted session, allow hooks, and make a supported structured edit. Kimi requires plugin installation/reload; DeepSeek requires the launch overlay. Compare the event count before and after the edit. After a rejected Gemini, Kimi or DeepSeek edit (or a lost post-edit hook) followed by a change to the file, the next edit to that file is not captured; later edits are. |
| Events exist, but current lines are Unmeasured or unchanged | Only Git-tracked files enter ownership. Historical events may concern deleted lines or edits without a usable range; event totals are not current line totals. A scan does not reconstruct every prior AI edit. |
| Private-state or unsafe-path warning | Run llmstatus init to update managed ignore rules, then recheck diagnostics. Setup rejects tracked private state and symlinked configuration. Preserve the private ledger; do not delete it as a setup fix. |
| Model is Unknown | The edit did not identify a model or overlapping edits made it ambiguous. Claude Code tool hooks and native Gemini, Kimi and DeepSeek events never include one. A model selected in the UI is not proof. |
| Linked worktree or Windows capture fails | Automatic integrations are qualified for main Git worktrees on macOS/Linux. Linked worktrees are rejected; live Windows hook qualification is incomplete. |
| HTML report does not open | Run llmstatus report --no-open and open the printed local HTML path on a machine with a browser. |
Before sharing diagnostics, review them for private paths and identifiers. Share the CLI/tool versions and a minimal reproduction; do not share your raw ledger, source, prompts or credentials.
Updating and removing integrations
Update the CLI with npm install -g llmstatus@latest, then check llmstatus --version. Review
each enabled integration's status. Re-run setup if the checkout or executable path moved, and follow
any plugin reload or session restart instructions printed by setup.
To remove capture from a repository, use its main checkout:
llmstatus integrate codex --remove
llmstatus integrations codex --statusRepeat with each configured tool. Removal preserves historical ledger events and unrelated user
settings. For Kimi, follow the printed plugin removal instructions; for DeepSeek, remove the
--patch launch argument and restart the harness. Remove integrations from every repository that
uses this installation before running npm uninstall -g llmstatus, so hooks do not keep a path to
an executable you removed.
How to read the numbers
| Metric | Meaning | | ------------------- | -------------------------------------------------------------------------------- | | AI Contribution | Currently AI-owned lines divided by all currently tracked lines. | | Measured Human | Lines supported by explicit Human evidence. | | Mixed | Lines with mixed or ambiguous ownership evidence. | | Unknown | Lines marked unknown by the ownership engine. | | Unmeasured | Lines without captured attribution. They are not presented as measured Human. | | By tool | Each AI tool's share of current tracked lines. | | By model | Current AI-owned lines per tool and recorded model ID; Unknown model if missing. | | Ledger events | Historical captured activity, including edits to lines that may no longer exist. | | Token usage | Observed tokens by tool/model over the selected history; not a code metric. |
Only Git-tracked files enter current ownership. Some historical last-touch evidence can be reconstructed from classified Git commits; a scan cannot recover every earlier AI edit. Mixed, Unknown and Unmeasured are not added to AI Contribution. The badge reads LLM Status | AI n.n%, or No Data / Partial / Unknown when evidence is insufficient.
Commands
| Goal | Command |
| ------------------------------------ | ----------------------------------------------------------------------------------------- |
| Prepare a repository | llmstatus init |
| Scan current ownership | llmstatus scan / llmstatus scan --json |
| Save scan / update badge | llmstatus scan --write / llmstatus scan --badge |
| Quick health summary | llmstatus status |
| Full diagnostics | llmstatus doctor / llmstatus doctor --ci |
| Open the offline report | llmstatus report (--no-open to only write it) |
| Generate a static badge | llmstatus badge --write / llmstatus badge --markdown |
| Connect or remove a coding tool | llmstatus integrate <tool> / llmstatus integrate <tool> --remove |
| Check integrations | llmstatus integrations / llmstatus integrations <tool> --status |
| Inspect historical events | llmstatus ledger / llmstatus ledger --tool codex |
| Declare provenance manually | llmstatus record --file PATH --type TYPE --method METHOD [options] |
| Inspect or persist current ownership | llmstatus ownership / llmstatus ownership --write |
| Replay captured history | llmstatus replay (filters are read-only previews) |
| Show repository token usage | llmstatus usage / llmstatus usage --since UTC --until UTC |
| Turn automatic token collection on | llmstatus usage auto enable / llmstatus usage auto disable |
| Refresh or import token usage | llmstatus usage sync [--tool ID] / llmstatus usage import --format FORMAT --file PATH |
| Diagnose or link a transferred repo | llmstatus repository / llmstatus repository link --from REMOTE_OR_ID |
| Generate repository CI | llmstatus ci init |
| Run repository CI locally | llmstatus ci --no-commit |
| Export a sanitized local bundle | llmstatus export --output ./llmstatus-export |
| Versions and full option reference | llmstatus version / llmstatus --help |
Most inspection commands support --json. JSON, --version and badge --markdown remain clean
when piped or redirected; presentation colors never enter those outputs. TERM=dumb also disables
color and decorative Unicode. The package adds no terminal UI runtime dependency.
GitHub Actions
llmstatus ci initReview and commit .github/workflows/llmstatus.yml. Generated workflows pin the installed CLI's
exact version and run on Node 22. GitHub gets aggregate summaries, not your ignored local ledger; CI
does not invent attribution that is missing from the clone. Automatic commits are limited to public
badge artifacts on permitted push runs; pull requests, including forks, never write the branch.
Privacy
The CLI makes no network calls and collects no telemetry. Your coding tools and npm/GitHub operate separately under their own settings.
- Raw source, prompts, responses, access tokens and credentials are not stored in the provenance ledger. Hooks may process source in bounded memory to compare edits; persistent evidence uses metadata, ranges, line statistics and fingerprints.
- When you run
usage syncor enable automatic token collection, LLM Status reads your coding tools' local session files for this checkout to count tokens. It stores only counts, model IDs, timestamps and hashed request IDs. - Git inspection uses local subprocesses without a shell; remote credentials are sanitized.
- Private metadata can still be sensitive. File paths, session/model/tool identifiers, hashes and local installation paths are not anonymous; review private artifacts before sharing.
| Files | Handling |
| ------------------------------------------------------------------------------------------------- | ------------------------------------------------------ |
| .llmstatus/public/ | Aggregate badge/summary; eligible for commit. |
| .llmstatus/ledger.jsonl | Private append-only evidence; keep it safe. |
| .llmstatus/analysis.json, ownership.json, replay-checkpoint.json | Private generated scan/replay state. |
| .llmstatus/usage.json, usage-auto.json, repository-links.json | Private token usage, collection consent and links. |
| .llmstatus/report/, export/, integrations/, tmp/ | Local reports, exports and integration state. |
| .claude/settings.local.json, .codex/hooks.json, .cursor/hooks.json, .gemini/settings.json | Machine-local integration configuration; keep ignored. |
FAQ
Does scan need an integration? No. Scan reconstructs current ownership from local Git history and captured ledger events. Tracked lines without attribution evidence are shown as Unmeasured.
Is Cursor an AI model? No. Cursor is a host application. Provider and model are recorded separately when they can be determined.
Can I use this without GitHub? Yes. init, scan, report and badge are local.
Will this rewrite my README? No. You paste the badge Markdown yourself.
Advanced reference
Optional .llmstatus.json accepts root-relative include/exclude language globs:
{
"include": ["src/**"],
"exclude": ["src/generated/**"],
"badge": { "autoUpdate": false }
}After init, scans save analysis and reconstructed ownership. An uninitialized scan stays read-only
unless --write or --badge is requested. scan --json uses analysis schema 0.3 and includes
current shares in currentOwnership on stdout. The saved .llmstatus/analysis.json keeps the base
analysis format without that field; current ranges are stored separately in ownership.json.
Historical attribution event counts remain separate from ownership metrics.
ownership performs a full deterministic replay without writing. ownership --write and unfiltered
replay persist the canonical snapshot. Filters such as replay --file src/example.ts, --session,
--until-event, --until-timestamp and --until-commit are read-only previews.
The ledger is schema 0.1, JSON Lines, append-only, capped at 64 MiB (64 KiB per event). Malformed
records fail closed. It is not automatically migrated, compacted or backed up. Analysis and
ownership snapshots are replaceable derived data; the ledger contains the original evidence.
Manual declarations complement automatic integrations. They are evidence you supply, not automatic verification of a model's authorship:
llmstatus record \
--file src/example.ts \
--type ai \
--tool my-agent \
--method manual_declaration \
--operation insert \
--start-line 10 \
--end-line 20--file, --type and --method are required. Paths are relative to the current directory and
must remain inside the Git worktree without traversing symlinks. Types: human, ai, mixed,
unknown. Optional --provider, --model and --tool keep those identities distinct;
--confidence ranges from 0 to 1. Line boundaries must be provided together. Use
--operation create to replace existing lines; modify merges with the current owner. Other options include
--session, --content-hash and --parent-event; see llmstatus --help.
llmstatus ledger --json returns aggregates, never raw events. Event counts and historical line
changes do not measure surviving lines.
Supported scope
Structured local capture is supported for the six tools above. Copilot, clipboard, generic Git-hook
and cloud-agent capture are not included. The separate web dashboard currently uses demo data;
llmstatus report is the local report backed by your repository's evidence.
This README contains everything needed to install and use the package. Source and engineering documentation live in the project repository, which currently requires collaborator access; a GitHub 404 there does not affect the npm package.
Support
Questions, bug reports and security reports: email [email protected]. For a security issue, please do not post details publicly. Include the CLI and coding-tool versions and a minimal reproduction, without source, prompts, credentials or your raw ledger.
License
MIT. See the LICENSE file included in the package.
