feat(analytics): add OTEL analytics source with session-detail report#384
Merged
Conversation
Add `analytics otel --file <path>`: maps a flattened otel-events.jsonl
(native Claude Code telemetry) into the existing analytics pipeline so it
renders the same HTML report (cost, tokens, tools, timeline, skills,
turns, project/branch) from OTEL data.
- AnalyticsSource seam (sources/{types,sessions-source,otel-source}) so
the CLI is agnostic to where the data comes from; the command is split
into a shared runner plus the `otel` subcommand.
- otel-loader: parse/filter events, authoritative cost index, per-model
rollup, timeline dispatches, synthesized deltas, transcript cwd/branch
join. Each agent api_request is attributed to a single dispatch so
parallel subagents with overlapping windows do not double-count.
- otel-source honors --session/--project/--agent/--branch so filtered
runs return the right sessions and reports are never mislabeled.
- usage-readers: keep the most complete row when Claude writes
progressive JSONL records for one streaming response.
- hook: on SessionStart re-entry, preserve accumulated
startTime/activeDurationMs for a live session (compact); clear/exit
start fresh instead of resurrecting a completed session.
- report: prompt/title column, per-session JSON export, full-window
timeline.
- Test fixtures use anonymized user identifiers (no real emails).
Generated with AI
Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
…l-source # Conflicts: # src/cli/commands/analytics/index.ts # src/cli/commands/analytics/report/client/app.js
…description Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
Contributor
|
The architecture seam is clean, the dispatch attribution logic works correctly for the core case, and the plan-vs-implementation is fully aligned. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds an
analytics otel --file <path>source that maps a flattened nativeClaude Code OTEL events file (
otel-events.jsonl) into the existing analyticspipeline, rendering the same HTML report (cost, tokens, tools, timeline, skills,
turns, project/branch) from OTEL data. The default local-session source is
unchanged.
Changes
sources/{types,sessions-source,otel-source}.ts):the CLI is now agnostic to where data comes from;
index.tsis split into ashared
runAnalyticsrunner plus theotelsubcommand.otel-loader.ts: parse/filter OTEL events, authoritative cost index(native
cost_usd), per-model rollup, timeline dispatches, synthesizedMetricDeltas, and a transcript cwd/branch join. Each agentapi_requestisattributed to a single dispatch, so parallel subagents with overlapping
windows do not double-count cost/tokens.
otel-source.ts: honors--session/--project/--agent/--branchsofiltered runs return the right sessions and reports are never mislabeled.
usage-readers.ts: keeps the most complete row when Claude writesprogressive JSONL records for a single streaming response.
hook.ts: on SessionStart re-entry, preserves accumulatedstartTime/activeDurationMsfor a live session (compact);clear/exitstart fresh instead of resurrecting a completed session.
app.js,template.html): prompt/title column, per-session JSONexport, full-window timeline.
Testing
usage-readers progressive-row case)
analytics otel --file <fixture> --reportrendersHTML + JSON; filter and dispatch attribution verified end to end)
Checklist
CI=true npm run ci— 2106 unit + 211 integration passing)main