ADE Stats accuracy overhaul + activity module redesign (ADE-113, ADE-114)#783
ADE Stats accuracy overhaul + activity module redesign (ADE-113, ADE-114)#783arul28 wants to merge 12 commits into
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
📝 WalkthroughWalkthroughChangesUsage analytics pipeline
Estimated code review effort: 5 (Critical) | ~120 minutes Possibly related PRs
Suggested labels: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
@copilot review but do not make fixes |
ADE-113: wire db into prod usage service, per-day input/output/cache split, local-timezone day keys (DST-safe), codeburn-parity dedup (cross-file message ids, streaming keep-last, codex fork replay), ADE-originated attribution with symmetric inclusion, machine/project scope toggle, labeled github-vs-local activity groups (no Math.max merges), estimation flags, GitHub PR scan early-out. 14 new named regression tests. ADE-114: tabbed ActivityModule (compact/full) replaces the carousel on the new-chat surface and Settings > Stats; sectioned Stats dashboard with scope toggle, unified range vocabulary, quiet meta footer; provider brand color tokens; streak/milestone chip; warm empty state; event-driven refresh; hero moved up with logo glow removed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Tabbed card parity with desktop (named tabs, unified range vocab incl. All, input/output/cache token split, GitHub underlay on code bars, tap tooltips, warm empty state, streak/milestone chip, skeleton loading, flat card without glow). Hero scooted up and logo glow removed to match. RemoteModels decodes the new optional daily fields. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Five-provider hand-computed fixture (resume/stream dedup, fork replay, project scope, ADE attribution, estimation flags, local midnight, DST). Oracle script (scripts/usage-oracle.mjs) diffs ADE token totals against codeburn JSON on real ledgers: claude exact-match on closed ranges; codex delta fully attributed to ADE-originated inclusion (external-only <0.5%). Accuracy fixes from oracle findings: recursive claude subagents/** scan, removed codex 14d/250-file/32MiB caps, cached-input double count, reasoning tokens separated from displayed output. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Correctness (three-perspective review): PR pagination now orders/stops on UPDATED_AT so long-lived PRs merged in-range are counted; GitHub-only background refresh emits usage.onUpdate so Stats stops showing stale zeros; empty-state predicate counts GitHub-only days; daily bucket scans capped at 250k newest rows with debug log. Judo: explicit scope branches in buildCostSnapshots, shared RANGE_OPTIONS, dead export + doc fix in providerColors, toDate helper in localDay. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Host-side sync command usage.getAdeStats now validates and forwards the new scope arg (was silently dropped; regression test added). Internal docs updated for the sectioned Stats dashboard, ActivityModule, localDay helpers, provider colors, and the scope/estimation/github-vs-local contracts. TUI and mobile verified in lockstep with no changes required. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Heatmap cells now scale to the box: one tall row for <=7 points, 7-row calendar grid for longer ranges. Active tab with an all-zero series shows a muted hint while keeping the legend, instead of a bare chart. iOS hasActivity made github-aware to match desktop. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Greptile P1: the host handler rebuilt getAdeUsageStats args with only preset+scope, silently ignoring exact date ranges from synced clients. Now validated and forwarded, with regression tests. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
4111cb2 to
3c6e7c6
Compare
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3c6e7c6d3c
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
The end-to-end fixture asserted DST deltas that only held in a DST-crossing timezone — assertions now derive expectations from the runtime's actual offsets and pass under UTC and Pacific/Auckland alike. Exact since/until requests now compute the in-ADE vs external split from a per-day ADE-originated series over the same range as the totals (omitted when the daily series is unavailable) instead of borrowing the whole preset window. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
When callers pass a custom since/until window that starts or ends mid-day, this includes every token entry for any local day that intersects the range. For example, 2026-07-01T12:00Z through 2026-07-02T12:00Z counts all provider tokens from both boundary days, while ADE DB and GitHub stats use exact timestamp comparisons, so custom range totals and daily charts can be inflated at the edges.
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (2)
apps/desktop/src/main/services/usage/usageTrackingService.ts (1)
1656-1708: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick winBound PR pagination for the
allpreset.range.sinceis null here, so this loop keeps fetching every PR page until history is exhausted. On large repos, a cache miss can still trigger many serialgh api graphqlround-trips. Consider a page cap or another explicit bound for the unbounded preset.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/desktop/src/main/services/usage/usageTrackingService.ts` around lines 1656 - 1708, Bound pagination in scanGithubPullRequestPages for ranges without range.since, such as the all preset. Add an explicit maximum page count or equivalent limit to stop repeated gh GraphQL requests after a reasonable bound, while preserving existing date-based termination and cursor handling.apps/desktop/src/renderer/components/usage/ActivityModule.tsx (1)
697-713: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winMove the milestone write out of
useMemo.
useFooterChipperforms a side effect (recordShownMilestone→localStorage.setItem) during render. Under React 18 StrictMode double-invocation (and concurrent renders that get discarded), the milestone can be recorded on a throwaway render — a subsequent recompute then reads it back as already-shown, sofreshflips tofalseand the celebration animation inFooterChipnever fires. Compute the chip purely and record the shown milestone in auseEffectkeyed on the crossed threshold.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/desktop/src/renderer/components/usage/ActivityModule.tsx` around lines 697 - 713, Move the recordShownMilestone side effect out of useFooterChip’s useMemo: compute the crossed milestone and fresh state purely during render, then use a useEffect keyed by the crossed milestone threshold to record it after commit, while preserving the existing trophy/streak chip behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@apps/desktop/src/main/services/ipc/registerIpc.ts`:
- Around line 4877-4884: Extend validation in the usageGetAdeStats IPC handler
to mirror the remote command path: validate preset with isAdeUsageRangePreset,
and reject since or until when Date.parse returns NaN. Keep the existing object
and scope checks, and throw clear errors before calling getAdeUsageStats.
In `@apps/desktop/src/renderer/components/usage/ActivityModule.tsx`:
- Around line 129-131: Update dayValue() to include githubCommits, githubPrs,
githubAdditions, and githubDeletions in its score, using the same activity
signal as dayHasActivity(), while preserving the existing tokens, sessions, and
interactions weighting.
In `@apps/ios/ADE/Views/Work/WorkUsageActivityCarousel.swift`:
- Around line 82-93: Extend WorkUsageBucketDetail with githubAdditions and
githubDeletions plus a githubCode computed property, populate both fields from
bucket in the heatmap and bars detail(_:) builders, and update WorkUsageTooltip
to show a “+X / -Y GitHub” line when detail.githubCode > 0.
- Around line 175-184: Update the hasActivity computed property to detect daily
token usage by summing each point’s inputTokens, outputTokens, and cachedTokens,
matching WorkUsageVisualBucket.tokens, instead of relying on point.totalTokens;
retain the existing checks for sessions, code changes, GitHub activity, and
interactions.
---
Nitpick comments:
In `@apps/desktop/src/main/services/usage/usageTrackingService.ts`:
- Around line 1656-1708: Bound pagination in scanGithubPullRequestPages for
ranges without range.since, such as the all preset. Add an explicit maximum page
count or equivalent limit to stop repeated gh GraphQL requests after a
reasonable bound, while preserving existing date-based termination and cursor
handling.
In `@apps/desktop/src/renderer/components/usage/ActivityModule.tsx`:
- Around line 697-713: Move the recordShownMilestone side effect out of
useFooterChip’s useMemo: compute the crossed milestone and fresh state purely
during render, then use a useEffect keyed by the crossed milestone threshold to
record it after commit, while preserving the existing trophy/streak chip
behavior.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: a78149f3-5a79-40ee-9ec8-6e268b7d7e0f
⛔ Files ignored due to path filters (4)
docs/features/chat/README.mdis excluded by!docs/**docs/features/chat/composer-and-ui.mdis excluded by!docs/**docs/features/onboarding-and-settings/README.mdis excluded by!docs/**docs/features/web-client/README.mdis excluded by!docs/**
📒 Files selected for processing (23)
apps/ade-cli/src/services/sync/syncRemoteCommandService.test.tsapps/ade-cli/src/services/sync/syncRemoteCommandService.tsapps/desktop/scripts/usage-oracle.mjsapps/desktop/src/main/main.tsapps/desktop/src/main/services/ipc/registerIpc.tsapps/desktop/src/main/services/usage/ledgers/localUsageLedgers.tsapps/desktop/src/main/services/usage/localDay.tsapps/desktop/src/main/services/usage/usageEndToEnd.test.tsapps/desktop/src/main/services/usage/usageStatsStore.tsapps/desktop/src/main/services/usage/usageTrackingService.test.tsapps/desktop/src/main/services/usage/usageTrackingService.tsapps/desktop/src/preload/preload.tsapps/desktop/src/renderer/components/chat/AgentChatPane.tsxapps/desktop/src/renderer/components/settings/AdeUsageSection.tsxapps/desktop/src/renderer/components/usage/ActivityModule.tsxapps/desktop/src/renderer/components/usage/UsageActivityCarousel.tsxapps/desktop/src/renderer/components/usage/providerColors.tsapps/desktop/src/renderer/components/usage/usage.test.tsxapps/desktop/src/shared/types/usage.tsapps/ios/ADE/Models/RemoteModels.swiftapps/ios/ADE/Views/Work/WorkNewChatScreen.swiftapps/ios/ADE/Views/Work/WorkUsageActivityCarousel.swiftapps/ios/ADETests/ADETests.swift
💤 Files with no reviewable changes (1)
- apps/desktop/src/renderer/components/usage/UsageActivityCarousel.tsx
…ltip gaps Custom since/until ranges now widen to whole machine-local days for all sources (provider snapshots are day-granular; DB/GitHub use the same aligned instants) and the contract documents it. Renderer IPC validates preset/ since/until like the sync path. Heatmap intensity counts GitHub-only activity on desktop and iOS; iOS tooltip carries GitHub +/− and hasActivity derives per-day tokens from the fields hosts actually send. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Codex P2 (exact since/until mid-day boundaries) addressed in db50b32: custom ranges are now day-granular by contract — since/until widen to whole machine-local days for provider, DB, and GitHub sources alike, so edges are consistent instead of mixed-granularity. Documented on GetAdeUsageStatsArgs. @codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: db50b32161
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Union merge: keeps ADE-117's quota snapshot/refresh commands, refresh reliability, and lifetime-total accuracy alongside this lane's newer ADE-113/114 pipeline and UI work (day-granular custom ranges, IPC validation, exact-range ADE attribution, heatmap fill, iOS tabbed module). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Per-client activeDays, global active days, streaks, and lastActiveAt now come from bounded distinct-local-day SQL aggregates; the capped newest-row slice only feeds daily chart points. Regression: 250,001 events across three days keeps day counts exact while charts use the capped slice. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4dd7b144ef
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
One helper per platform now drives both the warm-empty predicate and the heatmap intensity over the complete daily-point field set (tokens, sessions, interactions, local commits/prs/filesChanged/insertions/deletions, GitHub commits/prs/additions/deletions), so local-git-only and GitHub-commit-only days render and score consistently. iOS decodes per-day commits/prs. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Deployment failed with the following error: Learn More: https://vercel.com/arul28s-projects?upgradeToPro=build-rate-limit |
|
@codex review |
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
| select date(d.started_at, 'localtime') active_date | ||
| from session_deltas d | ||
| where ${deltaRange.sql} | ||
| and (coalesce(d.insertions, 0) > 0 or coalesce(d.deletions, 0) > 0) |
There was a problem hiding this comment.
Count file-only deltas
activeDateRows excludes session_deltas rows where files_changed > 0 but insertions and deletions are both zero. Those rows still contribute to summary.filesChanged and daily heatmap activity below, so rename/mode-only changes disappear from activeDays and streaks even though the same range reports code activity.
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/desktop/src/main/services/usage/usageStatsStore.ts
Line: 463
Comment:
**Count file-only deltas**
`activeDateRows` excludes `session_deltas` rows where `files_changed > 0` but insertions and deletions are both zero. Those rows still contribute to `summary.filesChanged` and daily heatmap activity below, so rename/mode-only changes disappear from `activeDays` and streaks even though the same range reports code activity.
How can I resolve this? If you propose a fix, please make it concise.
ADE-113 — Stats data correctness
dbhandle — every ADE-DB stat (sessions, lanes, commits, code movement, clients, streaks) rendered empty in shipping builds. Now wired.inputTokens).message.iddedup, streaming keep-last (first-occurrence timestamp), Codex fork/replay keys; recursive Claudesubagents/**scanning; Codex scan caps removed; cached-input double-count and reasoning/output conflation fixed.scopeSupported: false.Math.maxmerging of incomparable measures. PR scan paginates onUPDATED_ATso long-lived PRs merged in-range are counted, with a correct early-out.apps/desktop/scripts/usage-oracle.mjs): Claude token totals match exactly on closed ranges; Codex delta fully attributed to ADE-originated inclusion (external-only < 0.5%).ADE-114 — Activity module redesign
ActivityModule(Activity · Tokens · Code · Clients) replaces the arrow carousel on the new-chat surface and Settings > Stats; compact and full variants; flat card, no glow/shadow; hover/tap day tooltips; unified range vocabulary (Today/7d/30d/Year/All); event-driven refresh viausage.onUpdate(retry cap removed); skeleton loading; warm empty state; per-tab all-zero hints; streak/milestone chip; provider brand color tokens; heatmap scales to the chart area.scope.Tests
154 usage-domain tests (14 named pipeline regressions, hand-computed 5-provider e2e fixture with DST/dedup/fork cases, 28 component tests), iOS decode tests, CI shard green, proof screenshots in the lane's proof drawer.
Closes #768. Closes #771.
🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Bug Fixes
Greptile Summary
This PR updates ADE usage stats accuracy and redesigns the desktop and iOS activity views. The main changes are:
Confidence Score: 4/5
Mostly safe to merge after fixing the stats summary issue.
The changed paths are focused and covered by tests, with one contained correctness issue in ADE database active-day and streak aggregation.
apps/desktop/src/main/services/usage/usageStatsStore.tsWhat T-Rex did
Important Files Changed
since/untiltimestamps to the usage tracking service.Sequence Diagram
%%{init: {'theme': 'neutral'}}%% sequenceDiagram participant Renderer as Desktop Renderer / iOS Client participant IPC as IPC / Sync Command participant Usage as UsageTrackingService participant Providers as Provider Ledgers participant DB as ADE Database Stats participant GH as GitHub Scanner Renderer->>IPC: usage.getAdeStats(preset, scope, since, until) IPC->>IPC: validate preset/scope/timestamps IPC->>Usage: getAdeUsageStats(args) Usage->>Usage: resolve + widen to local-day range Usage->>Providers: aggregate provider daily token buckets Providers-->>Usage: totals + ADE/external split Usage->>DB: collectAdeDatabaseUsageStats(range) DB-->>Usage: sessions, deltas, clients, streaks, daily points Usage->>GH: scan/cache GitHub activity(range) GH-->>Usage: separate GitHub commits/PRs/code Usage-->>Renderer: AdeUsageStats with daily activity dimensions%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%% sequenceDiagram participant Renderer as Desktop Renderer / iOS Client participant IPC as IPC / Sync Command participant Usage as UsageTrackingService participant Providers as Provider Ledgers participant DB as ADE Database Stats participant GH as GitHub Scanner Renderer->>IPC: usage.getAdeStats(preset, scope, since, until) IPC->>IPC: validate preset/scope/timestamps IPC->>Usage: getAdeUsageStats(args) Usage->>Usage: resolve + widen to local-day range Usage->>Providers: aggregate provider daily token buckets Providers-->>Usage: totals + ADE/external split Usage->>DB: collectAdeDatabaseUsageStats(range) DB-->>Usage: sessions, deltas, clients, streaks, daily points Usage->>GH: scan/cache GitHub activity(range) GH-->>Usage: separate GitHub commits/PRs/code Usage-->>Renderer: AdeUsageStats with daily activity dimensionsComments Outside Diff (1)
apps/desktop/src/main/services/usage/usageTrackingService.ts, line 1304 (link)tokenBreakdownForExactRangeincludes an entire local day whenever it intersects the requestedsince/untilwindow. When a caller asks for2026-07-01T12:00Zthrough2026-07-02T12:00Z, provider tokens from all of both boundary days are included, while ADE DB and GitHub use exact timestamp comparisons. Custom ranges can return inflated provider usage for the first and last day.Prompt To Fix With AI
Prompt To Fix All With AI
Reviews (6): Last reviewed commit: "Unify day-activity scoring across every ..." | Re-trigger Greptile