From 566090980118d5648ca239dc9c7fb74faa925b0c Mon Sep 17 00:00:00 2001 From: iamtoruk Date: Tue, 18 Aug 2026 02:39:50 -0700 Subject: [PATCH] optimize: per-group subtotals in every finding render Each class header now carries its own token/dollar subtotal and finding count, so the apply-able slice is never mistaken for the whole board; the headline savings line names that slice explicitly. CLI and TUI share one classHeaderLine helper, the desktop app reads the same numbers from the new summary.byClass in --format json (add-only; the three subtotals sum to findingCount and potentialSavingsTokens). Also scopes the SHELL_PROFILE_SCOPE comment to what is actually true: the MCP deferral plans refuse to rewrite a shell profile, but bash-output-cap appends its own marker block to one. --- app/renderer/App.test.tsx | 5 +++ app/renderer/lib/types.ts | 1 + app/renderer/sections/Optimize.test.tsx | 11 +++++- app/renderer/sections/Optimize.tsx | 10 ++++-- src/dashboard.tsx | 5 +-- src/optimize.ts | 45 ++++++++++++++++++++++--- tests/optimize.test.ts | 17 +++++++++- 7 files changed, 82 insertions(+), 12 deletions(-) diff --git a/app/renderer/App.test.tsx b/app/renderer/App.test.tsx index 2832cb4d..d29b4c43 100644 --- a/app/renderer/App.test.tsx +++ b/app/renderer/App.test.tsx @@ -139,6 +139,11 @@ function installDefaultMocks() { healthScore: 100, healthGrade: 'A', findingCount: 0, periodCostUSD: 0, sessions: 0, calls: 0, potentialSavingsTokens: 0, potentialSavingsCostUSD: 0, potentialSavingsPercent: 0, costRateUSD: 0, measuredSavingsUSD: 0, + byClass: { + fix: { tokensSaved: 0, savingsUSD: 0, count: 0 }, + nudge: { tokensSaved: 0, savingsUSD: 0, count: 0 }, + keep: { tokensSaved: 0, savingsUSD: 0, count: 0 }, + }, }, findings: [], }) diff --git a/app/renderer/lib/types.ts b/app/renderer/lib/types.ts index d1f61a79..8cc1fd0a 100644 --- a/app/renderer/lib/types.ts +++ b/app/renderer/lib/types.ts @@ -423,6 +423,7 @@ export type OptimizeJsonReport = { potentialSavingsPercent: number | null costRateUSD: number measuredSavingsUSD: number + byClass: Record } findings: Array<{ id: string diff --git a/app/renderer/sections/Optimize.test.tsx b/app/renderer/sections/Optimize.test.tsx index 03b922b5..a01ed0e7 100644 --- a/app/renderer/sections/Optimize.test.tsx +++ b/app/renderer/sections/Optimize.test.tsx @@ -49,6 +49,11 @@ function makeOptimizeReport(): OptimizeJsonReport { sessions: 88, calls: 1220, potentialSavingsTokens: 184_000, potentialSavingsCostUSD: 94.4, potentialSavingsPercent: 15.4, costRateUSD: 0.0005, measuredSavingsUSD: 27.8, + byClass: { + fix: { tokensSaved: 18_200, savingsUSD: 9.1, count: 1 }, + nudge: { tokensSaved: 17_400, savingsUSD: 8.7, count: 1 }, + keep: { tokensSaved: 4_800, savingsUSD: 2.4, count: 1 }, + }, }, findings: [ { @@ -129,7 +134,11 @@ describe('Optimize', () => { await screen.findByText('Opus is doing your small talk') const groups = document.querySelectorAll('.opt-group') - expect([...groups].map(g => g.textContent)).toEqual(['Fix now (apply-able)', 'Habits', 'FYI']) + expect([...groups].map(g => g.textContent)).toEqual([ + 'Fix now (apply-able) · 18.2K tokens · $9.10 · 1 finding', + 'Habits · 17.4K tokens · $8.70 · 1 finding', + 'FYI · 4.8K tokens · $2.40 · 1 finding', + ]) }) it('renders tabs and actionable Waste findings with impact, savings, explanation, and copy-paste fix', async () => { diff --git a/app/renderer/sections/Optimize.tsx b/app/renderer/sections/Optimize.tsx index e0a6b347..0d6ea911 100644 --- a/app/renderer/sections/Optimize.tsx +++ b/app/renderer/sections/Optimize.tsx @@ -101,7 +101,7 @@ function WasteRows({ report }: { report: Polled }) {
{report.data.summary.findingCount.toLocaleString('en-US')} findings · {formatUsd(report.data.summary.potentialSavingsCostUSD)} potential · health {report.data.summary.healthScore}/100
- + ) } @@ -124,7 +124,7 @@ function actionText(fix: WasteAction): string { return fix.type === 'file-content' ? fix.content : fix.text } -function ActionableFindingRows({ findings }: { findings: OptimizeFinding[] }) { +function ActionableFindingRows({ findings, byClass }: { findings: OptimizeFinding[]; byClass: OptimizeJsonReport['summary']['byClass'] }) { const [expandedId, setExpandedId] = useState(null) const [copiedId, setCopiedId] = useState(null) @@ -145,7 +145,11 @@ function ActionableFindingRows({ findings }: { findings: OptimizeFinding[] }) { const showHeader = finding.class !== findings[i - 1]?.class return ( - {showHeader &&
{CLASS_HEADERS[finding.class]}
} + {showHeader && ( +
+ {CLASS_HEADERS[finding.class]} · {formatCompact(byClass[finding.class].tokensSaved)} tokens · {formatUsd(byClass[finding.class].savingsUSD)} · {byClass[finding.class].count} {byClass[finding.class].count === 1 ? 'finding' : 'findings'} +
+ )}