Remove redundant GlobalStats from settings store#439
Remove redundant GlobalStats from settings store#439pedramamini merged 6 commits intoRunMaestro:mainfrom
Conversation
…obalStats Extract totalActiveTimeMs into its own dedicated settings field, independent of the soon-to-be-removed globalStats object. Includes backward-compatible migration that copies the value from globalStats.totalActiveTimeMs on first load for users upgrading from older versions. Part of RunMaestro#438 (Phase 1).
Remove the redundant globalStats object from the settings store, its
GlobalStats interface, DEFAULT_GLOBAL_STATS constant, setGlobalStats and
updateGlobalStats actions, all three updateGlobalStats({ totalSessions: 1 })
calls in App.tsx, the token/cost increment in useAgentListeners, and the
updateGlobalStatsRef plumbing between App.tsx and useAgentListeners.
The totalActiveTimeMs migration from legacy globalStats is preserved in
loadAllSettings for users upgrading from older versions.
All correct UI consumers (AboutModal, AchievementCard) already use the
IPC-computed GlobalAgentStats. Test files are deferred to Phase 3.
Part of RunMaestro#438
Remove DEFAULT_GLOBAL_STATS import and all globalStats-related tests from settingsStore.test.ts. Replace with tests for the standalone totalActiveTimeMs field: setTotalActiveTimeMs, addTotalActiveTimeMs (accumulation + persistence), and three migration scenarios (legacy-only, both-present, neither-present). All 125 tests pass.
… hook tests Remove GlobalStats type import, DEFAULT_GLOBAL_STATS import, and all globalStats-related tests from useSettings.test.ts. Replace with totalActiveTimeMs tests covering default value, load from store, setTotalActiveTimeMs, addTotalActiveTimeMs, and persistence. All 117 tests pass.
Replace DEFAULT_GLOBAL_STATS import and mock state entry with totalActiveTimeMs: 0 in fonts-and-sizing.test.ts, completing the Phase 3 test cleanup for the globalStats removal (RunMaestro#438). All 20,581 tests pass. Lint and build verified clean.
📝 WalkthroughWalkthroughThis PR removes the composite Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related issues
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
Comment |
Greptile SummaryThis PR successfully eliminates data duplication by removing the settings-persisted Key changes:
The migration logic correctly handles three cases: legacy-only source, standalone-takes-precedence, and neither-exists. All 20,581 tests pass. Confidence Score: 5/5
Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[Settings Store Load] --> B{totalActiveTimeMs exists?}
B -->|Yes| C[Use standalone field]
B -->|No| D{Legacy globalStats.totalActiveTimeMs exists?}
D -->|Yes & > 0| E[Migrate to standalone]
D -->|No or = 0| F[Default to 0]
E --> G[Persist migrated value]
C --> H[Settings Store Ready]
F --> H
G --> H
I[Agent Message Event] --> J[agentSessions.getGlobalStats IPC]
J --> K[Calculate tokens/cost/sessions]
K --> L[Stream to UI via IPC]
M[User Activity] --> N[useHandsOnTimeTracker]
N --> O[addTotalActiveTimeMs]
O --> P[Persist to settings]
style E fill:#90EE90
style G fill:#90EE90
style J fill:#87CEEB
style L fill:#87CEEB
style O fill:#FFD700
style P fill:#FFD700
Last reviewed commit: 4901470 |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
src/renderer/stores/settingsStore.ts (1)
809-819: Consider clamping totalActiveTimeMs to non‑negative values.
Lines 809-819: A defensive clamp avoids negative/NaN totals if persisted data is corrupted or if a delta becomes negative (e.g., clock skew).♻️ Optional guard against negative/NaN totals
- setTotalActiveTimeMs: (value) => { - set({ totalActiveTimeMs: value }); - window.maestro.settings.set('totalActiveTimeMs', value); - }, + setTotalActiveTimeMs: (value) => { + const sanitized = Number.isFinite(value) ? Math.max(0, value) : 0; + set({ totalActiveTimeMs: sanitized }); + window.maestro.settings.set('totalActiveTimeMs', sanitized); + }, addTotalActiveTimeMs: (delta) => { const prev = get().totalActiveTimeMs; - const updated = prev + delta; + const next = prev + delta; + const updated = Number.isFinite(next) ? Math.max(0, next) : prev; set({ totalActiveTimeMs: updated }); window.maestro.settings.set('totalActiveTimeMs', updated); },🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/renderer/stores/settingsStore.ts` around lines 809 - 819, The setters setTotalActiveTimeMs and addTotalActiveTimeMs should defensively clamp values to non‑negative finite numbers before updating state or persisting; change setTotalActiveTimeMs to coerce the incoming value to a Number, guard against NaN/Infinity and use Math.max(0, value) when calling set({ totalActiveTimeMs: ... }) and window.maestro.settings.set(...), and update addTotalActiveTimeMs to derive prev via get().totalActiveTimeMs (coerce/guard it), compute updated as Math.max(0, prev + Number(delta) or 0) and then persist the clamped updated value.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@src/renderer/stores/settingsStore.ts`:
- Around line 809-819: The setters setTotalActiveTimeMs and addTotalActiveTimeMs
should defensively clamp values to non‑negative finite numbers before updating
state or persisting; change setTotalActiveTimeMs to coerce the incoming value to
a Number, guard against NaN/Infinity and use Math.max(0, value) when calling
set({ totalActiveTimeMs: ... }) and window.maestro.settings.set(...), and update
addTotalActiveTimeMs to derive prev via get().totalActiveTimeMs (coerce/guard
it), compute updated as Math.max(0, prev + Number(delta) or 0) and then persist
the clamped updated value.
Closes #438
Summary
GlobalStatsinterface (8 fields: sessions, messages, tokens, cost, active time) which duplicated data already tracked by theagentSessions.getGlobalStats()IPC systemtotalActiveTimeMsas a standalone setting, since hands-on time tracking is unique to the settings storeglobalStats.totalActiveTimeMsto the new standalone fieldupdateGlobalStatsReffrom agent listeners test mock and trailing blank lineTest plan
totalActiveTimeMsset/add actions verified in settingsStore and useSettings hook testsGlobalStatstype,DEFAULT_GLOBAL_STATS,setGlobalStats, orupdateGlobalStatsin settings layer