Skip to content
cccskills
FreePublished on GitHub

setup-cost-tracking

Install genuine per-session cost tracking for Claude Code by wiring bundled logger scripts into the user's statusline — preserving any existing statusline and hooks. Use when the user asks to set up, install, enable, or repair cost tracking / cost logging / session cost capture. Idempotent; safe to re-run.

The English summary is being prepared. Showing the original description.

See how to install

Files included (5)

  • SKILL.md6.4 KB
  • scripts/cost-logger.js6.0 KB
  • scripts/statusline-command.js4.1 KB
  • scripts/statusline-wrapper.js1.5 KB
  • scripts/turn-logger.js1.7 KB

SKILL.md (original)

Review the instructions the agent will receive before you install.

Setup Cost Tracking

Installs genuine cost capture for every Claude Code session on this machine. Cost data (cost.total_cost_usd etc.) is computed by Claude Code itself and is available only in the statusline payload — hooks never receive it. So this skill wires a logger into the statusline path while preserving whatever statusline and hooks the user already has.

What gets installed

Bundled in this skill's scripts/ directory, copied to ~/.claude/scripts/:

ScriptRole
cost-logger.jsCapture engine. Silent, crash-proof. Writes the log files below.
statusline-wrapper.jsUsed when the user already has a statusline: logs cost, then delegates the payload to their original command and passes its output through untouched.
statusline-command.jsUsed when the user has no statusline: full display (model, context bar, cost, cache stats) that also logs.
turn-logger.jsStop hook: stamps turn boundaries so cost samples can later be grouped into turns for analytics. No cost data itself.

Log outputs (created lazily, no setup needed):

  • ~/.claude/cost-log.jsonl — one row per session, exact cumulative totals (upserted).
  • ~/.claude/projects/<mapped-dir>/<session>.cost.jsonl — cost samples at ~5s resolution during activity.
  • ~/.claude/projects/<mapped-dir>/<session>.turn-boundaries.jsonl — one row per turn end, with transcript_path for deep-dive analytics.

Installation procedure

Follow these steps exactly. Use real JSON manipulation (a node -e script or jq) for every settings edit — never string/regex edits on settings files.

Step 0 — Preflight

  1. command -v node — if Node.js is missing, stop and tell the user it's required. Record the absolute path (call it $NODE). Use $NODE in every command you write into settings, not bare node (statusline/hook commands don't always get the user's full shell PATH).
  2. Read ~/.claude/settings.json (treat as {} if absent) and ~/.claude/settings.local.json (if present). The effective statusLine is the local one if defined there, else the user one. Remember which file defines it — edits must go to that same file.

Step 1 — Copy scripts

  1. mkdir -p ~/.claude/scripts
  2. Copy the four .js files from this skill's scripts/ directory into ~/.claude/scripts/ and chmod +x them. Overwriting previous versions of these four files is fine (that's how upgrades work). Never overwrite ~/.claude/scripts/statusline-original.json if it exists.

Step 2 — Wire the statusline (the load-bearing step)

Decide by the effective statusLine:

  • Case A — already ours: its command contains statusline-wrapper.js or statusline-command.js. Nothing to change; report "already installed" and continue to Step 3.
  • Case B — none configured: set in ~/.claude/settings.json:
    "statusLine": { "type": "command", "command": "$NODE /Users/<user>/.claude/scripts/statusline-command.js", "padding": 0 }
    
    (expand $NODE and the home directory to absolute paths).
  • Case C — user has their own statusline: preserve it.
    1. Write ~/.claude/scripts/statusline-original.json containing exactly { "command": "<their current statusLine.command>" }.
    2. In the file that defines statusLine, replace only the command value with $NODE /Users/<user>/.claude/scripts/statusline-wrapper.js. Keep type, padding, refreshInterval, and any other sibling keys untouched.

Before the first edit to any settings file, back it up: cp settings.json settings.json.bak-cost-tracking (same pattern for the local file). One backup per run is enough.

Step 3 — Add the turn-boundary hook (additive, never replaces)

If no existing hooks.Stop entry's command mentions turn-logger.js, append this entry to the hooks.Stop array (create the array/path if missing), leaving every existing hook alone:

{ "matcher": "", "hooks": [ { "type": "command", "command": "$NODE /Users/<user>/.claude/scripts/turn-logger.js" } ] }

This hook carries no cost data — it only stamps turn boundaries and the idle timer. If the user objects to hooks, skipping this step still leaves session cost capture fully working.

