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
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -577,6 +577,7 @@ jobs:
tests/test_tab_template_page_wrapper.py \
tests/test_grok_bot_runtime_wiring.py \
tests/test_lovable_runtime_wiring.py \
tests/test_muse_code_runtime_wiring.py \
tests/test_delegated_usage.py \
tests/test_local_query_api.py \
tests/test_harness_audit_reads_whole_adapter.py \
Expand Down
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
> **Read [`FLYWHEEL.md`](./FLYWHEEL.md) first.** It is how you ship a change end to end in this repo (code → PR → green CI → `[RELEASE]` → PyPI → cloud → verified live) and the non-negotiable "done" bar. Then [`CLAUDE.md`](./CLAUDE.md) for the architecture deep-dive. This file is the short "what to do"; those two carry the detail.

## Quick context
ClawMetry is an open-source, real-time observability and governance layer for **30 AI agent runtimes** (OpenClaw, NemoClaw and Goose free in OSS; Claude Code, Codex, Cursor and 24 more with the Pro plugin). The catalogue is `entitlements.FREE_RUNTIMES | PAID_RUNTIMES`, exported to [`SUPPORTED_RUNTIMES.txt`](./SUPPORTED_RUNTIMES.txt) — the single file every marketing surface and sibling repo reads. Never hardcode the list or the count; regenerate with `python3 scripts/sync_runtime_count.py`. `pip install clawmetry && clawmetry` — zero config, observation by default. It's a Flask app with an embedded, no-build vanilla-JS frontend; a sync daemon ingests filesystem/gateway/OTLP data into a local **DuckDB** store, and the app reads from DuckDB to serve the UI.
ClawMetry is an open-source, real-time observability and governance layer for **31 AI agent runtimes** (OpenClaw, NemoClaw and Goose free in OSS; Claude Code, Codex, Cursor and 25 more with the Pro plugin). The catalogue is `entitlements.FREE_RUNTIMES | PAID_RUNTIMES`, exported to [`SUPPORTED_RUNTIMES.txt`](./SUPPORTED_RUNTIMES.txt) — the single file every marketing surface and sibling repo reads. Never hardcode the list or the count; regenerate with `python3 scripts/sync_runtime_count.py`. `pip install clawmetry && clawmetry` — zero config, observation by default. It's a Flask app with an embedded, no-build vanilla-JS frontend; a sync daemon ingests filesystem/gateway/OTLP data into a local **DuckDB** store, and the app reads from DuckDB to serve the UI.

## Where new code goes (open-core split)

Expand Down
4 changes: 2 additions & 2 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
┌──────────────────────────────────────────────────────────────────────┐
│ Your Machine │
│ │
30 agent runtimes ClawMetry │
31 agent runtimes ClawMetry │
│ ┌──────────────────┐ ┌───────────────────────────────────┐ │
│ │ OpenClaw │ files │ Sync daemon (clawmetry sync) │ │
│ │ Claude Code │───────►│ • reads sessions, logs, hooks │ │
Expand Down Expand Up @@ -96,7 +96,7 @@ C4Context
title C1: ClawMetry (open source) system context

Person(dev, "Developer / Operator", "Runs AI agents; wants to see what they do, what they cost, and to stop one that has gone wrong")
System(clawmetry, "ClawMetry", "Local-first observability and governance for 30 agent runtimes. Reads what your agents already write; acts on them only through the five gated surfaces above.")
System(clawmetry, "ClawMetry", "Local-first observability and governance for 31 agent runtimes. Reads what your agents already write; acts on them only through the five gated surfaces above.")

System_Ext(runtimes, "AI Agent Runtimes", "OpenClaw, NVIDIA NemoClaw and Goose are free in OSS; the other 27 (Claude Code, Codex, Cursor, Copilot, Gemini CLI, Hermes, Aider, opencode, ...) come with the optional Pro plugin")
System_Ext(gateway, "OpenClaw Gateway", "WebSocket control plane (JSON-RPC, :18789) for live data + cron RPC")
Expand Down
2 changes: 1 addition & 1 deletion AUDIT.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
## Audit method (the only valid "pass")
1. Walk the trial path: hosted dashboard as a trial user, switch runtimes, click the tab → zero blank/wrong/error states + clean console.
2. For data/observability features: send a **real** message/turn and watch it travel channel → daemon → DuckDB → handler → rendered tab → (cloud) snapshot.
3. Verify across **all 30 runtimes**, not just OpenClaw (`/api/runtimes`).
3. Verify across **all 31 runtimes**, not just OpenClaw (`/api/runtimes`).
4. For device-facing slices: the 4-repo chain (pro adapter → OSS `_build_device_summary` → cloud wheel/relay → firmware render).

