CLI tool to track and analyze AI coding assistants' contributions in your codebase
npm install ai-credit

A command-line tool to track and analyze AI coding assistants' contributions in your codebase (macOS/Linux/Windows). Supports Claude Code, Codex CLI, Cursor, Gemini CLI, and Opencode.
``bashRun directly with npx (no installation required)
npx ai-credit
Features
- ๐ Auto-detection: Automatically finds AI tool session data on your system (macOS/Linux/Windows)
- ๐ Detailed Statistics: Lines of code, files modified, contribution ratios
- ๐ค Multi-tool Support: Claude Code, Codex CLI, Cursor, Gemini CLI, Opencode
- ๐ Visual Reports: Console, JSON, and Markdown output formats
- ๐
Timeline View: Track AI contributions over time
- ๐ File-level Analysis: See which files have the most AI contributions
Usage
`bash
Analyze current directory
npx ai-creditAnalyze a specific repository
npx ai-credit /path/to/your/repoExport as JSON
npx ai-credit -f json -o report.jsonOnly analyze specific tools
npx ai-credit -t claude,codexShow detailed file-level analysis
npx ai-credit -v
`Commands
$3
`bash
npx ai-credit [path]
npx ai-credit [path] --verification relaxedOptions:
-f, --format Output format (console/json/markdown)
-o, --output Output file path
-t, --tools AI tools to analyze (claude,codex,cursor,gemini,opencode,all)
--verification Verification mode (strict/relaxed/historical, default: relaxed)
-v, --verbose Show detailed output
`$3
`bash
npx ai-credit list
`Shows which AI tools have data available on your system:
`
๐ Detected AI Tools Claude Code ~/.claude/projects/ โ Available
Codex CLI ~/.codex/sessions/ โ Available
Cursor Cursor/User/workspaceStorage โ Available
Gemini CLI ~/.gemini/tmp/ โ Not found
Opencode ~/.local/share/opencode/ โ Available
`$3
`bash
npx ai-credit files [path] [-n LIMIT] [--verification MODE]
npx ai-credit files [path] --verification strict
`Shows which files have the most AI contributions.
$3
`bash
npx ai-credit history [path] [-n LIMIT] [--verification MODE]
npx ai-credit history [path] --verification historical
`Shows a timeline of AI contributions.
$3
`bash
npx ai-credit sessions [path] [-t TOOL]
`Lists all AI sessions for the repository.
Output Example
`
ai-credit (main) npx ai-credit
Leave a ๐ star if you like it: https://github.com/debugtheworldbot/ai-creditโญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ
โ AI Contribution Analysis โ
โ Repository: /Users/eric/Developer/ai-credit โ
โ Scan time: 2/2/2026, 4:22:53 PM โ
โ Verification: relaxed โ
โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏ
๐ Overview
โโโโโโโโโโโโโโโฌโโโโโโโโฌโโโโโโโโโโโโโโโโโโ
โ Metric โ Value โ AI Contribution โ
โโโโโโโโโโโโโโโผโโโโโโโโผโโโโโโโโโโโโโโโโโโค
โ Total Files โ 18 โ 15 (83.3%) โ
โโโโโโโโโโโโโโโผโโโโโโโโผโโโโโโโโโโโโโโโโโโค
โ Total Lines โ 3496 โ 1660 (47.5%) โ
โโโโโโโโโโโโโโโผโโโโโโโโผโโโโโโโโโโโโโโโโโโค
โ AI Sessions โ 6 โ - โ
โโโโโโโโโโโโโโโดโโโโโโโโดโโโโโโโโโโโโโโโโโโ
๐ค Contribution by AI Tool
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโฌโโโโโโโโฌโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโ
โ Tool / Model โ Sessions โ Files โ Lines Added โ Lines Removed โ Share โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโผโโโโโโโโผโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโค
โ Opencode โ 2 โ 12 โ +558 โ -128 โ 32.2% โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโผโโโโโโโโผโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโค
โ โโ kimi-k2.5-free โ 2 โ 12 โ +558 โ -128 โ 100.0% (of tool) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโผโโโโโโโโผโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโค
โ Codex CLI โ 1 โ 11 โ +482 โ -303 โ 27.8% โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโผโโโโโโโโผโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโค
โ โโ gpt-5.2-codex โ 1 โ 11 โ +482 โ -303 โ 100.0% (of tool) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโผโโโโโโโโผโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโค
โ Gemini CLI โ 2 โ 11 โ +357 โ -262 โ 20.6% โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโผโโโโโโโโผโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโค
โ โโ gemini-2.5-pro โ 1 โ 8 โ +330 โ -237 โ 92.4% (of tool) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโผโโโโโโโโผโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโค
โ โโ gemini-3-pro-preview โ 1 โ 5 โ +27 โ -25 โ 7.6% (of tool) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโผโโโโโโโโผโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโค
โ Claude Code โ 1 โ 5 โ +338 โ -452 โ 19.5% โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโผโโโโโโโโผโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโค
โ โโ claude-opus-4-5-20251101 โ 1 โ 5 โ +338 โ -452 โ 100.0% (of tool) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโดโโโโโโโโโโโดโโโโโโโโดโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโ
๐ Contribution Distribution
๐ง๐ง๐ง๐ง๐ง๐ง๐ฆ๐ฆ๐ฆ๐ฆ๐ฆ๐ช๐ช๐ช๐ช๐ช๐ช๐ฉ๐ฉ๐ฉโฌโฌโฌโฌโฌโฌโฌโฌโฌโฌโฌโฌโฌโฌโฌโฌโฌโฌ
๐ Opencode 15.3% (534 lines)
๐ต Codex CLI 13.2% (461 lines)
๐ฃ Gemini CLI 9.8% (342 lines)
๐ข Claude Code 9.2% (323 lines)
โช Unknown/Human 52.5% (1836 lines)
`Supported AI Tools
| Tool | Storage Location | Format |
|------|------------------|--------|
| Claude Code |
~/.claude/projects/ | JSONL |
| Codex CLI | ~/.codex/sessions/YYYY/MM/DD/ | JSONL |
| Cursor | ~/Library/Application Support/Cursor/User/workspaceStorage | SQLite (state.vscdb) |
| Gemini CLI | ~/.gemini/tmp/ | JSON |
| Opencode | ~/.local/share/opencode/ | JSON |How It Works: The JSON Parsing Logic
ai-credit's core is a multi-adapter parsing engine. It works by analyzing the session log files generated by different AI coding assistants. While each tool has a slightly different log format, they share a common pattern: recording interactions, especially AI tool calls (like file writing or editing), as structured data (JSON or JSONL). This tool identifies and parses these specific tool-call records to quantify code contributions.Here's a detailed breakdown of the parsing method for each supported tool:
$3
- File Format: JSONL (
.jsonl), one JSON object per line.
- Scan Path: ~/.claude/projects/
- Parsing Logic:
1. The scanner iterates through all .jsonl session files in the project's directory.
2. It reads the file line by line, parsing each line into a JSON object.
3. The scanner focuses on log entries with "type": "assistant", as these represent the AI's responses.
4. Within the assistant's response (message.content array), it looks for blocks of "type": "tool_use". This indicates the AI decided to use a tool.
5. In the tool_use block, the "name" field identifies the specific action, such as write, write_file, or edit_file.
6. It extracts parameters from the "input" field, including:
- path or file_path: The target file path.
- content or new_str: The new content to be written or to replace existing content.
- old_str: (In edit operations only) The old content being replaced.- Contribution Calculation:
- Lines Added: Calculated by counting the lines in the
content or new_str.
- Lines Removed: For edit operations, calculated by counting the lines in old_str.Example (Simplified Claude Code JSONL Entry):
`json
{
"timestamp": 1706860810000,
"type": "assistant",
"message": {
"content": [
{
"type": "tool_use",
"name": "write",
"input": {
"path": "src/main.py",
"content": "def hello():\n print(\"Hello, AI!\")\n"
}
}
]
}
}
`$3
- File Format: JSONL (
.jsonl).
- Scan Path: ~/.codex/sessions/YYYY/MM/DD/*.jsonl
- Parsing Logic:
1. The tool recursively scans the sessions directory for all .jsonl files.
2. In each JSON object, the scanner looks for a "tool_calls" array, which contains all tools called by the AI in that turn.
3. Each tool_call object contains a "function" field, where "name" specifies the function called (e.g., write_file, apply_diff) and "arguments" is a JSON string containing all parameters.
4. The scanner must first parse this arguments string into a JSON object.
5. From the parsed arguments object, it extracts the path (file path) and content (file content).Example (Simplified Codex CLI JSONL Entry):
`json
{
"timestamp": 1706947210000,
"tool_calls": [
{
"function": {
"name": "write_file",
"arguments": "{\"path\": \"src/utils.py\", \"content\": \"def helper():\\n return True\\n\"}"
}
}
]
}
`$3
- File Format: SQLite (
state.vscdb).
- Scan Paths:
- Workspace metadata: ~/Library/Application Support/Cursor/User/workspaceStorage/
- Global content: ~/Library/Application Support/Cursor/User/globalStorage/state.vscdb
- Parsing Logic:
1. Match Cursor workspaces to the target repo using workspace.json.
2. Read composer.composerData to get composer IDs tied to that workspace.
3. Load composerData: from the global DB.
4. For each file, read codeBlockDiff: and aggregate diff segments.
5. Fallback to original/current file contents when diffs are unavailable.- Contribution Calculation:
- Lines Added/Removed: Derived from
codeBlockDiff segments; fallback uses diff against current file contents.Note: The Cursor scanner relies on the
sqlite3 CLI being available.Note: Cursor tab completions are not included in the statistics.
Example (Simplified Cursor codeBlockDiff JSON):
`json
{
"newModelDiffWrtV0": [
{
"original": { "startLineNumber": 10, "endLineNumberExclusive": 12 },
"modified": [
"const enabled = true;",
"console.log('cursor');"
]
}
]
}
`$3
- File Format: JSON (
.json), where one file represents a complete session.
- Scan Paths: ~/.gemini/tmp/, ~/.gemini/history/.json, ~/.gemini/sessions/*.json
- Parsing Logic:
1. The scanner searches Geminiโs session JSON files under common locations (tmp, history, sessions).
2. It parses the entire JSON file, which typically contains a "messages" or "turns" array logging the conversation history.
3. It iterates through the messages array, looking for "parts" arrays within messages from the "assistant" role.
4. Within the parts array, it searches for an object containing a "functionCall" (or toolCalls). This object's structure is similar to Codex CLI.
5. It extracts the "name" (function name) and "args" (arguments dictionary) from the functionCall object.
6. Project matching: if the session JSON has an explicit project path (projectPath/cwd/...), it must match the target repo. If not, the scanner only keeps tool calls whose file_path is inside the target repo.Example (Simplified Gemini CLI JSON Fragment):
`json
{
"created_at": 1707033600000,
"projectPath": "/home/ubuntu/my-project",
"messages": [
{
"role": "assistant",
"parts": [
{
"functionCall": {
"name": "write_file",
"args": {
"path": "src/scanner.py",
"content": "class Scanner:\n pass\n"
}
}
}
]
}
]
}
`$3
- File Format: JSON (
.json) session and message files.
- Scan Paths:
- Sessions: ~/.local/share/opencode/storage/session/*/.json
- Messages: ~/.local/share/opencode/storage/message/
- Parsing Logic:
1. The scanner reads all session JSON files (stored under project-hash subfolders).
2. It filters sessions by project path using directory or projectPath in the session metadata.
3. If message files exist for the session, it parses each message and looks for summary.diffs.
4. If no message-level diffs are found, it falls back to summary.diffs in the session file.
5. Each diff entry provides:
- file: relative file path
- before: previous content
- after: new content
- additions / deletions: optional precomputed line counts
6. Lines added/removed are taken from additions/deletions when present, otherwise computed from before/after.
7. The scanner also extracts the model from message data (e.g., model.modelID) when available.Example (Simplified Opencode Message JSON):
`json
{
"sessionID": "sess_abc123",
"time": { "created": "2026-02-02T10:15:00Z" },
"model": { "modelID": "kimi-k2.5-free" },
"summary": {
"diffs": [
{
"file": "src/index.ts",
"before": "console.log('old');\n",
"after": "console.log('new');\n",
"additions": 1,
"deletions": 1
}
]
}
}
`$3
In essence,
ai-credit features a specialized scanner for each supported AI tool. Each scanner is programmed to know its corresponding tool's log storage location and data structure. During analysis, the main program invokes all available scanners, collects all FileChange events related to the target project, and then aggregates, deduplicates, and analyzes these events to generate the final contribution report.Contribution Statistics Methodology
$3
The tool applies a verification rule when calculating AI contribution statistics. The default is relaxed.
> Only lines that currently exist in the codebase are counted as AI contributions.
$3
1. Parse AI Session Logs: The scanner reads session files from each AI tool and extracts file change events (writes, edits, patches).
2. Build Repository File Set: The tool gathers repository files using text-file extensions, excluding common build/vendor folders and honoring the root
.gitignore.3. Extract Changed Content: For each file change, the tool captures:
- The file path
- Lines added (new content)
- Lines removed (old content)
4. Verify Against Current Codebase: Before counting any line as an AI contribution, the tool:
- Reads the current content of the target file from the repository
- For each line that AI claims to have added, checks if a matching line exists in the current file
- In relaxed mode, matching ignores whitespace-only differences (trim + collapse spaces)
- In strict mode, matching is character-for-character
5. Calculate Statistics: The verified lines are then aggregated into:
- Per-file contribution counts
- Per-tool contribution totals
- Overall repository contribution ratios
- Sessions, files, and models are counted only when at least one verified line exists
$3
If an AI tool's log shows it added these lines to
src/utils.py:`python
def helper():
return True
`But the current
src/utils.py in the repository contains:`python
def helper():
return False # Changed from True
`Then the line
return True will NOT be counted as an AI contribution because it no longer exists in the codebase. Only if the line matches exactly will it be included in the statistics.$3
You can switch modes with
--verification.-
relaxed (default): Match lines after normalizing whitespace.
- strict: Match lines exactly (character-for-character).
- historical: Count tool-reported added lines for files that still exist, capped by the current fileโs non-empty line count.$3
This methodology ensures that:
- Statistics reflect actual, surviving AI contributions
- Code that was later modified or removed by humans (or other AI tools) is not attributed to the original AI
- Contribution ratios are accurate and meaningful for understanding the current state of the codebase
Limitations
- Only tracks AI contributions that are recorded in local session files
- Cannot detect AI-generated code that was copy-pasted manually
- Accuracy depends on the completeness of AI tool session logs
- Some AI tools may not record all file operations
- Files ignored by the root
.gitignore are excluded from Total Files/Lines
- Windows support for some tools depends on their session storage format compatibilityContributing
Contributions are welcome! Please feel free to submit issues and pull requests.
$3
1. Create a new scanner in
src/scanners/
2. Extend the BaseScanner class
3. Implement tool, storagePath, scan(), and parseSessionFile() methods
4. Add the scanner to analyzer.ts`MIT License - see LICENSE for details.