logs-cli
v1.0.9
Published
Turns AI coding sessions into a clear, portable work trail. Git has the diff. Logs has the session.
Maintainers
Readme
Logs
Git has the diff. Logs has the session.
Logs keeps a trail of your AI coding sessions next to your code, and can block risky AI-touched files until the session is reviewed.
Why Git isn't enough
A commit shows what changed. It says nothing about the AI session that produced it — the prompt, what the AI tried, what broke, which files it touched and why. As AI writes more of your code, that missing layer is where the risk lives: changes land that no human fully accounts for.
Logs captures the session as a durable artifact, commits it into the repo next to the code, and lets CI refuse to merge AI-touched protected files until a human has reviewed the trail.
Install
npm install -g logs-cli
logs doctor # verify logging, git, and Claude are availableRequires Node 18+ and macOS or Linux. Logging works best in a real terminal.
Log automatically (recommended):
logs setup # wraps `claude` so every session is logged by defaultAfter this, just run claude as normal — a trail is created every time. Remove
with logs setup --remove. Without it, you log explicitly with logs start.
Already have Claude history? Logs starts empty on install — but Claude Code keeps every past session on disk, so you can backfill them:
logs import # build trails from your past Claude sessions in this repo (--all for every project)From source:
git clone https://github.com/wclinchard/logs && cd logs
npm install && npm run build && npm linkQuickstart
logs start auth-fix -- claude # log a Claude session
logs trail latest # read what happened
logs review latest # risk areas + review checklist
logs commit latest # save the trail into .logs/ in your repo
logs blame app/auth/callback.ts # which AI session produced this file
logs guard --base main # FAILS: auth file changed, not reviewed
logs reviewed auth-fix # mark the session human-reviewed
logs guard --base main # PASSESWhat each command does:
logs start <name> -- claude— runs Claude inside Logs and logs the session (prompts, tool calls, file changes, errors). Works like normal Claude.logs trail latest— prints the readable, chronological trail of the session.logs review latest— shows risk areas (auth, payments, secrets, DB) and a review checklist, from the files that changed.logs commit latest— copies the session into.logs/sessions/<id>/and updates.logs/index.json. The trail now lives in the repo.logs blame <file>— shows which committed AI sessions touched a file, newest first, with summary and review status. Git blame tells you who. Logs tells you why the AI made it this way.logs guard --base main— exits non-zero if changed files in protected paths lack a reviewed trail. The CI gate.logs reviewed <session>— marks a session human-reviewed (notes who and when).
Core flow
log → commit → review → enforce
start commit reviewed guard- Log every AI session with
logs start. - Commit the trail into
.logs/so it travels with the code. - Review the session and mark it reviewed.
- Enforce in CI with
logs guard— protected AI changes can't merge unreviewed.
The repo's .logs/ directory is the source of truth:
.logs/
index.json provenance index (files → sessions, reviewed status)
policy.json which paths are protected and what they require
sessions/
2026-06-05-auth-fix/
manifest.json the canonical AI Change Manifest
trail.md readable session trail
record.json structured session data
diff.patch what changed (or changes.txt)
review.json reviewed / reviewedAt / reviewedByThe AI Change Manifest
Every committed session has a manifest.json — the one object that ties the
session, its changes, the policy verdict, review status, and artifact paths
together. It is the source of truth for committed AI provenance, and what
logs guard reads.
logs manifest auth-fix # compact summary
logs manifest auth-fix --json # raw JSON{
"sessionId": "2026-06-05-auth-fix",
"intent": { "prompt": "fix the auth redirect loop", "summary": "Changed 2 files and matched auth review." },
"changes": [ { "path": "app/auth/callback.ts", "type": "modified", "riskAreas": ["auth"] } ],
"policy": { "matchedRules": ["auth"], "requires": ["logs_trail", "human_review"], "allowedToShip": false, "reasons": ["human_review missing"] },
"review": { "reviewed": false, "reviewedBy": null, "reviewedAt": null }
}allowedToShip flips to true (and reasons clears) once the session is
reviewed. That single boolean is the merge verdict.
Tamper-evident
Each manifest is stamped with a content hash over the immutable "what the AI
did" fields, and a review is signed against that exact content. If a committed
record is altered after the fact — or a review no longer matches the content it
covered — logs verify detects it, and logs guard refuses to pass it:
logs verify # recompute every record; fail if anything was alteredYou cannot review a session, then quietly change what it claims the AI did, and still ship. That is what makes the record an audit trail rather than a log.
Safe to commit (secrets never leak)
Your raw session history is private (stays in ~/.logs, including the full
terminal transcript). What goes into the repo is sanitized. Before writing
anything to .logs/, logs commit scans the trail, record, and diff for secrets
and refuses to commit if it finds any:
$ logs commit latest
Logs refused to commit "add-key" — 1 possible secret found:
diff.patch: Anthropic API key (sk-…ij)
logs commit latest --redact write a sanitized copy ([REDACTED]) ← recommendedlogs scan latest # check for secrets
logs redact latest # preview the sanitized version
logs commit latest --redact # commit with secrets replaced by [REDACTED]What it catches: named keys (Anthropic, OpenAI, Stripe, AWS, GitHub, Slack,
Google, JWTs), private-key blocks, database URLs with credentials, KEY=value
assignments, and a high-entropy net for unknown/custom token shapes — while
ignoring git/sha hashes and npm integrity strings (no false positives on your
own data). Teams can add org-specific patterns in .logs/policy.json:
{ "secretPatterns": ["MYCO_[A-Z0-9]{32}"] }You cannot bypass the gate casually — committing raw despite secrets requires
the explicit --allow-secrets flag (and --force alone won't do it). The
redacted, committed record still verifies (the integrity hash covers the
sanitized content), and your private ~/.logs copy is never modified. The rule:
raw history is private; repo provenance is sanitized.
CI enforcement
logs policy init # write .logs/policy.json (protected paths + rules)
logs init ci # write .github/workflows/logs-guard.ymlThe workflow runs on every pull request:
- run: logs guard --base origin/${{ github.base_ref }}If an AI-touched auth/payment/database file changed without a committed, reviewed trail, the check fails and the PR is blocked. See examples/github-actions/logs-guard.yml.
Policy lives in the repo and is enforced from the repo:
{
"version": 1,
"protected": [
{ "name": "auth", "patterns": ["**/*auth*", "**/*session*"], "requires": ["logs_trail", "human_review"] },
{ "name": "secrets", "patterns": [".env*", "**/*secret*"], "rule": "block" }
]
}Commands
logs start <name> -- <command> Log a session
logs trail latest Chronological trail
logs review latest Risk areas + review checklist
logs show latest One-screen summary
logs commit latest Save the session into the repo (.logs/)
logs scan latest Check a session for secrets before committing
logs redact latest Preview the sanitized, repo-safe version
logs manifest <session> Print the AI Change Manifest (--json for raw)
logs blame <file> Which AI session produced a file
logs why <file> Alias of blame
logs index Rebuild .logs/index.json from committed sessions
logs reviewed <session> Mark a session human-reviewed (--undo to revert)
logs policy init Create .logs/policy.json
logs guard --base <branch> CI gate: block unreviewed protected AI changes
logs verify Check committed records for tampering
logs setup Auto-log every claude session (--remove to undo)
logs import Backfill trails from your Claude session history
logs pr latest PR description text (provenance + review status)
logs init ci Create the GitHub Actions workflow
logs diff latest Git diff of the session
logs copy latest Copy a portable handoff to the clipboard
logs export latest Bundle the session as a .logs.zip
logs list All logged sessions
logs doctor Check setupAny command that takes latest also takes a session name: logs trail auth-fix.
Local-first, no cloud
Everything is local files. No accounts, no API, no telemetry, no AI calls. Your private session history lives in ~/.logs; the trails you choose to commit live in your repo's .logs/. The repo is the source of truth.
Limitations
- File-level provenance.
logs blamemaps files to AI sessions, not individual lines. Usegit blameplus the session trail for exact line history. - Provenance, not detection. A file is "AI-covered" if it appears in a committed Logs session — Logs does not try to detect AI authorship from the code itself.
- Guard reviews the latest session per file. A protected file passes only if the most recent AI session that touched it is reviewed. It does not yet verify that the reviewed session covers a specific later edit made outside Logs.
- Best-effort capture for non-Claude tools. Claude sessions are read from Claude's own structured log (clean). Other tools fall back to terminal capture, which can be noisy — the raw transcript is always kept.
