[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6C3870BKKRP7DPREVC4PCCE":3,"skill-same:01M6C3870BKKRP7DPREVC4PCCE":76},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":17,"publishedAt":50,"linkOnly":51,"markdownContent":52,"markdownBody":53,"frontMatter":54,"refName":55,"commitSha":56,"skillDirectory":57,"forksCount":58,"repositoryHtmlUrl":59,"repositoryHomepageUrl":6,"ownerHtmlUrl":60,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":61,"install":62,"resources":75},"01M6C3870BKKRP7DPREVC4PCCE","cli-usage-audit",null,"Daily request\u002Ftoken\u002Fcost breakdown across every AI CLI installed on this Mac (Claude Code, Codex, Hermes, OpenCode, Gemini, Kimi, Qwen, Copilot, Goose, Kilo, Droid, OpenClaw, Amp, Codebuff, Pi). Trigger when the user says \"how many requests do I do daily\", \"what am I spending on AI\", \"AI usage report\", \"daily AI cost\", \"token breakdown per day\", \"show me my per-day usage\", \"ai-usage-tracker\", or any natural-language request for a daily AI-tool activity report. Encodes the three-source recipe (ccusage hermes + direct JSONL parsing of ~\u002F.claude\u002Fprojects and ~\u002F.codex\u002Fsessions) that survives the schema-mismatch bug in the `ai-usage-tracker-js` npm wrapper, the 180s `ccusage daily --json` timeout trap, the executable-bit permission-denied trap on the wrapper shim, and the Claude `source` filter that separates real REPL prompts from agent-internal tool-loop rows. Verified 2026-07-21 against 7,558 Codex sessions, 6,348 Claude JSONLs, 30-day Hermes window.","jleechanorg\u002Fjleechan-skills","jleechanorg","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F221404966?v=4","01M6C1VJ99XG950X1DWPEBCBGX","01M6C1VJDK5YVDNT3362RT5WSB",6,"MIT","https:\u002F\u002Fgithub.com\u002Fjleechanorg\u002Fjleechan-skills\u002Fblob\u002Fmain\u002Fhermes\u002Fskills\u002Fdevops\u002Fcli-usage-audit\u002FSKILL.md",[],[18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49],"cli","cli usage audit","usage","audit","kilo","daily","show","across","bit","recipe","filter","schema","jsonl","natural-language","activity report","when","denied","opencode","pi","json","tool","projects","loop","how","show me","parsing","report","code","copilot","sessions","codex","gemini","2026-11-10 10:12:30",false,"---\nname: cli-usage-audit\ndescription: Daily request\u002Ftoken\u002Fcost breakdown across every AI CLI installed on this Mac (Claude Code, Codex, Hermes, OpenCode, Gemini, Kimi, Qwen, Copilot, Goose, Kilo, Droid, OpenClaw, Amp, Codebuff, Pi). Trigger when the user says \"how many requests do I do daily\", \"what am I spending on AI\", \"AI usage report\", \"daily AI cost\", \"token breakdown per day\", \"show me my per-day usage\", \"ai-usage-tracker\", or any natural-language request for a daily AI-tool activity report. Encodes the three-source recipe (ccusage hermes + direct JSONL parsing of ~\u002F.claude\u002Fprojects and ~\u002F.codex\u002Fsessions) that survives the schema-mismatch bug in the `ai-usage-tracker-js` npm wrapper, the 180s `ccusage daily --json` timeout trap, the executable-bit permission-denied trap on the wrapper shim, and the Claude `source` filter that separates real REPL prompts from agent-internal tool-loop rows. Verified 2026-07-21 against 7,558 Codex sessions, 6,348 Claude JSONLs, 30-day Hermes window.\n---\n\n# CLI Daily Usage Audit (per-CLI, per-day)\n\nA reproducible recipe for \"how many requests \u002F how much $$ \u002F how many tokens do I generate per day across all my AI CLIs\". The `ai-usage-tracker-js` npm wrapper does *not* work end-to-end on this machine as of v0.1.5 — its output is empty\u002Fzeros for Claude and Codex (schema-mismatch bug, see Pitfall 1). The recipe below is the verified replacement.\n\n## TL;DR\n\n```bash\n# Three independent commands, all under ~60s when run in parallel:\nSINCE=$(date -v-30d +%Y-%m-%d)\n\n# A) Hermes — fastest, cleanest, has request count per day\nccusage hermes daily --since \"$SINCE\" --order desc --json\n\n# B) Claude Code REPL prompts — direct JSONL parse (filter agent-internal rows!)\n#    see scripts\u002Fdaily_usage_audit.py for the full extractor\n\n# C) Codex CLI — also direct JSONL parse (different schema from ccusage-codex)\n#    see scripts\u002Fdaily_usage_audit.py\n```\n\nRun **all three in parallel via `terminal(background=true, notify_on_complete=true)`**, then pipe the outputs into the canonical formatter in `scripts\u002Fdaily_usage_audit.py`. That script returns one combined Markdown table with daily Hermes\u002FClaude\u002FCodex rows + 30-day totals + peak day.\n\n## What the user actually wants\n\nThe user almost always asks for **\"requests per day\"**, not tokens. They tolerate tokens\u002Fcost as context. Distinguish:\n- **Hermes** request count = `messageCount` field from `ccusage hermes daily --json` (clean, direct).\n- **Claude Code** request count = number of `type=user && source in (None,\"repl_main\") && has_text` rows in `~\u002F.claude\u002Fprojects\u002F**\u002F\u003Csession>.jsonl`, bucketed by the row's `timestamp` field. **Do NOT use the total row count** — it inflates 10–100× because agent-internal tool-loop rows are also `type=user` but with `source=\"agent_progress\"|\"compact\"|...` and no human text content. Use the `source` filter; the `has_text` check on the `message.content` (str or list-of-text-blocks) is the tie-breaker. Pitfall 2.\n- **Codex CLI** request count = number of `type=event_msg && payload.type==\"user_message\"` rows in `~\u002F.codex\u002Fsessions\u002F**\u002Frollout-*.jsonl`, bucketed by the inner `timestamp` field. The top-level Codex schema is `{\"timestamp\",\"type\",\"payload\":{...}}` — different from ccusage's. Pitfall 3. Use **inner timestamp** not file mtime; sessions that ran across midnight (or got rotated to an archive dir) bucket wrong by hours\u002Fdays if you key off mtime.\n\nThe three counts are not directly comparable (one Hermes call ≠ one Claude prompt ≠ one Codex user-message turn) but together they describe the user's daily AI tool activity.\n\n## Pitfall 1 — `ai-usage-tracker-js` v0.1.5 is broken on this machine\n\n**Symptom:** the wrapper prints an empty table \u002F 0\u002F0\u002F0 rows when invoked with `--days 30`. It also has TWO permission traps:\n\n```bash\n$ ai-usage-tracker-js --help\nbash: $HOME\u002F.nvm\u002Fversions\u002Fnode\u002Fv22.22.0\u002Fbin\u002Fai-usage-tracker-js: Permission denied\n\n$ ls -la $HOME\u002F.nvm\u002Fversions\u002Fnode\u002Fv22.22.0\u002Fbin\u002Fai-usage-tracker-js\nlrwxr-xr-x@ 1 $USER  staff  48 Mar  6 01:49 ... -> ..\u002Flib\u002Fnode_modules\u002Fai-usage-tracker\u002Fdist\u002Fcli.js\n# ^ symlink missing +x bit; chmod +x fixes the symlink target only if run via the\n# wrapper path; cleanest is `node \u003Cabs path>\u002Fdist\u002Fcli.js`\n\n$ ccusage daily --since 2026-06-21 --json\n# 180s tool timeout, exits 124, empty output — full log scan, not the data shape\n```\n\n**Root cause:** the wrapper expects `ccusage daily` to emit per-day `totalTokens` \u002F `totalCost` AND assume each entry has a request count. But `ccusage daily` (v0.x) has schema `[{date, totalTokens, totalCost, modelBreakdowns:[...], metadata:{agents:[...]}}]` — the `metadata.agents` field is now `[\"claude\",\"codex\",\"gemini\",\"hermes\"]` (aggregated!) AND there's no `messageCount`\u002F`requests` field on the day row. Worse, `ccusage-codex daily` returns a *different* schema (`{date, inputTokens, outputTokens, totalTokens, costUSD, models:{...}}`) — also no request count. The wrapper's combined output ends up zero for Claude and zero for Codex because the schema keys it reads (`entry.totalCost` for codex) are wrong.\n\n**Workaround (preferred): bypass the wrapper entirely and use `ccusage hermes daily --json` for the Hermes column (clean request counts) + direct JSONL parsing for Claude + Codex. The wrapper cannot be salvaged by patching alone; it needs a v0.2 that pulls per-day request counts from each tool's native log format.**\n\n**Workaround (less preferred):** `chmod +x $HOME\u002F.nvm\u002Fversions\u002Fnode\u002Fv22.22.0\u002Fbin\u002Fai-usage-tracker-js` first (resolves the Permission denied trap), then run `ccusage daily` \u002F `ccusage-codex daily` in `terminal(background=true, notify_on_complete=true)` with a 300s timeout — they will finish in ~8–9 minutes each on a 30-day window with this machine's log volume. Output still has zero request counts; only useful for tokens\u002F$.\n\n## Pitfall 2 — Claude JSONL `source` filter is the only thing separating \"user prompts\" from \"agent internals\"\n\nThe Claude Code session JSONL files (`~\u002F.claude\u002Fprojects\u002F\u003Ccwd-hash>\u002F\u003Csession-id>.jsonl`) write a row for every agent turn, not just yours. The rows look like:\n\n```json\n{\"type\":\"user\",\"isMeta\":true, ...}                  \u002F\u002F ignore (hook\u002Fmeta rows)\n{\"type\":\"user\",\"source\":\"repl_main\",\"message\":{\"content\":\"Fix the bug\"}}  \u002F\u002F COUNT\n{\"type\":\"user\",\"source\":\"agent_progress\",\"message\":{\"content\":[{\"type\":\"text\",\"text\":\"...\"}]}}  \u002F\u002F skip\n{\"type\":\"user\",\"source\":\"compact\",\"message\":{\"content\":\"Compaction summary...\"}}  \u002F\u002F skip\n{\"type\":\"user\",\"source\":null,\"message\":{\"content\":\"...\"}}  \u002F\u002F COUNT (newer SDK convention)\n```\n\n**Counterexample if you ignore the filter:** a single day with a busy Opus session can produce 10,000+ `type=user` rows, of which 200–1,500 are real REPL prompts. Reporting the unfiltered count (e.g. \"24,111 prompts\u002Fday\") is misleading by an order of magnitude.\n\n**Verified filter (2026-07-21, 6,348 JSONL files, 30 days):**\n- Keep iff `type == \"user\" and isMeta != true and source in (None, \"repl_main\") and message.content has text`.\n- Counts: 22,491 REPL prompts across 30 days → avg **726 prompts\u002Fday**, in 6,519 distinct sessions.\n- Skipping the `source` filter inflates to ~240,000 rows over the same window — >10× too high.\n\nDistinct sessions per day is a useful second axis: `obj[\"sessionId\"]` is populated on every row. Today (2026-07-21) showed 299 distinct sessions for 542 prompts — high concurrency (multiple parallel agent invocations).\n\n## Pitfall 3 — Codex JSONL schema is `event_msg` + inner `payload.type`, not what ccusage-codex says\n\n`~\u002F.codex\u002Fsessions\u002F**\u002Frollout-\u003Ctimestamp>-\u003Cuuid>.jsonl` looks like:\n\n```json\n{\"timestamp\":\"2026-06-03T19:19:05.123Z\",\"type\":\"session_meta\",\"payload\":{\"id\":\"...\"}}\n{\"timestamp\":\"...\",\"type\":\"event_msg\",\"payload\":{\"type\":\"task_started\"}}      \u002F\u002F 1 per Codex CLI invocation\n{\"timestamp\":\"...\",\"type\":\"event_msg\",\"payload\":{\"type\":\"user_message\"}}       \u002F\u002F 1 per user prompt\n{\"timestamp\":\"...\",\"type\":\"event_msg\",\"payload\":{\"type\":\"agent_message\"}}     \u002F\u002F 1 per assistant turn\n{\"timestamp\":\"...\",\"type\":\"response_item\",\"payload\":{\"type\":\"message\"}}        \u002F\u002F not a turn event\n{\"timestamp\":\"...\",\"type\":\"response_item\",\"payload\":{\"type\":\"function_call\"}}\n{\"timestamp\":\"...\",\"type\":\"event_msg\",\"payload\":{\"type\":\"token_count\"}}\n```\n\n**Bucketing rule:** use the inner `obj[\"timestamp\"]` (ISO 8601 with `Z` suffix) and convert to local date. **Do NOT use file mtime** — sessions get archived\u002Frotated, so the mtime reflects when the file was last touched, not when the events occurred. Observed drift: a session that ran 2026-07-19 had its JSONL mtime 2026-07-20 because the file was finalized the next day.\n\n**Request count definitions:**\n- `event_msg.payload.type == \"user_message\"` = 1 user prompt (analog to Claude REPL prompt) — **30-day total 11,476** for this user, avg **370\u002Fday**.\n- `event_msg.payload.type == \"agent_message\"` = 1 assistant turn. Inflated by tool-call round-trips: 30-day total **125,940** — ~11× user-prompt count.\n- `event_msg.payload.type == \"task_started\"` = 1 Codex CLI invocation (analog to Claude `sessionId`): **30-day total 12,145**.\n\nPick `user_message` for the \"requests per day\" column; it's the closest analog to \"I typed a thing into a CLI today\".\n\n## The script (canonical, run this — don't hand-type the JSONL parsing)\n\n`scripts\u002Fdaily_usage_audit.py` does all three pulls, joins by local-date, prints a single Markdown table plus 30-day totals. It runs in ~70 seconds on this machine with the typical log volume. Re-run it on any ask of the form \"daily AI usage\" — no human retyping required.\n\n```bash\npython3 ~\u002F.hermes\u002Fskills\u002Fdevops\u002Fcli-usage-audit\u002Fscripts\u002Fdaily_usage_audit.py --days 14\n```\n\nOutput shape:\n```\nDATE        HERMES     HERMES $   CLAUDE PROMPTS   CLAUDE SESSIONS   CODEX PROMPTS   CODEX AGENT-MSG\n2026-07-21   2,887    $  25.52            542              299             283             990\n...\n\n=== 30-day totals ===\n  Hermes            : 181,212 requests   $597.67   -> 5,846\u002Fday\n  Claude Code REPL  :  22,491 prompts         $0   ->   726\u002Fday  (in 6,519 distinct sessions)\n  Codex session entr.: 11,476 user_prompts   $0   ->   370\u002Fday\n```\n\n## When the user asks a narrower question\n\n| User asks for | Recipe | Notes |\n|---|---|---|\n| \"how many requests do I do daily\" | full 3-column audit | this skill |\n| \"Hermes-only\" \u002F \"gateway only\" | `ccusage hermes daily --since SINCE --json` | 5–10s, reliable, has both msg + cost |\n| \"Claude Code tokens\" | `ccusage claude daily --since SINCE --json` | slow (~8min for 30d, 180s timeout hits often); schema is tokens\u002F$ aggregated across all agents under `metadata.agents` |\n| \"Codex tokens\" | `ccusage-codex daily --since SINCE --json` | slow, schema `{date, totalTokens, costUSD, models:{...}}` |\n| \"what models did I use\" | `ccusage hermes daily --json` → `modelsUsed` field | gives the model roster |\n| \"am I over my rate limit\" | out of scope — use `verify-telemetry-alert` skill |\n\nIf the user wants **just Hermes** or **just one CLI**, skip the JSONL parses and run only the `ccusage \u003Cagent>` subcommand. Hermes comes back in ~5s.\n\n## Companion skills\n\n- `context-token-audit` — single-session context composition (different concern: how big is THIS conversation, not how much did I send across all sessions).\n- `gcp-cost-diagnosis-bq-billing-export` — same shape for cloud bills (BQ billing export vs local JSONLs). Parallel class.\n- `mac-di[REDACTED_OPENAI_KEY]` — parallel class for filesystem usage.\n- `swap-hermes-provider` — when a daily-usage report reveals the user is overspending on a specific model tier.\n\n## Support files\n\n- `scripts\u002Fdaily_usage_audit.py` — the canonical 3-source extractor. Run this; don't re-derive.\n- `references\u002F2026-07-21-ai-usage-tracker-js-schema-bug.md` — first documented instance of the wrapper's empty-output bug + the JSONL `source` filter discovery.\n- `references\u002Fcodex-session-schema.md` — full Codex rollout JSONL schema reference + per-event-type meanings.\n\n## Reporting findings (template)\n\n```\n? **AI CLI daily usage — last 14 days**\nDATE        HERMES     HERMES $   CLAUDE   CODEX   | daily notes\n2026-07-21   2,887    $25.52      542     283    | \u003C-- today\n...\n\n? 30-day totals:\n• Hermes:       181,212 requests, $597.67, avg 5,846\u002Fday\n• Claude Code:   22,491 REPL prompts, 6,519 sessions, avg 726\u002Fday\n• Codex:         11,476 user prompts, avg 370\u002Fday (avg ~11× tool-call round-trips)\n\nPeak: 2026-06-23 — 15,298 Hermes requests, $44.32\n```\n\nAlways include the raw JSON paths (`\u002Ftmp\u002Fccusage_*.json` if you generated them) so the user can re-run \u002F cross-check.","# CLI Daily Usage Audit (per-CLI, per-day)\n\nA reproducible recipe for \"how many requests \u002F how much $$ \u002F how many tokens do I generate per day across all my AI CLIs\". The `ai-usage-tracker-js` npm wrapper does *not* work end-to-end on this machine as of v0.1.5 — its output is empty\u002Fzeros for Claude and Codex (schema-mismatch bug, see Pitfall 1). The recipe below is the verified replacement.\n\n## TL;DR\n\n```bash\n# Three independent commands, all under ~60s when run in parallel:\nSINCE=$(date -v-30d +%Y-%m-%d)\n\n# A) Hermes — fastest, cleanest, has request count per day\nccusage hermes daily --since \"$SINCE\" --order desc --json\n\n# B) Claude Code REPL prompts — direct JSONL parse (filter agent-internal rows!)\n#    see scripts\u002Fdaily_usage_audit.py for the full extractor\n\n# C) Codex CLI — also direct JSONL parse (different schema from ccusage-codex)\n#    see scripts\u002Fdaily_usage_audit.py\n```\n\nRun **all three in parallel via `terminal(background=true, notify_on_complete=true)`**, then pipe the outputs into the canonical formatter in `scripts\u002Fdaily_usage_audit.py`. That script returns one combined Markdown table with daily Hermes\u002FClaude\u002FCodex rows + 30-day totals + peak day.\n\n## What the user actually wants\n\nThe user almost always asks for **\"requests per day\"**, not tokens. They tolerate tokens\u002Fcost as context. Distinguish:\n- **Hermes** request count = `messageCount` field from `ccusage hermes daily --json` (clean, direct).\n- **Claude Code** request count = number of `type=user && source in (None,\"repl_main\") && has_text` rows in `~\u002F.claude\u002Fprojects\u002F**\u002F\u003Csession>.jsonl`, bucketed by the row's `timestamp` field. **Do NOT use the total row count** — it inflates 10–100× because agent-internal tool-loop rows are also `type=user` but with `source=\"agent_progress\"|\"compact\"|...` and no human text content. Use the `source` filter; the `has_text` check on the `message.content` (str or list-of-text-blocks) is the tie-breaker. Pitfall 2.\n- **Codex CLI** request count = number of `type=event_msg && payload.type==\"user_message\"` rows in `~\u002F.codex\u002Fsessions\u002F**\u002Frollout-*.jsonl`, bucketed by the inner `timestamp` field. The top-level Codex schema is `{\"timestamp\",\"type\",\"payload\":{...}}` — different from ccusage's. Pitfall 3. Use **inner timestamp** not file mtime; sessions that ran across midnight (or got rotated to an archive dir) bucket wrong by hours\u002Fdays if you key off mtime.\n\nThe three counts are not directly comparable (one Hermes call ≠ one Claude prompt ≠ one Codex user-message turn) but together they describe the user's daily AI tool activity.\n\n## Pitfall 1 — `ai-usage-tracker-js` v0.1.5 is broken on this machine\n\n**Symptom:** the wrapper prints an empty table \u002F 0\u002F0\u002F0 rows when invoked with `--days 30`. It also has TWO permission traps:\n\n```bash\n$ ai-usage-tracker-js --help\nbash: $HOME\u002F.nvm\u002Fversions\u002Fnode\u002Fv22.22.0\u002Fbin\u002Fai-usage-tracker-js: Permission denied\n\n$ ls -la $HOME\u002F.nvm\u002Fversions\u002Fnode\u002Fv22.22.0\u002Fbin\u002Fai-usage-tracker-js\nlrwxr-xr-x@ 1 $USER  staff  48 Mar  6 01:49 ... -> ..\u002Flib\u002Fnode_modules\u002Fai-usage-tracker\u002Fdist\u002Fcli.js\n# ^ symlink missing +x bit; chmod +x fixes the symlink target only if run via the\n# wrapper path; cleanest is `node \u003Cabs path>\u002Fdist\u002Fcli.js`\n\n$ ccusage daily --since 2026-06-21 --json\n# 180s tool timeout, exits 124, empty output — full log scan, not the data shape\n```\n\n**Root cause:** the wrapper expects `ccusage daily` to emit per-day `totalTokens` \u002F `totalCost` AND assume each entry has a request count. But `ccusage daily` (v0.x) has schema `[{date, totalTokens, totalCost, modelBreakdowns:[...], metadata:{agents:[...]}}]` — the `metadata.agents` field is now `[\"claude\",\"codex\",\"gemini\",\"hermes\"]` (aggregated!) AND there's no `messageCount`\u002F`requests` field on the day row. Worse, `ccusage-codex daily` returns a *different* schema (`{date, inputTokens, outputTokens, totalTokens, costUSD, models:{...}}`) — also no request count. The wrapper's combined output ends up zero for Claude and zero for Codex because the schema keys it reads (`entry.totalCost` for codex) are wrong.\n\n**Workaround (preferred): bypass the wrapper entirely and use `ccusage hermes daily --json` for the Hermes column (clean request counts) + direct JSONL parsing for Claude + Codex. The wrapper cannot be salvaged by patching alone; it needs a v0.2 that pulls per-day request counts from each tool's native log format.**\n\n**Workaround (less preferred):** `chmod +x $HOME\u002F.nvm\u002Fversions\u002Fnode\u002Fv22.22.0\u002Fbin\u002Fai-usage-tracker-js` first (resolves the Permission denied trap), then run `ccusage daily` \u002F `ccusage-codex daily` in `terminal(background=true, notify_on_complete=true)` with a 300s timeout — they will finish in ~8–9 minutes each on a 30-day window with this machine's log volume. Output still has zero request counts; only useful for tokens\u002F$.\n\n## Pitfall 2 — Claude JSONL `source` filter is the only thing separating \"user prompts\" from \"agent internals\"\n\nThe Claude Code session JSONL files (`~\u002F.claude\u002Fprojects\u002F\u003Ccwd-hash>\u002F\u003Csession-id>.jsonl`) write a row for every agent turn, not just yours. The rows look like:\n\n```json\n{\"type\":\"user\",\"isMeta\":true, ...}                  \u002F\u002F ignore (hook\u002Fmeta rows)\n{\"type\":\"user\",\"source\":\"repl_main\",\"message\":{\"content\":\"Fix the bug\"}}  \u002F\u002F COUNT\n{\"type\":\"user\",\"source\":\"agent_progress\",\"message\":{\"content\":[{\"type\":\"text\",\"text\":\"...\"}]}}  \u002F\u002F skip\n{\"type\":\"user\",\"source\":\"compact\",\"message\":{\"content\":\"Compaction summary...\"}}  \u002F\u002F skip\n{\"type\":\"user\",\"source\":null,\"message\":{\"content\":\"...\"}}  \u002F\u002F COUNT (newer SDK convention)\n```\n\n**Counterexample if you ignore the filter:** a single day with a busy Opus session can produce 10,000+ `type=user` rows, of which 200–1,500 are real REPL prompts. Reporting the unfiltered count (e.g. \"24,111 prompts\u002Fday\") is misleading by an order of magnitude.\n\n**Verified filter (2026-07-21, 6,348 JSONL files, 30 days):**\n- Keep iff `type == \"user\" and isMeta != true and source in (None, \"repl_main\") and message.content has text`.\n- Counts: 22,491 REPL prompts across 30 days → avg **726 prompts\u002Fday**, in 6,519 distinct sessions.\n- Skipping the `source` filter inflates to ~240,000 rows over the same window — >10× too high.\n\nDistinct sessions per day is a useful second axis: `obj[\"sessionId\"]` is populated on every row. Today (2026-07-21) showed 299 distinct sessions for 542 prompts — high concurrency (multiple parallel agent invocations).\n\n## Pitfall 3 — Codex JSONL schema is `event_msg` + inner `payload.type`, not what ccusage-codex says\n\n`~\u002F.codex\u002Fsessions\u002F**\u002Frollout-\u003Ctimestamp>-\u003Cuuid>.jsonl` looks like:\n\n```json\n{\"timestamp\":\"2026-06-03T19:19:05.123Z\",\"type\":\"session_meta\",\"payload\":{\"id\":\"...\"}}\n{\"timestamp\":\"...\",\"type\":\"event_msg\",\"payload\":{\"type\":\"task_started\"}}      \u002F\u002F 1 per Codex CLI invocation\n{\"timestamp\":\"...\",\"type\":\"event_msg\",\"payload\":{\"type\":\"user_message\"}}       \u002F\u002F 1 per user prompt\n{\"timestamp\":\"...\",\"type\":\"event_msg\",\"payload\":{\"type\":\"agent_message\"}}     \u002F\u002F 1 per assistant turn\n{\"timestamp\":\"...\",\"type\":\"response_item\",\"payload\":{\"type\":\"message\"}}        \u002F\u002F not a turn event\n{\"timestamp\":\"...\",\"type\":\"response_item\",\"payload\":{\"type\":\"function_call\"}}\n{\"timestamp\":\"...\",\"type\":\"event_msg\",\"payload\":{\"type\":\"token_count\"}}\n```\n\n**Bucketing rule:** use the inner `obj[\"timestamp\"]` (ISO 8601 with `Z` suffix) and convert to local date. **Do NOT use file mtime** — sessions get archived\u002Frotated, so the mtime reflects when the file was last touched, not when the events occurred. Observed drift: a session that ran 2026-07-19 had its JSONL mtime 2026-07-20 because the file was finalized the next day.\n\n**Request count definitions:**\n- `event_msg.payload.type == \"user_message\"` = 1 user prompt (analog to Claude REPL prompt) — **30-day total 11,476** for this user, avg **370\u002Fday**.\n- `event_msg.payload.type == \"agent_message\"` = 1 assistant turn. Inflated by tool-call round-trips: 30-day total **125,940** — ~11× user-prompt count.\n- `event_msg.payload.type == \"task_started\"` = 1 Codex CLI invocation (analog to Claude `sessionId`): **30-day total 12,145**.\n\nPick `user_message` for the \"requests per day\" column; it's the closest analog to \"I typed a thing into a CLI today\".\n\n## The script (canonical, run this — don't hand-type the JSONL parsing)\n\n`scripts\u002Fdaily_usage_audit.py` does all three pulls, joins by local-date, prints a single Markdown table plus 30-day totals. It runs in ~70 seconds on this machine with the typical log volume. Re-run it on any ask of the form \"daily AI usage\" — no human retyping required.\n\n```bash\npython3 ~\u002F.hermes\u002Fskills\u002Fdevops\u002Fcli-usage-audit\u002Fscripts\u002Fdaily_usage_audit.py --days 14\n```\n\nOutput shape:\n```\nDATE        HERMES     HERMES $   CLAUDE PROMPTS   CLAUDE SESSIONS   CODEX PROMPTS   CODEX AGENT-MSG\n2026-07-21   2,887    $  25.52            542              299             283             990\n...\n\n=== 30-day totals ===\n  Hermes            : 181,212 requests   $597.67   -> 5,846\u002Fday\n  Claude Code REPL  :  22,491 prompts         $0   ->   726\u002Fday  (in 6,519 distinct sessions)\n  Codex session entr.: 11,476 user_prompts   $0   ->   370\u002Fday\n```\n\n## When the user asks a narrower question\n\n| User asks for | Recipe | Notes |\n|---|---|---|\n| \"how many requests do I do daily\" | full 3-column audit | this skill |\n| \"Hermes-only\" \u002F \"gateway only\" | `ccusage hermes daily --since SINCE --json` | 5–10s, reliable, has both msg + cost |\n| \"Claude Code tokens\" | `ccusage claude daily --since SINCE --json` | slow (~8min for 30d, 180s timeout hits often); schema is tokens\u002F$ aggregated across all agents under `metadata.agents` |\n| \"Codex tokens\" | `ccusage-codex daily --since SINCE --json` | slow, schema `{date, totalTokens, costUSD, models:{...}}` |\n| \"what models did I use\" | `ccusage hermes daily --json` → `modelsUsed` field | gives the model roster |\n| \"am I over my rate limit\" | out of scope — use `verify-telemetry-alert` skill |\n\nIf the user wants **just Hermes** or **just one CLI**, skip the JSONL parses and run only the `ccusage \u003Cagent>` subcommand. Hermes comes back in ~5s.\n\n## Companion skills\n\n- `context-token-audit` — single-session context composition (different concern: how big is THIS conversation, not how much did I send across all sessions).\n- `gcp-cost-diagnosis-bq-billing-export` — same shape for cloud bills (BQ billing export vs local JSONLs). Parallel class.\n- `mac-di[REDACTED_OPENAI_KEY]` — parallel class for filesystem usage.\n- `swap-hermes-provider` — when a daily-usage report reveals the user is overspending on a specific model tier.\n\n## Support files\n\n- `scripts\u002Fdaily_usage_audit.py` — the canonical 3-source extractor. Run this; don't re-derive.\n- `references\u002F2026-07-21-ai-usage-tracker-js-schema-bug.md` — first documented instance of the wrapper's empty-output bug + the JSONL `source` filter discovery.\n- `references\u002Fcodex-session-schema.md` — full Codex rollout JSONL schema reference + per-event-type meanings.\n\n## Reporting findings (template)\n\n```\n? **AI CLI daily usage — last 14 days**\nDATE        HERMES     HERMES $   CLAUDE   CODEX   | daily notes\n2026-07-21   2,887    $25.52      542     283    | \u003C-- today\n...\n\n? 30-day totals:\n• Hermes:       181,212 requests, $597.67, avg 5,846\u002Fday\n• Claude Code:   22,491 REPL prompts, 6,519 sessions, avg 726\u002Fday\n• Codex:         11,476 user prompts, avg 370\u002Fday (avg ~11× tool-call round-trips)\n\nPeak: 2026-06-23 — 15,298 Hermes requests, $44.32\n```\n\nAlways include the raw JSON paths (`\u002Ftmp\u002Fccusage_*.json` if you generated them) so the user can re-run \u002F cross-check.",{"name":5,"description":7},"main","42ccd02cbf5e8e47839dc3eab6fc754dc6b339cf","hermes\u002Fskills\u002Fdevops\u002Fcli-usage-audit",0,"https:\u002F\u002Fgithub.com\u002Fjleechanorg\u002Fjleechan-skills","https:\u002F\u002Fgithub.com\u002Fjleechanorg","2026-11-11 22:19:36",{"source":8,"skillName":5,"commands":63,"prompt":73,"zipAvailable":74},[64,67,70],{"tool":65,"command":66},"npx","npx skills add jleechanorg\u002Fjleechan-skills --skill cli-usage-audit",{"tool":68,"command":69},"bunx","bunx skills add jleechanorg\u002Fjleechan-skills --skill cli-usage-audit",{"tool":71,"command":72},"pnpm","pnpm dlx skills add jleechanorg\u002Fjleechan-skills --skill cli-usage-audit","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fjleechanorg\u002Fjleechan-skills\u002Fblob\u002Fmain\u002Fhermes\u002Fskills\u002Fdevops\u002Fcli-usage-audit\u002FSKILL.md",true,[],[77,94,116,130,144,159],{"skillNo":78,"name":79,"nameZh":6,"description":80,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":81,"categories":82,"keywords":83,"publishedAt":50},"01M716Y5MTJ6GYJZ2ATXCJK8G4","instinct","Use when the user invokes \u002Finstinct or \u002Fin, or asks to \"message Instinct\", \"ask Instinct\", \"tell Instinct\", \"check Instinct\", or read replies from the configured peer assistant. iMessage first, WhatsApp Web as fallback.","https:\u002F\u002Fgithub.com\u002Fjleechanorg\u002Fjleechan-skills\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Finstinct\u002FSKILL.md",[],[79,84,33,85,86,87,88,89,90,91,92,93],"user","replies","check","use","identity","whatsapp","gmail","read","message","ask",{"skillNo":95,"name":96,"nameZh":6,"description":97,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":98,"categories":99,"keywords":105,"publishedAt":50},"01M716Y4HF7FVVMJSA2CCVN5VF","hr","Compatibility alias for history-resume; produce the same fresh-state, provenance-aware resume briefing.","https:\u002F\u002Fgithub.com\u002Fjleechanorg\u002Fjleechan-skills\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fhr\u002FSKILL.md",[100],{"categoryNo":101,"categoryName":102,"taxonomyType":103,"taxonomyTypeDesc":104},"01JBSEEDCAT000000000000038","人力资源","PROFESSION","适用职业",[96,106,107,108,109,110,111,112,113,114,115],"resume","compatibility","provenance","for","history","produce","alias","briefing","state","fresh",{"skillNo":117,"name":118,"nameZh":6,"description":119,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":120,"categories":121,"keywords":123,"publishedAt":50},"01M716Y1FFNFKFJYYKF8HQA6T8","history-resume","Resume briefing for the current repository branch or worktree using fresh state and admitted history sources.","https:\u002F\u002Fgithub.com\u002Fjleechanorg\u002Fjleechan-skills\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fhistory-resume\u002FSKILL.md",[122],{"categoryNo":101,"categoryName":102,"taxonomyType":103,"taxonomyTypeDesc":104},[110,106,124,125,84,126,113,127,109,128,129,114,115],"history resume","branch","analysis","repository","worktree","sources",{"skillNo":131,"name":132,"nameZh":6,"description":133,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":134,"categories":135,"keywords":136,"publishedAt":50},"01M716XWXJ8EPHK4RH9T14TR85","grok","Alias for the canonical grokbot browser conversation workflow; \u002Fgrok talks to the Grok bot the same way \u002Fdot talks to Dot.","https:\u002F\u002Fgithub.com\u002Fjleechanorg\u002Fjleechan-skills\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fgrok\u002FSKILL.md",[],[132,137,138,139,109,140,112,141,142,143],"dot","bot","workflow","canonical","conversation","browser","grokbot",{"skillNo":145,"name":146,"nameZh":6,"description":147,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":148,"categories":149,"keywords":150,"publishedAt":50},"01M70N9Q07DTE0EW5KFXMMMSJ0","codexa-bench","Compare `codexa` and normal `codex` on a fair split of comparable work by default; use `--strict` for duplicate runs of the exact same task.","https:\u002F\u002Fgithub.com\u002Fjleechanorg\u002Fjleechan-skills\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fcodexa-bench\u002FSKILL.md",[],[151,152,153,87,154,109,155,156,157,158,48],"codexa bench","work","split","default","duplicate","task","compare","normal",{"skillNo":160,"name":161,"nameZh":6,"description":162,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":163,"licenseFileUrl":164,"sourceHtmlUrl":165,"categories":166,"keywords":178,"publishedAt":50},"01M6C24S2X60SP8BBFGAEKPEGW","frontend-design","Create distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, artifacts, posters, or applications (examples include websites, landing pages, dashboards, React components, HTML\u002FCSS layouts, or when styling\u002Fbeautifying any web UI). Generates creative, polished code and UI design that avoids generic AI aesthetics.","Apache-2.0","https:\u002F\u002Fgithub.com\u002Fjleechanorg\u002Fjleechan-skills\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Ffrontend-design\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002Fjleechanorg\u002Fjleechan-skills\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Ffrontend-design\u002FSKILL.md",[167,172,175],{"categoryNo":168,"categoryName":169,"taxonomyType":170,"taxonomyTypeDesc":171},"01JBSEEDCAT000000000000009","前端开发","SCENARIO","使用场景",{"categoryNo":173,"categoryName":174,"taxonomyType":170,"taxonomyTypeDesc":171},"01JBSEEDCAT000000000000015","视觉设计",{"categoryNo":176,"categoryName":177,"taxonomyType":103,"taxonomyTypeDesc":104},"01JBSEEDCAT000000000000032","设计师",[179,180,181,87,182,183,184,84,185,186,45,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,33,202],"frontend","design","frontend design","generic","ui design","react","html","components","artifacts","ui","aesthetics","Production","web components","landing","applications","quality","web","css","create","examples","with","react components","web ui","pages"]