From 393628481143c75ef37bbda5e3f6e9279615158f Mon Sep 17 00:00:00 2001 From: iamtoruk Date: Tue, 18 Aug 2026 03:15:12 -0700 Subject: [PATCH] optimize: show the applied-fix verdicts in the TUI and desktop app Same section, compact: one line per still-applied fix with the verdict glyph, and the undo command for the ones that measured nothing. The app reads appliedFixes[] off the optimize JSON, tolerating its absence from an older CLI. --- app/renderer/lib/types.ts | 11 +++++++ app/renderer/sections/Optimize.test.tsx | 28 ++++++++++++++++ app/renderer/sections/Optimize.tsx | 44 +++++++++++++++++++++++++ app/renderer/styles/plain.css | 9 +++++ src/dashboard.tsx | 29 ++++++++++++++-- 5 files changed, 119 insertions(+), 2 deletions(-) diff --git a/app/renderer/lib/types.ts b/app/renderer/lib/types.ts index 8cc1fd0a..f1531ad8 100644 --- a/app/renderer/lib/types.ts +++ b/app/renderer/lib/types.ts @@ -437,6 +437,17 @@ export type OptimizeJsonReport = { basis: 'measured' | 'estimated' fix: WasteAction }> + /** Still-applied fixes, re-measured on every run. Absent on older CLIs. */ + appliedFixes?: Array<{ + id: string + kind: string + findingId: string | null + appliedAt: string + verdict: 'worked' | 'partial' | 'no-effect' | 'pending' + estimatedTokens: number + realizedTokens: number + undoCommand: string + }> } // ————— T1b: src/sharing/* (defined by the shared contract) ————— diff --git a/app/renderer/sections/Optimize.test.tsx b/app/renderer/sections/Optimize.test.tsx index a01ed0e7..443eec08 100644 --- a/app/renderer/sections/Optimize.test.tsx +++ b/app/renderer/sections/Optimize.test.tsx @@ -129,6 +129,34 @@ describe('Optimize', () => { Object.defineProperty(navigator, 'clipboard', { configurable: true, value: { writeText } }) }) + it('lists applied fixes with a glyph per verdict and the undo hint', async () => { + const report = makeOptimizeReport() + report.appliedFixes = [ + { id: 'a1', kind: 'archive-skill', findingId: 'unused-skills', appliedAt: '2026-07-06T00:00:00.000Z', verdict: 'worked', estimatedTokens: 300_000, realizedTokens: 280_000, undoCommand: 'codeburn act undo a1' }, + { id: 'b2', kind: 'defer-threshold', findingId: 'mcp-defer-threshold', appliedAt: '2026-07-07T00:00:00.000Z', verdict: 'partial', estimatedTokens: 600_000, realizedTokens: 420_000, undoCommand: 'codeburn act undo b2' }, + { id: 'c3', kind: 'shell-config', findingId: 'bash-output-cap', appliedAt: '2026-07-05T00:00:00.000Z', verdict: 'no-effect', estimatedTokens: 41_000, realizedTokens: 0, undoCommand: 'codeburn act undo c3' }, + { id: 'd4', kind: 'mcp-remove', findingId: null, appliedAt: '2026-07-09T00:00:00.000Z', verdict: 'pending', estimatedTokens: 0, realizedTokens: 0, undoCommand: 'codeburn act undo d4' }, + ] + getOptimizeReport.mockResolvedValue(report) + render() + + await screen.findByText('Applied fixes') + const rows = [...document.querySelectorAll('.opt-applied-row')] + expect(rows.map(r => r.className.split(' ')[1])).toEqual([ + 'opt-applied-worked', 'opt-applied-partial', 'opt-applied-no-effect', 'opt-applied-pending', + ]) + expect(rows[0]!.textContent).toContain('unused-skills') + expect(rows[0]!.textContent).toContain('est. 300K \u2192 280K') + expect(rows[3]!.textContent).toContain('mcp-remove') + expect(screen.getByText('codeburn act undo c3')).toBeTruthy() + }) + + it('omits the applied-fixes list when nothing is applied', async () => { + render() + await screen.findByText('Opus is doing your small talk') + expect(document.querySelector('.opt-applied')).toBeNull() + }) + it('groups Waste findings under the fix / habits / FYI headers in order', async () => { render() diff --git a/app/renderer/sections/Optimize.tsx b/app/renderer/sections/Optimize.tsx index 0d6ea911..ac9350c2 100644 --- a/app/renderer/sections/Optimize.tsx +++ b/app/renderer/sections/Optimize.tsx @@ -102,6 +102,50 @@ 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 + + + ) +} + +type AppliedFix = NonNullable[number] + +const VERDICT_GLYPH: Record = { + worked: '\u2713', + partial: '~', + 'no-effect': '\u2717', + pending: '\u2026', +} + +const VERDICT_LABEL: Record = { + worked: 'worked', + partial: 'under estimate', + 'no-effect': 'did not help', + pending: 'measuring', +} + +// Closes the loop after `optimize --apply`: what each applied fix actually +// measured, and for the ones that did nothing, how to put them back. +function AppliedFixRows({ fixes }: { fixes: AppliedFix[] }) { + if (!fixes.length) return null + + return ( +
+
Applied fixes
+ {fixes.map(fix => ( +
+ + {fix.findingId ?? fix.kind} + {VERDICT_LABEL[fix.verdict]} + + {fix.verdict === 'pending' + ? '\u2014' + : `est. ${formatCompact(fix.estimatedTokens)} \u2192 ${formatCompact(fix.realizedTokens)}`} + +
+ ))} + {fixes.some(fix => fix.verdict === 'no-effect') && ( +
Revert one that did not help: {fixes.find(fix => fix.verdict === 'no-effect')!.undoCommand}
+ )}
) } diff --git a/app/renderer/styles/plain.css b/app/renderer/styles/plain.css index ad1c10ee..6d7a86c4 100644 --- a/app/renderer/styles/plain.css +++ b/app/renderer/styles/plain.css @@ -671,6 +671,15 @@ td:first-child { font-size: var(--fs-body); font-weight: var(--fw-body); } .opt-fix-code { max-width: 100%; overflow-x: auto; margin: 0; padding: 10px 11px; border: 1px solid var(--line); border-radius: 6px; background: var(--phead); color: var(--ink); font-family: var(--mono); font-size: 11px; line-height: 1.5; white-space: pre; } .opt-fix-command .opt-fix-code code::before { content: '$ '; color: var(--mut2); user-select: none; } .opt-copy { flex: 0 0 auto; padding: 4px 9px; border: 1px solid var(--line); border-radius: 6px; background: var(--panel); color: var(--mut); font: inherit; font-size: 10.5px; cursor: pointer; } +.opt-applied { padding-top: 12px; } +.opt-applied-row { display: grid; grid-template-columns: 16px minmax(0, 1fr) 110px 140px; align-items: center; column-gap: 12px; min-height: 34px; border-top: 1px solid var(--line2); } +.opt-applied-glyph { color: var(--mut2); font-family: var(--mono); font-size: 12px; } +.opt-applied-verdict { color: var(--mut); font-size: 10.5px; } +.opt-applied-worked .opt-applied-glyph, .opt-applied-worked .opt-applied-verdict { color: var(--ok); } +.opt-applied-partial .opt-applied-glyph, .opt-applied-partial .opt-applied-verdict { color: var(--warn); } +.opt-applied-no-effect .opt-applied-glyph, .opt-applied-no-effect .opt-applied-verdict { color: var(--bad); } +.opt-applied-hint { padding: 9px 0 0; } +.opt-applied-hint code { font-family: var(--mono); } .opt-copy:hover, .opt-copy:focus-visible { border-color: var(--accent); color: var(--ink); outline: none; } .ov-analytics-row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; align-items: stretch; } .ov-analytics-row > :only-child { grid-column: 1 / -1; } diff --git a/src/dashboard.tsx b/src/dashboard.tsx index 68ff3b1a..3a844784 100644 --- a/src/dashboard.tsx +++ b/src/dashboard.tsx @@ -11,6 +11,7 @@ import { aggregateModelTotals } from './model-breakdown.js' import { buildDurablePeriod } from './usage-aggregator.js' import { getAllProviders } from './providers/index.js' import { classHeaderLine, classTotals, findingBasis, findingClass, scanAndDetect, type FindingClass, type WasteFinding, type WasteAction, type OptimizeResult } from './optimize.js' +import { appliedFixGlyph, formatAppliedFix, type AppliedFix } from './act/types.js' import { aggregateFileChurn, buildCoachingNotes, computePricingCoverage, medianTimeToFirstEditMs, scanUserCorrections, worstOneShotCategory, type ReworkedFile } from './workflow-insights.js' import { estimateContextBudget, type ContextBudget } from './context-budget.js' import { dateKey } from './day-aggregator.js' @@ -1094,7 +1095,14 @@ const GRADE_COLORS: Record = { A: '#5BF5A0', B: '#5BF5A0', C: GO // off the alt-buffer top and the user couldn't see the StatusBar at all. const FINDINGS_WINDOW_SIZE = 3 -function OptimizeView({ findings, costRate, projects, label, width, healthScore, healthGrade, cursor }: { findings: WasteFinding[]; costRate: number; projects: ProjectSummary[]; label: string; width: number; healthScore: number; healthGrade: string; cursor: number }) { +const APPLIED_FIX_COLORS: Record = { + worked: '#5BF5A0', + partial: GOLD, + 'no-effect': '#F55B5B', + pending: DIM, +} + +function OptimizeView({ findings, costRate, projects, label, width, healthScore, healthGrade, cursor, appliedFixes = [] }: { findings: WasteFinding[]; costRate: number; projects: ProjectSummary[]; label: string; width: number; healthScore: number; healthGrade: string; cursor: number; appliedFixes?: AppliedFix[] }) { const periodCost = projects.reduce((s, p) => s + p.totalCostUSD, 0) const totalTokens = findings.reduce((s, f) => s + f.tokensSaved, 0) const totalCost = totalTokens * costRate @@ -1132,6 +1140,16 @@ function OptimizeView({ findings, costRate, projects, label, width, healthScore, ) })} + {appliedFixes.length > 0 && ( + + Applied fixes + {appliedFixes.map(fix => ( + + {appliedFixGlyph(fix)} {formatAppliedFix(fix)} + + ))} + + )} ) } @@ -1313,6 +1331,7 @@ export function InteractiveDashboard({ initialProjects, initialDailyHistoryProje const [detectedProviders, setDetectedProviders] = useState([]) const [view, setView] = useState('dashboard') const [optimizeResult, setOptimizeResult] = useState(null) + const [appliedFixes, setAppliedFixes] = useState([]) const [optimizeLoading, setOptimizeLoading] = useState(false) const [projectBudgets, setProjectBudgets] = useState>(new Map()) const [planUsages, setPlanUsages] = useState(initialPlanUsages ?? []) @@ -1473,6 +1492,12 @@ export function InteractiveDashboard({ initialProjects, initialDailyHistoryProje try { const result = await scanAndDetect(projects, currentRange(), activeProvider) if (reloadGenerationRef.current === generation) setOptimizeResult(result) + // Best effort: a bad journal never keeps the findings off screen. + try { + const { computeActReport } = await import('./act/report.js') + const applied = await computeActReport() + if (reloadGenerationRef.current === generation) setAppliedFixes(applied.appliedFixes) + } catch { /* the applied section is optional */ } } catch (error) { console.error(error) } finally { @@ -1637,7 +1662,7 @@ export function InteractiveDashboard({ initialProjects, initialDailyHistoryProje {view === 'compare' ? setView('dashboard')} /> : view === 'optimize' && optimizeResult - ? + ? : } {coachingNote && (