---
Expand Down
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
> **Read [`FLYWHEEL.md`](./FLYWHEEL.md) first.** It is how you ship a change end to end here (code → PR → green CI → `[RELEASE]` → PyPI → cloud → verified live) and the non-negotiable "done" bar. This file is the architecture reference; FLYWHEEL.md is the shipping loop.

## What is this?
ClawMetry is an open-source, real-time observability and governance layer for **30 AI agent runtimes** — [OpenClaw](https://github.com/openclaw/openclaw), NVIDIA NemoClaw and Goose free in OSS, the other 27 (Claude Code, Codex, Cursor, Copilot, Gemini CLI, Hermes, Aider, opencode, ...) with the optional Pro plugin. **Never type that number or that list anywhere new: [`SUPPORTED_RUNTIMES.txt`](./SUPPORTED_RUNTIMES.txt) is the generated single source every surface derives from** (`python3 scripts/sync_runtime_count.py`; `--check` fails CI on drift). `pip install clawmetry && clawmetry` — that's it. Zero config, observation by default.
ClawMetry is an open-source, real-time observability and governance layer for **31 AI agent runtimes** — [OpenClaw](https://github.com/openclaw/openclaw), NVIDIA NemoClaw and Goose free in OSS, the other 28 (Claude Code, Codex, Cursor, Copilot, Gemini CLI, Hermes, Aider, opencode, ...) with the optional Pro plugin. **Never type that number or that list anywhere new: [`SUPPORTED_RUNTIMES.txt`](./SUPPORTED_RUNTIMES.txt) is the generated single source every surface derives from** (`python3 scripts/sync_runtime_count.py`; `--check` fails CI on drift). `pip install clawmetry && clawmetry` — that's it. Zero config, observation by default.

**Never hardcode the runtime count or the runtime list anywhere new.** The authoritative sources are `entitlements.FREE_RUNTIMES | entitlements.PAID_RUNTIMES` (the catalogue, and what every quoted number is derived from) and `sync._FAMILY_ADAPTER_SPECS` (what the daemon actually loads — a `clawmetry-pro` adapter is inert until it is named there). `scripts/sync_runtime_count.py` rewrites the number in prose and CI fails on drift; the same script checks the chat-channel count against `entitlements.ALL_CHANNELS`.

Expand Down
6 changes: 3 additions & 3 deletions FLYWHEEL.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ The north star: **don't stop at "code compiles." Stop at "verified working in pr
> - **Before adding any poller/fetch, ask:** does this need to run on *every* tab? every *N* seconds? can it reuse an existing fetch or the snapshot?
> - **Measure before shipping:** open the Network panel / Resource Timing and confirm no endpoint is fetched N× per cycle and no background poller fires off its own screen. "It works" is not enough — "it works without a request storm" is the bar.

> ## Multi-runtime: ClawMetry observes 30 agent runtimes, not just OpenClaw (non-negotiable)
> **ClawMetry is runtime-neutral. It observes 30 AI agent runtimes, not OpenClaw alone.**
> ## Multi-runtime: ClawMetry observes 31 agent runtimes, not just OpenClaw (non-negotiable)
> **ClawMetry is runtime-neutral. It observes 31 AI agent runtimes, not OpenClaw alone.**
> **[`SUPPORTED_RUNTIMES.txt`](./SUPPORTED_RUNTIMES.txt) is the one list — do not type a second one.**
> It is generated from `FREE_RUNTIMES | PAID_RUNTIMES` in `clawmetry/entitlements.py` and carries every
> runtime's id, display label, free/paid tier and clawmetry.com path, plus the derived count and the
Expand All @@ -47,7 +47,7 @@ The north star: **don't stop at "code compiles." Stop at "verified working in pr
> clawmetry-pro's FLYWHEEL said 22, clawmetry-landing's said 21 and clawmetry-cloud's said 14 — four
> hand-maintained lists, four different numbers, none of them visible to the others' CI.
> - **User-facing copy and UI must never imply OpenClaw-only.** Framing like "designed for OpenClaw agents", "your OpenClaw machine", "No OpenClaw detected", or "Looking for OpenClaw activity" is a bug. Use runtime-neutral language ("your AI agent", "the machine your agent runs on") or name the runtimes ("OpenClaw, NVIDIA NemoClaw + 10 more runtimes", matching the homepage install card). Naming runtimes is public; pricing and tier internals stay private.
> - **Verify across all 30 runtimes, end to end.** Never ship a change verified only on OpenClaw. Use a `/workflow` to fan out a per-runtime E2E check: one agent per runtime that installs or configures it, runs a real turn, and asserts it lands correctly (in Brain by agent_type, in the right tab, with cost and tokens). "Works on OpenClaw" is not "works".
> - **Verify across all 31 runtimes, end to end.** Never ship a change verified only on OpenClaw. Use a `/workflow` to fan out a per-runtime E2E check: one agent per runtime that installs or configures it, runs a real turn, and asserts it lands correctly (in Brain by agent_type, in the right tab, with cost and tokens). "Works on OpenClaw" is not "works".
> Burned 2026-06-01: the docs FAQ said "ClawMetry is designed for OpenClaw agents" and the cloud empty-states plus the radar assumed OpenClaw-only. Many surfaces still need this sweep; when you touch a screen, fix its runtime framing.

---
Expand Down
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ reads the session files your coding agents already write, and puts the timeline,
the tool calls and whatever token and cost data the runtime exposes into one
view — so you can tell a long run that is working from one that is stuck.

Works with **30 AI agent runtimes** — Claude Code, OpenAI Codex, Hermes, OpenClaw & 26 more. One dashboard for your whole agent fleet. ([the full list](SUPPORTED_RUNTIMES.txt), generated from the catalogue.)
Works with **31 AI agent runtimes** — Claude Code, OpenAI Codex, Hermes, OpenClaw & 27 more. One dashboard for your whole agent fleet. ([the full list](SUPPORTED_RUNTIMES.txt), generated from the catalogue.)

> 🌐 **Read this in:** [English](README.md) · [简体中文](docs/i18n/zh-CN/README.md) · [日本語](docs/i18n/ja/README.md) · [한국어](docs/i18n/ko/README.md) · [Español](docs/i18n/es/README.md) · [Português (BR)](docs/i18n/pt-BR/README.md) · [Français](docs/i18n/fr/README.md) · [Deutsch](docs/i18n/de/README.md) · [हिन्दी](docs/i18n/hi/README.md) · [العربية](docs/i18n/ar/README.md) · [Русский](docs/i18n/ru/README.md) · [more →](docs/i18n/)

Expand Down Expand Up @@ -44,11 +44,11 @@ says which, per runtime), and observing an action is not the same as being able
to block it ([which controls are real, per runtime](docs/APPROVALS.md)).


## Works with 30 agent runtimes
## Works with 31 agent runtimes

**Free in the open source app:** 🦞 **[OpenClaw](https://clawmetry.com/runtimes/openclaw)** · 🟩 **[NVIDIA NemoClaw](https://clawmetry.com/nemoclaw)** · 🪿 **[Goose](https://clawmetry.com/runtimes/goose)**

**On a paid plan:** ◆ **[Claude Code](https://clawmetry.com/runtimes/claude-code)** · **[Cursor](https://clawmetry.com/runtimes/cursor)** · 🐙 **[GitHub Copilot](https://clawmetry.com/runtimes/copilot)** · ⬡ **[OpenAI Codex](https://clawmetry.com/runtimes/codex)** · ♊ **[Gemini CLI](https://clawmetry.com/runtimes/gemini-cli)** · 💗 **[Lovable](https://clawmetry.com/runtimes/lovable)** · ⠕ **[Replit Agent](https://clawmetry.com/runtimes/replit)** · 🖇 **[Cline](https://clawmetry.com/runtimes/cline)** · 🙌 **[OpenHands](https://clawmetry.com/runtimes/openhands)** · 🧑‍💼 **[OpenWorker](https://clawmetry.com/runtimes/openworker)** · **[opencode](https://clawmetry.com/runtimes/opencode)** · **[Aider](https://clawmetry.com/runtimes/aider)** · 🔗 **[n8n](https://clawmetry.com/runtimes/n8n)** · ◈ **[Qwen Code](https://clawmetry.com/runtimes/qwen-code)** · 🅳 **[Devin](https://clawmetry.com/runtimes/devin)** · 🪐 **[Antigravity](https://clawmetry.com/runtimes/antigravity)** · **[Grok Build](https://clawmetry.com/runtimes/grok)** · 🤖 **[Grok Bot](https://clawmetry.com/runtimes/grok-bot)** · ⚡ **[Hermes](https://clawmetry.com/runtimes/hermes)** · **[Pi](https://clawmetry.com/runtimes/pi)** · **[Deep Agents](https://clawmetry.com/runtimes/deep-agents)** · 🌙 **[Kimi CLI](https://clawmetry.com/runtimes/kimi)** · 🐋 **[DeepSeek Harness](https://clawmetry.com/runtimes/deepseek-harness)** · 🦾 **[Exo](https://clawmetry.com/runtimes/exo)** · **[NanoClaw](https://clawmetry.com/runtimes/nanoclaw)** · **[PicoClaw](https://clawmetry.com/runtimes/picoclaw)** · **[QM](https://clawmetry.com/runtimes/qm)**
**On a paid plan:** ◆ **[Claude Code](https://clawmetry.com/runtimes/claude-code)** · **[Cursor](https://clawmetry.com/runtimes/cursor)** · 🐙 **[GitHub Copilot](https://clawmetry.com/runtimes/copilot)** · ⬡ **[OpenAI Codex](https://clawmetry.com/runtimes/codex)** · ♊ **[Gemini CLI](https://clawmetry.com/runtimes/gemini-cli)** · 💗 **[Lovable](https://clawmetry.com/runtimes/lovable)** · ⠕ **[Replit Agent](https://clawmetry.com/runtimes/replit)** · 🖇 **[Cline](https://clawmetry.com/runtimes/cline)** · 🙌 **[OpenHands](https://clawmetry.com/runtimes/openhands)** · 🧑‍💼 **[OpenWorker](https://clawmetry.com/runtimes/openworker)** · 🎭 **[Muse Code](https://clawmetry.com/runtimes/muse-code)** · **[opencode](https://clawmetry.com/runtimes/opencode)** · **[Aider](https://clawmetry.com/runtimes/aider)** · 🔗 **[n8n](https://clawmetry.com/runtimes/n8n)** · ◈ **[Qwen Code](https://clawmetry.com/runtimes/qwen-code)** · 🅳 **[Devin](https://clawmetry.com/runtimes/devin)** · 🪐 **[Antigravity](https://clawmetry.com/runtimes/antigravity)** · **[Grok Build](https://clawmetry.com/runtimes/grok)** · 🤖 **[Grok Bot](https://clawmetry.com/runtimes/grok-bot)** · ⚡ **[Hermes](https://clawmetry.com/runtimes/hermes)** · **[Pi](https://clawmetry.com/runtimes/pi)** · **[Deep Agents](https://clawmetry.com/runtimes/deep-agents)** · 🌙 **[Kimi CLI](https://clawmetry.com/runtimes/kimi)** · 🐋 **[DeepSeek Harness](https://clawmetry.com/runtimes/deepseek-harness)** · 🦾 **[Exo](https://clawmetry.com/runtimes/exo)** · **[NanoClaw](https://clawmetry.com/runtimes/nanoclaw)** · **[PicoClaw](https://clawmetry.com/runtimes/picoclaw)** · **[QM](https://clawmetry.com/runtimes/qm)**

Every runtime gets the same dashboard. Run several at once and the header
switcher re-scopes every tab to one of them.
Expand Down Expand Up @@ -77,7 +77,7 @@ Two questions worth answering before you trust any agent-comparison tool.
A utilization percentage is only as honest as what it divides by. ClawMetry
sizes the window per provider from [a table you can read and
PR](clawmetry/context_windows.py), covering Anthropic, OpenAI, Google, xAI,
DeepSeek, Kimi, Qwen, Mistral, Llama and GLM. It does not measure all 30
DeepSeek, Kimi, Qwen, Mistral, Llama and GLM. It does not measure all 31
runtimes with one vendor's ruler. That matters: a 300K GPT-5 turn scored
against Anthropic's 200K reads ">100%, blown" when it is really at 75% of
GPT-5's 400K. The same ruler hides a genuinely overflowed 130K DeepSeek turn
Expand All @@ -97,7 +97,7 @@ ClawMetry can only see compaction events on some runtimes. So

| Path | Added to your agent | Default? |
|---|---|---|
| Session-file tailing (all 30 runtimes) | **0**. Separate process, no ClawMetry code in your agent | on |
| Session-file tailing (all 31 runtimes) | **0**. Separate process, no ClawMetry code in your agent | on |
| HTTP interceptor (`CLAWMETRY_INTERCEPT=1`) | **+0.44 ms** per LLM call, or 0.009% of a 5s call | off |
| Pre-tool hook gate (warm cache) | **+44 ms** per gated tool call, over a 36 ms interpreter floor | off |
| Enforcement proxy | **+9.7 ms** per LLM call | off |
Expand Down
7 changes: 4 additions & 3 deletions SUPPORTED_RUNTIMES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@
# (read by the closed-source clawmetry-pro companion). 'landing_path'
# is relative to https://clawmetry.com.

COUNT = 30
COUNT = 31
FREE_COUNT = 3
PAID_COUNT = 27
BLURB = See your agent think. Zero-config observability & governance for 30 AI agent runtimes: Claude Code, OpenAI Codex, Hermes, OpenClaw & 26 more. Live token costs, sessions, tool calls, crons.
PAID_COUNT = 28
BLURB = See your agent think. Zero-config observability & governance for 31 AI agent runtimes: Claude Code, OpenAI Codex, Hermes, OpenClaw & 27 more. Live token costs, sessions, tool calls, crons.

goose Goose free /runtimes/goose
nemoclaw NemoClaw free /nemoclaw
Expand All @@ -48,6 +48,7 @@ grok_bot Grok Bot paid /runtimes/grok-bot
hermes Hermes paid /runtimes/hermes
kimi Kimi CLI paid /runtimes/kimi
lovable Lovable paid /runtimes/lovable
muse_code Muse Code paid /runtimes/muse-code
n8n n8n paid /runtimes/n8n
nanoclaw NanoClaw paid /runtimes/nanoclaw
opencode opencode paid /runtimes/opencode
Expand Down
1 change: 1 addition & 0 deletions clawmetry/behaviour_signals.py
Original file line number Diff line number Diff line change
Expand Up @@ -881,6 +881,7 @@ def _in_prev(d: int) -> bool:
"picoclaw": "PicoClaw", "nanoclaw": "NanoClaw", "antigravity": "Antigravity",
"kimi": "Kimi", "n8n": "n8n", "openhands": "OpenHands", "deepagents": "DeepAgents",
"lovable": "Lovable", "replit": "Replit", "openworker": "OpenWorker",
"muse_code": "Muse Code",
}


Expand Down
4 changes: 2 additions & 2 deletions clawmetry/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -1334,7 +1334,7 @@ def _input(prompt):
from clawmetry.license import auto_provision_pro
_pro_installed, _pro_msg = auto_provision_pro(api_key, node_id)
if _pro_installed:
print(" Pro adapters installed - all 30 runtimes available.")
print(" Pro adapters installed - all 31 runtimes available.")
elif _pro_msg:
# Entitled but the wheel could not be installed right now; surface a
# quiet hint without alarming the user (connect still succeeded).
Expand Down Expand Up @@ -4239,7 +4239,7 @@ def _input(prompt):
print()
print(f" {BOLD('Plans')} {DIM('(same either way; each tier includes the one before):')}")
print(f" {DIM('Free $0 watch OpenClaw + NVIDIA NemoClaw, forever')}")
print(f" {DIM('Starter $9/node/mo everything in Free + observability for all 30 runtimes')}")
print(f" {DIM('Starter $9/node/mo everything in Free + observability for all 31 runtimes')}")
print(f" {DIM('Pro $19/node/mo everything in Starter + governance (alerts, approvals, evals)')}")
print()
print(f" {BOLD('How do you want to run ClawMetry?')}")
Expand Down
2 changes: 2 additions & 0 deletions clawmetry/detector_calibration.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,8 @@
# exclusively through them looks like it made no progress at all. It also
# drives a shell (``run_shell``), which the shell-mutation rule covers.
"openworker": {"write_tools": ("replace_in_file", "apply_unified_diff")},
# Muse Code's edit tools, as named in the toolCall items MSP serves.
"muse_code": {"write_tools": ("edit_file", "write_file", "apply_patch")},
# Replit Agent writes through ``write``/``edit`` (both match the module
# defaults) and shells through ``bash`` (covered by the shell-mutation
# rule) — vocabulary verified against real in-workspace journals (pro
Expand Down
6 changes: 6 additions & 0 deletions clawmetry/entitlements.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,10 @@
# transcript journals into the Repl workspace filesystem, where the
# daemon reads them (in-Repl install or a local clone).
"replit",
# Muse Code (developer.meta.com/ai/products/muse-code) -- Meta's
# terminal coding agent on Muse Spark. NOT the consumer Muse personal
# agent, which runs wholly inside Meta's cloud VM and is unobservable.
"muse_code",
}
)

Expand Down Expand Up @@ -177,6 +181,7 @@
"openworker": "OpenWorker",
"lovable": "Lovable",
"replit": "Replit Agent",
"muse_code": "Muse Code",

}

Expand Down Expand Up @@ -219,6 +224,7 @@
"openworker": "/runtimes/openworker",
"lovable": "/runtimes/lovable",
"replit": "/runtimes/replit",
"muse_code": "/runtimes/muse-code",

}

Expand Down
Loading
Loading