Step 4 — Verify

  1. Build a fake statusline payload with session_id "cost-setup-verify", a workspace.current_dir of /tmp/cost-setup-verify, and nonzero cost.total_cost_usd / cost.total_api_duration_ms / model.display_name values.
  2. Pipe it via stdin into the exact statusLine.command now in settings (run through sh -c).
    • Case B: expect the rendered multi-line statusline.
    • Case C: expect the original statusline's output (the wrapper delegates). If their original command errors on the synthetic payload, that's their script's quirk — check instead that the log file below was written.
  3. Confirm ~/.claude/projects/-tmp-cost-setup-verify/cost-setup-verify.cost.jsonl now exists and contains the fake cost.
  4. Clean up all verification artifacts: that projects subdirectory, the cost-setup-verify line in ~/.claude/cost-log.jsonl, and /tmp/statusline-*-cost-setup-verify state files.

Step 5 — Report

Tell the user, concretely:

  • which case applied (fresh install / wrapped their existing statusline / already installed),
  • every file created or modified (settings edits, backups, copied scripts),
  • where their cost data will accumulate (the three log paths above),
  • that changes take effect in new sessions,
  • how to uninstall: restore the .bak-cost-tracking settings backup (or, by hand: point statusLine.command back to the command saved in ~/.claude/scripts/statusline-original.json and remove the turn-logger Stop hook entry), then delete the four scripts.

Invariants

  • Never delete or rewrite the user's hooks, statusline command, or unrelated settings keys. All changes are additive or a single-value swap that is recorded for reversal.
  • Idempotent: re-running on an installed machine must change nothing and say so.
  • If any step fails midway, restore the settings backup and report what happened.

Reviews

No reviews yet. Tell others what you thought.

Comments

No login needed. Share how it worked for you, ask a question, or note where it did not run.

No comments yet. Be the first to write one.

Comments are published right away. Do not include personal information such as email addresses or phone numbers. Up to 2 URLs.

0 / 1,000 characters

This form is protected by reCAPTCHA, and the Google Privacy Policy and Terms of Service apply.

More skills from this repository

Retire a closed issue's working artifacts out of specs/ into the GitHub wiki. Use only when the user asks to archive a finished issue, empty out specs/ for a done task, or move an issue's requirements/architecture/tasks/review/QA docs to the wiki.

The English summary is being prepared. Showing the original description.

foyzulkarim/skills43Updated Sep 4, 2026

commit

Free

One-shot conventional commit; bundled scripts adaptively gather diff context, draft the message, and stage+commit — pass `ask` to confirm first or add a hint for the title. Use only when the user asks for a commit.

The English summary is being prepared. Showing the original description.

foyzulkarim/skills43Updated Sep 4, 2026

Executes a QA specification (specs/qa/QA-<N>-<slug>.md) written by /plan-qa: drives every step with the plan's drivers, verifies each Expected line mechanically ([assert]) or by evidence-backed judgment against the plan's written criterion ([judge]), pauses at named operator handoffs, and writes the results artifact QA-RESULTS-<N>-<slug>.md. Use only when the user asks to run or execute a QA plan — never trigger automatically.

The English summary is being prepared. Showing the original description.

foyzulkarim/skills43Updated Sep 4, 2026

After an issue's PR has squash-merged on GitHub and its issue has closed: fast-forward the default branch, remove the issue-numbered nested worktree (.worktrees/<issue#>), and delete the local feature branch. Use when the user says to finish, tear down, or clean up a lane or worktree for a merged issue.

The English summary is being prepared. Showing the original description.

foyzulkarim/skills43Updated Sep 4, 2026

Phase 3 of 5 — slices the ARCH doc into verification-ready task specs (tdd/test-after/ui/checklist), emitted as a separate TASKS-<N>-<slug>.md file alongside ARCH for the implement skill. Use only when the user asks to run Phase 3 or generate tasks from an ARCH doc — never trigger automatically.

The English summary is being prepared. Showing the original description.

foyzulkarim/skills43Updated Sep 4, 2026

Phase 4 of 5 — implements tasks from TASKS-<N>-<slug>.md (with ARCH-<N>-<slug>.md as architecture-only context) using mode-appropriate verification (tdd, test-after, ui, checklist); pass 'auto' to run without stepping. Use only when the user asks to run Phase 4 or implement tasks from an ARCH doc — never trigger automatically from a coding request.

The English summary is being prepared. Showing the original description.

foyzulkarim/skills43Updated Sep 4, 2026

See all skills by foyzulkarim

Report a problem with this skill