Meow Ops is the local inbox for AI coding work. It shows what happened, what it cost, and what you should decide next.
Meow Operations turns local Claude Code, OpenAI Codex Desktop, Aider, Cursor, Hermes, and Google Antigravity activity into an installable PWA. Five surfaces: Today, Review, Ledger, Sanctum, Learn. The focus timer sits on every screen as a chip. Companion is gone. Nothing applies until you say so. No required account. No telemetry. MIT-licensed.
The sidebar is five words: Today, Review, Ledger, Sanctum, Learn. The focus timer is a chip on every screen. Companion is removed.
Learn mines concepts from sessions you already ran. Each card has a name, a short industry technical summary, a layman "what you did" line, a source, and an I get this mark. You search YouTube yourself. No school, no XP.
Today answers what happened. Review holds proposals until you approve them. Ledger holds spend. Sanctum and Learn are the two rooms that stayed.
- Node.js 18+ — check with
node --version - npm (comes with Node) or pnpm
- Claude Code installed and used at least once (your sessions live in
~/.claude/projects/)
git clone https://github.com/merak3i/meow-ops.git
cd meow-ops
npm install
node sync/export-local.mjs # parses ~/.claude/projects → public/data/sessions.json
npm run dev # opens http://localhost:5173That's it. Your real session data loads on first page hit.
- Open
http://localhost:5173in Chrome - The dashboard loads your parsed local sessions immediately
- Codex Desktop sessions are read from
~/.codex/sessions/automatically when present - To add Aider sessions:
AIDER_PROJECTS=/path/to/your/project node sync/export-local.mjs - Cursor agent transcripts are read from
~/.cursor/projectswhen present. Optional Enterprise usage enrichment: setCURSOR_ADMIN_API_KEY(never commit it) - Re-run the sync command any time after new AI sessions to refresh
Every parsed session is preserved in an uncapped, append-only local archive. The
generated sessions.json file is only a bounded browser compatibility preview;
it defaults to the latest 1,000 sessions so older browsers and static tooling
stay responsive. Change the preview size with:
MEOW_SESSION_PREVIEW_LIMIT=2000 node sync/export-local.mjsAll-time totals and date-range queries use the complete archive and its
summaries, not the compatibility preview. MEOW_MAX_SESSIONS remains accepted
as a legacy alias for the preview limit; it is not a retention setting.
Run locally, then in Chrome: address bar → install icon (⊕) → the dashboard installs to your dock or desktop. Works offline via service worker.
For a hosted shell that still reads local data from the same machine, see the Hosted shell (still local-only for session data) section below.
Developers using AI tools — Claude, GPT-4o, Gemini, Codex, Cursor, Aider — spend hundreds of dollars a month on tokens with almost no visibility into what they got for it. Not cost-per-model. Not which project burns the most. Not whether a session actually shipped something or just spun its wheels.
As workflows get more layered, it also gets harder to see what is verified, what is assumed, and what still needs review.
The tools that do exist count tokens. None of them:
- Tell you what those tokens produced
- Work across multiple AI models in one view
- Let you watch your agents operate in real time
- Make any of it fun to look at
Meow Operations fixes all four. For free. For everyone.
Tracks sessions from Claude Code, OpenAI Codex Desktop, Aider, Cursor, and Google Antigravity in one unified view. Cost tables for 30+ models.
Google Antigravity note: Antigravity stores session time, tools, and project locally (parsed from
~/.gemini/antigravity/brain/<id>/.system_generated/logs/transcript.jsonl), but it does not expose token counts, the model used, or cost on disk — the conversation store is encrypted and usage lives server-side. Antigravity sessions are therefore tracked for time/tools/project and shown withusage_available: false; tokens and cost are never fabricated or estimated for them.
Cursor note: Local agent transcripts under
~/.cursor/projects/*/agent-transcripts/expose messages, tools, and parent/subagent hierarchy. They do not expose authoritative model, token, or cost values. meow-ops never infers a historical model from the currently selected Cursor model, and never treats a nested Task argument such asmodel="fast"as the parent model. Optional official enrichment usesPOST /teams/filtered-usage-eventswhen a team administrator setsCURSOR_ADMIN_API_KEY. Cursor's published response schema currently documents model, token, and cost fields but not a conversation or cloud-agent identifier. If the API explicitly returns a known conversation/cloud-agent id variant, it joins only on exact equality with a local id. Otherwise, usage stays incost-summary.jsonas aggregate Cursor usage and is never assigned to a session. The credential is never logged, exported, or written to disk. Without a key, the local parser still works.
Safe activation is owner-operated: open the Cursor dashboard, go to Settings → Cursor Admin API Keys, and stop if your account does not expose that team-admin surface. Create/copy the key yourself, then place CURSOR_ADMIN_API_KEY=<YOUR_KEY> in this repository's gitignored .env using a local text editor. Never paste the key into chat, Terminal history, issues, commits, screenshots, or generated data. Re-run node sync/export-local.mjs; verify only the non-secret cursorUsage.status, matched_sessions, and unmatched fields in public/data/cost-summary.json. Ledger displays unmatched totals separately and never attributes them to a local session.
| Surface | What you see |
|---|---|
| Today | Sessions, tokens, cost, and where the work went. Tabs: Summary, Sessions, Runs. |
| Review | Pending proposals and project evidence. Nothing applies until you say so. Tabs: Inbox, Projects, Map. |
| Ledger | Spend, tokens, and unattributed provider usage. |
| Sanctum | The same runs as a 3D scene. |
| Learn | Concepts you already practiced, mined from your sessions. Name, technical summary, what you did, source, I get this. |
The focus timer is a chip on every screen, not a page. Companion is removed from the product.
Learn is a concept map inferred from real sessions. Each card has a name, a short industry technical summary, a layman "what you did", a source, and an I get this mark. No YouTube finder, no school, no XP, no workshop.
When more than one source has data, Today shows a source split:
- Sessions, tokens, and cost per source
- Ghost rate per source
- Filter the view to one source from the page
Ledger is the place for unmatched provider usage that cannot be joined to a local session.
Codex Desktop support is first-class, not a CSV import. sync/parse-codex.mjs walks:
~/.codex/sessions/YYYY/MM/DD/rollout-<timestamp>-<uuid>.jsonl
It extracts rollout ID, project path, model family, token totals, tool calls, first user-message snippet, session title from session_index.jsonl when available, and estimated model cost. Malformed historical rows are skipped instead of blocking the export.
When Claude Code runs with subagents, meow-ops turns the session tree into a Gantt timeline showing exactly what ran in parallel vs. sequentially:
Run: storefront-redesign — 3 agents — $0.84 — 12m ago
⏱ 10:32:14 ───────────────────────────── 10:34:57 IST
├── 📐 Sonnet code-explorer ████████████ 47s $0.12
├── 📐 Sonnet code-architect ███████████████████ 1m42s $0.51
└── 🔍 Haiku code-reviewer ████████ 38s $0.09
⚡ 14,200 tok/$ (efficiency index)
Click any row for a full breakdown: token split, cache hit rate, tool usage, sidechain flag.
A 3D Dalaran-style multi-agent pipeline visualizer for local session data. Watch agent runs, token flow, latency, and session health traverse the network as animated runestones along glowing ley lines.
Argent Vanguard ──────────── Ebon Blade Scout ──────────── Dalaran Archmage ──── Argent Herald
[active] healthy ley [active] choked ley [active] [idle]
$0.0009 $0.0041 $0.0223 $0.0003
112ms 1480ms 3240ms 58ms
Features:
- Four champion node types with distinct sigils and accent colors
- Ley line health states:
healthy(fast flow),choked(slow flow),severed(flickering) - Animated runestones travel along ley line paths carrying JSON/text/error payloads
- Click any runestone to open a Loot Box modal showing full payload, token count, and latency
- WebGL plaza scene with performance guardrails, minimap, Lich King custodian, and LLM Sun token emitter
- Demo mode and local-session mode with no Supabase account required
- Supabase Realtime schema remains available for external pipelines in
db/migrations/0003_scrying_sanctum.sql
See db/migrations/0003_scrying_sanctum.sql for the full schema and RLS policies.
Review Map is the read-only topology and evidence view for loop-based workflows. It imports a workbook or workflow spec, builds the hierarchy on top of it, and renders the result as an interactive React Flow canvas. Review Inbox is the owner-governed change surface.
Use it when a loop matters more than a single run:
- Check the shape of the loop before execution starts.
- Open any node to see ownership, access, last verified state, and what remains unverified.
- Keep review and refresh local while the source spec changes.
- Compare recorded runs with current cost and evidence.
- Keep unverified items clearly labeled until evidence appears.
Main Coordinator
┌──────────┬──────┴───────┬─────────────┐
Research Dir Build Dir Review Dir Ops Dir
┌──┬──┐ ┌──┬──┐ ┌──┬──┐ ┌──┐
W1 W2 … W3 W4 … W5 W6 … W7 …
[review] [covered] [passed] [blocked]
Review Map lives under Review · Map. It is the same inbox as a graph.
What it shows:
- Excel workbook importer with fail-loud validation. Unknown groups, duplicate keys, missing columns, or secret-shaped content stop the import with named violations.
- Collapsible wave clusters keep dense lanes readable. Minimap, keyboard access, light and dark theme, and reduced-motion support stay on.
- Every node answers four questions: what owns this, what it can touch, last verified state, and what was not verified.
- Inspector shows workflow-spec knobs, guardrails, eval gates, and copyable validation commands. Review Map never executes anything itself; execution is a separate Review Inbox action that requires approval.
- Run timeline joins recorded loop runs against real session costs. An empty evidence list stays suspicious.
- Permanent "production writes disabled" badge. The alarm branch wears red, never the safe green.
- All loop data is local-only, and the hosted demo intentionally shows the instructional empty state.
Local API endpoints (sync/local-api.mjs): GET /loop-ops/spec|status|runs, POST /loop-ops/sync re-runs the importer. Import manually with node sync/loop-ops-import.mjs.
Loop Engineering is the review loop around the agents: capture what happened, turn recurring friction into small proposals, let the owner decide, and measure the next run. It is designed to improve the workflow without letting automation approve itself.
The local pipeline can:
- Capture loop runs and compare them against prior evidence.
- Intake content-free summaries from Claude, Codex, Antigravity, and optional screenshots.
- Mine recurring failures, wasted work, high-friction task types, and automation-health drift.
- Generate deterministic proposals, optionally enrich drafts with a bounded local/DeepSeek model call, and produce a daily digest with history.
- Route decisions through Review Inbox. Nothing applies until you say so.
- Execute only an approved, actionable proposal, with evidence recorded back to the local ledger.
Commands:
npm run loop:capture -- --loop <LOOP_ID> --since <ISO_TIME>
npm run intake
npm run digest
npm run daily
npm run loop:propose
npm run loop:review
npm run loop:simulate -- --proposal <PROPOSAL_ID>
node sync/local-api.mjs
npm run devnpm run loop:review runs the local sync tests, evals, lint, typecheck, and build. It writes only check IDs and exit codes outside the worktree, then creates review-only Inbox drafts for failures; raw terminal output is never stored. Include browser coverage when needed with npm run loop:review -- --with-e2e.
Open http://localhost:5173/#/review/inbox for the owner surface. The optional executor runs an approved proposal in a temporary detached git worktree, applies the proposed diff, runs npm ci, npm run test:sync, npm run eval, and npm run build, then either records a dry-run or, in push mode, creates an executor/<proposal-id> branch and pull request. Only the hard-coded test and prompt categories may auto-merge after green PR checks; privacy, security, money, client-data, and production-infrastructure paths are forced to review-only.
Guarantees:
- Assistants can only create drafts. They cannot self-approve.
- Owner approvals happen through Review Inbox or the nonce-protected local API.
- Every ledger write goes through
appendRecord(), field allowlists, validators, and redaction checks. - The ledger lives outside the git worktree at
~/.meow-ops/loop-ledger/. - Real session data, secrets, local paths, and transcript content do not belong in tracked fixtures or PRs.
- Expired drafts are marked by
system:expire, leave the active queue, and stay visible under the expired filter.
The Excel workbook is the structure (which surfaces exist). The live truth states (which gate passed, the db status, last-verified time) come from a Supabase table — e.g. one an upstream system keeps current. They join through the importer's existing truth CSV, so nothing in the importer changes:
Supabase table → sync/loop-ops-supabase.mjs → truth.csv → loop-ops-import.mjs --truth → spec.json → Review Map
(live state) (this connector, opt-in) (local) (joins Excel + truth) (local) (renders)
The connector is opt-in and a no-op until configured (set LOOP_OPS_SUPABASE_URL/_KEY/_TABLE in .env; remap differing column names with LOOP_OPS_SUPABASE_COLMAP). Each row is keyed by surface_key — the same key the workbook uses. Only the cloud pull needs network; the importer, spec.json, and Review Map stay fully local/offline.
Three ways to keep it synced:
| Cadence | How | Freshness |
|---|---|---|
| Manual | node sync/loop-ops-supabase.mjs && node sync/loop-ops-import.mjs --truth public/data/loop-ops/truth.csv (or Review Map Refresh after a pull) |
on demand |
| Near-real-time (pull) | run that pair on a launchd / GitHub Actions cron every N minutes |
minutes |
| Real-time (push) | node sync/loop-ops-supabase-watch.mjs — subscribes to Supabase Realtime (postgres_changes) and regenerates on every table change |
seconds |
The real-time watcher needs Realtime enabled on the table: ALTER PUBLICATION supabase_realtime ADD TABLE <your_table>;.
Seats (hidden)
A local-first SuperAdmin cockpit for the operator's software stack: GitHub Actions run volume, cache and artifact footprint, SaaS subscription run rate, renewal pressure, and source wiring for private usage ledgers. Reachable from the command palette, not the sidebar.
The public build ships a generic demo screen. Real account usage stays local in public/data/superadmin-usage.json, which is gitignored. Refresh it with:
npm run sync:superadminOptional environment:
MEOW_SUPERADMIN_GITHUB_REPOS=merak3i/meow-ops,<REPO_OWNER>/<REPO_NAME>
MEOW_SUPERADMIN_USAGE_SNAPSHOT=/absolute/path/to/superadmin-usage.json
MEOW_GITHUB_ACTIONS_MINUTES_LIMIT=3000
MEOW_GITHUB_ACTIONS_STORAGE_GB_LIMIT=10The exporter accepts a local JSON snapshot shaped as [{...}], { "services": [...] }, { "rows": [...] }, or { "saas": { "services": [...] } }. Service-role keys and provider tokens do not belong in the snapshot.
A native-feeling menu bar widget can request a background sync through the same observable runner used by the dashboard. Install the persistent helper and the single daily operator job with:
npm run agents:installThe installer renders paths for the current clone, keeps logs under ~/Library/Logs/meow-ops/, removes the retired duplicate hourly jobs, keeps com.meowops.localapi alive, and runs com.meowops.daily once at 08:30 local time.
For a hosted dashboard that can trigger sync from the browser, run the local API on your machine:
node sync/local-api.mjs # export local data (no git push — that is retired)It listens on http://localhost:7337, serves fresh local sessions.json and cost-summary.json, and exposes asynchronous POST /sync, GET /sync/status, and GET /sync/runs/:id. A POST returns 202 with a run ID; the UI then follows preflight → export sessions → verify artifacts → refresh limits. Failures remain visible with a sanitized phase, code, and retry hint. Runtime metadata lives outside the worktree at ~/.meow-ops/runtime/. This process reads only local files on your machine and never pushes to git. Requests are restricted to localhost; if you call it from a hosted dashboard URL, allowlist that origin with MEOW_DASHBOARD_ORIGIN (see .env.example).
Every session is auto-tagged by tool usage profile:
| Type | Trigger | Meaning |
|---|---|---|
| 🏗️ Builder | >40% Write + Edit | Heavy coding/writing |
| 🔍 Detective | >50% Read + Grep + Glob | Code exploration |
| 💻 Commander | >40% Bash | Shell/system work |
| 📐 Architect | >20% Agent + PlanMode | Planning/orchestration |
| 🛡️ Guardian | Top tool is Grep/Read | Audits and reviews |
| 📝 Storyteller | Top tool is Write | Docs and content |
| 👻 Ghost | <3 messages or no tools | Empty session |
30+ models with accurate pricing:
| Family | Models |
|---|---|
| Claude | Opus 4, Sonnet 4.6, Sonnet 4.5, Haiku 4.5 |
| OpenAI | GPT-4o, GPT-4o-mini, GPT-5, o3, o4-mini |
| DeepSeek | V3, R1, R1-0528 |
| Qwen | Max, Plus, Turbo (Alibaba DashScope) |
| Moonshot | Kimi K2 |
| Zhipu | GLM-4, GLM-4-Flash (free) |
| ByteDance | Doubao-Pro |
| xAI | Grok-3, Grok-3-mini, Grok-2 |
| Cohere | Command R+, Command R |
| Amazon | Nova Pro, Nova Lite, Nova Micro |
| Gemini 3 Pro, 3 Flash, 2.5 Pro, 2.5 Flash, 2.0 Flash, 1.5 Pro, 1.5 Flash | |
| Mistral | Large, Small |
| Perplexity | Sonar Pro, Sonar |
| Local | Llama 3.3-70B (cost = $0) |
Unknown variants match by family fuzzy search.
sync/export-local.mjs is the source of truth for generated dashboard data.
It currently:
- Reads Claude Code JSONL files from
~/.claude/projects/ - Reads Codex Desktop rollouts from
~/.codex/sessions/ - Reads Google Antigravity transcripts from
~/.gemini/antigravity/(time/tools/project only; usage not exposed by Antigravity) - Reads Cursor agent transcripts from
CURSOR_PROJECTS_DIRor~/.cur





0 comments
log in to comment.