Context
Claude Code has a comprehensive OpenTelemetry telemetry system that exports metrics, events, and traces. Crow already orchestrates Claude Code sessions — we should tap into this telemetry to surface analytics and metrics directly in the Crow UI.
What Claude Code Exposes
Metrics (time-series via OTel Metrics)
| Metric |
What it tells us |
claude_code.cost.usage |
Cost in USD per API request (by model) |
claude_code.token.usage |
Token counts by type: input, output, cacheRead, cacheCreation (by model) |
claude_code.active_time.total |
Active time in seconds (user interaction vs CLI processing) |
claude_code.lines_of_code.count |
Lines added/removed |
claude_code.commit.count |
Git commits created |
claude_code.pull_request.count |
PRs created |
claude_code.session.count |
Session starts |
claude_code.code_edit_tool.decision |
Accept/reject counts for Edit/Write tools |
Events (via OTel Logs)
| Event |
What it tells us |
claude_code.user_prompt |
Each user prompt (length, optional content) |
claude_code.tool_result |
Tool name, success/failure, duration_ms, error details |
claude_code.api_request |
Model, cost_usd, duration_ms, token breakdown, fast/normal mode |
claude_code.api_error |
Error messages, status codes, retry attempts |
claude_code.tool_decision |
Permission accept/reject with source |
Traces (beta — via OTel Traces)
Full distributed traces linking user prompts → API requests → tool executions as spans, giving a complete request waterfall.
Key Attributes Available on All Data
session.id — maps directly to a Crow session
user.account_uuid / user.email — user identity
organization.id — org-level grouping
model — which Claude model was used
prompt.id — correlates all events from a single user prompt
Brainstorm: How Crow Could Use This
1. Embedded OTel Collector
Crow could run a lightweight OTel collector (or just an OTLP HTTP receiver) that Claude Code sessions export to. Crow would set the env vars when launching each session:
CLAUDE_CODE_ENABLE_TELEMETRY=1
OTEL_METRICS_EXPORTER=otlp
OTEL_LOGS_EXPORTER=otlp
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:{crow_port}
Since Crow already controls how Claude Code is launched (via crow new-terminal + crow send), injecting these env vars is straightforward.
2. Per-Session Dashboard
Map session.id to Crow session UUIDs. Show per-session:
- Cost: running total and cost-per-prompt sparkline
- Tokens: input/output/cache breakdown (pie or stacked bar)
- Active time: wall clock vs active time
- Tool usage: most-used tools, success rates, avg execution time
- Lines changed: additions vs removals over time
- Commits / PRs: count with links
3. Cross-Session Analytics
Aggregate across sessions for a higher-level view:
- Daily/weekly cost trends across all sessions
- Model usage distribution (Opus vs Sonnet vs Haiku)
- Most expensive sessions (cost leaderboard)
- Tool error rates — which tools fail most often?
- Avg time-to-first-commit per session
- Cache hit ratios (cacheRead vs input tokens)
4. Real-Time Session Activity Feed
Stream events as they happen:
- Prompt submitted → tool running → API call → result
- Like a live activity log but structured and visual
- Could use the
prompt.id correlation to group related events
5. Cost Alerts / Budgets
- Set a per-session or daily cost budget
- Alert in Crow UI when a session approaches the threshold
- Could pause/flag sessions that exceed limits
6. Session Summary on Completion
When a session completes, auto-generate a summary card:
- Total cost, tokens, active time
- Files changed, commits made, PR created
- Number of prompts, tool calls, errors
Architecture Options
Option A: In-Process OTel Receiver
Crow's Swift app listens on a local port for OTLP (gRPC or HTTP). Parses protobuf/JSON payloads directly. Stores in SQLite or in-memory.
- Pro: No external dependencies, tight integration
- Con: Must implement OTLP protocol parsing
Option B: Sidecar Collector + SQLite
Ship a lightweight OTel collector binary that writes to a local SQLite DB. Crow reads from the DB.
- Pro: Battle-tested OTel collector handles protocol details
- Con: Extra process to manage
Option C: Prometheus Scrape
Use OTEL_METRICS_EXPORTER=prometheus and scrape the /metrics endpoint.
- Pro: Simple, well-understood
- Con: Only gets metrics, not events. Loses the rich event data (tool results, API requests, prompts).
Option D: Console Exporter + Log Parsing
Use OTEL_METRICS_EXPORTER=console and parse stdout from the Claude Code terminal.
- Pro: Zero infrastructure
- Con: Fragile, mixes with regular output, hard to parse reliably
Recommendation: Option A is the cleanest for a native app. OTel's OTLP HTTP/JSON protocol is straightforward to receive — it's just POST requests with a known schema.
Configuration Surface
Crow would need:
- A setting to enable/disable telemetry collection
- Optional: which signals to collect (metrics, events, traces)
- Optional: retention period for stored telemetry data
- The OTLP receiver port (auto-assigned or configurable)
Reference
Success Criteria
Context
Claude Code has a comprehensive OpenTelemetry telemetry system that exports metrics, events, and traces. Crow already orchestrates Claude Code sessions — we should tap into this telemetry to surface analytics and metrics directly in the Crow UI.
What Claude Code Exposes
Metrics (time-series via OTel Metrics)
claude_code.cost.usageclaude_code.token.usageclaude_code.active_time.totalclaude_code.lines_of_code.countclaude_code.commit.countclaude_code.pull_request.countclaude_code.session.countclaude_code.code_edit_tool.decisionEvents (via OTel Logs)
claude_code.user_promptclaude_code.tool_resultclaude_code.api_requestclaude_code.api_errorclaude_code.tool_decisionTraces (beta — via OTel Traces)
Full distributed traces linking user prompts → API requests → tool executions as spans, giving a complete request waterfall.
Key Attributes Available on All Data
session.id— maps directly to a Crow sessionuser.account_uuid/user.email— user identityorganization.id— org-level groupingmodel— which Claude model was usedprompt.id— correlates all events from a single user promptBrainstorm: How Crow Could Use This
1. Embedded OTel Collector
Crow could run a lightweight OTel collector (or just an OTLP HTTP receiver) that Claude Code sessions export to. Crow would set the env vars when launching each session:
Since Crow already controls how Claude Code is launched (via
crow new-terminal+crow send), injecting these env vars is straightforward.2. Per-Session Dashboard
Map
session.idto Crow session UUIDs. Show per-session:3. Cross-Session Analytics
Aggregate across sessions for a higher-level view:
4. Real-Time Session Activity Feed
Stream events as they happen:
prompt.idcorrelation to group related events5. Cost Alerts / Budgets
6. Session Summary on Completion
When a session completes, auto-generate a summary card:
Architecture Options
Option A: In-Process OTel Receiver
Crow's Swift app listens on a local port for OTLP (gRPC or HTTP). Parses protobuf/JSON payloads directly. Stores in SQLite or in-memory.
Option B: Sidecar Collector + SQLite
Ship a lightweight OTel collector binary that writes to a local SQLite DB. Crow reads from the DB.
Option C: Prometheus Scrape
Use
OTEL_METRICS_EXPORTER=prometheusand scrape the/metricsendpoint.Option D: Console Exporter + Log Parsing
Use
OTEL_METRICS_EXPORTER=consoleand parse stdout from the Claude Code terminal.Recommendation: Option A is the cleanest for a native app. OTel's OTLP HTTP/JSON protocol is straightforward to receive — it's just POST requests with a known schema.
Configuration Surface
Crow would need:
Reference
Success Criteria