Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
162 changes: 160 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

A CLI tool that analyzes your Claude Code session history to identify token waste patterns and provide actionable fixes. Runs locally, no LLM needed.

**v2.2** adds human-readable findings with plain-English explanations, collapsible HTML report sections, and evidence-based action items.
**v2.3** adds `--analyze-skill` — analyze any AI agent skill package for token efficiency with cost estimates, letter grades, section-level breakdowns, and actionable shortening tips. Designed for integration with skill registries like [Tank](https://github.com/tankpkg/tank).

**The mental model: tokenomics is a coach, not a remote control.** It writes suggestions into your CLAUDE.md where Claude can see them. Claude is smart enough to follow most of them — suggesting `/compact` when context grows, recommending Sonnet for simple tasks, warning when you're overspending. But it cannot switch models, run commands, or force behavior. The user is always in control.

Expand Down Expand Up @@ -240,6 +240,7 @@ Budget config lives at `~/.claude/tokenomics.json`:
| `--inject` | Re-analyze sessions + update CLAUDE.md findings | false |
| `--quiet` | Suppress terminal output (used by hooks) | false |
| `--verbose` | Show discovery progress and debug info | false |
| `--analyze-skill <dir>` | Analyze skill package for token efficiency | - |
| `--help` | Show help message | - |
| `--version` | Show version | - |

Expand All @@ -264,13 +265,170 @@ Budget config lives at `~/.claude/tokenomics.json`:
| Subagent Opportunity | Delegation opportunities | Parallel execution |
| Smart Router | Historical routing patterns | ~80% on simple tasks |

## Skill Analysis (`--analyze-skill`)

Analyze an AI agent skill package directory for token efficiency. Produces a grade (A/B/C/D), cost per use in real money, per-section token breakdowns, and actionable suggestions for what to cut and why.

```bash
# Terminal report (default)
tokenomics --analyze-skill ./my-skill

# JSON output (for scripts, CI, Tank integration)
tokenomics --analyze-skill ./my-skill --json
```

### Terminal output

```
SKILL TOKEN ANALYSIS
──────────────────────────────────────────────────

"Well-structured skill with no significant waste."

Grade: A (86/100)
Size: 33,598 tokens — above average (avg is ~20,000 tokens)

[░░░░░░░░░░░░░█░░░░░░░░░░░░░░░░]
▲ avg

Cost per use: ~$0.18 (Sonnet) | ~$0.91 (Opus)

Findings (3):
● prompt-size [medium]
Prompt file "SKILL.md" is ~2,388 tokens (9,549 chars).
Consider trimming for faster invocations.
Fix: Consider trimming "SKILL.md" to under 2000 tokens.
Extract verbose examples into separate reference files.

● section-analysis [low]
SKILL.md: 2 section(s) overlap each other.
Fix: "web app setup" overlaps with "library setup":
consolidate shared content into one section.
Tip: References 18 specific file paths — consider
replacing with a glob pattern or naming convention rule.
```

### JSON output

With `--json`, the output includes all fields for programmatic consumption:

```json
{
"one_liner": "Slightly above average size. Works fine, could be leaner.",
"grade": "B",
"estimated_tokens": 8500,
"comparison": "8,500 tokens — below average (avg is ~20,000 tokens)",
"cost_per_use": {
"sonnet": "~$0.05",
"opus": "~$0.23"
},
"what_this_means": "Bigger skills cost more per invocation and leave less room for conversation. Smaller skills respond faster and cost less.",
"findings": [
{
"rule": "section-analysis",
"severity": "low",
"description": "SKILL.md: 2 section(s) overlap each other...",
"remediation": "\"Setup\" overlaps with \"Config\": consolidate...",
"sections": [
{ "heading": "Setup", "tokens": 420, "redundantWith": ["Config"] },
{ "heading": "Config", "tokens": 380, "redundantWith": ["Setup"] }
]
}
],
"summary": {
"total_findings": 3,
"estimated_tokens_per_invocation": 8500,
"efficiency_score": 72
}
}
```

### Report fields

| Field | What it means |
|-------|---------------|
| `one_liner` | Plain English summary of the skill's efficiency |
| `grade` | A (lean) / B (good) / C (bloated) / D (wasteful) |
| `estimated_tokens` | Total token count across all skill files |
| `comparison` | How this skill compares to average (~20k tokens) |
| `cost_per_use` | Real money per invocation on Sonnet and Opus |
| `what_this_means` | Why size matters: cost + speed + context window competition |
| `sections[]` | Per-heading token breakdown with redundancy and shortening tips |

### Analysis rules

| Rule | What it checks | Thresholds |
|------|---------------|------------|
| `prompt-size` | SKILL.md and `.atom.md` files exceeding token limits | >2000 tokens = medium, >4000 = high |
| `claude-md-size` | CLAUDE.md injection blocks that bloat system prompts | >1500 tokens = medium, >3000 = high |
| `tool-overhead` | Tool definitions in manifest (tank.json, skills.json) | >8 tools = medium, >15 = high |
| `large-files` | Files with >500 lines that are expensive to read | >500 lines = low, >1000 = medium |
| `redundant-instructions` | Duplicated instruction lines across skill files | >30% duplication = low/medium |
| `section-analysis` | Per-section token breakdown, cross-file redundancy, content tips | See below |

### Section analysis details

The `section-analysis` rule parses markdown headings and provides:

**Token breakdown**: Every section gets a token count, so you can see exactly where the weight is.

**Cross-file redundancy**: Detects when a section in SKILL.md says the same thing as a section in `references/*.md`. Example: `"The Bridge"` in SKILL.md duplicates `"The Bridge Model"` in `references/orchestration-workflow.md`.

**Content-level shortening tips** (not just structural):

| Tip | What it detects |
|-----|----------------|
| Concept repetition | Same key phrase restated 3+ times — state once, reference elsewhere |
| Restatements | "remember that", "note that", "in other words" — AI understood the first time |
| Bad/good example pairs | Shows both wrong and right patterns — use a negative constraint rule instead |
| File path enumeration | 6+ specific paths — replace with glob patterns or naming conventions |
| Verbose justification | "this is important because" — AI follows rules without persuasion |
| Large directory trees | ASCII trees >10 lines — keep top-level, link to reference |
| Repeated lines | Identical lines within a section — dedup or collapse |
| Code block bloat | 2+ code blocks — replace with file references |
| Long lists | 8+ list items — group into categories |
| Table bloat | 15+ table rows — move details to reference files |

### Cost estimation

Based on Claude API pricing with an 80/20 input/output token split:

| Tokens | Sonnet cost | Opus cost |
|--------|-------------|-----------|
| 5,000 | ~$0.03 | ~$0.15 |
| 20,000 (avg) | ~$0.12 | ~$0.59 |
| 50,000 | ~$0.29 | ~$1.47 |
| 100,000 | ~$0.59 | ~$2.94 |

Every skill is loaded into context on every turn. A 50k-token skill costs ~$1.47 per turn on Opus — trimming it to 20k saves ~$0.88 per turn.

### Integration with skill registries

Designed to be called as a subprocess from scanning pipelines:

```python
import subprocess, json

result = subprocess.run(
["tokenomics", "--analyze-skill", skill_dir, "--json"],
capture_output=True, text=True, timeout=10
)
if result.returncode == 0:
analysis = json.loads(result.stdout)
print(f"Grade: {analysis['grade']} | Cost: {analysis['cost_per_use']['sonnet']}/use")
for finding in analysis["findings"]:
print(f"[{finding['severity']}] {finding['rule']}: {finding['description']}")
```

Graceful degradation: if tokenomics is not installed, skip the stage and continue.

## Output Examples

### Terminal

```
TOKENOMICS — Token Intelligence for Claude Code
60 sessions // 30 day range // v2.2.2
60 sessions // 30 day range // v2.3.0

Sessions: 60
Total: 1.2M tokens
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "tokenomics",
"version": "2.2.2",
"version": "2.3.0",
"description": "Token intelligence for Claude Code — analyze sessions, find waste, get actionable fixes",
"type": "module",
"main": "dist/analyze.js",
Expand Down
20 changes: 19 additions & 1 deletion src/analyze.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { writeFileSync, mkdirSync } from 'node:fs';
import { homedir } from 'node:os';
import { join } from 'node:path';
import type { AnalysisOutput, CliOptions, DetectorResult, SessionData } from './types.js';
import { analyzeSkill, renderSkillReport } from './skill-analyzer.js';
import { discoverFiles, logDiscoverySummary } from './discovery.js';
import { extractHumanReadableBlock, renderTerminalBlock } from './recommendation.js';
import { parseSessionFiles } from './parser.js';
Expand All @@ -34,7 +35,7 @@ import { auditPrompt } from './auditor.js';
import { renderPromptOutput } from './prompt-output.js';
import { ensureBudgetConfig, readBudgetConfig } from './budget-config.js';

const VERSION = '2.2.2';
const VERSION = '2.3.0';

// ─── CLI ──────────────────────────────────────────────────────────────────────

Expand All @@ -60,6 +61,7 @@ function parseCliArgs(): CliOptions {
budget: { type: 'boolean', default: false },
'budget-check': { type: 'boolean', default: false },
'no-alerts': { type: 'boolean', default: false },
'analyze-skill': { type: 'string' },
},
strict: true,
});
Expand Down Expand Up @@ -88,6 +90,7 @@ function parseCliArgs(): CliOptions {
budget: values.budget,
budgetCheck: values['budget-check'],
noAlerts: values['no-alerts'],
analyzeSkill: values['analyze-skill'],
};
}

Expand Down Expand Up @@ -131,6 +134,10 @@ PROMPT ANALYSIS
--budget-check Lightweight budget check (for hooks)
--no-alerts Suppress budget alerts (no CLAUDE.md injection)

SKILL ANALYSIS
--analyze-skill <dir> Analyze skill package for token efficiency
Outputs JSON with findings and efficiency score

OTHER
--verbose Show discovery progress and debug info
--help Show this message
Expand Down Expand Up @@ -516,6 +523,17 @@ async function main(): Promise<void> {
process.exit(result.ceilingExceeded ? 1 : 0);
}

// ── Skill analysis mode ──
if (options.analyzeSkill) {
const result = analyzeSkill(options.analyzeSkill);
if (options.json) {
console.log(JSON.stringify(result, null, options.verbose ? 2 : 0));
} else {
console.log(renderSkillReport(result));
}
return;
}

// Discover JSONL files (auto-detects all ~/.claude* installations)
const discoveryOpts: import('./types.js').DiscoveryOptions = {
days: options.days,
Expand Down
Loading
Loading