{"_id":"@amirdor/openbar","_rev":"2-080f73f7f53c7e5a7461ec2d52691d40","name":"@amirdor/openbar","dist-tags":{"latest":"0.1.1"},"versions":{"0.1.0":{"name":"@amirdor/openbar","version":"0.1.0","keywords":["claude-code","codex","cli","ai-agents","cost","tokens","observability","hooks","devtools"],"author":{"name":"Dor Amir","email":"amirdor@gmail.com"},"license":"MIT","_id":"@amirdor/openbar@0.1.0","maintainers":[{"name":"amirdor","email":"amirdor+npm@gmail.com"}],"homepage":"https://doramirdor.github.io/openbar/","bugs":{"url":"https://github.com/doramirdor/openbar/issues"},"bin":{"openbar":"bin/openbar.js"},"dist":{"shasum":"2c0ccc64cc843b9f037b01edd6092b3f69a89d69","tarball":"https://registry.npmjs.org/@amirdor/openbar/-/openbar-0.1.0.tgz","fileCount":28,"integrity":"sha512-UKIZcdIWgQEjXBZlhbBaqAW0xE4K8SwvqCK0RKlaDrQvs9Q23tw5+qVEcl6+mCtUKTMRGAPgbPCcDq3A0HXBKA==","signatures":[{"sig":"MEUCICUY181RJCi6O4aRjDJ5+/VOJ+TN68O5tb1rhAy+TBrQAiEAud1eyFjnKUk9WnDh5kH3nTfgpuU897gCiPZQoGobJOA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":139984},"type":"commonjs","engines":{"node":">=22.5.0"},"gitHead":"8d42790e80142fe9cc6fc37017fc09417bb68016","scripts":{"dev":"tsc -p tsconfig.json --watch","test":"node scripts/e2e.js && node scripts/e2e-codex.js","build":"tsc -p tsconfig.json","openbar":"node bin/openbar.js","prepare":"tsc -p tsconfig.json"},"_npmUser":{"name":"amirdor","email":"amirdor+npm@gmail.com"},"repository":{"url":"git+https://github.com/doramirdor/openbar.git","type":"git"},"_npmVersion":"11.13.0","description":"A spending tab for your coding agent. Local-first cost + bloat receipts for Claude Code and Codex.","directories":{},"_nodeVersion":"24.16.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.6.0","@types/node":"^22.0.0"},"optionalDependencies":{"@resvg/resvg-js":"^2.6.2"},"_npmOperationalInternal":{"tmp":"tmp/openbar_0.1.0_1781704531575_0.3212567903837913","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@amirdor/openbar","version":"0.1.1","description":"A spending tab for your coding agent. Local-first cost + bloat receipts for Claude Code and Codex.","license":"MIT","author":{"name":"Dor Amir","email":"amirdor@gmail.com"},"publishConfig":{"access":"public"},"homepage":"https://doramirdor.github.io/openbar/","repository":{"type":"git","url":"git+https://github.com/doramirdor/openbar.git"},"bugs":{"url":"https://github.com/doramirdor/openbar/issues"},"type":"commonjs","bin":{"openbar":"bin/openbar.js"},"engines":{"node":">=22.5.0"},"scripts":{"build":"tsc -p tsconfig.json","prepare":"tsc -p tsconfig.json","dev":"tsc -p tsconfig.json --watch","test":"node scripts/e2e.js && node scripts/e2e-codex.js","openbar":"node bin/openbar.js"},"keywords":["claude-code","codex","cli","ai-agents","cost","tokens","observability","hooks","devtools"],"devDependencies":{"@types/node":"^22.0.0","typescript":"^5.6.0"},"optionalDependencies":{"@resvg/resvg-js":"^2.6.2"},"gitHead":"6cbc310a254e7f4946a7d29460a17189aa061b30","_id":"@amirdor/openbar@0.1.1","_nodeVersion":"24.16.0","_npmVersion":"11.13.0","dist":{"integrity":"sha512-OhbHGJdE1eKyXlvyDwD/raNgbPryRHSNUlT4WQqFA2LKohu7KhCBfqFqz8G5M9/nJLqXAwdFTllABsOKOMEGZg==","shasum":"b27633a14cc1a0215a1056517a1f9381d448cad7","tarball":"https://registry.npmjs.org/@amirdor/openbar/-/openbar-0.1.1.tgz","fileCount":28,"unpackedSize":143261,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCILa7uoCstEZqCOhECXpcmTrCBMwC3THw5PacyzHLzZAIgVfkSCoZOwcl2p1P6yEZefbB5NFm6rzxvQpUBCr4imv8="}]},"_npmUser":{"name":"amirdor","email":"amirdor+npm@gmail.com"},"directories":{},"maintainers":[{"name":"amirdor","email":"amirdor+npm@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/openbar_0.1.1_1781797241884_0.07543395445871792"},"_hasShrinkwrap":false}},"time":{"created":"2026-06-17T13:55:31.366Z","modified":"2026-06-18T15:40:42.152Z","0.1.0":"2026-06-17T13:55:31.706Z","0.1.1":"2026-06-18T15:40:42.021Z"},"bugs":{"url":"https://github.com/doramirdor/openbar/issues"},"author":{"name":"Dor Amir","email":"amirdor@gmail.com"},"license":"MIT","homepage":"https://doramirdor.github.io/openbar/","keywords":["claude-code","codex","cli","ai-agents","cost","tokens","observability","hooks","devtools"],"repository":{"type":"git","url":"git+https://github.com/doramirdor/openbar.git"},"description":"A spending tab for your coding agent. Local-first cost + bloat receipts for Claude Code and Codex.","maintainers":[{"name":"amirdor","email":"amirdor+npm@gmail.com"}],"readme":"# OpenBar\n\n[![CI](https://github.com/doramirdor/openbar/actions/workflows/ci.yml/badge.svg)](https://github.com/doramirdor/openbar/actions/workflows/ci.yml)\n[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)\n[![Node](https://img.shields.io/badge/node-%E2%89%A522.5-43853d.svg)](https://nodejs.org)\n\n**A spending tab for your coding agent.** Local-first cost + bloat receipts for Claude Code and Codex.\n\n🌐 [doramirdor.github.io/openbar](https://doramirdor.github.io/openbar/) · 📐 [Architecture](docs/ARCHITECTURE.md) · 🤝 [Contributing](CONTRIBUTING.md) · 🔒 [Security](SECURITY.md)\n\n```text\n  OpenBar  ·  Claude Code\n\n  $1.42 estimated run cost\n  213k input tokens  (claude-opus-4-8)\n  9.8k output tokens\n  18 files touched  +612 -83  5 new\n  27 commands run\n  5 retries\n\n  Bloat score: 87/100  █████████████████░░░\n\n  Biggest waste:\n  Re-read package-lock.json 7 times\n\n  Fix:\n  Add lockfiles to your agent ignore rules.\n```\n\nIt runs entirely on your machine. No account, no upload, no API key.\n\n## Quick start\n\n```bash\nnpm i -g @amirdor/openbar   # installs the `openbar` command\nopenbar install             # add Claude Code hooks to this project\n# ... use Claude Code as usual ...\nopenbar report              # print the receipt for the last run\nopenbar summary             # your weekly agent bill across runs\nopenbar fix                 # turn the biggest wastes into CLAUDE.md rules\nopenbar share --png         # render a shareable card\n```\n\nNo global install? `npx @amirdor/openbar install`. Using Codex too? add `--codex`.\n\n## How it works\n\n```text\nClaude Code / Codex\n   │  (lifecycle hooks: SessionStart, PreToolUse, PostToolUse, Stop, …)\n   ▼\nopenbar hook  ──►  .openbar/runs/<session>.jsonl   (append-only event log)\n   │\n   ▼\nanalyzer  ──►  transcript/rollout token usage + git diff + waste detectors\n   │\n   ├─►  receipt (terminal)             openbar report\n   ├─►  weekly bill (terminal)         openbar summary\n   ├─►  shareable card (SVG/PNG/HTML)  openbar share\n   ├─►  agent rules (CLAUDE.md)        openbar fix\n   └─►  history (SQLite)               openbar report --history\n```\n\n- **`install`** writes hooks into `.claude/settings.json` (or `--global` / `--local`). It's idempotent and reversible (`uninstall`).\n- **`hook`** is called by Claude Code at each lifecycle point. It reads the hook JSON from stdin and appends a compact event to the per-session log. It is wrapped to never block or slow down the agent.\n- **`report`** reconstructs the run: real token usage from the Claude Code transcript, file changes from `git diff` (or tool events when there's no repo), waste detectors, and a bloat score.\n\n## Accurate cost, honestly labeled\n\nToken counts come from the real Claude Code transcript (`message.usage`), not estimates — including the 5-minute vs 1-hour cache-write split. Cost is computed per-model with Anthropic's cache multipliers (read ×0.10, write-5m ×1.25, write-1h ×2.0).\n\nIt's still labeled **estimated** because pricing for some legacy models is approximate and discount tiers can't be detected. We never show false precision. (Note: on a Claude subscription you don't pay per token — the figure is the API-rate equivalent, a \"what this would cost\" signal, not an invoice.)\n\nRates live in a built-in table. To set exact, negotiated, or Batch (50%-off) rates — or price a model OpenBar doesn't know — drop a `~/.openbar/pricing.json`:\n\n```json\n{ \"claude-opus-4-8\": { \"input\": 5, \"output\": 25 }, \"my-model\": { \"input\": 2, \"output\": 8 } }\n```\n\nYour file wins over the defaults, stays on your machine, and its rates are treated as exact.\n\n> One subtlety handled correctly: a single API response is written to the transcript as multiple lines (one per content block) that all repeat the same `usage`. OpenBar dedupes by request id so tokens aren't counted 3–5× over.\n\n## Bloat score\n\nA transparent 0–100 score (higher = more wasteful), capped per dimension so nothing dominates:\n\n| Dimension | Max |\n|---|---|\n| files touched | 18 |\n| lines added | 14 |\n| repeated reads | 20 |\n| retries / failures | 16 |\n| dependency changes | 10 |\n| generated-file changes | 12 |\n| big diff for a tiny prompt | 10 |\n\n## Waste detectors\n\nRe-read files, lockfile reads, `node_modules`/`dist` reads, repeated commands, failing-test loops, dependency changes, edits to generated output, huge file reads, huge tool outputs, edit churn, output-heavy runs, file sprawl, and big-diff-for-small-prompt. Each finding carries a concrete fix.\n\n## Codex\n\nCodex has official hooks too, so the same flow works:\n\n```bash\nnpx openbar install --codex   # writes .codex/hooks.json (--global for ~/.codex)\n```\n\nTwo Codex specifics OpenBar handles for you:\n\n- **Tokens** come from Codex's on-disk rollout (`~/.codex/sessions/.../rollout-*.jsonl`, the `token_count` lines), normalized so the shared cost math applies. OpenAI pricing is approximate and the receipt says so.\n- **Trust model:** Codex skips a freshly-written command hook until you trust it — run `/hooks` inside Codex once after installing (or launch with `--dangerously-bypass-hook-trust`).\n\n## `openbar fix`\n\nWrites a managed block into `CLAUDE.md` (and `AGENTS.md` with `--all`), generated from what actually wasted money in your runs:\n\n```md\n<!-- openbar:start -->\n## Agent cost rules\n\n- Do not read lockfiles unless explicitly asked. Use the manifest for dependency questions.\n- If the same command fails twice for the same reason, stop and explain the blocker.\n- Prefer editing existing files over creating new ones.\n<!-- openbar:end -->\n```\n\nThe block is re-written in place on each run, so it stays current.\n\n## Commands\n\n| Command | Description |\n|---|---|\n| `openbar install [--codex] [--global\\|--local] [--print]` | Add hooks to Claude Code (or Codex) |\n| `openbar uninstall [--codex]` | Remove openbar hooks |\n| `openbar report [session] [--json] [--history] [--transcript path] [--no-save]` | Print a receipt |\n| `openbar summary [--days n\\|--all] [--json]` | Aggregate recent runs (weekly bill) |\n| `openbar share [session] [--png] [--html] [--out file]` | Render a shareable card |\n| `openbar fix [session] [--all] [--target file] [--print]` | Write rules into CLAUDE.md / AGENTS.md |\n\n## Requirements\n\n- Node ≥ 22.5 (uses the built-in `node:sqlite` for history; history degrades gracefully if unavailable).\n- Zero required runtime dependencies. PNG export uses the optional `@resvg/resvg-js`; without it, `share --png` writes a browser-based PNG exporter instead.\n\n## Development\n\n```bash\nnpm install      # builds via the prepare script\nnpm run build\nnpm test         # end-to-end smoke tests (Claude Code + Codex) against the compiled binary\n```\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for the project layout and how to add a detector,\nand [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) for the data flow.\n\n## Troubleshooting\n\nHooks are silent by design (agents can inject hook stdout into the model). If a run isn't\nshowing up, set `OPENBAR_DEBUG=1` and check `.openbar/openbar.log`. Confirm the\nhooks are registered with `openbar install --print`. On Codex, remember to trust the\nhook via `/hooks` after installing.\n\n## Status\n\nV0 — Claude Code + Codex, fully local. Done: receipts, accurate per-model cost, bloat score, waste detectors, `fix` rules, SVG/PNG/HTML share cards, local history + weekly summary.\n\nDeliberately deferred until the receipt is getting shared (per the original plan): cloud sync, team dashboard, PR comments, budget alerts, and billing. None of that is required to get value from the receipt.\n\n## License\n\nMIT\n","readmeFilename":"README.md"}