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.
This commit is contained in:
iamtoruk 2026-08-18 03:15:12 -07:00
parent 52eb9fdb8d
commit 3936284811
5 changed files with 119 additions and 2 deletions

View file

@ -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) —————

View file

@ -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(<Optimize period="30days" provider="all" />)
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(<Optimize period="30days" provider="all" />)
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(<Optimize period="30days" provider="all" />)

View file

@ -102,6 +102,50 @@ function WasteRows({ report }: { report: Polled<OptimizeJsonReport> }) {
{report.data.summary.findingCount.toLocaleString('en-US')} findings · {formatUsd(report.data.summary.potentialSavingsCostUSD)} potential · health {report.data.summary.healthScore}/100
</div>
<ActionableFindingRows findings={report.data.findings} byClass={report.data.summary.byClass} />
<AppliedFixRows fixes={report.data.appliedFixes ?? []} />
</div>
)
}
type AppliedFix = NonNullable<OptimizeJsonReport['appliedFixes']>[number]
const VERDICT_GLYPH: Record<AppliedFix['verdict'], string> = {
worked: '\u2713',
partial: '~',
'no-effect': '\u2717',
pending: '\u2026',
}
const VERDICT_LABEL: Record<AppliedFix['verdict'], string> = {
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 (
<div className="opt-findings opt-applied">
<div className="opt-group">Applied fixes</div>
{fixes.map(fix => (
<div className={`opt-applied-row opt-applied-${fix.verdict}`} key={fix.id}>
<span className="opt-applied-glyph" aria-hidden="true">{VERDICT_GLYPH[fix.verdict]}</span>
<b className="opt-finding-title">{fix.findingId ?? fix.kind}</b>
<span className="opt-applied-verdict">{VERDICT_LABEL[fix.verdict]}</span>
<span className="opt-finding-tokens">
{fix.verdict === 'pending'
? '\u2014'
: `est. ${formatCompact(fix.estimatedTokens)} \u2192 ${formatCompact(fix.realizedTokens)}`}
</span>
</div>
))}
{fixes.some(fix => fix.verdict === 'no-effect') && (
<div className="opt-summary opt-applied-hint">Revert one that did not help: <code>{fixes.find(fix => fix.verdict === 'no-effect')!.undoCommand}</code></div>
)}
</div>
)
}

View file

@ -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; }

View file

@ -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<string, string> = { 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<AppliedFix['verdict'], string> = {
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,
</Fragment>
)
})}
{appliedFixes.length > 0 && (
<Box flexDirection="column" paddingX={1} width={width}>
<Text bold color={ORANGE} wrap="truncate-end">Applied fixes</Text>
{appliedFixes.map(fix => (
<Text key={fix.id} color={APPLIED_FIX_COLORS[fix.verdict]} wrap="truncate-end">
{appliedFixGlyph(fix)} {formatAppliedFix(fix)}
</Text>
))}
</Box>
)}
</Box>
)
}
@ -1313,6 +1331,7 @@ export function InteractiveDashboard({ initialProjects, initialDailyHistoryProje
const [detectedProviders, setDetectedProviders] = useState<string[]>([])
const [view, setView] = useState<View>('dashboard')
const [optimizeResult, setOptimizeResult] = useState<OptimizeResult | null>(null)
const [appliedFixes, setAppliedFixes] = useState<AppliedFix[]>([])
const [optimizeLoading, setOptimizeLoading] = useState(false)
const [projectBudgets, setProjectBudgets] = useState<Map<string, ContextBudget>>(new Map())
const [planUsages, setPlanUsages] = useState<PlanUsage[]>(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'
? <CompareView projects={projects} onBack={() => setView('dashboard')} />
: view === 'optimize' && optimizeResult
? <OptimizeView findings={optimizeResult.findings} costRate={optimizeResult.costRate} projects={projects} label={headerLabel} width={dashWidth} healthScore={optimizeResult.healthScore} healthGrade={optimizeResult.healthGrade} cursor={findingsCursor} />
? <OptimizeView findings={optimizeResult.findings} costRate={optimizeResult.costRate} projects={projects} label={headerLabel} width={dashWidth} healthScore={optimizeResult.healthScore} healthGrade={optimizeResult.healthGrade} cursor={findingsCursor} appliedFixes={appliedFixes} />
: <DashboardContent projects={projects} period={period} columns={columns} maxContentWidth={maxContentWidth} activeProvider={activeProvider} budgets={projectBudgets} planUsages={planUsages} label={headerLabel} dayMode={isDayMode} dailyHistoryProjects={dailyHistoryProjects} dailyHistoryPageSize={dailyHistoryPageSize} scrollableDailyHistory={scrollableDailyHistory} dailyHistoryCursor={Math.min(dailyHistoryCursor, dailyHistoryMaxCursor)} durable={durable} />}
{coachingNote && (
<Box width={dashWidth} paddingX={1}>