Tempo

Tempo CLI

Git hooks that detect AI tool usage and associate supported session file paths with commits. Detection runs locally; an optional API token enables attribution uploads.

Install with Homebrew

brew install usetempo/tap/tempo-cli

Supported platforms: macOS and Linux (Intel & ARM)

Quick start

Example commands and output. Detection results depend on the local sessions and committed files.

# Optional: configure attribution uploads
$ tempo-cli auth <your-token>

# Install hooks in your repo
$ cd /path/to/your/repo
$ tempo-cli enable
โœ“ post-commit hook installed
โœ“ pre-push hook installed

# Verify detection works
$ tempo-cli test
Commit:  a1b2c3d
Author:  dev@example.com
Repo:    example/repo

๐ŸŸข  claude-code (high confidence, file-match)
   Files: 2/5 committed files matched
     - src/auth.ts
     - src/auth.test.ts
   Model: claude-opus-4-6
   Tokens: 24,500
   Session: 14m0s

# Attribution runs automatically after each commit.

How it works

Session file matching

High

Extracts file paths from Claude Code and Codex JSONL, Copilot Agent JSON, Cursor SQLite sessions, and Aider history, then intersects them with committed files.

Process detection

Medium

Checks for running Claude Code, Cursor, Copilot, Codex, or Aider processes on macOS and Linux when no file match exists for that tool. A running process does not prove that it changed the commit.

Git trailers

Medium

Checks supported Co-Authored-By trailers and Aider commit-message patterns when no stronger signal exists for that tool.

Supported tools

ToolFile matchingProcess detectionGit trailers
Claude Codeโœ“โœ“โœ“
Cursorโœ“โœ“โœ“
GitHub Copilotโœ“โœ“โœ“
Codexโœ“โœ“โ€”
Aiderโœ“โœ“โœ“

Cursor file matching requires the sqlite3 command. These detectors read supported local session formats; a tool being installed does not guarantee a file match.

Commands

CommandDescription
tempo-cli enableInstall post-commit and pre-push hooks
tempo-cli disableRemove Tempo hooks (preserves other hooks)
tempo-cli auth <token>Save API token for Tempo cloud
tempo-cli statusShow hooks, pending records, and config
tempo-cli testDry-run detection against the last commit
tempo-cli test --jsonSame as above, but output raw JSON

Attribution payload

Each detection produces a JSON file in .tempo/pending/. The payload contains attribution metadata, excluding source code, diffs, prompts, and conversation transcripts. Example:

.tempo/pending/a1b2c3d.json
{
  "commit_sha": "a1b2c3d",
  "commit_author": "dev@example.com",
  "repo": "example/repo",
  "timestamp": "2026-02-12T17:08:00Z",
  "detections": [
    {
      "tool": "claude-code",
      "confidence": "high",
      "method": "file-match",
      "files_matched": ["src/auth.ts", "src/auth.test.ts"],
      "files_committed": 5,
      "ai_files": 2,
      "model": "claude-opus-4-6",
      "token_usage": 24500,
      "session_duration_sec": 840
    }
  ]
}

Privacy

Tempo CLI parses supported session files locally. When an API token is configured, it uploads the attribution metadata shown above. Entire Checkpoints is a separate integration with different stored session data.

Excluded from the attribution payload

โœ•Source code or file contents
โœ•Diffs or patches
โœ•AI prompts or conversations

What Tempo CLI does send

Only if API token configured

โœ“Commit SHA, timestamp, repository, and git email
โœ“Tool name, confidence, method
โœ“File names matched (not contents)
โœ“Model, tokens, session duration

Offline mode

Without an API token, everything works the same โ€” detection runs, JSON files are saved locally, nothing is sent to the cloud. You can inspect results anytime:

$ cat .tempo/pending/*.json | jq '.detections[].tool'
"claude-code"
"claude-code"
"copilot"

Configuration

Config file location: ~/.tempo/config.json

~/.tempo/config.json
{
  "api_token": "tmp_...",
  "api_endpoint": "https://api.usetempo.dev",
  "session_max_age_hours": 72
}

Environment variables

VariableDescription
TEMPO_API_ENDPOINTOverride the API endpoint
TEMPO_SESSION_MAX_AGESession recency window in hours (default: 72)