From 710316053eadad595b491a359f163ed96a0950c9 Mon Sep 17 00:00:00 2001 From: AgentSeal Date: Thu, 16 Apr 2026 04:04:37 -0700 Subject: [PATCH 01/70] feat: add optimize command, in-TUI optimize view, and per-project context budget Optimize engine detects 8 waste patterns from Claude Code session data: - Junk directory reads (node_modules, .git, dist, etc.) - Duplicate file reads per session - Unused MCP servers (configured but never called) - Missing .claudeignore in projects with junk dirs - Bloated CLAUDE.md files (>200 lines) - Uncapped BASH_MAX_OUTPUT_LENGTH - Low Read:Edit ratio (edit-without-reading, per #42796) - High cache_creation overhead (per #46917) Each finding includes impact rating, token/cost savings estimate, and exact fix (paste, command, or file content). Dashboard integration: - o key switches to in-TUI optimize view, b key goes back - Background scan on load, o button only when findings exist - Per-project Context Budget column in By Project panel showing estimated per-call overhead (system + MCP tools + skills + CLAUDE.md) CLI: codeburn optimize [-p period] [--provider] --- src/cli.ts | 13 + src/context-budget.ts | 146 +++++++++ src/dashboard.tsx | 375 +++++++++++----------- src/optimize.ts | 696 +++++++++++++++++++++++++++++++++++++++++ tests/optimize.test.ts | 238 ++++++++++++++ 5 files changed, 1280 insertions(+), 188 deletions(-) create mode 100644 src/context-budget.ts create mode 100644 src/optimize.ts create mode 100644 tests/optimize.test.ts diff --git a/src/cli.ts b/src/cli.ts index 2c83efc..7372507 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -6,6 +6,7 @@ import { renderStatusBar } from './format.js' import { installMenubar, renderMenubarFormat, type PeriodData, type ProviderCost, uninstallMenubar } from './menubar.js' import { CATEGORY_LABELS, type DateRange, type ProjectSummary, type TaskCategory } from './types.js' import { renderDashboard } from './dashboard.js' +import { runOptimize } from './optimize.js' import { getAllProviders } from './providers/index.js' import { readConfig, saveConfig, getConfigFilePath } from './config.js' import { createRequire } from 'node:module' @@ -273,4 +274,16 @@ program console.log(` Config saved to ${getConfigFilePath()}\n`) }) +program + .command('optimize') + .description('Find token waste and get exact fixes') + .option('-p, --period ', 'Analysis period: today, week, 30days, month, all', '30days') + .option('--provider ', 'Filter by provider: all, claude, codex, cursor', 'all') + .action(async (opts) => { + await loadPricing() + const { range, label } = getDateRange(opts.period) + const projects = await parseAllSessions(range, opts.provider) + await runOptimize(projects, label, range) + }) + program.parse() diff --git a/src/context-budget.ts b/src/context-budget.ts new file mode 100644 index 0000000..3db8e95 --- /dev/null +++ b/src/context-budget.ts @@ -0,0 +1,146 @@ +import { readdir, readFile } from 'fs/promises' +import { existsSync } from 'fs' +import { join } from 'path' +import { homedir } from 'os' + +const CHARS_PER_TOKEN = 4 +const SYSTEM_BASE_TOKENS = 10400 +const TOOL_TOKENS_OVERHEAD = 400 +const SKILL_FRONTMATTER_TOKENS = 80 + +export type ContextBudget = { + systemBase: number + mcpTools: { count: number; tokens: number } + skills: { count: number; tokens: number } + memory: { count: number; tokens: number; files: Array<{ name: string; tokens: number }> } + total: number + modelContext: number +} + +function estimateTokens(text: string): number { + return Math.ceil(text.length / CHARS_PER_TOKEN) +} + +async function readConfigFile(path: string): Promise | null> { + if (!existsSync(path)) return null + try { + return JSON.parse(await readFile(path, 'utf-8')) + } catch { return null } +} + +async function countMcpTools(projectPath?: string): Promise { + const home = homedir() + const configPaths = [ + join(home, '.claude', 'settings.json'), + join(home, '.claude', 'settings.local.json'), + ] + if (projectPath) { + configPaths.push(join(projectPath, '.mcp.json')) + configPaths.push(join(projectPath, '.claude', 'settings.json')) + configPaths.push(join(projectPath, '.claude', 'settings.local.json')) + } + + const servers = new Set() + let toolCount = 0 + + for (const p of configPaths) { + const config = await readConfigFile(p) + if (!config) continue + const mcpServers = (config.mcpServers ?? {}) as Record + for (const name of Object.keys(mcpServers)) { + if (servers.has(name)) continue + servers.add(name) + toolCount += 5 + } + } + + return toolCount +} + +async function countSkills(projectPath?: string): Promise { + const dirs = [join(homedir(), '.claude', 'skills')] + if (projectPath) dirs.push(join(projectPath, '.claude', 'skills')) + + let count = 0 + for (const dir of dirs) { + if (!existsSync(dir)) continue + try { + const entries = await readdir(dir) + for (const entry of entries) { + const skillFile = join(dir, entry, 'SKILL.md') + if (existsSync(skillFile)) count++ + } + } catch { continue } + } + + return count +} + +async function scanMemoryFiles(projectPath?: string): Promise> { + const home = homedir() + const files: Array<{ name: string; tokens: number }> = [] + const paths: Array<{ path: string; name: string }> = [ + { path: join(home, '.claude', 'CLAUDE.md'), name: '~/.claude/CLAUDE.md' }, + ] + + if (projectPath) { + paths.push({ path: join(projectPath, 'CLAUDE.md'), name: 'CLAUDE.md' }) + paths.push({ path: join(projectPath, '.claude', 'CLAUDE.md'), name: '.claude/CLAUDE.md' }) + paths.push({ path: join(projectPath, 'CLAUDE.local.md'), name: 'CLAUDE.local.md' }) + } + + for (const { path, name } of paths) { + if (!existsSync(path)) continue + try { + const content = await readFile(path, 'utf-8') + files.push({ name, tokens: estimateTokens(content) }) + } catch { continue } + } + + return files +} + +export async function estimateContextBudget(projectPath?: string, modelContext = 1_000_000): Promise { + const mcpToolCount = await countMcpTools(projectPath) + const skillCount = await countSkills(projectPath) + const memoryFiles = await scanMemoryFiles(projectPath) + + const mcpTokens = mcpToolCount * TOOL_TOKENS_OVERHEAD + const skillTokens = skillCount * SKILL_FRONTMATTER_TOKENS + const memoryTokens = memoryFiles.reduce((s, f) => s + f.tokens, 0) + const total = SYSTEM_BASE_TOKENS + mcpTokens + skillTokens + memoryTokens + + return { + systemBase: SYSTEM_BASE_TOKENS, + mcpTools: { count: mcpToolCount, tokens: mcpTokens }, + skills: { count: skillCount, tokens: skillTokens }, + memory: { count: memoryFiles.length, tokens: memoryTokens, files: memoryFiles }, + total, + modelContext, + } +} + +export async function estimateBudgetsByProject(projectPaths: Map): Promise> { + const results = new Map() + for (const [project, cwd] of projectPaths) { + const budget = await estimateContextBudget(cwd) + results.set(project, budget) + } + return results +} + +export async function discoverProjectCwd(sessionDir: string): Promise { + try { + const files = (await readdir(sessionDir)).filter(f => f.endsWith('.jsonl')) + if (files.length === 0) return null + const content = await readFile(join(sessionDir, files[0]), 'utf-8') + for (const line of content.split('\n')) { + if (!line.trim()) continue + try { + const entry = JSON.parse(line) + if (entry.cwd && typeof entry.cwd === 'string') return entry.cwd + } catch { continue } + } + } catch { return null } + return null +} diff --git a/src/dashboard.tsx b/src/dashboard.tsx index e8aabf6..4d92287 100644 --- a/src/dashboard.tsx +++ b/src/dashboard.tsx @@ -1,14 +1,18 @@ import { homedir } from 'os' -import React, { useState, useCallback, useEffect } from 'react' +import React, { useState, useCallback, useEffect, useRef } from 'react' import { render, Box, Text, useInput, useApp, useWindowSize } from 'ink' import { CATEGORY_LABELS, type ProjectSummary, type TaskCategory } from './types.js' import { formatCost, formatTokens } from './format.js' import { parseAllSessions } from './parser.js' import { loadPricing } from './models.js' import { getAllProviders } from './providers/index.js' +import { scanAndDetect, type WasteFinding, type WasteAction, type OptimizeResult } from './optimize.js' +import { estimateContextBudget, discoverProjectCwd, type ContextBudget } from './context-budget.js' +import { join } from 'path' type Period = 'today' | 'week' | '30days' | 'month' +type View = 'dashboard' | 'optimize' const PERIODS: Period[] = ['today', 'week', '30days', 'month'] const PERIOD_LABELS: Record = { @@ -69,6 +73,8 @@ const CATEGORY_COLORS: Record = { general: '#666666', } +const IMPACT_PANEL_COLORS: Record = { high: '#F55B5B', medium: ORANGE, low: DIM } + function toHex(r: number, g: number, b: number): string { return '#' + [r, g, b].map(v => Math.round(v).toString(16).padStart(2, '0')).join('') } @@ -77,7 +83,6 @@ function lerp(a: number, b: number, t: number): number { return a + t * (b - a) } -// Blue -> amber -> orange gradient across the bar width function gradientColor(pct: number): string { if (pct <= 0.33) { const t = pct / 0.33 @@ -213,37 +218,37 @@ const _homeEncoded = homedir().replace(/\//g, '-') function shortProject(encoded: string): string { let path = encoded.replace(/^-/, '') - if (path.startsWith(_homeEncoded.replace(/^-/, ''))) { path = path.slice(_homeEncoded.replace(/^-/, '').length).replace(/^-/, '') } - - path = path - .replace(/^private-tmp-[^-]+-[^-]+-/, '') // /private/tmp/// - .replace(/^private-tmp-/, '') - .replace(/^tmp-/, '') - + path = path.replace(/^private-tmp-[^-]+-[^-]+-/, '').replace(/^private-tmp-/, '').replace(/^tmp-/, '') if (!path) return 'home' - const parts = path.split('-').filter(Boolean) if (parts.length <= 3) return parts.join('/') return parts.slice(-3).join('/') } -function ProjectBreakdown({ projects, pw, bw }: { projects: ProjectSummary[]; pw: number; bw: number }) { +function ProjectBreakdown({ projects, pw, bw, budgets }: { projects: ProjectSummary[]; pw: number; bw: number; budgets?: Map }) { const maxCost = Math.max(...projects.map(p => p.totalCostUSD)) - const nw = Math.max(8, pw - bw - 23) + const hasBudgets = budgets && budgets.size > 0 + const nw = Math.max(8, pw - bw - (hasBudgets ? 31 : 23)) return ( - {''.padEnd(bw + 1 + nw)}{'cost'.padStart(8)}{'sess'.padStart(6)} - {projects.slice(0, 8).map((project, i) => ( - - - {fit(shortProject(project.project), nw)} - {formatCost(project.totalCostUSD).padStart(8)} - {String(project.sessions.length).padStart(6)} - - ))} + + {''.padEnd(bw + 1 + nw)}{'cost'.padStart(8)}{'sess'.padStart(6)}{hasBudgets ? 'ctx'.padStart(8) : ''} + + {projects.slice(0, 8).map((project, i) => { + const budget = budgets?.get(project.project) + return ( + + + {fit(shortProject(project.project), nw)} + {formatCost(project.totalCostUSD).padStart(8)} + {String(project.sessions.length).padStart(6)} + {hasBudgets && {(budget ? formatTokens(budget.total) : '-').padStart(8)}} + + ) + })} ) } @@ -306,7 +311,6 @@ function ActivityBreakdown({ projects, pw, bw }: { projects: ProjectSummary[]; p } const sorted = Object.entries(categoryTotals).sort(([, a], [, b]) => b.costUSD - a.costUSD) const maxCost = sorted[0]?.[1]?.costUSD ?? 0 - return ( {''.padEnd(bw + 14)}{'cost'.padStart(8)}{'turns'.padStart(6)}{'1-shot'.padStart(7)} @@ -315,9 +319,7 @@ function ActivityBreakdown({ projects, pw, bw }: { projects: ProjectSummary[]; p return ( - - {' '}{fit(CATEGORY_LABELS[cat as TaskCategory] ?? cat, 13)} - + {fit(CATEGORY_LABELS[cat as TaskCategory] ?? cat, 13)} {formatCost(data.costUSD).padStart(8)} {String(data.turns).padStart(6)} {String(oneShotPct).padStart(7)} @@ -333,11 +335,7 @@ function ToolBreakdown({ projects, pw, bw, title, filterPrefix }: { projects: Pr for (const project of projects) { for (const session of project.sessions) { for (const [tool, data] of Object.entries(session.toolBreakdown)) { - if (filterPrefix) { - if (!tool.startsWith(filterPrefix)) continue - } else { - if (tool.startsWith('lang:')) continue - } + if (filterPrefix) { if (!tool.startsWith(filterPrefix)) continue } else { if (tool.startsWith('lang:')) continue } toolTotals[tool] = (toolTotals[tool] ?? 0) + data.calls } } @@ -345,7 +343,6 @@ function ToolBreakdown({ projects, pw, bw, title, filterPrefix }: { projects: Pr const sorted = Object.entries(toolTotals).sort(([, a], [, b]) => b - a) const maxCalls = sorted[0]?.[1] ?? 0 const nw = Math.max(6, pw - bw - 15) - return ( {''.padEnd(bw + 1 + nw)}{'calls'.padStart(7)} @@ -366,29 +363,16 @@ function ToolBreakdown({ projects, pw, bw, title, filterPrefix }: { projects: Pr function McpBreakdown({ projects, pw, bw }: { projects: ProjectSummary[]; pw: number; bw: number }) { const mcpTotals: Record = {} - for (const project of projects) { - for (const session of project.sessions) { - for (const [server, data] of Object.entries(session.mcpBreakdown)) { - mcpTotals[server] = (mcpTotals[server] ?? 0) + data.calls - } - } - } + for (const project of projects) { for (const session of project.sessions) { for (const [server, data] of Object.entries(session.mcpBreakdown)) { mcpTotals[server] = (mcpTotals[server] ?? 0) + data.calls } } } const sorted = Object.entries(mcpTotals).sort(([, a], [, b]) => b - a) - if (sorted.length === 0) { - return No MCP usage - } + if (sorted.length === 0) return No MCP usage const maxCalls = sorted[0]?.[1] ?? 0 const nw = Math.max(6, pw - bw - 15) - return ( {''.padEnd(bw + 1 + nw)}{'calls'.padStart(6)} {sorted.slice(0, 8).map(([server, calls]) => ( - - - {fit(server, nw)} - {String(calls).padStart(6)} - + {fit(server, nw)}{String(calls).padStart(6)} ))} ) @@ -396,29 +380,16 @@ function McpBreakdown({ projects, pw, bw }: { projects: ProjectSummary[]; pw: nu function BashBreakdown({ projects, pw, bw }: { projects: ProjectSummary[]; pw: number; bw: number }) { const bashTotals: Record = {} - for (const project of projects) { - for (const session of project.sessions) { - for (const [cmd, data] of Object.entries(session.bashBreakdown)) { - bashTotals[cmd] = (bashTotals[cmd] ?? 0) + data.calls - } - } - } + for (const project of projects) { for (const session of project.sessions) { for (const [cmd, data] of Object.entries(session.bashBreakdown)) { bashTotals[cmd] = (bashTotals[cmd] ?? 0) + data.calls } } } const sorted = Object.entries(bashTotals).sort(([, a], [, b]) => b - a) - if (sorted.length === 0) { - return No shell commands - } + if (sorted.length === 0) return No shell commands const maxCalls = sorted[0]?.[1] ?? 0 const nw = Math.max(6, pw - bw - 15) - return ( {''.padEnd(bw + 1 + nw)}{'calls'.padStart(7)} {sorted.slice(0, 10).map(([cmd, calls]) => ( - - - {fit(cmd, nw)} - {String(calls).padStart(7)} - + {fit(cmd, nw)}{String(calls).padStart(7)} ))} ) @@ -432,16 +403,9 @@ const PROVIDER_DISPLAY_NAMES: Record = { opencode: 'OpenCode', pi: 'Pi', } +function getProviderDisplayName(name: string): string { return PROVIDER_DISPLAY_NAMES[name] ?? name } -function getProviderDisplayName(name: string): string { - return PROVIDER_DISPLAY_NAMES[name] ?? name -} - -function PeriodTabs({ active, providerName, showProvider }: { - active: Period - providerName?: string - showProvider?: boolean -}) { +function PeriodTabs({ active, providerName, showProvider }: { active: Period; providerName?: string; showProvider?: boolean }) { return ( @@ -452,39 +416,95 @@ function PeriodTabs({ active, providerName, showProvider }: { ))} {showProvider && providerName && ( - - | - [p] - {getProviderDisplayName(providerName)} - + | [p] {getProviderDisplayName(providerName)} )} ) } -function StatusBar({ width, showProvider }: { width: number; showProvider?: boolean }) { +function ContextBudgetPanel({ budget, pw }: { budget: ContextBudget; pw: number }) { + const pct = ((budget.total / budget.modelContext) * 100).toFixed(1) + const available = budget.modelContext - budget.total + const items: Array<{ label: string; tokens: number; color: string }> = [ + { label: 'System base', tokens: budget.systemBase, color: '#5B9EF5' }, + { label: `MCP tools (${budget.mcpTools.count})`, tokens: budget.mcpTools.tokens, color: '#F55BE0' }, + { label: `Skills (${budget.skills.count})`, tokens: budget.skills.tokens, color: '#F5C85B' }, + { label: `Memory (${budget.memory.count})`, tokens: budget.memory.tokens, color: '#5BF5A0' }, + ] + const maxTokens = Math.max(...items.map(i => i.tokens)) + const bw = 6 + return ( + + {''.padEnd(bw + 20)}{'tokens'.padStart(8)} + {items.filter(i => i.tokens > 0).map(item => ( + + + {fit(item.label, 19)} + {formatTokens(item.tokens).padStart(8)} + + ))} + + Overhead: {formatTokens(budget.total)} ({pct}%) Free: {formatTokens(available)} + + + ) +} + +function FindingAction({ action }: { action: WasteAction }) { + const lines = action.type === 'file-content' ? action.content.split('\n') : action.type === 'command' ? action.text.split('\n') : [action.text] + return (<>{action.label}{lines.map((line, i) => {line})}) +} + +function FindingPanel({ index, finding, costRate, width }: { index: number; finding: WasteFinding; costRate: number; width: number }) { + const costSaved = finding.tokensSaved * costRate + const color = IMPACT_PANEL_COLORS[finding.impact] ?? DIM + const label = finding.impact.charAt(0).toUpperCase() + finding.impact.slice(1) + return ( + + {index}. {finding.title} {label} + {finding.explanation} + Savings: ~{formatTokens(finding.tokensSaved)} tokens (~{formatCost(costSaved)}) + + + + ) +} + +function OptimizeView({ findings, costRate, projects, label, width }: { findings: WasteFinding[]; costRate: number; projects: ProjectSummary[]; label: string; width: number }) { + const periodCost = projects.reduce((s, p) => s + p.totalCostUSD, 0) + const totalTokens = findings.reduce((s, f) => s + f.tokensSaved, 0) + const totalCost = totalTokens * costRate + const pctRaw = periodCost > 0 ? (totalCost / periodCost) * 100 : 0 + const pct = pctRaw >= 1 ? pctRaw.toFixed(0) : pctRaw.toFixed(1) + return ( + + + CodeBurn Optimize {label} + Savings: ~{formatTokens(totalTokens)} tokens (~{formatCost(totalCost)}, ~{pct}% of spend) + + {findings.map((f, i) => )} + Token estimates are approximate. + + ) +} + +function StatusBar({ width, showProvider, view, findingCount, optimizeAvailable }: { width: number; showProvider?: boolean; view?: View; findingCount?: number; optimizeAvailable?: boolean }) { + const isOptimize = view === 'optimize' return ( - {'<'}{'>'} - switch - q - quit - 1 - today - 2 - week - 3 - 30 days - 4 - month - {showProvider && ( - <> - - p - provider - + {isOptimize + ? <>b back + : <>{'<'}{'>'} switch } + q quit + 1 today + 2 week + 3 30 days + 4 month + {!isOptimize && optimizeAvailable && findingCount != null && findingCount > 0 && ( + <> o optimize ({findingCount}) )} + {showProvider && (<> p provider)} ) @@ -495,88 +515,87 @@ function Row({ wide, width, children }: { wide: boolean; width: number; children return <>{children} } -function DashboardContent({ projects, period, columns, activeProvider }: { projects: ProjectSummary[]; period: Period; columns?: number; activeProvider?: string }) { +function DashboardContent({ projects, period, columns, activeProvider, budgets }: { projects: ProjectSummary[]; period: Period; columns?: number; activeProvider?: string; budgets?: Map }) { const { dashWidth, wide, halfWidth, barWidth } = getLayout(columns) const isCursor = activeProvider === 'cursor' - - if (projects.length === 0) { - return ( - - No usage data found for {PERIOD_LABELS[period]}. - - ) - } - + if (projects.length === 0) return No usage data found for {PERIOD_LABELS[period]}. const pw = wide ? halfWidth : dashWidth const days = period === 'month' || period === '30days' ? 31 : 14 - return ( - - - - - - - - - - - + + {isCursor ? ( ) : ( - <> - - - - - - + <> )} ) } -function InteractiveDashboard({ initialProjects, initialPeriod, initialProvider, refreshSeconds }: { - initialProjects: ProjectSummary[] - initialPeriod: Period - initialProvider: string - refreshSeconds?: number -}) { +function InteractiveDashboard({ initialProjects, initialPeriod, initialProvider, refreshSeconds }: { initialProjects: ProjectSummary[]; initialPeriod: Period; initialProvider: string; refreshSeconds?: number }) { const { exit } = useApp() const [period, setPeriod] = useState(initialPeriod) const [projects, setProjects] = useState(initialProjects) const [loading, setLoading] = useState(false) const [activeProvider, setActiveProvider] = useState(initialProvider) const [detectedProviders, setDetectedProviders] = useState([]) + const [view, setView] = useState('dashboard') + const [optimizeResult, setOptimizeResult] = useState(null) + const [projectBudgets, setProjectBudgets] = useState>(new Map()) const { columns } = useWindowSize() const { dashWidth } = getLayout(columns) const multipleProviders = detectedProviders.length > 1 + const optimizeAvailable = activeProvider === 'all' || activeProvider === 'claude' + const debounceRef = useRef | null>(null) + const findingCount = optimizeResult?.findings.length ?? 0 useEffect(() => { let cancelled = false async function detect() { const found: string[] = [] - const allProviders = await getAllProviders() - for (const p of allProviders) { - const sessions = await p.discoverSessions() - if (sessions.length > 0) found.push(p.name) - } - if (!cancelled) { - setDetectedProviders(found) - } + for (const p of await getAllProviders()) { const s = await p.discoverSessions(); if (s.length > 0) found.push(p.name) } + if (!cancelled) setDetectedProviders(found) } detect() return () => { cancelled = true } }, []) + useEffect(() => { + let cancelled = false + async function loadBudgets() { + const claudeDir = join(homedir(), '.claude', 'projects') + const budgets = new Map() + for (const project of projects.slice(0, 8)) { + if (cancelled) return + const cwd = await discoverProjectCwd(join(claudeDir, project.project)) + if (!cwd) continue + budgets.set(project.project, await estimateContextBudget(cwd)) + } + if (!cancelled) setProjectBudgets(budgets) + } + loadBudgets() + return () => { cancelled = true } + }, [projects]) + + useEffect(() => { + if (!optimizeAvailable) { setOptimizeResult(null); return } + let cancelled = false + async function scan() { + if (projects.length === 0) { setOptimizeResult(null); return } + const result = await scanAndDetect(projects, getDateRange(period)) + if (!cancelled) setOptimizeResult(result) + } + scan() + return () => { cancelled = true } + }, [projects, period, optimizeAvailable]) + const reloadData = useCallback(async (p: Period, prov: string) => { setLoading(true) - const range = getDateRange(p) - const data = await parseAllSessions(range, prov) - setProjects(data) + setOptimizeResult(null) + setProjects(await parseAllSessions(getDateRange(p), prov)) setLoading(false) }, []) @@ -586,46 +605,34 @@ function InteractiveDashboard({ initialProjects, initialPeriod, initialProvider, return () => clearInterval(id) }, [refreshSeconds, period, activeProvider, reloadData]) - const debounceRef = React.useRef | null>(null) - - const switchPeriod = useCallback((newPeriod: Period) => { - if (newPeriod === period) return - setPeriod(newPeriod) + const switchPeriod = useCallback((np: Period) => { + if (np === period) return + setPeriod(np); setView('dashboard') if (debounceRef.current) clearTimeout(debounceRef.current) - debounceRef.current = setTimeout(() => { - reloadData(newPeriod, activeProvider) - }, 600) + debounceRef.current = setTimeout(() => { reloadData(np, activeProvider) }, 600) }, [period, activeProvider, reloadData]) - const switchPeriodImmediate = useCallback(async (newPeriod: Period) => { - if (newPeriod === period) return - setPeriod(newPeriod) + const switchPeriodImmediate = useCallback(async (np: Period) => { + if (np === period) return + setPeriod(np); setView('dashboard') if (debounceRef.current) clearTimeout(debounceRef.current) - await reloadData(newPeriod, activeProvider) + await reloadData(np, activeProvider) }, [period, activeProvider, reloadData]) useInput((input, key) => { - if (input === 'q') { - exit() - return - } - + if (input === 'q') { exit(); return } + if (input === 'o' && findingCount > 0 && view === 'dashboard' && optimizeAvailable) { setView('optimize'); return } + if ((input === 'b' || key.escape) && view === 'optimize') { setView('dashboard'); return } if (input === 'p' && multipleProviders) { - const options = ['all', ...detectedProviders] - const idx = options.indexOf(activeProvider) - const next = options[(idx + 1) % options.length] - setActiveProvider(next) + const opts = ['all', ...detectedProviders]; const next = opts[(opts.indexOf(activeProvider) + 1) % opts.length] + setActiveProvider(next); setView('dashboard') if (debounceRef.current) clearTimeout(debounceRef.current) - reloadData(period, next) - return + reloadData(period, next); return } - const idx = PERIODS.indexOf(period) - if (key.leftArrow) { - switchPeriod(PERIODS[(idx - 1 + PERIODS.length) % PERIODS.length]) - } else if (key.rightArrow || key.tab) { - switchPeriod(PERIODS[(idx + 1) % PERIODS.length]) - } else if (input === '1') switchPeriodImmediate('today') + if (key.leftArrow && view === 'dashboard') switchPeriod(PERIODS[(idx - 1 + PERIODS.length) % PERIODS.length]) + else if ((key.rightArrow || key.tab) && view === 'dashboard') switchPeriod(PERIODS[(idx + 1) % PERIODS.length]) + else if (input === '1') switchPeriodImmediate('today') else if (input === '2') switchPeriodImmediate('week') else if (input === '3') switchPeriodImmediate('30days') else if (input === '4') switchPeriodImmediate('month') @@ -635,10 +642,8 @@ function InteractiveDashboard({ initialProjects, initialPeriod, initialProvider, return ( - - Loading {PERIOD_LABELS[period]}... - - + Loading {PERIOD_LABELS[period]}... + ) } @@ -646,8 +651,10 @@ function InteractiveDashboard({ initialProjects, initialPeriod, initialProvider, return ( - - + {view === 'optimize' && optimizeResult + ? + : } + ) } @@ -665,21 +672,13 @@ function StaticDashboard({ projects, period, activeProvider }: { projects: Proje export async function renderDashboard(period: Period = 'week', provider: string = 'all', refreshSeconds?: number): Promise { await loadPricing() - const range = getDateRange(period) - const projects = await parseAllSessions(range, provider) - + const projects = await parseAllSessions(getDateRange(period), provider) const isTTY = process.stdin.isTTY && process.stdout.isTTY - if (isTTY) { - const { waitUntilExit } = render( - - ) + const { waitUntilExit } = render() await waitUntilExit() } else { - const { unmount } = render( - , - { patchConsole: false } - ) + const { unmount } = render(, { patchConsole: false }) unmount() } } diff --git a/src/optimize.ts b/src/optimize.ts new file mode 100644 index 0000000..f29a904 --- /dev/null +++ b/src/optimize.ts @@ -0,0 +1,696 @@ +import chalk from 'chalk' +import { readdir, readFile, stat } from 'fs/promises' +import { existsSync, readFileSync } from 'fs' +import { basename, join } from 'path' +import { homedir } from 'os' + +import { discoverAllSessions } from './providers/index.js' +import type { DateRange, ProjectSummary } from './types.js' +import { formatCost } from './currency.js' +import { formatTokens } from './format.js' + +const ORANGE = '#FF8C42' +const DIM = '#666666' +const GOLD = '#FFD700' +const CYAN = '#5BF5E0' +const GREEN = '#5BF5A0' + +const JUNK_DIRS = [ + 'node_modules', '.git', 'dist', 'build', '__pycache__', '.next', + '.nuxt', '.output', 'coverage', '.cache', '.tsbuildinfo', + '.venv', 'venv', '.svn', '.hg', +] +const JUNK_PATTERN = new RegExp(`/(${JUNK_DIRS.join('|')})/`) + +const AVG_TOKENS_PER_READ = 1500 +const TOKENS_PER_MCP_TOOL = 400 +const CLAUDEMD_HEALTHY_LINES = 200 + +export type WasteAction = + | { type: 'paste'; label: string; text: string } + | { type: 'command'; label: string; text: string } + | { type: 'file-content'; label: string; path: string; content: string } + +export type WasteFinding = { + title: string + explanation: string + impact: 'high' | 'medium' | 'low' + tokensSaved: number + fix: WasteAction +} + +export type OptimizeResult = { + findings: WasteFinding[] + costRate: number +} + +type ToolCall = { + name: string + input: Record + sessionId: string + project: string +} + +type ApiCallMeta = { + cacheCreationTokens: number + version: string +} + +type ScanData = { + toolCalls: ToolCall[] + projectCwds: Set + apiCalls: ApiCallMeta[] + versions: Set +} + +const IMPACT_ORDER: Record = { high: 3, medium: 2, low: 1 } + +async function collectJsonlFiles(dirPath: string): Promise { + const files = await readdir(dirPath).catch(() => []) + const result = files.filter(f => f.endsWith('.jsonl')).map(f => join(dirPath, f)) + for (const entry of files) { + if (entry.endsWith('.jsonl')) continue + const subPath = join(dirPath, entry, 'subagents') + const subFiles = await readdir(subPath).catch(() => []) + for (const sf of subFiles) { + if (sf.endsWith('.jsonl')) result.push(join(subPath, sf)) + } + } + return result +} + +type ScanFileResult = { + calls: ToolCall[] + cwds: string[] + apiCalls: ApiCallMeta[] + versions: string[] +} + +async function scanJsonlFile( + filePath: string, + project: string, + dateRange: DateRange | undefined, +): Promise { + let content: string + try { + content = await readFile(filePath, 'utf-8') + } catch { return { calls: [], cwds: [], apiCalls: [], versions: [] } } + + const calls: ToolCall[] = [] + const cwds: string[] = [] + const apiCalls: ApiCallMeta[] = [] + const versions: string[] = [] + const sessionId = basename(filePath, '.jsonl') + + for (const line of content.split('\n')) { + if (!line.trim()) continue + let entry: Record + try { entry = JSON.parse(line) } catch { continue } + + if (entry.cwd && typeof entry.cwd === 'string') cwds.push(entry.cwd) + if (entry.version && typeof entry.version === 'string') versions.push(entry.version) + + if (entry.type !== 'assistant') continue + + if (dateRange && typeof entry.timestamp === 'string') { + const ts = new Date(entry.timestamp) + if (ts < dateRange.start || ts > dateRange.end) continue + } + + const msg = entry.message as Record | undefined + const usage = msg?.usage as Record | undefined + if (usage) { + const cacheCreate = (usage.cache_creation_input_tokens as number) ?? 0 + const ver = versions[versions.length - 1] ?? '' + if (cacheCreate > 0) apiCalls.push({ cacheCreationTokens: cacheCreate, version: ver }) + } + + const blocks = msg?.content + if (!Array.isArray(blocks)) continue + + for (const block of blocks) { + if (block.type !== 'tool_use') continue + calls.push({ + name: block.name as string, + input: (block.input as Record) ?? {}, + sessionId, + project, + }) + } + } + + return { calls, cwds, apiCalls, versions } +} + +async function scanSessions(dateRange?: DateRange): Promise { + const sources = await discoverAllSessions('claude') + const allCalls: ToolCall[] = [] + const allCwds = new Set() + const allApiCalls: ApiCallMeta[] = [] + const allVersions = new Set() + + for (const source of sources) { + const files = await collectJsonlFiles(source.path) + for (const file of files) { + const { calls, cwds, apiCalls, versions } = await scanJsonlFile(file, source.project, dateRange) + allCalls.push(...calls) + for (const cwd of cwds) allCwds.add(cwd) + allApiCalls.push(...apiCalls) + for (const v of versions) if (v) allVersions.add(v) + } + } + + return { toolCalls: allCalls, projectCwds: allCwds, apiCalls: allApiCalls, versions: allVersions } +} + +function detectJunkReads(calls: ToolCall[]): WasteFinding | null { + const readCalls = calls.filter(c => c.name === 'Read' || c.name === 'FileReadTool') + + const dirCounts = new Map() + let totalJunkReads = 0 + + for (const call of readCalls) { + const filePath = call.input.file_path as string | undefined + if (!filePath) continue + if (!JUNK_PATTERN.test(filePath)) continue + + totalJunkReads++ + for (const dir of JUNK_DIRS) { + if (filePath.includes(`/${dir}/`)) { + dirCounts.set(dir, (dirCounts.get(dir) ?? 0) + 1) + break + } + } + } + + if (totalJunkReads < 3) return null + + const sorted = [...dirCounts.entries()].sort((a, b) => b[1] - a[1]) + const dirList = sorted.slice(0, 3).map(([d, n]) => `${d}/ (${n}x)`).join(', ') + const tokensSaved = totalJunkReads * AVG_TOKENS_PER_READ + + const detected = sorted.map(([d]) => d) + const extras = ['node_modules', '.git', 'dist', '__pycache__'] + .filter(d => !dirCounts.has(d)) + .slice(0, Math.max(0, 6 - detected.length)) + const ignoreContent = [...detected, ...extras].join('\n') + + return { + title: 'STOP READING JUNK DIRECTORIES', + explanation: `Claude read into ${dirList} -- ${totalJunkReads} times total. Each read loads ~${AVG_TOKENS_PER_READ.toLocaleString()} tokens of irrelevant content into context. A .claudeignore blocks this.`, + impact: totalJunkReads > 20 ? 'high' : totalJunkReads > 5 ? 'medium' : 'low', + tokensSaved, + fix: { + type: 'file-content', + label: 'Create .claudeignore in your project root:', + path: '.claudeignore', + content: ignoreContent, + }, + } +} + +function detectDuplicateReads(calls: ToolCall[]): WasteFinding | null { + const readCalls = calls.filter(c => c.name === 'Read' || c.name === 'FileReadTool') + + const sessionFiles = new Map>() + + for (const call of readCalls) { + const filePath = call.input.file_path as string | undefined + if (!filePath || JUNK_PATTERN.test(filePath)) continue + + const key = `${call.project}:${call.sessionId}` + if (!sessionFiles.has(key)) sessionFiles.set(key, new Map()) + const fm = sessionFiles.get(key)! + fm.set(filePath, (fm.get(filePath) ?? 0) + 1) + } + + let totalDuplicates = 0 + const fileDupes = new Map() + + for (const fm of sessionFiles.values()) { + for (const [file, count] of fm) { + if (count <= 1) continue + const extra = count - 1 + totalDuplicates += extra + const name = basename(file) + fileDupes.set(name, (fileDupes.get(name) ?? 0) + extra) + } + } + + if (totalDuplicates < 5) return null + + const worst = [...fileDupes.entries()] + .sort((a, b) => b[1] - a[1]) + .slice(0, 3) + .map(([name, n]) => `${name} (+${n})`) + .join(', ') + + const tokensSaved = totalDuplicates * AVG_TOKENS_PER_READ + + return { + title: 'CUT DUPLICATE FILE READS', + explanation: `Claude re-read the same file ${totalDuplicates} times across sessions. Top offenders: ${worst}. Each re-read loads ~${AVG_TOKENS_PER_READ.toLocaleString()} tokens that are already in context.`, + impact: totalDuplicates > 30 ? 'high' : totalDuplicates > 10 ? 'medium' : 'low', + tokensSaved, + fix: { + type: 'paste', + label: 'Give Claude exact locations so it reads once:', + text: 'Look at src/auth.ts lines 45-80, the validateToken function.', + }, + } +} + +function readJsonFile(path: string): Record | null { + try { + return JSON.parse(readFileSync(path, 'utf-8')) + } catch { return null } +} + +function detectUnusedMcp( + calls: ToolCall[], + projects: ProjectSummary[], + projectCwds: Set, +): WasteFinding | null { + const configuredServers = new Map() + + const configPaths = [ + join(homedir(), '.claude', 'settings.json'), + join(homedir(), '.claude', 'settings.local.json'), + ] + for (const cwd of projectCwds) { + configPaths.push(join(cwd, '.mcp.json')) + configPaths.push(join(cwd, '.claude', 'settings.json')) + configPaths.push(join(cwd, '.claude', 'settings.local.json')) + } + + for (const p of configPaths) { + if (!existsSync(p)) continue + const config = readJsonFile(p) + if (!config) continue + const servers = (config.mcpServers ?? {}) as Record + for (const name of Object.keys(servers)) { + const normalized = name.replace(/:/g, '_') + configuredServers.set(normalized, name) + } + } + + if (configuredServers.size === 0) return null + + const calledServers = new Set() + for (const call of calls) { + if (!call.name.startsWith('mcp__')) continue + const seg = call.name.split('__')[1] + if (seg) calledServers.add(seg) + } + for (const p of projects) { + for (const s of p.sessions) { + for (const server of Object.keys(s.mcpBreakdown)) { + calledServers.add(server) + } + } + } + + const unused: string[] = [] + for (const [normalized, original] of configuredServers) { + if (!calledServers.has(normalized)) unused.push(original) + } + + if (unused.length === 0) return null + + const totalSessions = projects.reduce((s, p) => s + p.sessions.length, 0) + const estimatedTools = 5 + const schemaTokens = unused.length * estimatedTools * TOKENS_PER_MCP_TOOL + const tokensSaved = schemaTokens * totalSessions + + return { + title: 'REMOVE UNUSED MCP SERVERS', + explanation: `${unused.length} MCP server${unused.length > 1 ? 's' : ''} configured but never called: ${unused.join(', ')}. Each loads ~${(estimatedTools * TOKENS_PER_MCP_TOOL).toLocaleString()} tokens of schema into every session (${totalSessions.toLocaleString()} sessions in this period).`, + impact: unused.length >= 3 ? 'high' : 'medium', + tokensSaved, + fix: { + type: 'command', + label: `Remove unused server${unused.length > 1 ? 's' : ''}:`, + text: unused.map(s => `claude mcp remove ${s}`).join('\n'), + }, + } +} + +function detectMissingClaudeignore(projectCwds: Set): WasteFinding | null { + const missing: string[] = [] + const hasJunkDir: string[] = [] + + for (const cwd of projectCwds) { + if (existsSync(join(cwd, '.claudeignore'))) continue + if (!existsSync(cwd)) continue + + for (const dir of JUNK_DIRS) { + if (existsSync(join(cwd, dir))) { + missing.push(cwd) + hasJunkDir.push(dir) + break + } + } + } + + if (missing.length === 0) return null + + const shortPaths = missing.map(p => { + const home = homedir() + return p.startsWith(home) ? '~' + p.slice(home.length) : p + }) + const display = shortPaths.length <= 3 + ? shortPaths.join(', ') + : `${shortPaths.slice(0, 2).join(', ')} + ${shortPaths.length - 2} more` + + const tokensSaved = missing.length * 10 * AVG_TOKENS_PER_READ + + return { + title: 'ADD .claudeignore FILES', + explanation: `${missing.length} project${missing.length > 1 ? 's' : ''} ha${missing.length > 1 ? 've' : 's'} junk directories (node_modules, .git, etc.) but no .claudeignore: ${display}. Without it, Claude may read/search these directories.`, + impact: missing.length >= 3 ? 'high' : 'medium', + tokensSaved, + fix: { + type: 'file-content', + label: 'Create .claudeignore in each project root:', + path: '.claudeignore', + content: JUNK_DIRS.slice(0, 8).join('\n'), + }, + } +} + +function detectBloatedClaudeMd(projectCwds: Set): WasteFinding | null { + const bloated: { path: string; lines: number }[] = [] + + for (const cwd of projectCwds) { + for (const name of ['CLAUDE.md', '.claude/CLAUDE.md']) { + const fullPath = join(cwd, name) + if (!existsSync(fullPath)) continue + try { + const content = readFileSync(fullPath, 'utf-8') + const lineCount = content.split('\n').length + if (lineCount > CLAUDEMD_HEALTHY_LINES) { + const short = cwd.startsWith(homedir()) ? '~' + cwd.slice(homedir().length) : cwd + bloated.push({ path: `${short}/${name}`, lines: lineCount }) + } + } catch { continue } + } + } + + if (bloated.length === 0) return null + + const sorted = bloated.sort((a, b) => b.lines - a.lines) + const worst = sorted[0] + const totalExtraLines = sorted.reduce((s, b) => s + (b.lines - CLAUDEMD_HEALTHY_LINES), 0) + const tokensPerLine = 25 + const tokensSaved = totalExtraLines * tokensPerLine + + const list = sorted.slice(0, 3).map(b => `${b.path} (${b.lines} lines)`).join(', ') + + return { + title: 'TRIM BLOATED CLAUDE.md', + explanation: `${list}. Every line loads into every API call as context. Beyond ${CLAUDEMD_HEALTHY_LINES} lines, the extra ~${totalExtraLines} lines cost ~${formatTokens(tokensSaved)} tokens per call.`, + impact: worst.lines > 400 ? 'high' : 'medium', + tokensSaved, + fix: { + type: 'paste', + label: 'Ask Claude to trim it:', + text: 'Review CLAUDE.md and cut it to under 200 lines. Remove anything Claude can figure out from the code itself: file paths, architecture, imports. Keep only: rules, gotchas, and non-obvious conventions.', + }, + } +} + +const READ_TOOL_NAMES = new Set(['Read', 'Grep', 'Glob', 'FileReadTool', 'GrepTool', 'GlobTool']) +const EDIT_TOOL_NAMES = new Set(['Edit', 'Write', 'FileEditTool', 'FileWriteTool', 'NotebookEdit']) + +function detectLowReadEditRatio(calls: ToolCall[]): WasteFinding | null { + let reads = 0 + let edits = 0 + + for (const call of calls) { + if (READ_TOOL_NAMES.has(call.name)) reads++ + else if (EDIT_TOOL_NAMES.has(call.name)) edits++ + } + + if (edits < 10) return null + + const ratio = reads / edits + if (ratio >= 4) return null + + const ratioStr = ratio.toFixed(1) + const impact: 'high' | 'medium' | 'low' = ratio < 2 ? 'high' : ratio < 3 ? 'medium' : 'low' + + const extraReadsNeeded = Math.round(edits * 4) - reads + const tokensSaved = extraReadsNeeded * AVG_TOKENS_PER_READ + + return { + title: 'CLAUDE IS EDITING WITHOUT READING', + explanation: `Read:Edit ratio is ${ratioStr}:1 (${reads} reads, ${edits} edits). Healthy is 4:1+. A low ratio means Claude edits files without fully understanding the codebase first -- leading to more retries and wasted tokens.`, + impact, + tokensSaved: Math.max(tokensSaved, 0), + fix: { + type: 'paste', + label: 'Add to your CLAUDE.md:', + text: 'Before editing any file, read it first. Before modifying a function, grep for all callers. Research before you edit.', + }, + } +} + +function detectCacheBloat(apiCalls: ApiCallMeta[]): WasteFinding | null { + if (apiCalls.length < 10) return null + + const sorted = apiCalls.map(c => c.cacheCreationTokens).sort((a, b) => a - b) + const median = sorted[Math.floor(sorted.length / 2)] + + if (median < 55000) return null + + const versionCounts = new Map() + for (const call of apiCalls) { + if (!call.version) continue + const v = call.version + const entry = versionCounts.get(v) ?? { total: 0, count: 0 } + entry.total += call.cacheCreationTokens + entry.count++ + versionCounts.set(v, entry) + } + + const versionAvgs = [...versionCounts.entries()] + .filter(([, d]) => d.count >= 5) + .map(([v, d]) => ({ version: v, avg: Math.round(d.total / d.count), count: d.count })) + .sort((a, b) => b.avg - a.avg) + + const excess = median - 50000 + const tokensSaved = excess * apiCalls.length + + let versionNote = '' + if (versionAvgs.length >= 2) { + const highest = versionAvgs[0] + const lowest = versionAvgs[versionAvgs.length - 1] + if (highest.avg - lowest.avg > 10000) { + versionNote = ` Version ${highest.version} averages ${formatTokens(highest.avg)} vs ${lowest.version} at ${formatTokens(lowest.avg)}.` + } + } + + return { + title: 'HIGH CACHE CREATION OVERHEAD', + explanation: `Median cache_creation per call is ${formatTokens(median)} tokens (baseline ~50K). The extra ~${formatTokens(excess)} tokens per call may be server-injected content invisible to you.${versionNote} See anthropics/claude-code#46917.`, + impact: excess > 15000 ? 'high' : 'medium', + tokensSaved, + fix: { + type: 'paste', + label: 'Spoof older User-Agent to reduce overhead:', + text: 'export ANTHROPIC_CUSTOM_HEADERS=\'User-Agent: claude-cli/2.1.98 (external, sdk-cli)\'', + }, + } +} + +function detectBashBloat(): WasteFinding | null { + const current = process.env['BASH_MAX_OUTPUT_LENGTH'] + if (current && parseInt(current, 10) <= 15000) return null + + const limit = current ? parseInt(current, 10) : 30000 + const saved = limit - 15000 + const tokensSaved = Math.round(saved * 0.25) + + return { + title: 'CAP BASH OUTPUT LENGTH', + explanation: `Bash output limit is ${(limit / 1000).toFixed(0)}K characters (${current ? 'configured' : 'default'}). Most useful output is under 15K. The extra ${(saved / 1000).toFixed(0)}K chars waste ~${formatTokens(tokensSaved)} tokens per bash call.`, + impact: 'medium', + tokensSaved, + fix: { + type: 'paste', + label: 'Add to your shell profile (~/.zshrc or ~/.bashrc):', + text: 'export BASH_MAX_OUTPUT_LENGTH=15000', + }, + } +} + +function computeInputCostRate(projects: ProjectSummary[]): number { + const sessions = projects.flatMap(p => p.sessions) + const totalCost = sessions.reduce((s, sess) => s + sess.totalCostUSD, 0) + const totalTokens = sessions.reduce((s, sess) => + s + sess.totalInputTokens + sess.totalCacheReadTokens + sess.totalCacheWriteTokens, 0) + if (totalTokens === 0 || totalCost === 0) return 1 / 1_000_000 + return (totalCost * 0.7) / totalTokens +} + +function wrap(text: string, width: number, indent: string): string { + const words = text.split(' ') + const lines: string[] = [] + let current = '' + for (const word of words) { + if (current && current.length + word.length + 1 > width) { + lines.push(indent + current) + current = word + } else { + current = current ? current + ' ' + word : word + } + } + if (current) lines.push(indent + current) + return lines.join('\n') +} + +const IMPACT_COLORS: Record = { high: '#F55B5B', medium: ORANGE, low: DIM } + +function renderFinding(n: number, f: WasteFinding, costRate: number, W: number): string[] { + const lines: string[] = [] + const sep = '\u2500' + const costSaved = f.tokensSaved * costRate + const impactLabel = f.impact.charAt(0).toUpperCase() + f.impact.slice(1) + const savings = `~${formatTokens(f.tokensSaved)} tokens (~${formatCost(costSaved)})` + const titlePad = W - f.title.length - impactLabel.length - 8 + const pad = titlePad > 0 ? ' ' + sep.repeat(titlePad) + ' ' : ' ' + + lines.push(chalk.hex(DIM)(` ${sep}${sep}${sep} `) + + chalk.bold(`${n}. ${f.title}`) + + chalk.hex(DIM)(pad) + + chalk.hex(IMPACT_COLORS[f.impact] ?? DIM)(impactLabel) + + chalk.hex(DIM)(` ${sep}${sep}${sep}`)) + lines.push('') + lines.push(wrap(f.explanation, W - 4, ' ')) + lines.push('') + lines.push(chalk.hex(GOLD)(` Potential savings: ${savings}`)) + lines.push('') + + const a = f.fix + if (a.type === 'file-content') { + lines.push(chalk.hex(DIM)(` ${a.label}`)) + for (const line of a.content.split('\n')) { + lines.push(chalk.hex(CYAN)(` ${line}`)) + } + } else if (a.type === 'command') { + lines.push(chalk.hex(DIM)(` ${a.label}`)) + for (const line of a.text.split('\n')) { + lines.push(chalk.hex(CYAN)(` ${line}`)) + } + } else { + lines.push(chalk.hex(DIM)(` ${a.label}`)) + lines.push(chalk.hex(CYAN)(` ${a.text}`)) + } + + lines.push('') + return lines +} + +function renderOptimize( + findings: WasteFinding[], + costRate: number, + periodLabel: string, + periodCost: number, + sessionCount: number, + callCount: number, +): string { + const lines: string[] = [] + const W = 62 + const sep = '\u2500' + + lines.push('') + lines.push(` ${chalk.bold.hex(ORANGE)('CodeBurn Optimize')}${chalk.dim(' ' + periodLabel)}`) + lines.push(chalk.hex(DIM)(' ' + sep.repeat(W))) + + lines.push(' ' + [ + `${sessionCount} sessions`, + `${callCount.toLocaleString()} calls`, + chalk.hex(GOLD)(formatCost(periodCost)), + ].join(chalk.hex(DIM)(' '))) + lines.push('') + + if (findings.length === 0) { + lines.push(chalk.hex(GREEN)(' No waste detected -- your setup looks clean.')) + lines.push('') + return lines.join('\n') + } + + const totalTokens = findings.reduce((s, f) => s + f.tokensSaved, 0) + const totalCost = totalTokens * costRate + const pctRaw = periodCost > 0 ? (totalCost / periodCost) * 100 : 0 + const pct = pctRaw >= 1 ? pctRaw.toFixed(0) : pctRaw.toFixed(1) + + lines.push(chalk.hex(GREEN)(` Potential savings: ~${formatTokens(totalTokens)} tokens (~${formatCost(totalCost)}, ~${pct}% of spend)`)) + lines.push('') + + const sorted = findings.sort((a, b) => + (IMPACT_ORDER[b.impact] ?? 0) - (IMPACT_ORDER[a.impact] ?? 0) || b.tokensSaved - a.tokensSaved + ) + + for (let i = 0; i < sorted.length; i++) { + lines.push(...renderFinding(i + 1, sorted[i], costRate, W)) + } + + lines.push(chalk.hex(DIM)(' ' + sep.repeat(W))) + lines.push(chalk.dim(' Token estimates are approximate. Actual savings vary by file size and model.')) + lines.push('') + + return lines.join('\n') +} + +export async function scanAndDetect( + projects: ProjectSummary[], + dateRange?: DateRange, +): Promise { + const costRate = computeInputCostRate(projects) + const { toolCalls, projectCwds, apiCalls } = await scanSessions(dateRange) + + const findings: WasteFinding[] = [] + const detectors = [ + () => detectCacheBloat(apiCalls), + () => detectLowReadEditRatio(toolCalls), + () => detectJunkReads(toolCalls), + () => detectDuplicateReads(toolCalls), + () => detectUnusedMcp(toolCalls, projects, projectCwds), + () => detectMissingClaudeignore(projectCwds), + () => detectBloatedClaudeMd(projectCwds), + () => detectBashBloat(), + ] + + for (const detect of detectors) { + const finding = detect() + if (finding) findings.push(finding) + } + + findings.sort((a, b) => + (IMPACT_ORDER[b.impact] ?? 0) - (IMPACT_ORDER[a.impact] ?? 0) || b.tokensSaved - a.tokensSaved + ) + + return { findings, costRate } +} + +export async function runOptimize( + projects: ProjectSummary[], + periodLabel: string, + dateRange?: DateRange, +): Promise { + if (projects.length === 0) { + console.log(chalk.dim('\n No usage data found for this period.\n')) + return + } + + process.stderr.write(chalk.dim(' Scanning sessions for waste patterns...\n')) + + const { findings, costRate } = await scanAndDetect(projects, dateRange) + const sessions = projects.flatMap(p => p.sessions) + const periodCost = projects.reduce((s, p) => s + p.totalCostUSD, 0) + const callCount = projects.reduce((s, p) => s + p.totalApiCalls, 0) + + const output = renderOptimize(findings, costRate, periodLabel, periodCost, sessions.length, callCount) + console.log(output) +} diff --git a/tests/optimize.test.ts b/tests/optimize.test.ts new file mode 100644 index 0000000..c8514ea --- /dev/null +++ b/tests/optimize.test.ts @@ -0,0 +1,238 @@ +import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest' +import { existsSync, readFileSync } from 'fs' +import { homedir } from 'os' +import { join } from 'path' + +vi.mock('fs', async () => { + const actual = await vi.importActual('fs') + return { ...actual, existsSync: vi.fn(), readFileSync: vi.fn() } +}) + +const mockExistsSync = vi.mocked(existsSync) +const mockReadFileSync = vi.mocked(readFileSync) + +type ToolCall = { + name: string + input: Record + sessionId: string + project: string +} + +// Re-implement detector logic for isolated testing +// This avoids importing the module which has side-effect imports + +function detectJunkReadsLogic(calls: ToolCall[]) { + const JUNK_PATTERN = /\/(node_modules|\.git|dist|build|__pycache__|\.next|\.nuxt|\.output|coverage|\.cache|\.tsbuildinfo|\.venv|venv|\.svn|\.hg)\// + const readCalls = calls.filter(c => c.name === 'Read' || c.name === 'FileReadTool') + const dirCounts = new Map() + let total = 0 + for (const call of readCalls) { + const fp = call.input.file_path as string | undefined + if (!fp || !JUNK_PATTERN.test(fp)) continue + total++ + const dirs = ['node_modules', '.git', 'dist', 'build', '__pycache__', '.next', '.venv', 'venv'] + for (const d of dirs) { + if (fp.includes(`/${d}/`)) { dirCounts.set(d, (dirCounts.get(d) ?? 0) + 1); break } + } + } + return { total, dirCounts } +} + +function detectDuplicateReadsLogic(calls: ToolCall[]) { + const JUNK_PATTERN = /\/(node_modules|\.git|dist|build|__pycache__|\.next)\// + const readCalls = calls.filter(c => c.name === 'Read' || c.name === 'FileReadTool') + const sessionFiles = new Map>() + for (const call of readCalls) { + const fp = call.input.file_path as string | undefined + if (!fp || JUNK_PATTERN.test(fp)) continue + const key = `${call.project}:${call.sessionId}` + if (!sessionFiles.has(key)) sessionFiles.set(key, new Map()) + const fm = sessionFiles.get(key)! + fm.set(fp, (fm.get(fp) ?? 0) + 1) + } + let totalDuplicates = 0 + for (const fm of sessionFiles.values()) { + for (const [, count] of fm) { + if (count > 1) totalDuplicates += count - 1 + } + } + return totalDuplicates +} + +describe('optimize: junk reads detection', () => { + it('detects node_modules reads', () => { + const calls: ToolCall[] = [ + { name: 'Read', input: { file_path: '/project/node_modules/foo/index.js' }, sessionId: 's1', project: 'p1' }, + { name: 'Read', input: { file_path: '/project/node_modules/bar/package.json' }, sessionId: 's1', project: 'p1' }, + { name: 'Read', input: { file_path: '/project/node_modules/baz/lib.js' }, sessionId: 's1', project: 'p1' }, + { name: 'Read', input: { file_path: '/project/src/main.ts' }, sessionId: 's1', project: 'p1' }, + ] + const result = detectJunkReadsLogic(calls) + expect(result.total).toBe(3) + expect(result.dirCounts.get('node_modules')).toBe(3) + }) + + it('detects .git reads', () => { + const calls: ToolCall[] = [ + { name: 'Read', input: { file_path: '/project/.git/config' }, sessionId: 's1', project: 'p1' }, + { name: 'Read', input: { file_path: '/project/.git/HEAD' }, sessionId: 's1', project: 'p1' }, + ] + const result = detectJunkReadsLogic(calls) + expect(result.total).toBe(2) + expect(result.dirCounts.get('.git')).toBe(2) + }) + + it('detects mixed junk directories', () => { + const calls: ToolCall[] = [ + { name: 'Read', input: { file_path: '/project/node_modules/a.js' }, sessionId: 's1', project: 'p1' }, + { name: 'Read', input: { file_path: '/project/dist/bundle.js' }, sessionId: 's1', project: 'p1' }, + { name: 'Read', input: { file_path: '/project/.venv/lib/python/site.py' }, sessionId: 's1', project: 'p1' }, + ] + const result = detectJunkReadsLogic(calls) + expect(result.total).toBe(3) + expect(result.dirCounts.get('node_modules')).toBe(1) + expect(result.dirCounts.get('dist')).toBe(1) + expect(result.dirCounts.get('.venv')).toBe(1) + }) + + it('ignores non-junk paths', () => { + const calls: ToolCall[] = [ + { name: 'Read', input: { file_path: '/project/src/index.ts' }, sessionId: 's1', project: 'p1' }, + { name: 'Read', input: { file_path: '/project/README.md' }, sessionId: 's1', project: 'p1' }, + ] + const result = detectJunkReadsLogic(calls) + expect(result.total).toBe(0) + }) + + it('ignores non-Read tools', () => { + const calls: ToolCall[] = [ + { name: 'Edit', input: { file_path: '/project/node_modules/foo.js' }, sessionId: 's1', project: 'p1' }, + { name: 'Bash', input: { command: 'ls node_modules' }, sessionId: 's1', project: 'p1' }, + ] + const result = detectJunkReadsLogic(calls) + expect(result.total).toBe(0) + }) + + it('handles missing file_path', () => { + const calls: ToolCall[] = [ + { name: 'Read', input: {}, sessionId: 's1', project: 'p1' }, + { name: 'Read', input: { file_path: null as unknown as string }, sessionId: 's1', project: 'p1' }, + ] + const result = detectJunkReadsLogic(calls) + expect(result.total).toBe(0) + }) +}) + +describe('optimize: duplicate reads detection', () => { + it('detects files read multiple times in same session', () => { + const calls: ToolCall[] = [ + { name: 'Read', input: { file_path: '/project/src/main.ts' }, sessionId: 's1', project: 'p1' }, + { name: 'Read', input: { file_path: '/project/src/main.ts' }, sessionId: 's1', project: 'p1' }, + { name: 'Read', input: { file_path: '/project/src/main.ts' }, sessionId: 's1', project: 'p1' }, + ] + expect(detectDuplicateReadsLogic(calls)).toBe(2) + }) + + it('does not count reads across different sessions', () => { + const calls: ToolCall[] = [ + { name: 'Read', input: { file_path: '/project/src/main.ts' }, sessionId: 's1', project: 'p1' }, + { name: 'Read', input: { file_path: '/project/src/main.ts' }, sessionId: 's2', project: 'p1' }, + ] + expect(detectDuplicateReadsLogic(calls)).toBe(0) + }) + + it('excludes junk directory reads from duplicate count', () => { + const calls: ToolCall[] = [ + { name: 'Read', input: { file_path: '/project/node_modules/foo.js' }, sessionId: 's1', project: 'p1' }, + { name: 'Read', input: { file_path: '/project/node_modules/foo.js' }, sessionId: 's1', project: 'p1' }, + ] + expect(detectDuplicateReadsLogic(calls)).toBe(0) + }) + + it('counts duplicates per file independently', () => { + const calls: ToolCall[] = [ + { name: 'Read', input: { file_path: '/project/a.ts' }, sessionId: 's1', project: 'p1' }, + { name: 'Read', input: { file_path: '/project/a.ts' }, sessionId: 's1', project: 'p1' }, + { name: 'Read', input: { file_path: '/project/b.ts' }, sessionId: 's1', project: 'p1' }, + { name: 'Read', input: { file_path: '/project/b.ts' }, sessionId: 's1', project: 'p1' }, + { name: 'Read', input: { file_path: '/project/b.ts' }, sessionId: 's1', project: 'p1' }, + ] + expect(detectDuplicateReadsLogic(calls)).toBe(3) + }) + + it('returns 0 for single reads', () => { + const calls: ToolCall[] = [ + { name: 'Read', input: { file_path: '/project/a.ts' }, sessionId: 's1', project: 'p1' }, + { name: 'Read', input: { file_path: '/project/b.ts' }, sessionId: 's1', project: 'p1' }, + { name: 'Read', input: { file_path: '/project/c.ts' }, sessionId: 's1', project: 'p1' }, + ] + expect(detectDuplicateReadsLogic(calls)).toBe(0) + }) + + it('handles empty calls', () => { + expect(detectDuplicateReadsLogic([])).toBe(0) + }) +}) + +function detectReadEditRatioLogic(calls: ToolCall[]) { + const READ_NAMES = new Set(['Read', 'Grep', 'Glob', 'FileReadTool', 'GrepTool', 'GlobTool']) + const EDIT_NAMES = new Set(['Edit', 'Write', 'FileEditTool', 'FileWriteTool', 'NotebookEdit']) + let reads = 0, edits = 0 + for (const c of calls) { + if (READ_NAMES.has(c.name)) reads++ + else if (EDIT_NAMES.has(c.name)) edits++ + } + return { reads, edits, ratio: edits > 0 ? reads / edits : Infinity } +} + +describe('optimize: read:edit ratio detection', () => { + it('detects low ratio (edit-heavy)', () => { + const calls: ToolCall[] = [ + ...Array(5).fill(null).map(() => ({ name: 'Read', input: {}, sessionId: 's1', project: 'p1' })), + ...Array(10).fill(null).map(() => ({ name: 'Edit', input: {}, sessionId: 's1', project: 'p1' })), + ] + const { ratio } = detectReadEditRatioLogic(calls) + expect(ratio).toBe(0.5) + }) + + it('healthy ratio passes (4:1+)', () => { + const calls: ToolCall[] = [ + ...Array(40).fill(null).map(() => ({ name: 'Read', input: {}, sessionId: 's1', project: 'p1' })), + ...Array(10).fill(null).map(() => ({ name: 'Edit', input: {}, sessionId: 's1', project: 'p1' })), + ] + const { ratio } = detectReadEditRatioLogic(calls) + expect(ratio).toBe(4) + }) + + it('counts Grep and Glob as reads', () => { + const calls: ToolCall[] = [ + { name: 'Read', input: {}, sessionId: 's1', project: 'p1' }, + { name: 'Grep', input: {}, sessionId: 's1', project: 'p1' }, + { name: 'Glob', input: {}, sessionId: 's1', project: 'p1' }, + { name: 'Edit', input: {}, sessionId: 's1', project: 'p1' }, + ] + const { reads, edits } = detectReadEditRatioLogic(calls) + expect(reads).toBe(3) + expect(edits).toBe(1) + }) + + it('counts Write as edit', () => { + const calls: ToolCall[] = [ + { name: 'Write', input: {}, sessionId: 's1', project: 'p1' }, + { name: 'Edit', input: {}, sessionId: 's1', project: 'p1' }, + ] + const { edits } = detectReadEditRatioLogic(calls) + expect(edits).toBe(2) + }) + + it('ignores non-read non-edit tools', () => { + const calls: ToolCall[] = [ + { name: 'Bash', input: {}, sessionId: 's1', project: 'p1' }, + { name: 'Agent', input: {}, sessionId: 's1', project: 'p1' }, + { name: 'mcp__foo__bar', input: {}, sessionId: 's1', project: 'p1' }, + ] + const { reads, edits } = detectReadEditRatioLogic(calls) + expect(reads).toBe(0) + expect(edits).toBe(0) + }) +}) From b88f2cd730984ab0788f4c447d12c8ff761d7923 Mon Sep 17 00:00:00 2001 From: AgentSeal Date: Thu, 16 Apr 2026 05:09:01 -0700 Subject: [PATCH 02/70] feat: ghost detectors, health grade, @-import expansion Expanded the optimize engine with new detectors and scoring: 1. Health score + letter grade (A-F) in optimize header. Weighted per-impact with caps. Gives users an instant "is my setup healthy" read that doubles as a shareable number. 2. Urgency score replaces impact-enum sort. Weighted 0.7 * impact + 0.3 * normalized tokens. Produces better-ranked findings. 3. Three new ghost detectors: - Ghost agents: files in ~/.claude/agents/ never invoked via Agent/Task tool - Ghost skills: SKILL.md directories never triggered - Ghost slash-commands: ~/.claude/commands/ files never referenced in user messages 4. @-import chain expansion for CLAUDE.md. Recursively follows @path/to/file imports (max depth 5) so bloat detection counts transitive load, not just the base file. Fixes undercounting for users with modular CLAUDE.md setups. 9 new tests covering health scoring and import expansion. --- src/dashboard.tsx | 14 ++- src/optimize.ts | 257 ++++++++++++++++++++++++++++++++++++----- tests/optimize.test.ts | 80 +++++++++++++ 3 files changed, 322 insertions(+), 29 deletions(-) diff --git a/src/dashboard.tsx b/src/dashboard.tsx index 4d92287..6587614 100644 --- a/src/dashboard.tsx +++ b/src/dashboard.tsx @@ -470,16 +470,24 @@ function FindingPanel({ index, finding, costRate, width }: { index: number; find ) } -function OptimizeView({ findings, costRate, projects, label, width }: { findings: WasteFinding[]; costRate: number; projects: ProjectSummary[]; label: string; width: number }) { +const GRADE_COLORS: Record = { A: '#5BF5A0', B: '#5BF5A0', C: GOLD, D: ORANGE, F: '#F55B5B' } + +function OptimizeView({ findings, costRate, projects, label, width, healthScore, healthGrade }: { findings: WasteFinding[]; costRate: number; projects: ProjectSummary[]; label: string; width: number; healthScore: number; healthGrade: string }) { const periodCost = projects.reduce((s, p) => s + p.totalCostUSD, 0) const totalTokens = findings.reduce((s, f) => s + f.tokensSaved, 0) const totalCost = totalTokens * costRate const pctRaw = periodCost > 0 ? (totalCost / periodCost) * 100 : 0 const pct = pctRaw >= 1 ? pctRaw.toFixed(0) : pctRaw.toFixed(1) + const gradeColor = GRADE_COLORS[healthGrade] ?? DIM return ( - CodeBurn Optimize {label} + + CodeBurn Optimize + {label} Setup: + {healthGrade} + ({healthScore}/100) + Savings: ~{formatTokens(totalTokens)} tokens (~{formatCost(totalCost)}, ~{pct}% of spend) {findings.map((f, i) => )} @@ -652,7 +660,7 @@ function InteractiveDashboard({ initialProjects, initialPeriod, initialProvider, {view === 'optimize' && optimizeResult - ? + ? : } diff --git a/src/optimize.ts b/src/optimize.ts index f29a904..e80744a 100644 --- a/src/optimize.ts +++ b/src/optimize.ts @@ -39,9 +39,13 @@ export type WasteFinding = { fix: WasteAction } +export type HealthGrade = 'A' | 'B' | 'C' | 'D' | 'F' + export type OptimizeResult = { findings: WasteFinding[] costRate: number + healthScore: number + healthGrade: HealthGrade } type ToolCall = { @@ -61,6 +65,7 @@ type ScanData = { projectCwds: Set apiCalls: ApiCallMeta[] versions: Set + userMessages: string[] } const IMPACT_ORDER: Record = { high: 3, medium: 2, low: 1 } @@ -84,6 +89,7 @@ type ScanFileResult = { cwds: string[] apiCalls: ApiCallMeta[] versions: string[] + userMessages: string[] } async function scanJsonlFile( @@ -94,12 +100,13 @@ async function scanJsonlFile( let content: string try { content = await readFile(filePath, 'utf-8') - } catch { return { calls: [], cwds: [], apiCalls: [], versions: [] } } + } catch { return { calls: [], cwds: [], apiCalls: [], versions: [], userMessages: [] } } const calls: ToolCall[] = [] const cwds: string[] = [] const apiCalls: ApiCallMeta[] = [] const versions: string[] = [] + const userMessages: string[] = [] const sessionId = basename(filePath, '.jsonl') for (const line of content.split('\n')) { @@ -110,6 +117,21 @@ async function scanJsonlFile( if (entry.cwd && typeof entry.cwd === 'string') cwds.push(entry.cwd) if (entry.version && typeof entry.version === 'string') versions.push(entry.version) + if (entry.type === 'user') { + const msg = entry.message as Record | undefined + const msgContent = msg?.content + if (typeof msgContent === 'string') { + userMessages.push(msgContent) + } else if (Array.isArray(msgContent)) { + for (const block of msgContent) { + if (block && typeof block === 'object' && block.type === 'text' && typeof block.text === 'string') { + userMessages.push(block.text) + } + } + } + continue + } + if (entry.type !== 'assistant') continue if (dateRange && typeof entry.timestamp === 'string') { @@ -139,7 +161,7 @@ async function scanJsonlFile( } } - return { calls, cwds, apiCalls, versions } + return { calls, cwds, apiCalls, versions, userMessages } } async function scanSessions(dateRange?: DateRange): Promise { @@ -148,19 +170,21 @@ async function scanSessions(dateRange?: DateRange): Promise { const allCwds = new Set() const allApiCalls: ApiCallMeta[] = [] const allVersions = new Set() + const allUserMessages: string[] = [] for (const source of sources) { const files = await collectJsonlFiles(source.path) for (const file of files) { - const { calls, cwds, apiCalls, versions } = await scanJsonlFile(file, source.project, dateRange) + const { calls, cwds, apiCalls, versions, userMessages } = await scanJsonlFile(file, source.project, dateRange) allCalls.push(...calls) for (const cwd of cwds) allCwds.add(cwd) allApiCalls.push(...apiCalls) for (const v of versions) if (v) allVersions.add(v) + allUserMessages.push(...userMessages) } } - return { toolCalls: allCalls, projectCwds: allCwds, apiCalls: allApiCalls, versions: allVersions } + return { toolCalls: allCalls, projectCwds: allCwds, apiCalls: allApiCalls, versions: allVersions, userMessages: allUserMessages } } function detectJunkReads(calls: ToolCall[]): WasteFinding | null { @@ -378,8 +402,36 @@ function detectMissingClaudeignore(projectCwds: Set): WasteFinding | nul } } +const MAX_IMPORT_DEPTH = 5 +const IMPORT_PATTERN = /^@([^\s]+)/gm + +function expandImports(filePath: string, seen: Set, depth: number): { totalLines: number; importedFiles: number } { + if (depth > MAX_IMPORT_DEPTH || seen.has(filePath)) return { totalLines: 0, importedFiles: 0 } + seen.add(filePath) + let content: string + try { content = readFileSync(filePath, 'utf-8') } catch { return { totalLines: 0, importedFiles: 0 } } + + const lines = content.split('\n').length + let totalLines = lines + let importedFiles = 0 + const dir = join(filePath, '..') + + const matches = content.matchAll(IMPORT_PATTERN) + for (const match of matches) { + const rawPath = match[1] + if (!rawPath || rawPath.startsWith('http') || rawPath.includes('@')) continue + const resolved = rawPath.startsWith('/') ? rawPath : join(dir, rawPath) + if (!existsSync(resolved)) continue + const nested = expandImports(resolved, seen, depth + 1) + totalLines += nested.totalLines + importedFiles += 1 + nested.importedFiles + } + + return { totalLines, importedFiles } +} + function detectBloatedClaudeMd(projectCwds: Set): WasteFinding | null { - const bloated: { path: string; lines: number }[] = [] + const bloated: { path: string; lines: number; expandedLines: number; imports: number }[] = [] for (const cwd of projectCwds) { for (const name of ['CLAUDE.md', '.claude/CLAUDE.md']) { @@ -388,9 +440,10 @@ function detectBloatedClaudeMd(projectCwds: Set): WasteFinding | null { try { const content = readFileSync(fullPath, 'utf-8') const lineCount = content.split('\n').length - if (lineCount > CLAUDEMD_HEALTHY_LINES) { + const { totalLines, importedFiles } = expandImports(fullPath, new Set(), 0) + if (totalLines > CLAUDEMD_HEALTHY_LINES) { const short = cwd.startsWith(homedir()) ? '~' + cwd.slice(homedir().length) : cwd - bloated.push({ path: `${short}/${name}`, lines: lineCount }) + bloated.push({ path: `${short}/${name}`, lines: lineCount, expandedLines: totalLines, imports: importedFiles }) } } catch { continue } } @@ -398,23 +451,26 @@ function detectBloatedClaudeMd(projectCwds: Set): WasteFinding | null { if (bloated.length === 0) return null - const sorted = bloated.sort((a, b) => b.lines - a.lines) + const sorted = bloated.sort((a, b) => b.expandedLines - a.expandedLines) const worst = sorted[0] - const totalExtraLines = sorted.reduce((s, b) => s + (b.lines - CLAUDEMD_HEALTHY_LINES), 0) + const totalExtraLines = sorted.reduce((s, b) => s + (b.expandedLines - CLAUDEMD_HEALTHY_LINES), 0) const tokensPerLine = 25 const tokensSaved = totalExtraLines * tokensPerLine - const list = sorted.slice(0, 3).map(b => `${b.path} (${b.lines} lines)`).join(', ') + const list = sorted.slice(0, 3).map(b => { + const importNote = b.imports > 0 ? ` + ${b.imports} imported` : '' + return `${b.path} (${b.expandedLines} lines${importNote})` + }).join(', ') return { title: 'TRIM BLOATED CLAUDE.md', - explanation: `${list}. Every line loads into every API call as context. Beyond ${CLAUDEMD_HEALTHY_LINES} lines, the extra ~${totalExtraLines} lines cost ~${formatTokens(tokensSaved)} tokens per call.`, - impact: worst.lines > 400 ? 'high' : 'medium', + explanation: `${list}. Every line loads into every API call as context, including @-imports. Beyond ${CLAUDEMD_HEALTHY_LINES} lines, the extra ~${totalExtraLines} lines cost ~${formatTokens(tokensSaved)} tokens per call.`, + impact: worst.expandedLines > 400 ? 'high' : 'medium', tokensSaved, fix: { type: 'paste', label: 'Ask Claude to trim it:', - text: 'Review CLAUDE.md and cut it to under 200 lines. Remove anything Claude can figure out from the code itself: file paths, architecture, imports. Keep only: rules, gotchas, and non-obvious conventions.', + text: 'Review CLAUDE.md and all @-imported files. Cut total expanded content to under 200 lines. Remove anything Claude can figure out from the code itself: file paths, architecture, imports. Keep only: rules, gotchas, and non-obvious conventions.', }, } } @@ -503,6 +559,126 @@ function detectCacheBloat(apiCalls: ApiCallMeta[]): WasteFinding | null { } } +const TOKENS_PER_AGENT_DEF = 80 +const TOKENS_PER_COMMAND_DEF = 60 +const SKILL_FRONTMATTER_TOKENS = 80 + +async function listMarkdownFiles(dir: string): Promise { + if (!existsSync(dir)) return [] + try { + const entries = await readdir(dir) + return entries.filter(e => e.endsWith('.md')).map(e => e.replace(/\.md$/, '')) + } catch { return [] } +} + +async function listSkillDirs(dir: string): Promise { + if (!existsSync(dir)) return [] + try { + const entries = await readdir(dir) + const names: string[] = [] + for (const entry of entries) { + if (existsSync(join(dir, entry, 'SKILL.md'))) names.push(entry) + } + return names + } catch { return [] } +} + +async function detectGhostAgents(calls: ToolCall[]): Promise { + const agentDir = join(homedir(), '.claude', 'agents') + const defined = await listMarkdownFiles(agentDir) + if (defined.length === 0) return null + + const invoked = new Set() + for (const call of calls) { + if (call.name !== 'Agent' && call.name !== 'Task') continue + const subType = call.input.subagent_type as string | undefined + if (subType) invoked.add(subType) + } + + const ghosts = defined.filter(name => !invoked.has(name)) + if (ghosts.length === 0) return null + + const tokensSaved = ghosts.length * TOKENS_PER_AGENT_DEF + const list = ghosts.slice(0, 5).join(', ') + (ghosts.length > 5 ? `, +${ghosts.length - 5} more` : '') + + return { + title: 'REMOVE UNUSED CUSTOM AGENTS', + explanation: `${ghosts.length} agent definition${ghosts.length > 1 ? 's' : ''} in ~/.claude/agents/ never invoked: ${list}. Each agent adds ~${TOKENS_PER_AGENT_DEF} tokens of description to the Task tool schema on every session.`, + impact: ghosts.length >= 5 ? 'high' : ghosts.length >= 2 ? 'medium' : 'low', + tokensSaved, + fix: { + type: 'command', + label: `Archive unused agent${ghosts.length > 1 ? 's' : ''}:`, + text: ghosts.slice(0, 10).map(name => `mv ~/.claude/agents/${name}.md ~/.claude/agents/.archived/`).join('\n'), + }, + } +} + +async function detectGhostSkills(calls: ToolCall[]): Promise { + const skillDir = join(homedir(), '.claude', 'skills') + const defined = await listSkillDirs(skillDir) + if (defined.length === 0) return null + + const invoked = new Set() + for (const call of calls) { + if (call.name !== 'Skill') continue + const skillName = (call.input.skill as string) || (call.input.name as string) + if (skillName) invoked.add(skillName) + } + + const ghosts = defined.filter(name => !invoked.has(name)) + if (ghosts.length === 0 || ghosts.length < 3) return null + + const tokensSaved = ghosts.length * SKILL_FRONTMATTER_TOKENS + const list = ghosts.slice(0, 5).join(', ') + (ghosts.length > 5 ? `, +${ghosts.length - 5} more` : '') + + return { + title: 'REMOVE UNUSED SKILLS', + explanation: `${ghosts.length} skill${ghosts.length > 1 ? 's' : ''} in ~/.claude/skills/ never invoked: ${list}. Each skill's frontmatter adds ~${SKILL_FRONTMATTER_TOKENS} tokens to the Skill tool invocation index on every session.`, + impact: ghosts.length >= 10 ? 'high' : ghosts.length >= 5 ? 'medium' : 'low', + tokensSaved, + fix: { + type: 'command', + label: `Archive unused skill${ghosts.length > 1 ? 's' : ''}:`, + text: ghosts.slice(0, 10).map(name => `mv ~/.claude/skills/${name} ~/.claude/skills/.archived/`).join('\n'), + }, + } +} + +async function detectGhostCommands(userMessages: string[]): Promise { + const cmdDir = join(homedir(), '.claude', 'commands') + const defined = await listMarkdownFiles(cmdDir) + if (defined.length === 0) return null + + const invoked = new Set() + const cmdPattern = /([^<]+)<\/command-name>|\/(\w+[-\w]*)/g + for (const msg of userMessages) { + const matches = msg.matchAll(cmdPattern) + for (const m of matches) { + const name = (m[1] || m[2] || '').replace(/^\//, '') + if (name) invoked.add(name) + } + } + + const ghosts = defined.filter(name => !invoked.has(name)) + if (ghosts.length === 0) return null + + const tokensSaved = ghosts.length * TOKENS_PER_COMMAND_DEF + const list = ghosts.slice(0, 5).join(', ') + (ghosts.length > 5 ? `, +${ghosts.length - 5} more` : '') + + return { + title: 'REMOVE UNUSED SLASH COMMANDS', + explanation: `${ghosts.length} slash command${ghosts.length > 1 ? 's' : ''} in ~/.claude/commands/ never used: ${list}. Each adds ~${TOKENS_PER_COMMAND_DEF} tokens of definition per session.`, + impact: ghosts.length >= 10 ? 'medium' : 'low', + tokensSaved, + fix: { + type: 'command', + label: `Archive unused command${ghosts.length > 1 ? 's' : ''}:`, + text: ghosts.slice(0, 10).map(name => `mv ~/.claude/commands/${name}.md ~/.claude/commands/.archived/`).join('\n'), + }, + } +} + function detectBashBloat(): WasteFinding | null { const current = process.env['BASH_MAX_OUTPUT_LENGTH'] if (current && parseInt(current, 10) <= 15000) return null @@ -591,6 +767,8 @@ function renderFinding(n: number, f: WasteFinding, costRate: number, W: number): return lines } +const GRADE_COLORS: Record = { A: GREEN, B: GREEN, C: GOLD, D: ORANGE, F: '#F55B5B' } + function renderOptimize( findings: WasteFinding[], costRate: number, @@ -598,6 +776,8 @@ function renderOptimize( periodCost: number, sessionCount: number, callCount: number, + healthScore: number, + healthGrade: HealthGrade, ): string { const lines: string[] = [] const W = 62 @@ -611,6 +791,7 @@ function renderOptimize( `${sessionCount} sessions`, `${callCount.toLocaleString()} calls`, chalk.hex(GOLD)(formatCost(periodCost)), + `Setup: ${chalk.bold.hex(GRADE_COLORS[healthGrade])(healthGrade)} ${chalk.dim(`(${healthScore}/100)`)}`, ].join(chalk.hex(DIM)(' '))) lines.push('') @@ -628,9 +809,7 @@ function renderOptimize( lines.push(chalk.hex(GREEN)(` Potential savings: ~${formatTokens(totalTokens)} tokens (~${formatCost(totalCost)}, ~${pct}% of spend)`)) lines.push('') - const sorted = findings.sort((a, b) => - (IMPACT_ORDER[b.impact] ?? 0) - (IMPACT_ORDER[a.impact] ?? 0) || b.tokensSaved - a.tokensSaved - ) + const sorted = findings for (let i = 0; i < sorted.length; i++) { lines.push(...renderFinding(i + 1, sorted[i], costRate, W)) @@ -643,15 +822,33 @@ function renderOptimize( return lines.join('\n') } +function computeHealth(findings: WasteFinding[]): { score: number; grade: HealthGrade } { + if (findings.length === 0) return { score: 100, grade: 'A' } + + const impactWeight: Record = { high: 15, medium: 7, low: 3 } + let penalty = 0 + for (const f of findings) penalty += impactWeight[f.impact] ?? 0 + + const score = Math.max(0, 100 - Math.min(80, penalty)) + const grade: HealthGrade = score >= 90 ? 'A' : score >= 75 ? 'B' : score >= 55 ? 'C' : score >= 30 ? 'D' : 'F' + return { score, grade } +} + +function urgencyScore(f: WasteFinding): number { + const impactWeight: Record = { high: 1, medium: 0.5, low: 0.2 } + const normalizedTokens = Math.min(1, f.tokensSaved / 500_000) + return (impactWeight[f.impact] ?? 0) * 0.7 + normalizedTokens * 0.3 +} + export async function scanAndDetect( projects: ProjectSummary[], dateRange?: DateRange, ): Promise { const costRate = computeInputCostRate(projects) - const { toolCalls, projectCwds, apiCalls } = await scanSessions(dateRange) + const { toolCalls, projectCwds, apiCalls, userMessages } = await scanSessions(dateRange) const findings: WasteFinding[] = [] - const detectors = [ + const syncDetectors = [ () => detectCacheBloat(apiCalls), () => detectLowReadEditRatio(toolCalls), () => detectJunkReads(toolCalls), @@ -661,17 +858,25 @@ export async function scanAndDetect( () => detectBloatedClaudeMd(projectCwds), () => detectBashBloat(), ] - - for (const detect of detectors) { + for (const detect of syncDetectors) { const finding = detect() if (finding) findings.push(finding) } - findings.sort((a, b) => - (IMPACT_ORDER[b.impact] ?? 0) - (IMPACT_ORDER[a.impact] ?? 0) || b.tokensSaved - a.tokensSaved - ) + const asyncDetectors = [ + () => detectGhostAgents(toolCalls), + () => detectGhostSkills(toolCalls), + () => detectGhostCommands(userMessages), + ] + for (const detect of asyncDetectors) { + const finding = await detect() + if (finding) findings.push(finding) + } - return { findings, costRate } + findings.sort((a, b) => urgencyScore(b) - urgencyScore(a)) + + const { score, grade } = computeHealth(findings) + return { findings, costRate, healthScore: score, healthGrade: grade } } export async function runOptimize( @@ -686,11 +891,11 @@ export async function runOptimize( process.stderr.write(chalk.dim(' Scanning sessions for waste patterns...\n')) - const { findings, costRate } = await scanAndDetect(projects, dateRange) + const { findings, costRate, healthScore, healthGrade } = await scanAndDetect(projects, dateRange) const sessions = projects.flatMap(p => p.sessions) const periodCost = projects.reduce((s, p) => s + p.totalCostUSD, 0) const callCount = projects.reduce((s, p) => s + p.totalApiCalls, 0) - const output = renderOptimize(findings, costRate, periodLabel, periodCost, sessions.length, callCount) + const output = renderOptimize(findings, costRate, periodLabel, periodCost, sessions.length, callCount, healthScore, healthGrade) console.log(output) } diff --git a/tests/optimize.test.ts b/tests/optimize.test.ts index c8514ea..b77ba25 100644 --- a/tests/optimize.test.ts +++ b/tests/optimize.test.ts @@ -236,3 +236,83 @@ describe('optimize: read:edit ratio detection', () => { expect(edits).toBe(0) }) }) + +function computeHealthLogic(impacts: Array<'high' | 'medium' | 'low'>): { score: number; grade: string } { + if (impacts.length === 0) return { score: 100, grade: 'A' } + const impactWeight: Record = { high: 15, medium: 7, low: 3 } + let penalty = 0 + for (const i of impacts) penalty += impactWeight[i] ?? 0 + const score = Math.max(0, 100 - Math.min(80, penalty)) + const grade = score >= 90 ? 'A' : score >= 75 ? 'B' : score >= 55 ? 'C' : score >= 30 ? 'D' : 'F' + return { score, grade } +} + +describe('optimize: health score and grade', () => { + it('returns A with no findings', () => { + const { score, grade } = computeHealthLogic([]) + expect(score).toBe(100) + expect(grade).toBe('A') + }) + + it('one low finding keeps grade at A', () => { + const { score, grade } = computeHealthLogic(['low']) + expect(score).toBe(97) + expect(grade).toBe('A') + }) + + it('two high findings drop to C', () => { + const { score, grade } = computeHealthLogic(['high', 'high']) + expect(score).toBe(70) + expect(grade).toBe('C') + }) + + it('caps penalty at 80 to prevent going below 20', () => { + const impacts = Array(20).fill('high' as const) + const { score } = computeHealthLogic(impacts) + expect(score).toBe(20) + }) + + it('mix produces D grade', () => { + const { score, grade } = computeHealthLogic(['high', 'high', 'medium', 'medium', 'low']) + expect(score).toBe(100 - 15 - 15 - 7 - 7 - 3) + expect(grade).toBe('D') + }) +}) + +function expandImportsLogic(content: string, resolveMap: Record, depth = 0): number { + if (depth > 5) return 0 + let total = content.split('\n').length + const matches = content.matchAll(/^@([^\s]+)/gm) + for (const m of matches) { + const key = m[1] || '' + if (resolveMap[key]) { + total += expandImportsLogic(resolveMap[key], resolveMap, depth + 1) + } + } + return total +} + +describe('optimize: @-import expansion', () => { + it('counts only the base file when no imports', () => { + const total = expandImportsLogic('line 1\nline 2\nline 3', {}) + expect(total).toBe(3) + }) + + it('expands single @-import', () => { + const main = 'line 1\n@./imported.md\nline 3' + const imported = 'i1\ni2\ni3\ni4\ni5' + expect(expandImportsLogic(main, { './imported.md': imported })).toBe(3 + 5) + }) + + it('expands nested @-imports recursively', () => { + const main = 'a\n@b.md' + const b = 'b1\nb2\n@c.md' + const c = 'c1\nc2\nc3' + expect(expandImportsLogic(main, { 'b.md': b, 'c.md': c })).toBe(2 + 3 + 3) + }) + + it('caps recursion depth', () => { + const circular = '@x.md' + expect(expandImportsLogic(circular, { 'x.md': circular })).toBeLessThan(10) + }) +}) From be45045fd81b510de03b9d7d3539414953b19971 Mon Sep 17 00:00:00 2001 From: AgentSeal Date: Thu, 16 Apr 2026 06:30:15 -0700 Subject: [PATCH 03/70] refactor(optimize): correctness, constants, and real tests Phase 1 hardening pass. Bug fixes: - Move cwd/version collection inside date-range filter. 7d and 30d now produce different findings for filesystem detectors. - detectGhostSkills threshold aligned with peer detectors. - detectUnusedMcp gets 24-hour grace period via config file mtime so newly added servers are not flagged as unused. - detectCacheBloat replaces hardcoded 50K baseline with user-derived p25 of cache writes. Flags only when median exceeds 1.4x baseline. - detectBashBloat scans user shell profiles instead of the auditor's process.env. - @-import pattern requires ./ ../ or / to avoid matching email addresses or npm scopes. - Command usage pattern requires leading whitespace/start-of-line before /cmd so path references like /tmp are not counted as usage. - AVG_TOKENS_PER_READ lowered from 1500 to 600 and CLAUDEMD_TOKENS_PER_LINE lowered from 25 to 13 for realistic prose/config sizing. Code quality: - Every magic number extracted to named module-scope constants. - Dead code removed (IMPACT_ORDER, unused stat import). - Shared loadMcpConfigs helper deduplicates config walking. - Shared shortHomePath, isReadTool, inRange helpers. - All detectors and computeHealth exported for real tests. - Ghost detectors run in parallel via Promise.all. - Cost rate defaults to 0 when unknown so UI can suppress instead of showing fabricated numbers. Tests: - Replaced 17 fake tests that re-implemented detector logic with 26 tests importing and exercising the real exports. - Cover threshold boundaries, impact scaling, edge cases. - 121 tests pass. UX header: "Setup" renamed to "Health", issue count shown inline. CLAUDE.md: adds rule against "steal/copy/rip-off" wording in public-facing text. --- CLAUDE.md | 7 + src/optimize.ts | 694 ++++++++++++++++++++++++----------------- tests/optimize.test.ts | 436 +++++++++++--------------- 3 files changed, 600 insertions(+), 537 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index f1cd611..1661a28 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -75,3 +75,10 @@ gh pr comment --body "Merged, thanks!" - NEVER include personal names or usernames in commits - Small, focused commits. One feature per commit - Test locally before every commit + +### Public-facing language (commits, PRs, release notes, README) +- Commits and release notes are public. Write like you'd publish them. +- NEVER use words like "steal", "stealing", "copy", "rip off", "inspired by" in commit messages +- Describe what the code does, not where ideas came from +- If you must credit prior art, do it in code comments or docs, not commit messages +- No snark, no filler, no self-deprecation. Treat each commit as a product statement diff --git a/src/optimize.ts b/src/optimize.ts index e80744a..11b7172 100644 --- a/src/optimize.ts +++ b/src/optimize.ts @@ -1,6 +1,6 @@ import chalk from 'chalk' -import { readdir, readFile, stat } from 'fs/promises' -import { existsSync, readFileSync } from 'fs' +import { readdir, readFile } from 'fs/promises' +import { existsSync, readFileSync, statSync } from 'fs' import { basename, join } from 'path' import { homedir } from 'os' @@ -9,22 +9,99 @@ import type { DateRange, ProjectSummary } from './types.js' import { formatCost } from './currency.js' import { formatTokens } from './format.js' +// ============================================================================ +// Display constants +// ============================================================================ + const ORANGE = '#FF8C42' const DIM = '#666666' const GOLD = '#FFD700' const CYAN = '#5BF5E0' const GREEN = '#5BF5A0' +const RED = '#F55B5B' + +// ============================================================================ +// Token estimation constants +// ============================================================================ + +const AVG_TOKENS_PER_READ = 600 +const TOKENS_PER_MCP_TOOL = 400 +const TOOLS_PER_MCP_SERVER = 5 +const TOKENS_PER_AGENT_DEF = 80 +const TOKENS_PER_SKILL_DEF = 80 +const TOKENS_PER_COMMAND_DEF = 60 +const CLAUDEMD_TOKENS_PER_LINE = 13 +const BASH_TOKENS_PER_CHAR = 0.25 +const ESTIMATED_READS_PER_MISSING_IGNORE = 10 + +// ============================================================================ +// Detector thresholds +// ============================================================================ + +const CLAUDEMD_HEALTHY_LINES = 200 +const CLAUDEMD_HIGH_THRESHOLD_LINES = 400 +const MIN_JUNK_READS_TO_FLAG = 3 +const JUNK_READS_HIGH_THRESHOLD = 20 +const JUNK_READS_MEDIUM_THRESHOLD = 5 +const MIN_DUPLICATE_READS_TO_FLAG = 5 +const DUPLICATE_READS_HIGH_THRESHOLD = 30 +const DUPLICATE_READS_MEDIUM_THRESHOLD = 10 +const MIN_EDITS_FOR_RATIO = 10 +const HEALTHY_READ_EDIT_RATIO = 4 +const LOW_RATIO_HIGH_THRESHOLD = 2 +const LOW_RATIO_MEDIUM_THRESHOLD = 3 +const MIN_API_CALLS_FOR_CACHE = 10 +const CACHE_EXCESS_HIGH_THRESHOLD = 15000 +const MISSING_IGNORE_HIGH_THRESHOLD = 3 +const UNUSED_MCP_HIGH_THRESHOLD = 3 +const GHOST_AGENTS_HIGH_THRESHOLD = 5 +const GHOST_AGENTS_MEDIUM_THRESHOLD = 2 +const GHOST_SKILLS_HIGH_THRESHOLD = 10 +const GHOST_SKILLS_MEDIUM_THRESHOLD = 5 +const GHOST_COMMANDS_MEDIUM_THRESHOLD = 10 +const MCP_NEW_CONFIG_GRACE_MS = 24 * 60 * 60 * 1000 +const BASH_DEFAULT_LIMIT = 30000 +const BASH_RECOMMENDED_LIMIT = 15000 + +// ============================================================================ +// Scoring constants +// ============================================================================ + +const HEALTH_WEIGHT_HIGH = 15 +const HEALTH_WEIGHT_MEDIUM = 7 +const HEALTH_WEIGHT_LOW = 3 +const HEALTH_MAX_PENALTY = 80 +const GRADE_A_MIN = 90 +const GRADE_B_MIN = 75 +const GRADE_C_MIN = 55 +const GRADE_D_MIN = 30 +const URGENCY_IMPACT_WEIGHT = 0.7 +const URGENCY_TOKEN_WEIGHT = 0.3 +const URGENCY_TOKEN_NORMALIZE = 500_000 + +// ============================================================================ +// File system constants +// ============================================================================ + +const MAX_IMPORT_DEPTH = 5 +const IMPORT_PATTERN = /^@(\.\.?\/[^\s]+|\/[^\s]+)/gm +const COMMAND_PATTERN = /([^<]+)<\/command-name>|(?:^|\s)\/([a-zA-Z][\w-]*)/gm const JUNK_DIRS = [ 'node_modules', '.git', 'dist', 'build', '__pycache__', '.next', '.nuxt', '.output', 'coverage', '.cache', '.tsbuildinfo', '.venv', 'venv', '.svn', '.hg', ] -const JUNK_PATTERN = new RegExp(`/(${JUNK_DIRS.join('|')})/`) +const JUNK_PATTERN = new RegExp(`/(?:${JUNK_DIRS.join('|')})/`) -const AVG_TOKENS_PER_READ = 1500 -const TOKENS_PER_MCP_TOOL = 400 -const CLAUDEMD_HEALTHY_LINES = 200 +const SHELL_PROFILES = ['.zshrc', '.bashrc', '.bash_profile', '.profile'] + +// ============================================================================ +// Types +// ============================================================================ + +export type Impact = 'high' | 'medium' | 'low' +export type HealthGrade = 'A' | 'B' | 'C' | 'D' | 'F' export type WasteAction = | { type: 'paste'; label: string; text: string } @@ -34,13 +111,11 @@ export type WasteAction = export type WasteFinding = { title: string explanation: string - impact: 'high' | 'medium' | 'low' + impact: Impact tokensSaved: number fix: WasteAction } -export type HealthGrade = 'A' | 'B' | 'C' | 'D' | 'F' - export type OptimizeResult = { findings: WasteFinding[] costRate: number @@ -48,14 +123,14 @@ export type OptimizeResult = { healthGrade: HealthGrade } -type ToolCall = { +export type ToolCall = { name: string input: Record sessionId: string project: string } -type ApiCallMeta = { +export type ApiCallMeta = { cacheCreationTokens: number version: string } @@ -68,7 +143,9 @@ type ScanData = { userMessages: string[] } -const IMPACT_ORDER: Record = { high: 3, medium: 2, low: 1 } +// ============================================================================ +// JSONL scanner +// ============================================================================ async function collectJsonlFiles(dirPath: string): Promise { const files = await readdir(dirPath).catch(() => []) @@ -92,7 +169,14 @@ type ScanFileResult = { userMessages: string[] } -async function scanJsonlFile( +function inRange(timestamp: string | undefined, range: DateRange | undefined): boolean { + if (!range) return true + if (!timestamp) return false + const ts = new Date(timestamp) + return ts >= range.start && ts <= range.end +} + +export async function scanJsonlFile( filePath: string, project: string, dateRange: DateRange | undefined, @@ -108,16 +192,23 @@ async function scanJsonlFile( const versions: string[] = [] const userMessages: string[] = [] const sessionId = basename(filePath, '.jsonl') + let lastVersion = '' for (const line of content.split('\n')) { if (!line.trim()) continue let entry: Record try { entry = JSON.parse(line) } catch { continue } - if (entry.cwd && typeof entry.cwd === 'string') cwds.push(entry.cwd) - if (entry.version && typeof entry.version === 'string') versions.push(entry.version) + if (entry.version && typeof entry.version === 'string') lastVersion = entry.version + + const ts = typeof entry.timestamp === 'string' ? entry.timestamp : undefined + const withinRange = inRange(ts, dateRange) + + if (entry.cwd && typeof entry.cwd === 'string' && withinRange) cwds.push(entry.cwd) + if (entry.version && typeof entry.version === 'string' && withinRange) versions.push(entry.version) if (entry.type === 'user') { + if (!withinRange) continue const msg = entry.message as Record | undefined const msgContent = msg?.content if (typeof msgContent === 'string') { @@ -133,18 +224,13 @@ async function scanJsonlFile( } if (entry.type !== 'assistant') continue - - if (dateRange && typeof entry.timestamp === 'string') { - const ts = new Date(entry.timestamp) - if (ts < dateRange.start || ts > dateRange.end) continue - } + if (!withinRange) continue const msg = entry.message as Record | undefined const usage = msg?.usage as Record | undefined if (usage) { const cacheCreate = (usage.cache_creation_input_tokens as number) ?? 0 - const ver = versions[versions.length - 1] ?? '' - if (cacheCreate > 0) apiCalls.push({ cacheCreationTokens: cacheCreate, version: ver }) + if (cacheCreate > 0) apiCalls.push({ cacheCreationTokens: cacheCreate, version: lastVersion }) } const blocks = msg?.content @@ -187,17 +273,67 @@ async function scanSessions(dateRange?: DateRange): Promise { return { toolCalls: allCalls, projectCwds: allCwds, apiCalls: allApiCalls, versions: allVersions, userMessages: allUserMessages } } -function detectJunkReads(calls: ToolCall[]): WasteFinding | null { - const readCalls = calls.filter(c => c.name === 'Read' || c.name === 'FileReadTool') +// ============================================================================ +// Shared helpers +// ============================================================================ +function readJsonFile(path: string): Record | null { + try { return JSON.parse(readFileSync(path, 'utf-8')) } catch { return null } +} + +function shortHomePath(absPath: string): string { + const home = homedir() + return absPath.startsWith(home) ? '~' + absPath.slice(home.length) : absPath +} + +function isReadTool(name: string): boolean { + return name === 'Read' || name === 'FileReadTool' +} + +type McpConfigEntry = { normalized: string; original: string; mtime: number } + +export function loadMcpConfigs(projectCwds: Iterable): Map { + const servers = new Map() + const configPaths = [ + join(homedir(), '.claude', 'settings.json'), + join(homedir(), '.claude', 'settings.local.json'), + ] + for (const cwd of projectCwds) { + configPaths.push(join(cwd, '.mcp.json')) + configPaths.push(join(cwd, '.claude', 'settings.json')) + configPaths.push(join(cwd, '.claude', 'settings.local.json')) + } + + for (const p of configPaths) { + if (!existsSync(p)) continue + const config = readJsonFile(p) + if (!config) continue + let mtime = 0 + try { mtime = statSync(p).mtimeMs } catch {} + const serversObj = (config.mcpServers ?? {}) as Record + for (const name of Object.keys(serversObj)) { + const normalized = name.replace(/:/g, '_') + const existing = servers.get(normalized) + if (!existing || existing.mtime < mtime) { + servers.set(normalized, { normalized, original: name, mtime }) + } + } + } + return servers +} + +// ============================================================================ +// Detectors +// ============================================================================ + +export function detectJunkReads(calls: ToolCall[]): WasteFinding | null { const dirCounts = new Map() let totalJunkReads = 0 - for (const call of readCalls) { + for (const call of calls) { + if (!isReadTool(call.name)) continue const filePath = call.input.file_path as string | undefined - if (!filePath) continue - if (!JUNK_PATTERN.test(filePath)) continue - + if (!filePath || !JUNK_PATTERN.test(filePath)) continue totalJunkReads++ for (const dir of JUNK_DIRS) { if (filePath.includes(`/${dir}/`)) { @@ -207,22 +343,21 @@ function detectJunkReads(calls: ToolCall[]): WasteFinding | null { } } - if (totalJunkReads < 3) return null + if (totalJunkReads < MIN_JUNK_READS_TO_FLAG) return null const sorted = [...dirCounts.entries()].sort((a, b) => b[1] - a[1]) const dirList = sorted.slice(0, 3).map(([d, n]) => `${d}/ (${n}x)`).join(', ') const tokensSaved = totalJunkReads * AVG_TOKENS_PER_READ const detected = sorted.map(([d]) => d) - const extras = ['node_modules', '.git', 'dist', '__pycache__'] - .filter(d => !dirCounts.has(d)) - .slice(0, Math.max(0, 6 - detected.length)) + const commonDefaults = ['node_modules', '.git', 'dist', '__pycache__'] + const extras = commonDefaults.filter(d => !dirCounts.has(d)).slice(0, Math.max(0, 6 - detected.length)) const ignoreContent = [...detected, ...extras].join('\n') return { - title: 'STOP READING JUNK DIRECTORIES', - explanation: `Claude read into ${dirList} -- ${totalJunkReads} times total. Each read loads ~${AVG_TOKENS_PER_READ.toLocaleString()} tokens of irrelevant content into context. A .claudeignore blocks this.`, - impact: totalJunkReads > 20 ? 'high' : totalJunkReads > 5 ? 'medium' : 'low', + title: 'Claude is reading build/dependency folders', + explanation: `Claude read into ${dirList} (${totalJunkReads} reads). These are generated or dependency directories, not your code. A .claudeignore tells Claude to skip them.`, + impact: totalJunkReads > JUNK_READS_HIGH_THRESHOLD ? 'high' : totalJunkReads > JUNK_READS_MEDIUM_THRESHOLD ? 'medium' : 'low', tokensSaved, fix: { type: 'file-content', @@ -233,15 +368,13 @@ function detectJunkReads(calls: ToolCall[]): WasteFinding | null { } } -function detectDuplicateReads(calls: ToolCall[]): WasteFinding | null { - const readCalls = calls.filter(c => c.name === 'Read' || c.name === 'FileReadTool') - +export function detectDuplicateReads(calls: ToolCall[]): WasteFinding | null { const sessionFiles = new Map>() - for (const call of readCalls) { + for (const call of calls) { + if (!isReadTool(call.name)) continue const filePath = call.input.file_path as string | undefined if (!filePath || JUNK_PATTERN.test(filePath)) continue - const key = `${call.project}:${call.sessionId}` if (!sessionFiles.has(key)) sessionFiles.set(key, new Map()) const fm = sessionFiles.get(key)! @@ -261,64 +394,36 @@ function detectDuplicateReads(calls: ToolCall[]): WasteFinding | null { } } - if (totalDuplicates < 5) return null + if (totalDuplicates < MIN_DUPLICATE_READS_TO_FLAG) return null const worst = [...fileDupes.entries()] .sort((a, b) => b[1] - a[1]) .slice(0, 3) - .map(([name, n]) => `${name} (+${n})`) + .map(([name, n]) => `${name} (${n + 1}x)`) .join(', ') const tokensSaved = totalDuplicates * AVG_TOKENS_PER_READ return { - title: 'CUT DUPLICATE FILE READS', - explanation: `Claude re-read the same file ${totalDuplicates} times across sessions. Top offenders: ${worst}. Each re-read loads ~${AVG_TOKENS_PER_READ.toLocaleString()} tokens that are already in context.`, - impact: totalDuplicates > 30 ? 'high' : totalDuplicates > 10 ? 'medium' : 'low', + title: 'Claude is re-reading the same files', + explanation: `${totalDuplicates} redundant re-reads across sessions. Top repeats: ${worst}. Each re-read loads the same content into context again.`, + impact: totalDuplicates > DUPLICATE_READS_HIGH_THRESHOLD ? 'high' : totalDuplicates > DUPLICATE_READS_MEDIUM_THRESHOLD ? 'medium' : 'low', tokensSaved, fix: { type: 'paste', - label: 'Give Claude exact locations so it reads once:', - text: 'Look at src/auth.ts lines 45-80, the validateToken function.', + label: 'Point Claude at exact locations in your prompt, for example:', + text: 'In lines -, look at the function.', }, } } -function readJsonFile(path: string): Record | null { - try { - return JSON.parse(readFileSync(path, 'utf-8')) - } catch { return null } -} - -function detectUnusedMcp( +export function detectUnusedMcp( calls: ToolCall[], projects: ProjectSummary[], projectCwds: Set, ): WasteFinding | null { - const configuredServers = new Map() - - const configPaths = [ - join(homedir(), '.claude', 'settings.json'), - join(homedir(), '.claude', 'settings.local.json'), - ] - for (const cwd of projectCwds) { - configPaths.push(join(cwd, '.mcp.json')) - configPaths.push(join(cwd, '.claude', 'settings.json')) - configPaths.push(join(cwd, '.claude', 'settings.local.json')) - } - - for (const p of configPaths) { - if (!existsSync(p)) continue - const config = readJsonFile(p) - if (!config) continue - const servers = (config.mcpServers ?? {}) as Record - for (const name of Object.keys(servers)) { - const normalized = name.replace(/:/g, '_') - configuredServers.set(normalized, name) - } - } - - if (configuredServers.size === 0) return null + const configured = loadMcpConfigs(projectCwds) + if (configured.size === 0) return null const calledServers = new Set() for (const call of calls) { @@ -328,28 +433,28 @@ function detectUnusedMcp( } for (const p of projects) { for (const s of p.sessions) { - for (const server of Object.keys(s.mcpBreakdown)) { - calledServers.add(server) - } + for (const server of Object.keys(s.mcpBreakdown)) calledServers.add(server) } } + const now = Date.now() const unused: string[] = [] - for (const [normalized, original] of configuredServers) { - if (!calledServers.has(normalized)) unused.push(original) + for (const entry of configured.values()) { + if (calledServers.has(entry.normalized)) continue + if (entry.mtime > 0 && now - entry.mtime < MCP_NEW_CONFIG_GRACE_MS) continue + unused.push(entry.original) } if (unused.length === 0) return null const totalSessions = projects.reduce((s, p) => s + p.sessions.length, 0) - const estimatedTools = 5 - const schemaTokens = unused.length * estimatedTools * TOKENS_PER_MCP_TOOL - const tokensSaved = schemaTokens * totalSessions + const schemaTokensPerSession = unused.length * TOOLS_PER_MCP_SERVER * TOKENS_PER_MCP_TOOL + const tokensSaved = schemaTokensPerSession * Math.max(totalSessions, 1) return { - title: 'REMOVE UNUSED MCP SERVERS', - explanation: `${unused.length} MCP server${unused.length > 1 ? 's' : ''} configured but never called: ${unused.join(', ')}. Each loads ~${(estimatedTools * TOKENS_PER_MCP_TOOL).toLocaleString()} tokens of schema into every session (${totalSessions.toLocaleString()} sessions in this period).`, - impact: unused.length >= 3 ? 'high' : 'medium', + title: `${unused.length} MCP server${unused.length > 1 ? 's' : ''} configured but never used`, + explanation: `Never called in this period: ${unused.join(', ')}. Each server loads ~${TOOLS_PER_MCP_SERVER * TOKENS_PER_MCP_TOOL} tokens of tool schema into every session.`, + impact: unused.length >= UNUSED_MCP_HIGH_THRESHOLD ? 'high' : 'medium', tokensSaved, fix: { type: 'command', @@ -359,18 +464,15 @@ function detectUnusedMcp( } } -function detectMissingClaudeignore(projectCwds: Set): WasteFinding | null { +export function detectMissingClaudeignore(projectCwds: Set): WasteFinding | null { const missing: string[] = [] - const hasJunkDir: string[] = [] for (const cwd of projectCwds) { - if (existsSync(join(cwd, '.claudeignore'))) continue if (!existsSync(cwd)) continue - + if (existsSync(join(cwd, '.claudeignore'))) continue for (const dir of JUNK_DIRS) { if (existsSync(join(cwd, dir))) { missing.push(cwd) - hasJunkDir.push(dir) break } } @@ -378,20 +480,17 @@ function detectMissingClaudeignore(projectCwds: Set): WasteFinding | nul if (missing.length === 0) return null - const shortPaths = missing.map(p => { - const home = homedir() - return p.startsWith(home) ? '~' + p.slice(home.length) : p - }) + const shortPaths = missing.map(shortHomePath) const display = shortPaths.length <= 3 ? shortPaths.join(', ') : `${shortPaths.slice(0, 2).join(', ')} + ${shortPaths.length - 2} more` - const tokensSaved = missing.length * 10 * AVG_TOKENS_PER_READ + const tokensSaved = missing.length * ESTIMATED_READS_PER_MISSING_IGNORE * AVG_TOKENS_PER_READ return { - title: 'ADD .claudeignore FILES', - explanation: `${missing.length} project${missing.length > 1 ? 's' : ''} ha${missing.length > 1 ? 've' : 's'} junk directories (node_modules, .git, etc.) but no .claudeignore: ${display}. Without it, Claude may read/search these directories.`, - impact: missing.length >= 3 ? 'high' : 'medium', + title: `Add .claudeignore to ${missing.length} project${missing.length > 1 ? 's' : ''}`, + explanation: `${missing.length} project${missing.length > 1 ? 's have' : ' has'} build/dependency folders (node_modules, .git, etc.) but no .claudeignore: ${display}. Without it, Claude can wander into them.`, + impact: missing.length >= MISSING_IGNORE_HIGH_THRESHOLD ? 'high' : 'medium', tokensSaved, fix: { type: 'file-content', @@ -402,24 +501,20 @@ function detectMissingClaudeignore(projectCwds: Set): WasteFinding | nul } } -const MAX_IMPORT_DEPTH = 5 -const IMPORT_PATTERN = /^@([^\s]+)/gm - function expandImports(filePath: string, seen: Set, depth: number): { totalLines: number; importedFiles: number } { if (depth > MAX_IMPORT_DEPTH || seen.has(filePath)) return { totalLines: 0, importedFiles: 0 } seen.add(filePath) let content: string try { content = readFileSync(filePath, 'utf-8') } catch { return { totalLines: 0, importedFiles: 0 } } - const lines = content.split('\n').length - let totalLines = lines + let totalLines = content.split('\n').length let importedFiles = 0 const dir = join(filePath, '..') - const matches = content.matchAll(IMPORT_PATTERN) - for (const match of matches) { + IMPORT_PATTERN.lastIndex = 0 + for (const match of content.matchAll(IMPORT_PATTERN)) { const rawPath = match[1] - if (!rawPath || rawPath.startsWith('http') || rawPath.includes('@')) continue + if (!rawPath) continue const resolved = rawPath.startsWith('/') ? rawPath : join(dir, rawPath) if (!existsSync(resolved)) continue const nested = expandImports(resolved, seen, depth + 1) @@ -430,22 +525,17 @@ function expandImports(filePath: string, seen: Set, depth: number): { to return { totalLines, importedFiles } } -function detectBloatedClaudeMd(projectCwds: Set): WasteFinding | null { - const bloated: { path: string; lines: number; expandedLines: number; imports: number }[] = [] +export function detectBloatedClaudeMd(projectCwds: Set): WasteFinding | null { + const bloated: { path: string; expandedLines: number; imports: number }[] = [] for (const cwd of projectCwds) { for (const name of ['CLAUDE.md', '.claude/CLAUDE.md']) { const fullPath = join(cwd, name) if (!existsSync(fullPath)) continue - try { - const content = readFileSync(fullPath, 'utf-8') - const lineCount = content.split('\n').length - const { totalLines, importedFiles } = expandImports(fullPath, new Set(), 0) - if (totalLines > CLAUDEMD_HEALTHY_LINES) { - const short = cwd.startsWith(homedir()) ? '~' + cwd.slice(homedir().length) : cwd - bloated.push({ path: `${short}/${name}`, lines: lineCount, expandedLines: totalLines, imports: importedFiles }) - } - } catch { continue } + const { totalLines, importedFiles } = expandImports(fullPath, new Set(), 0) + if (totalLines > CLAUDEMD_HEALTHY_LINES) { + bloated.push({ path: `${shortHomePath(cwd)}/${name}`, expandedLines: totalLines, imports: importedFiles }) + } } } @@ -454,23 +544,22 @@ function detectBloatedClaudeMd(projectCwds: Set): WasteFinding | null { const sorted = bloated.sort((a, b) => b.expandedLines - a.expandedLines) const worst = sorted[0] const totalExtraLines = sorted.reduce((s, b) => s + (b.expandedLines - CLAUDEMD_HEALTHY_LINES), 0) - const tokensPerLine = 25 - const tokensSaved = totalExtraLines * tokensPerLine + const tokensSaved = totalExtraLines * CLAUDEMD_TOKENS_PER_LINE const list = sorted.slice(0, 3).map(b => { - const importNote = b.imports > 0 ? ` + ${b.imports} imported` : '' + const importNote = b.imports > 0 ? ` with ${b.imports} @-import${b.imports > 1 ? 's' : ''}` : '' return `${b.path} (${b.expandedLines} lines${importNote})` }).join(', ') return { - title: 'TRIM BLOATED CLAUDE.md', - explanation: `${list}. Every line loads into every API call as context, including @-imports. Beyond ${CLAUDEMD_HEALTHY_LINES} lines, the extra ~${totalExtraLines} lines cost ~${formatTokens(tokensSaved)} tokens per call.`, - impact: worst.expandedLines > 400 ? 'high' : 'medium', + title: `Your CLAUDE.md is too long`, + explanation: `${list}. CLAUDE.md plus all @-imported files load into every API call. Trimming below ${CLAUDEMD_HEALTHY_LINES} lines saves ~${formatTokens(tokensSaved)} tokens per call.`, + impact: worst.expandedLines > CLAUDEMD_HIGH_THRESHOLD_LINES ? 'high' : 'medium', tokensSaved, fix: { type: 'paste', label: 'Ask Claude to trim it:', - text: 'Review CLAUDE.md and all @-imported files. Cut total expanded content to under 200 lines. Remove anything Claude can figure out from the code itself: file paths, architecture, imports. Keep only: rules, gotchas, and non-obvious conventions.', + text: `Review CLAUDE.md and all @-imported files. Cut total expanded content to under ${CLAUDEMD_HEALTHY_LINES} lines. Remove anything Claude can figure out from the code itself. Keep only rules, gotchas, and non-obvious conventions.`, }, } } @@ -478,31 +567,27 @@ function detectBloatedClaudeMd(projectCwds: Set): WasteFinding | null { const READ_TOOL_NAMES = new Set(['Read', 'Grep', 'Glob', 'FileReadTool', 'GrepTool', 'GlobTool']) const EDIT_TOOL_NAMES = new Set(['Edit', 'Write', 'FileEditTool', 'FileWriteTool', 'NotebookEdit']) -function detectLowReadEditRatio(calls: ToolCall[]): WasteFinding | null { +export function detectLowReadEditRatio(calls: ToolCall[]): WasteFinding | null { let reads = 0 let edits = 0 - for (const call of calls) { if (READ_TOOL_NAMES.has(call.name)) reads++ else if (EDIT_TOOL_NAMES.has(call.name)) edits++ } - if (edits < 10) return null - + if (edits < MIN_EDITS_FOR_RATIO) return null const ratio = reads / edits - if (ratio >= 4) return null + if (ratio >= HEALTHY_READ_EDIT_RATIO) return null - const ratioStr = ratio.toFixed(1) - const impact: 'high' | 'medium' | 'low' = ratio < 2 ? 'high' : ratio < 3 ? 'medium' : 'low' - - const extraReadsNeeded = Math.round(edits * 4) - reads + const impact: Impact = ratio < LOW_RATIO_HIGH_THRESHOLD ? 'high' : ratio < LOW_RATIO_MEDIUM_THRESHOLD ? 'medium' : 'low' + const extraReadsNeeded = Math.max(Math.round(edits * HEALTHY_READ_EDIT_RATIO) - reads, 0) const tokensSaved = extraReadsNeeded * AVG_TOKENS_PER_READ return { - title: 'CLAUDE IS EDITING WITHOUT READING', - explanation: `Read:Edit ratio is ${ratioStr}:1 (${reads} reads, ${edits} edits). Healthy is 4:1+. A low ratio means Claude edits files without fully understanding the codebase first -- leading to more retries and wasted tokens.`, + title: 'Claude edits more than it reads', + explanation: `Claude made ${reads} reads and ${edits} edits (ratio ${ratio.toFixed(1)}:1). A healthy ratio is ${HEALTHY_READ_EDIT_RATIO}+ reads per edit. Editing without reading leads to retries and wasted tokens.`, impact, - tokensSaved: Math.max(tokensSaved, 0), + tokensSaved, fix: { type: 'paste', label: 'Add to your CLAUDE.md:', @@ -511,58 +596,63 @@ function detectLowReadEditRatio(calls: ToolCall[]): WasteFinding | null { } } -function detectCacheBloat(apiCalls: ApiCallMeta[]): WasteFinding | null { - if (apiCalls.length < 10) return null +function computeBudgetAwareCacheBaseline(projects: ProjectSummary[]): number { + const sessions = projects.flatMap(p => p.sessions) + if (sessions.length === 0) return 50_000 + const cacheWrites = sessions.map(s => s.totalCacheWriteTokens).filter(n => n > 0) + if (cacheWrites.length < MIN_API_CALLS_FOR_CACHE) return 50_000 + const sorted = cacheWrites.sort((a, b) => a - b) + return sorted[Math.floor(sorted.length * 0.25)] || 50_000 +} + +export function detectCacheBloat(apiCalls: ApiCallMeta[], projects: ProjectSummary[]): WasteFinding | null { + if (apiCalls.length < MIN_API_CALLS_FOR_CACHE) return null const sorted = apiCalls.map(c => c.cacheCreationTokens).sort((a, b) => a - b) const median = sorted[Math.floor(sorted.length / 2)] + const baseline = computeBudgetAwareCacheBaseline(projects) + const bloatThreshold = baseline * 1.4 - if (median < 55000) return null + if (median < bloatThreshold) return null const versionCounts = new Map() for (const call of apiCalls) { if (!call.version) continue - const v = call.version - const entry = versionCounts.get(v) ?? { total: 0, count: 0 } + const entry = versionCounts.get(call.version) ?? { total: 0, count: 0 } entry.total += call.cacheCreationTokens entry.count++ - versionCounts.set(v, entry) + versionCounts.set(call.version, entry) } - const versionAvgs = [...versionCounts.entries()] .filter(([, d]) => d.count >= 5) - .map(([v, d]) => ({ version: v, avg: Math.round(d.total / d.count), count: d.count })) + .map(([v, d]) => ({ version: v, avg: Math.round(d.total / d.count) })) .sort((a, b) => b.avg - a.avg) - const excess = median - 50000 + const excess = median - baseline const tokensSaved = excess * apiCalls.length let versionNote = '' if (versionAvgs.length >= 2) { - const highest = versionAvgs[0] - const lowest = versionAvgs[versionAvgs.length - 1] - if (highest.avg - lowest.avg > 10000) { - versionNote = ` Version ${highest.version} averages ${formatTokens(highest.avg)} vs ${lowest.version} at ${formatTokens(lowest.avg)}.` + const [high, ...rest] = versionAvgs + const low = rest[rest.length - 1] + if (high.avg - low.avg > 10_000) { + versionNote = ` Version ${high.version} averages ${formatTokens(high.avg)} vs ${low.version} at ${formatTokens(low.avg)}.` } } return { - title: 'HIGH CACHE CREATION OVERHEAD', - explanation: `Median cache_creation per call is ${formatTokens(median)} tokens (baseline ~50K). The extra ~${formatTokens(excess)} tokens per call may be server-injected content invisible to you.${versionNote} See anthropics/claude-code#46917.`, - impact: excess > 15000 ? 'high' : 'medium', + title: 'Session warmup is unusually large', + explanation: `Median cache_creation per call is ${formatTokens(median)} tokens, about ${formatTokens(excess)} above your baseline of ${formatTokens(baseline)}.${versionNote}`, + impact: excess > CACHE_EXCESS_HIGH_THRESHOLD ? 'high' : 'medium', tokensSaved, fix: { type: 'paste', - label: 'Spoof older User-Agent to reduce overhead:', + label: 'Check for recent Claude Code updates or heavy MCP/skill additions. As a workaround (not officially supported):', text: 'export ANTHROPIC_CUSTOM_HEADERS=\'User-Agent: claude-cli/2.1.98 (external, sdk-cli)\'', }, } } -const TOKENS_PER_AGENT_DEF = 80 -const TOKENS_PER_COMMAND_DEF = 60 -const SKILL_FRONTMATTER_TOKENS = 80 - async function listMarkdownFiles(dir: string): Promise { if (!existsSync(dir)) return [] try { @@ -583,9 +673,8 @@ async function listSkillDirs(dir: string): Promise { } catch { return [] } } -async function detectGhostAgents(calls: ToolCall[]): Promise { - const agentDir = join(homedir(), '.claude', 'agents') - const defined = await listMarkdownFiles(agentDir) +export async function detectGhostAgents(calls: ToolCall[]): Promise { + const defined = await listMarkdownFiles(join(homedir(), '.claude', 'agents')) if (defined.length === 0) return null const invoked = new Set() @@ -602,9 +691,9 @@ async function detectGhostAgents(calls: ToolCall[]): Promise 5 ? `, +${ghosts.length - 5} more` : '') return { - title: 'REMOVE UNUSED CUSTOM AGENTS', - explanation: `${ghosts.length} agent definition${ghosts.length > 1 ? 's' : ''} in ~/.claude/agents/ never invoked: ${list}. Each agent adds ~${TOKENS_PER_AGENT_DEF} tokens of description to the Task tool schema on every session.`, - impact: ghosts.length >= 5 ? 'high' : ghosts.length >= 2 ? 'medium' : 'low', + title: `${ghosts.length} custom agent${ghosts.length > 1 ? 's' : ''} you never use`, + explanation: `Defined in ~/.claude/agents/ but never invoked in this period: ${list}. Each adds ~${TOKENS_PER_AGENT_DEF} tokens to the Task tool schema on every session.`, + impact: ghosts.length >= GHOST_AGENTS_HIGH_THRESHOLD ? 'high' : ghosts.length >= GHOST_AGENTS_MEDIUM_THRESHOLD ? 'medium' : 'low', tokensSaved, fix: { type: 'command', @@ -614,9 +703,8 @@ async function detectGhostAgents(calls: ToolCall[]): Promise { - const skillDir = join(homedir(), '.claude', 'skills') - const defined = await listSkillDirs(skillDir) +export async function detectGhostSkills(calls: ToolCall[]): Promise { + const defined = await listSkillDirs(join(homedir(), '.claude', 'skills')) if (defined.length === 0) return null const invoked = new Set() @@ -627,15 +715,15 @@ async function detectGhostSkills(calls: ToolCall[]): Promise !invoked.has(name)) - if (ghosts.length === 0 || ghosts.length < 3) return null + if (ghosts.length === 0) return null - const tokensSaved = ghosts.length * SKILL_FRONTMATTER_TOKENS + const tokensSaved = ghosts.length * TOKENS_PER_SKILL_DEF const list = ghosts.slice(0, 5).join(', ') + (ghosts.length > 5 ? `, +${ghosts.length - 5} more` : '') return { - title: 'REMOVE UNUSED SKILLS', - explanation: `${ghosts.length} skill${ghosts.length > 1 ? 's' : ''} in ~/.claude/skills/ never invoked: ${list}. Each skill's frontmatter adds ~${SKILL_FRONTMATTER_TOKENS} tokens to the Skill tool invocation index on every session.`, - impact: ghosts.length >= 10 ? 'high' : ghosts.length >= 5 ? 'medium' : 'low', + title: `${ghosts.length} skill${ghosts.length > 1 ? 's' : ''} you never use`, + explanation: `In ~/.claude/skills/ but not invoked this period: ${list}. Each adds ~${TOKENS_PER_SKILL_DEF} tokens of metadata to every session.`, + impact: ghosts.length >= GHOST_SKILLS_HIGH_THRESHOLD ? 'high' : ghosts.length >= GHOST_SKILLS_MEDIUM_THRESHOLD ? 'medium' : 'low', tokensSaved, fix: { type: 'command', @@ -645,17 +733,15 @@ async function detectGhostSkills(calls: ToolCall[]): Promise { - const cmdDir = join(homedir(), '.claude', 'commands') - const defined = await listMarkdownFiles(cmdDir) +export async function detectGhostCommands(userMessages: string[]): Promise { + const defined = await listMarkdownFiles(join(homedir(), '.claude', 'commands')) if (defined.length === 0) return null const invoked = new Set() - const cmdPattern = /([^<]+)<\/command-name>|\/(\w+[-\w]*)/g for (const msg of userMessages) { - const matches = msg.matchAll(cmdPattern) - for (const m of matches) { - const name = (m[1] || m[2] || '').replace(/^\//, '') + COMMAND_PATTERN.lastIndex = 0 + for (const m of msg.matchAll(COMMAND_PATTERN)) { + const name = (m[1] || m[2] || '').trim() if (name) invoked.add(name) } } @@ -667,9 +753,9 @@ async function detectGhostCommands(userMessages: string[]): Promise 5 ? `, +${ghosts.length - 5} more` : '') return { - title: 'REMOVE UNUSED SLASH COMMANDS', - explanation: `${ghosts.length} slash command${ghosts.length > 1 ? 's' : ''} in ~/.claude/commands/ never used: ${list}. Each adds ~${TOKENS_PER_COMMAND_DEF} tokens of definition per session.`, - impact: ghosts.length >= 10 ? 'medium' : 'low', + title: `${ghosts.length} slash command${ghosts.length > 1 ? 's' : ''} you never use`, + explanation: `In ~/.claude/commands/ but not referenced this period: ${list}. Each adds ~${TOKENS_PER_COMMAND_DEF} tokens of definition per session.`, + impact: ghosts.length >= GHOST_COMMANDS_MEDIUM_THRESHOLD ? 'medium' : 'low', tokensSaved, fix: { type: 'command', @@ -679,36 +765,137 @@ async function detectGhostCommands(userMessages: string[]): Promise = { + high: HEALTH_WEIGHT_HIGH, + medium: HEALTH_WEIGHT_MEDIUM, + low: HEALTH_WEIGHT_LOW, +} + +export function computeHealth(findings: WasteFinding[]): { score: number; grade: HealthGrade } { + if (findings.length === 0) return { score: 100, grade: 'A' } + let penalty = 0 + for (const f of findings) penalty += HEALTH_WEIGHTS[f.impact] ?? 0 + const score = Math.max(0, 100 - Math.min(HEALTH_MAX_PENALTY, penalty)) + const grade: HealthGrade = + score >= GRADE_A_MIN ? 'A' : + score >= GRADE_B_MIN ? 'B' : + score >= GRADE_C_MIN ? 'C' : + score >= GRADE_D_MIN ? 'D' : 'F' + return { score, grade } +} + +const URGENCY_WEIGHTS: Record = { high: 1, medium: 0.5, low: 0.2 } + +function urgencyScore(f: WasteFinding): number { + const normalizedTokens = Math.min(1, f.tokensSaved / URGENCY_TOKEN_NORMALIZE) + return URGENCY_WEIGHTS[f.impact] * URGENCY_IMPACT_WEIGHT + normalizedTokens * URGENCY_TOKEN_WEIGHT +} + +// ============================================================================ +// Cost estimation +// ============================================================================ + +const INPUT_COST_RATIO = 0.7 +const DEFAULT_COST_PER_TOKEN = 0 + function computeInputCostRate(projects: ProjectSummary[]): number { const sessions = projects.flatMap(p => p.sessions) const totalCost = sessions.reduce((s, sess) => s + sess.totalCostUSD, 0) const totalTokens = sessions.reduce((s, sess) => s + sess.totalInputTokens + sess.totalCacheReadTokens + sess.totalCacheWriteTokens, 0) - if (totalTokens === 0 || totalCost === 0) return 1 / 1_000_000 - return (totalCost * 0.7) / totalTokens + if (totalTokens === 0 || totalCost === 0) return DEFAULT_COST_PER_TOKEN + return (totalCost * INPUT_COST_RATIO) / totalTokens } +// ============================================================================ +// Main entry points +// ============================================================================ + +export async function scanAndDetect( + projects: ProjectSummary[], + dateRange?: DateRange, +): Promise { + const costRate = computeInputCostRate(projects) + const { toolCalls, projectCwds, apiCalls, userMessages } = await scanSessions(dateRange) + + const findings: WasteFinding[] = [] + const syncDetectors: Array<() => WasteFinding | null> = [ + () => detectCacheBloat(apiCalls, projects), + () => detectLowReadEditRatio(toolCalls), + () => detectJunkReads(toolCalls), + () => detectDuplicateReads(toolCalls), + () => detectUnusedMcp(toolCalls, projects, projectCwds), + () => detectMissingClaudeignore(projectCwds), + () => detectBloatedClaudeMd(projectCwds), + () => detectBashBloat(), + ] + for (const detect of syncDetectors) { + const finding = detect() + if (finding) findings.push(finding) + } + + const ghostResults = await Promise.all([ + detectGhostAgents(toolCalls), + detectGhostSkills(toolCalls), + detectGhostCommands(userMessages), + ]) + for (const f of ghostResults) if (f) findings.push(f) + + findings.sort((a, b) => urgencyScore(b) - urgencyScore(a)) + const { score, grade } = computeHealth(findings) + return { findings, costRate, healthScore: score, healthGrade: grade } +} + +// ============================================================================ +// CLI rendering +// ============================================================================ + +const PANEL_WIDTH = 62 +const SEP = '\u2500' +const IMPACT_COLORS: Record = { high: RED, medium: ORANGE, low: DIM } +const GRADE_COLORS: Record = { A: GREEN, B: GREEN, C: GOLD, D: ORANGE, F: RED } + function wrap(text: string, width: number, indent: string): string { const words = text.split(' ') const lines: string[] = [] @@ -725,24 +912,21 @@ function wrap(text: string, width: number, indent: string): string { return lines.join('\n') } -const IMPACT_COLORS: Record = { high: '#F55B5B', medium: ORANGE, low: DIM } - -function renderFinding(n: number, f: WasteFinding, costRate: number, W: number): string[] { +function renderFinding(n: number, f: WasteFinding, costRate: number): string[] { const lines: string[] = [] - const sep = '\u2500' const costSaved = f.tokensSaved * costRate const impactLabel = f.impact.charAt(0).toUpperCase() + f.impact.slice(1) const savings = `~${formatTokens(f.tokensSaved)} tokens (~${formatCost(costSaved)})` - const titlePad = W - f.title.length - impactLabel.length - 8 - const pad = titlePad > 0 ? ' ' + sep.repeat(titlePad) + ' ' : ' ' + const titlePad = PANEL_WIDTH - f.title.length - impactLabel.length - 8 + const pad = titlePad > 0 ? ' ' + SEP.repeat(titlePad) + ' ' : ' ' - lines.push(chalk.hex(DIM)(` ${sep}${sep}${sep} `) + + lines.push(chalk.hex(DIM)(` ${SEP}${SEP}${SEP} `) + chalk.bold(`${n}. ${f.title}`) + chalk.hex(DIM)(pad) + - chalk.hex(IMPACT_COLORS[f.impact] ?? DIM)(impactLabel) + - chalk.hex(DIM)(` ${sep}${sep}${sep}`)) + chalk.hex(IMPACT_COLORS[f.impact])(impactLabel) + + chalk.hex(DIM)(` ${SEP}${SEP}${SEP}`)) lines.push('') - lines.push(wrap(f.explanation, W - 4, ' ')) + lines.push(wrap(f.explanation, PANEL_WIDTH - 4, ' ')) lines.push('') lines.push(chalk.hex(GOLD)(` Potential savings: ${savings}`)) lines.push('') @@ -750,25 +934,18 @@ function renderFinding(n: number, f: WasteFinding, costRate: number, W: number): const a = f.fix if (a.type === 'file-content') { lines.push(chalk.hex(DIM)(` ${a.label}`)) - for (const line of a.content.split('\n')) { - lines.push(chalk.hex(CYAN)(` ${line}`)) - } + for (const line of a.content.split('\n')) lines.push(chalk.hex(CYAN)(` ${line}`)) } else if (a.type === 'command') { lines.push(chalk.hex(DIM)(` ${a.label}`)) - for (const line of a.text.split('\n')) { - lines.push(chalk.hex(CYAN)(` ${line}`)) - } + for (const line of a.text.split('\n')) lines.push(chalk.hex(CYAN)(` ${line}`)) } else { lines.push(chalk.hex(DIM)(` ${a.label}`)) lines.push(chalk.hex(CYAN)(` ${a.text}`)) } - lines.push('') return lines } -const GRADE_COLORS: Record = { A: GREEN, B: GREEN, C: GOLD, D: ORANGE, F: '#F55B5B' } - function renderOptimize( findings: WasteFinding[], costRate: number, @@ -780,23 +957,21 @@ function renderOptimize( healthGrade: HealthGrade, ): string { const lines: string[] = [] - const W = 62 - const sep = '\u2500' - lines.push('') - lines.push(` ${chalk.bold.hex(ORANGE)('CodeBurn Optimize')}${chalk.dim(' ' + periodLabel)}`) - lines.push(chalk.hex(DIM)(' ' + sep.repeat(W))) + lines.push(` ${chalk.bold.hex(ORANGE)('CodeBurn -- config health')}${chalk.dim(' ' + periodLabel)}`) + lines.push(chalk.hex(DIM)(' ' + SEP.repeat(PANEL_WIDTH))) + const issueSuffix = findings.length > 0 ? `, ${findings.length} issue${findings.length > 1 ? 's' : ''}` : '' lines.push(' ' + [ `${sessionCount} sessions`, `${callCount.toLocaleString()} calls`, chalk.hex(GOLD)(formatCost(periodCost)), - `Setup: ${chalk.bold.hex(GRADE_COLORS[healthGrade])(healthGrade)} ${chalk.dim(`(${healthScore}/100)`)}`, + `Health: ${chalk.bold.hex(GRADE_COLORS[healthGrade])(healthGrade)}${chalk.dim(` (${healthScore}/100${issueSuffix})`)}`, ].join(chalk.hex(DIM)(' '))) lines.push('') if (findings.length === 0) { - lines.push(chalk.hex(GREEN)(' No waste detected -- your setup looks clean.')) + lines.push(chalk.hex(GREEN)(' Nothing to fix. Your setup is lean.')) lines.push('') return lines.join('\n') } @@ -806,79 +981,20 @@ function renderOptimize( const pctRaw = periodCost > 0 ? (totalCost / periodCost) * 100 : 0 const pct = pctRaw >= 1 ? pctRaw.toFixed(0) : pctRaw.toFixed(1) - lines.push(chalk.hex(GREEN)(` Potential savings: ~${formatTokens(totalTokens)} tokens (~${formatCost(totalCost)}, ~${pct}% of spend)`)) + const costText = costRate > 0 ? ` (~${formatCost(totalCost)}, ~${pct}% of spend)` : '' + lines.push(chalk.hex(GREEN)(` Potential savings: ~${formatTokens(totalTokens)} tokens${costText}`)) lines.push('') - const sorted = findings - - for (let i = 0; i < sorted.length; i++) { - lines.push(...renderFinding(i + 1, sorted[i], costRate, W)) + for (let i = 0; i < findings.length; i++) { + lines.push(...renderFinding(i + 1, findings[i], costRate)) } - lines.push(chalk.hex(DIM)(' ' + sep.repeat(W))) - lines.push(chalk.dim(' Token estimates are approximate. Actual savings vary by file size and model.')) + lines.push(chalk.hex(DIM)(' ' + SEP.repeat(PANEL_WIDTH))) + lines.push(chalk.dim(' Estimates only.')) lines.push('') - return lines.join('\n') } -function computeHealth(findings: WasteFinding[]): { score: number; grade: HealthGrade } { - if (findings.length === 0) return { score: 100, grade: 'A' } - - const impactWeight: Record = { high: 15, medium: 7, low: 3 } - let penalty = 0 - for (const f of findings) penalty += impactWeight[f.impact] ?? 0 - - const score = Math.max(0, 100 - Math.min(80, penalty)) - const grade: HealthGrade = score >= 90 ? 'A' : score >= 75 ? 'B' : score >= 55 ? 'C' : score >= 30 ? 'D' : 'F' - return { score, grade } -} - -function urgencyScore(f: WasteFinding): number { - const impactWeight: Record = { high: 1, medium: 0.5, low: 0.2 } - const normalizedTokens = Math.min(1, f.tokensSaved / 500_000) - return (impactWeight[f.impact] ?? 0) * 0.7 + normalizedTokens * 0.3 -} - -export async function scanAndDetect( - projects: ProjectSummary[], - dateRange?: DateRange, -): Promise { - const costRate = computeInputCostRate(projects) - const { toolCalls, projectCwds, apiCalls, userMessages } = await scanSessions(dateRange) - - const findings: WasteFinding[] = [] - const syncDetectors = [ - () => detectCacheBloat(apiCalls), - () => detectLowReadEditRatio(toolCalls), - () => detectJunkReads(toolCalls), - () => detectDuplicateReads(toolCalls), - () => detectUnusedMcp(toolCalls, projects, projectCwds), - () => detectMissingClaudeignore(projectCwds), - () => detectBloatedClaudeMd(projectCwds), - () => detectBashBloat(), - ] - for (const detect of syncDetectors) { - const finding = detect() - if (finding) findings.push(finding) - } - - const asyncDetectors = [ - () => detectGhostAgents(toolCalls), - () => detectGhostSkills(toolCalls), - () => detectGhostCommands(userMessages), - ] - for (const detect of asyncDetectors) { - const finding = await detect() - if (finding) findings.push(finding) - } - - findings.sort((a, b) => urgencyScore(b) - urgencyScore(a)) - - const { score, grade } = computeHealth(findings) - return { findings, costRate, healthScore: score, healthGrade: grade } -} - export async function runOptimize( projects: ProjectSummary[], periodLabel: string, @@ -889,7 +1005,7 @@ export async function runOptimize( return } - process.stderr.write(chalk.dim(' Scanning sessions for waste patterns...\n')) + process.stderr.write(chalk.dim(' Analyzing your sessions...\n')) const { findings, costRate, healthScore, healthGrade } = await scanAndDetect(projects, dateRange) const sessions = projects.flatMap(p => p.sessions) diff --git a/tests/optimize.test.ts b/tests/optimize.test.ts index b77ba25..fc2954d 100644 --- a/tests/optimize.test.ts +++ b/tests/optimize.test.ts @@ -1,318 +1,258 @@ -import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest' -import { existsSync, readFileSync } from 'fs' -import { homedir } from 'os' -import { join } from 'path' +import { describe, it, expect } from 'vitest' -vi.mock('fs', async () => { - const actual = await vi.importActual('fs') - return { ...actual, existsSync: vi.fn(), readFileSync: vi.fn() } -}) +import { + detectJunkReads, + detectDuplicateReads, + detectLowReadEditRatio, + detectCacheBloat, + detectBloatedClaudeMd, + detectMissingClaudeignore, + computeHealth, + type ToolCall, + type ApiCallMeta, + type WasteFinding, +} from '../src/optimize.js' +import type { ProjectSummary } from '../src/types.js' -const mockExistsSync = vi.mocked(existsSync) -const mockReadFileSync = vi.mocked(readFileSync) - -type ToolCall = { - name: string - input: Record - sessionId: string - project: string +function call(name: string, input: Record, sessionId = 's1', project = 'p1'): ToolCall { + return { name, input, sessionId, project } } -// Re-implement detector logic for isolated testing -// This avoids importing the module which has side-effect imports - -function detectJunkReadsLogic(calls: ToolCall[]) { - const JUNK_PATTERN = /\/(node_modules|\.git|dist|build|__pycache__|\.next|\.nuxt|\.output|coverage|\.cache|\.tsbuildinfo|\.venv|venv|\.svn|\.hg)\// - const readCalls = calls.filter(c => c.name === 'Read' || c.name === 'FileReadTool') - const dirCounts = new Map() - let total = 0 - for (const call of readCalls) { - const fp = call.input.file_path as string | undefined - if (!fp || !JUNK_PATTERN.test(fp)) continue - total++ - const dirs = ['node_modules', '.git', 'dist', 'build', '__pycache__', '.next', '.venv', 'venv'] - for (const d of dirs) { - if (fp.includes(`/${d}/`)) { dirCounts.set(d, (dirCounts.get(d) ?? 0) + 1); break } - } - } - return { total, dirCounts } +function emptyProjects(): ProjectSummary[] { + return [] } -function detectDuplicateReadsLogic(calls: ToolCall[]) { - const JUNK_PATTERN = /\/(node_modules|\.git|dist|build|__pycache__|\.next)\// - const readCalls = calls.filter(c => c.name === 'Read' || c.name === 'FileReadTool') - const sessionFiles = new Map>() - for (const call of readCalls) { - const fp = call.input.file_path as string | undefined - if (!fp || JUNK_PATTERN.test(fp)) continue - const key = `${call.project}:${call.sessionId}` - if (!sessionFiles.has(key)) sessionFiles.set(key, new Map()) - const fm = sessionFiles.get(key)! - fm.set(fp, (fm.get(fp) ?? 0) + 1) - } - let totalDuplicates = 0 - for (const fm of sessionFiles.values()) { - for (const [, count] of fm) { - if (count > 1) totalDuplicates += count - 1 - } - } - return totalDuplicates -} - -describe('optimize: junk reads detection', () => { - it('detects node_modules reads', () => { - const calls: ToolCall[] = [ - { name: 'Read', input: { file_path: '/project/node_modules/foo/index.js' }, sessionId: 's1', project: 'p1' }, - { name: 'Read', input: { file_path: '/project/node_modules/bar/package.json' }, sessionId: 's1', project: 'p1' }, - { name: 'Read', input: { file_path: '/project/node_modules/baz/lib.js' }, sessionId: 's1', project: 'p1' }, - { name: 'Read', input: { file_path: '/project/src/main.ts' }, sessionId: 's1', project: 'p1' }, +describe('detectJunkReads', () => { + it('returns null below minimum threshold', () => { + const calls = [ + call('Read', { file_path: '/x/node_modules/a.js' }), + call('Read', { file_path: '/x/node_modules/b.js' }), ] - const result = detectJunkReadsLogic(calls) - expect(result.total).toBe(3) - expect(result.dirCounts.get('node_modules')).toBe(3) + expect(detectJunkReads(calls)).toBeNull() }) - it('detects .git reads', () => { - const calls: ToolCall[] = [ - { name: 'Read', input: { file_path: '/project/.git/config' }, sessionId: 's1', project: 'p1' }, - { name: 'Read', input: { file_path: '/project/.git/HEAD' }, sessionId: 's1', project: 'p1' }, + it('flags when threshold is met', () => { + const calls = [ + call('Read', { file_path: '/x/node_modules/a.js' }), + call('Read', { file_path: '/x/node_modules/b.js' }), + call('Read', { file_path: '/x/.git/config' }), ] - const result = detectJunkReadsLogic(calls) - expect(result.total).toBe(2) - expect(result.dirCounts.get('.git')).toBe(2) + const finding = detectJunkReads(calls) + expect(finding).not.toBeNull() + expect(finding!.impact).toBe('low') }) - it('detects mixed junk directories', () => { - const calls: ToolCall[] = [ - { name: 'Read', input: { file_path: '/project/node_modules/a.js' }, sessionId: 's1', project: 'p1' }, - { name: 'Read', input: { file_path: '/project/dist/bundle.js' }, sessionId: 's1', project: 'p1' }, - { name: 'Read', input: { file_path: '/project/.venv/lib/python/site.py' }, sessionId: 's1', project: 'p1' }, - ] - const result = detectJunkReadsLogic(calls) - expect(result.total).toBe(3) - expect(result.dirCounts.get('node_modules')).toBe(1) - expect(result.dirCounts.get('dist')).toBe(1) - expect(result.dirCounts.get('.venv')).toBe(1) + it('scales impact with read count', () => { + const make = (n: number) => Array.from({ length: n }, (_, i) => + call('Read', { file_path: `/x/node_modules/file-${i}.js` }) + ) + expect(detectJunkReads(make(25))!.impact).toBe('high') + expect(detectJunkReads(make(10))!.impact).toBe('medium') }) it('ignores non-junk paths', () => { - const calls: ToolCall[] = [ - { name: 'Read', input: { file_path: '/project/src/index.ts' }, sessionId: 's1', project: 'p1' }, - { name: 'Read', input: { file_path: '/project/README.md' }, sessionId: 's1', project: 'p1' }, + const calls = [ + call('Read', { file_path: '/x/src/a.ts' }), + call('Read', { file_path: '/x/src/b.ts' }), + call('Read', { file_path: '/x/README.md' }), ] - const result = detectJunkReadsLogic(calls) - expect(result.total).toBe(0) + expect(detectJunkReads(calls)).toBeNull() }) - it('ignores non-Read tools', () => { - const calls: ToolCall[] = [ - { name: 'Edit', input: { file_path: '/project/node_modules/foo.js' }, sessionId: 's1', project: 'p1' }, - { name: 'Bash', input: { command: 'ls node_modules' }, sessionId: 's1', project: 'p1' }, + it('ignores non-read tools', () => { + const calls = [ + call('Edit', { file_path: '/x/node_modules/a.js' }), + call('Bash', { command: 'ls node_modules' }), + call('Grep', { pattern: 'test', path: '/x/node_modules' }), ] - const result = detectJunkReadsLogic(calls) - expect(result.total).toBe(0) + expect(detectJunkReads(calls)).toBeNull() }) - it('handles missing file_path', () => { - const calls: ToolCall[] = [ - { name: 'Read', input: {}, sessionId: 's1', project: 'p1' }, - { name: 'Read', input: { file_path: null as unknown as string }, sessionId: 's1', project: 'p1' }, + it('handles missing file_path gracefully', () => { + const calls = [ + call('Read', {}), + call('Read', { file_path: null as unknown as string }), ] - const result = detectJunkReadsLogic(calls) - expect(result.total).toBe(0) + expect(detectJunkReads(calls)).toBeNull() + }) + + it('builds .claudeignore content from detected + common extras', () => { + const calls = Array.from({ length: 5 }, () => call('Read', { file_path: '/x/node_modules/a.js' })) + const finding = detectJunkReads(calls)! + expect(finding.fix.type).toBe('file-content') + if (finding.fix.type === 'file-content') { + expect(finding.fix.content).toContain('node_modules') + } }) }) -describe('optimize: duplicate reads detection', () => { - it('detects files read multiple times in same session', () => { - const calls: ToolCall[] = [ - { name: 'Read', input: { file_path: '/project/src/main.ts' }, sessionId: 's1', project: 'p1' }, - { name: 'Read', input: { file_path: '/project/src/main.ts' }, sessionId: 's1', project: 'p1' }, - { name: 'Read', input: { file_path: '/project/src/main.ts' }, sessionId: 's1', project: 'p1' }, +describe('detectDuplicateReads', () => { + it('counts same file read multiple times in same session', () => { + const calls = [ + ...Array.from({ length: 4 }, () => call('Read', { file_path: '/src/a.ts' }, 's1')), + ...Array.from({ length: 4 }, () => call('Read', { file_path: '/src/b.ts' }, 's1')), ] - expect(detectDuplicateReadsLogic(calls)).toBe(2) + const finding = detectDuplicateReads(calls) + expect(finding).not.toBeNull() }) - it('does not count reads across different sessions', () => { - const calls: ToolCall[] = [ - { name: 'Read', input: { file_path: '/project/src/main.ts' }, sessionId: 's1', project: 'p1' }, - { name: 'Read', input: { file_path: '/project/src/main.ts' }, sessionId: 's2', project: 'p1' }, + it('does not count across sessions', () => { + const calls = [ + call('Read', { file_path: '/src/a.ts' }, 's1'), + call('Read', { file_path: '/src/a.ts' }, 's2'), + call('Read', { file_path: '/src/a.ts' }, 's3'), ] - expect(detectDuplicateReadsLogic(calls)).toBe(0) + expect(detectDuplicateReads(calls)).toBeNull() }) - it('excludes junk directory reads from duplicate count', () => { - const calls: ToolCall[] = [ - { name: 'Read', input: { file_path: '/project/node_modules/foo.js' }, sessionId: 's1', project: 'p1' }, - { name: 'Read', input: { file_path: '/project/node_modules/foo.js' }, sessionId: 's1', project: 'p1' }, - ] - expect(detectDuplicateReadsLogic(calls)).toBe(0) + it('excludes junk directory reads', () => { + const calls = Array.from({ length: 10 }, () => + call('Read', { file_path: '/x/node_modules/foo.js' }, 's1') + ) + expect(detectDuplicateReads(calls)).toBeNull() }) - it('counts duplicates per file independently', () => { - const calls: ToolCall[] = [ - { name: 'Read', input: { file_path: '/project/a.ts' }, sessionId: 's1', project: 'p1' }, - { name: 'Read', input: { file_path: '/project/a.ts' }, sessionId: 's1', project: 'p1' }, - { name: 'Read', input: { file_path: '/project/b.ts' }, sessionId: 's1', project: 'p1' }, - { name: 'Read', input: { file_path: '/project/b.ts' }, sessionId: 's1', project: 'p1' }, - { name: 'Read', input: { file_path: '/project/b.ts' }, sessionId: 's1', project: 'p1' }, + it('returns null for single reads', () => { + const calls = [ + call('Read', { file_path: '/src/a.ts' }, 's1'), + call('Read', { file_path: '/src/b.ts' }, 's1'), ] - expect(detectDuplicateReadsLogic(calls)).toBe(3) - }) - - it('returns 0 for single reads', () => { - const calls: ToolCall[] = [ - { name: 'Read', input: { file_path: '/project/a.ts' }, sessionId: 's1', project: 'p1' }, - { name: 'Read', input: { file_path: '/project/b.ts' }, sessionId: 's1', project: 'p1' }, - { name: 'Read', input: { file_path: '/project/c.ts' }, sessionId: 's1', project: 'p1' }, - ] - expect(detectDuplicateReadsLogic(calls)).toBe(0) - }) - - it('handles empty calls', () => { - expect(detectDuplicateReadsLogic([])).toBe(0) + expect(detectDuplicateReads(calls)).toBeNull() }) }) -function detectReadEditRatioLogic(calls: ToolCall[]) { - const READ_NAMES = new Set(['Read', 'Grep', 'Glob', 'FileReadTool', 'GrepTool', 'GlobTool']) - const EDIT_NAMES = new Set(['Edit', 'Write', 'FileEditTool', 'FileWriteTool', 'NotebookEdit']) - let reads = 0, edits = 0 - for (const c of calls) { - if (READ_NAMES.has(c.name)) reads++ - else if (EDIT_NAMES.has(c.name)) edits++ - } - return { reads, edits, ratio: edits > 0 ? reads / edits : Infinity } -} - -describe('optimize: read:edit ratio detection', () => { - it('detects low ratio (edit-heavy)', () => { - const calls: ToolCall[] = [ - ...Array(5).fill(null).map(() => ({ name: 'Read', input: {}, sessionId: 's1', project: 'p1' })), - ...Array(10).fill(null).map(() => ({ name: 'Edit', input: {}, sessionId: 's1', project: 'p1' })), +describe('detectLowReadEditRatio', () => { + it('returns null below minimum edit count', () => { + const calls = [ + call('Edit', {}), + call('Edit', {}), + call('Read', {}), ] - const { ratio } = detectReadEditRatioLogic(calls) - expect(ratio).toBe(0.5) + expect(detectLowReadEditRatio(calls)).toBeNull() }) - it('healthy ratio passes (4:1+)', () => { - const calls: ToolCall[] = [ - ...Array(40).fill(null).map(() => ({ name: 'Read', input: {}, sessionId: 's1', project: 'p1' })), - ...Array(10).fill(null).map(() => ({ name: 'Edit', input: {}, sessionId: 's1', project: 'p1' })), + it('returns null when ratio is healthy', () => { + const calls = [ + ...Array.from({ length: 40 }, () => call('Read', {})), + ...Array.from({ length: 10 }, () => call('Edit', {})), ] - const { ratio } = detectReadEditRatioLogic(calls) - expect(ratio).toBe(4) + expect(detectLowReadEditRatio(calls)).toBeNull() }) - it('counts Grep and Glob as reads', () => { - const calls: ToolCall[] = [ - { name: 'Read', input: {}, sessionId: 's1', project: 'p1' }, - { name: 'Grep', input: {}, sessionId: 's1', project: 'p1' }, - { name: 'Glob', input: {}, sessionId: 's1', project: 'p1' }, - { name: 'Edit', input: {}, sessionId: 's1', project: 'p1' }, + it('flags when edits outpace reads', () => { + const calls = [ + ...Array.from({ length: 5 }, () => call('Read', {})), + ...Array.from({ length: 10 }, () => call('Edit', {})), ] - const { reads, edits } = detectReadEditRatioLogic(calls) - expect(reads).toBe(3) - expect(edits).toBe(1) + const finding = detectLowReadEditRatio(calls) + expect(finding).not.toBeNull() + expect(finding!.impact).toBe('high') + }) + + it('counts Grep and Glob as reads for ratio', () => { + const calls = [ + ...Array.from({ length: 40 }, () => call('Grep', {})), + ...Array.from({ length: 10 }, () => call('Edit', {})), + ] + expect(detectLowReadEditRatio(calls)).toBeNull() }) it('counts Write as edit', () => { - const calls: ToolCall[] = [ - { name: 'Write', input: {}, sessionId: 's1', project: 'p1' }, - { name: 'Edit', input: {}, sessionId: 's1', project: 'p1' }, + const calls = [ + ...Array.from({ length: 15 }, () => call('Read', {})), + ...Array.from({ length: 10 }, () => call('Write', {})), ] - const { edits } = detectReadEditRatioLogic(calls) - expect(edits).toBe(2) - }) - - it('ignores non-read non-edit tools', () => { - const calls: ToolCall[] = [ - { name: 'Bash', input: {}, sessionId: 's1', project: 'p1' }, - { name: 'Agent', input: {}, sessionId: 's1', project: 'p1' }, - { name: 'mcp__foo__bar', input: {}, sessionId: 's1', project: 'p1' }, - ] - const { reads, edits } = detectReadEditRatioLogic(calls) - expect(reads).toBe(0) - expect(edits).toBe(0) + const finding = detectLowReadEditRatio(calls) + expect(finding).not.toBeNull() }) }) -function computeHealthLogic(impacts: Array<'high' | 'medium' | 'low'>): { score: number; grade: string } { - if (impacts.length === 0) return { score: 100, grade: 'A' } - const impactWeight: Record = { high: 15, medium: 7, low: 3 } - let penalty = 0 - for (const i of impacts) penalty += impactWeight[i] ?? 0 - const score = Math.max(0, 100 - Math.min(80, penalty)) - const grade = score >= 90 ? 'A' : score >= 75 ? 'B' : score >= 55 ? 'C' : score >= 30 ? 'D' : 'F' - return { score, grade } -} +describe('detectCacheBloat', () => { + it('returns null below minimum api calls', () => { + const apiCalls: ApiCallMeta[] = [ + { cacheCreationTokens: 80000, version: '2.1.100' }, + { cacheCreationTokens: 80000, version: '2.1.100' }, + ] + expect(detectCacheBloat(apiCalls, emptyProjects())).toBeNull() + }) -describe('optimize: health score and grade', () => { - it('returns A with no findings', () => { - const { score, grade } = computeHealthLogic([]) + it('returns null when median is close to baseline', () => { + const apiCalls: ApiCallMeta[] = Array.from({ length: 20 }, () => ({ + cacheCreationTokens: 50000, + version: '2.1.98', + })) + expect(detectCacheBloat(apiCalls, emptyProjects())).toBeNull() + }) + + it('flags when median exceeds 1.4x baseline', () => { + const apiCalls: ApiCallMeta[] = Array.from({ length: 20 }, () => ({ + cacheCreationTokens: 80000, + version: '2.1.100', + })) + const finding = detectCacheBloat(apiCalls, emptyProjects()) + expect(finding).not.toBeNull() + }) +}) + +describe('detectBloatedClaudeMd', () => { + it('returns null when no projects have CLAUDE.md', () => { + const result = detectBloatedClaudeMd(new Set(['/nonexistent/path'])) + expect(result).toBeNull() + }) + + it('returns null for empty project set', () => { + const result = detectBloatedClaudeMd(new Set()) + expect(result).toBeNull() + }) +}) + +describe('detectMissingClaudeignore', () => { + it('returns null for empty set', () => { + expect(detectMissingClaudeignore(new Set())).toBeNull() + }) + + it('returns null for non-existent cwds', () => { + expect(detectMissingClaudeignore(new Set(['/does/not/exist']))).toBeNull() + }) +}) + +describe('computeHealth', () => { + it('returns A with 100 for no findings', () => { + const { score, grade } = computeHealth([]) expect(score).toBe(100) expect(grade).toBe('A') }) - it('one low finding keeps grade at A', () => { - const { score, grade } = computeHealthLogic(['low']) + function mockFinding(impact: 'high' | 'medium' | 'low'): WasteFinding { + return { + title: 't', explanation: 'e', impact, tokensSaved: 1000, + fix: { type: 'paste', label: 'l', text: 't' }, + } + } + + it('one low finding stays at A', () => { + const { score, grade } = computeHealth([mockFinding('low')]) expect(score).toBe(97) expect(grade).toBe('A') }) it('two high findings drop to C', () => { - const { score, grade } = computeHealthLogic(['high', 'high']) + const { score, grade } = computeHealth([mockFinding('high'), mockFinding('high')]) expect(score).toBe(70) expect(grade).toBe('C') }) - it('caps penalty at 80 to prevent going below 20', () => { - const impacts = Array(20).fill('high' as const) - const { score } = computeHealthLogic(impacts) + it('caps penalty at 80 to prevent score below 20', () => { + const findings = Array.from({ length: 20 }, () => mockFinding('high')) + const { score } = computeHealth(findings) expect(score).toBe(20) }) - it('mix produces D grade', () => { - const { score, grade } = computeHealthLogic(['high', 'high', 'medium', 'medium', 'low']) - expect(score).toBe(100 - 15 - 15 - 7 - 7 - 3) - expect(grade).toBe('D') - }) -}) - -function expandImportsLogic(content: string, resolveMap: Record, depth = 0): number { - if (depth > 5) return 0 - let total = content.split('\n').length - const matches = content.matchAll(/^@([^\s]+)/gm) - for (const m of matches) { - const key = m[1] || '' - if (resolveMap[key]) { - total += expandImportsLogic(resolveMap[key], resolveMap, depth + 1) - } - } - return total -} - -describe('optimize: @-import expansion', () => { - it('counts only the base file when no imports', () => { - const total = expandImportsLogic('line 1\nline 2\nline 3', {}) - expect(total).toBe(3) - }) - - it('expands single @-import', () => { - const main = 'line 1\n@./imported.md\nline 3' - const imported = 'i1\ni2\ni3\ni4\ni5' - expect(expandImportsLogic(main, { './imported.md': imported })).toBe(3 + 5) - }) - - it('expands nested @-imports recursively', () => { - const main = 'a\n@b.md' - const b = 'b1\nb2\n@c.md' - const c = 'c1\nc2\nc3' - expect(expandImportsLogic(main, { 'b.md': b, 'c.md': c })).toBe(2 + 3 + 3) - }) - - it('caps recursion depth', () => { - const circular = '@x.md' - expect(expandImportsLogic(circular, { 'x.md': circular })).toBeLessThan(10) + it('progresses grades predictably', () => { + expect(computeHealth([mockFinding('low')]).grade).toBe('A') + expect(computeHealth([mockFinding('medium')]).grade).toBe('A') + expect(computeHealth([mockFinding('medium'), mockFinding('medium')]).grade).toBe('B') + expect(computeHealth([mockFinding('high'), mockFinding('high'), mockFinding('high')]).grade).toBe('C') + expect(computeHealth([mockFinding('high'), mockFinding('high'), mockFinding('high'), mockFinding('high'), mockFinding('high')]).grade).toBe('F') }) }) From 7e4edf66b645a9a3a4726fb0b688b203455ab84f Mon Sep 17 00:00:00 2001 From: AgentSeal Date: Thu, 16 Apr 2026 06:35:39 -0700 Subject: [PATCH 04/70] perf(optimize): mtime pre-filter, parallel reads, result cache - runWithConcurrency helper runs file reads with configurable parallelism (default 16) instead of sequential await. - isFileStaleForRange skips files whose mtime is older than the date range start, avoiding unnecessary reads for narrow periods. - Result-level cache keyed on (dateRange, project fingerprint) with 60s TTL. Warm dashboard 'o' press now hits cache instead of rescanning. - Early-return when projects array is empty so empty-state path does not trigger filesystem walk. Measured CLI cold scan on 12K files, 1833 sessions week: before: 12-17s after: 6-7s Dashboard warm cache hit: <50ms. --- src/optimize.ts | 67 +++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 59 insertions(+), 8 deletions(-) diff --git a/src/optimize.ts b/src/optimize.ts index 11b7172..7cb0e61 100644 --- a/src/optimize.ts +++ b/src/optimize.ts @@ -1,5 +1,5 @@ import chalk from 'chalk' -import { readdir, readFile } from 'fs/promises' +import { readdir, readFile, stat } from 'fs/promises' import { existsSync, readFileSync, statSync } from 'fs' import { basename, join } from 'path' import { homedir } from 'os' @@ -147,6 +147,9 @@ type ScanData = { // JSONL scanner // ============================================================================ +const FILE_READ_CONCURRENCY = 16 +const RESULT_CACHE_TTL_MS = 60_000 + async function collectJsonlFiles(dirPath: string): Promise { const files = await readdir(dirPath).catch(() => []) const result = files.filter(f => f.endsWith('.jsonl')).map(f => join(dirPath, f)) @@ -161,6 +164,29 @@ async function collectJsonlFiles(dirPath: string): Promise { return result } +async function isFileStaleForRange(filePath: string, range: DateRange | undefined): Promise { + if (!range) return false + try { + const s = await stat(filePath) + return s.mtimeMs < range.start.getTime() + } catch { return false } +} + +async function runWithConcurrency( + items: T[], + limit: number, + worker: (item: T) => Promise, +): Promise { + let idx = 0 + async function next(): Promise { + while (idx < items.length) { + const current = idx++ + await worker(items[current]) + } + } + await Promise.all(Array.from({ length: Math.min(limit, items.length) }, () => next())) +} + type ScanFileResult = { calls: ToolCall[] cwds: string[] @@ -258,18 +284,24 @@ async function scanSessions(dateRange?: DateRange): Promise { const allVersions = new Set() const allUserMessages: string[] = [] + const tasks: Array<{ file: string; project: string }> = [] for (const source of sources) { const files = await collectJsonlFiles(source.path) for (const file of files) { - const { calls, cwds, apiCalls, versions, userMessages } = await scanJsonlFile(file, source.project, dateRange) - allCalls.push(...calls) - for (const cwd of cwds) allCwds.add(cwd) - allApiCalls.push(...apiCalls) - for (const v of versions) if (v) allVersions.add(v) - allUserMessages.push(...userMessages) + if (await isFileStaleForRange(file, dateRange)) continue + tasks.push({ file, project: source.project }) } } + await runWithConcurrency(tasks, FILE_READ_CONCURRENCY, async ({ file, project }) => { + const { calls, cwds, apiCalls, versions, userMessages } = await scanJsonlFile(file, project, dateRange) + allCalls.push(...calls) + for (const cwd of cwds) allCwds.add(cwd) + allApiCalls.push(...apiCalls) + for (const v of versions) if (v) allVersions.add(v) + allUserMessages.push(...userMessages) + }) + return { toolCalls: allCalls, projectCwds: allCwds, apiCalls: allApiCalls, versions: allVersions, userMessages: allUserMessages } } @@ -852,10 +884,27 @@ function computeInputCostRate(projects: ProjectSummary[]): number { // Main entry points // ============================================================================ +type CacheEntry = { data: OptimizeResult; ts: number } +const resultCache = new Map() + +function cacheKey(projects: ProjectSummary[], dateRange: DateRange | undefined): string { + const dr = dateRange ? `${dateRange.start.getTime()}-${dateRange.end.getTime()}` : 'all' + const fingerprint = projects.length + ':' + projects.reduce((s, p) => s + p.totalApiCalls, 0) + return `${dr}:${fingerprint}` +} + export async function scanAndDetect( projects: ProjectSummary[], dateRange?: DateRange, ): Promise { + if (projects.length === 0) { + return { findings: [], costRate: 0, healthScore: 100, healthGrade: 'A' } + } + + const key = cacheKey(projects, dateRange) + const cached = resultCache.get(key) + if (cached && Date.now() - cached.ts < RESULT_CACHE_TTL_MS) return cached.data + const costRate = computeInputCostRate(projects) const { toolCalls, projectCwds, apiCalls, userMessages } = await scanSessions(dateRange) @@ -884,7 +933,9 @@ export async function scanAndDetect( findings.sort((a, b) => urgencyScore(b) - urgencyScore(a)) const { score, grade } = computeHealth(findings) - return { findings, costRate, healthScore: score, healthGrade: grade } + const result: OptimizeResult = { findings, costRate, healthScore: score, healthGrade: grade } + resultCache.set(key, { data: result, ts: Date.now() }) + return result } // ============================================================================ From a9ca2a1134f2c43b1f452e4a1c81b5a732860ade Mon Sep 17 00:00:00 2001 From: AgentSeal Date: Thu, 16 Apr 2026 06:53:08 -0700 Subject: [PATCH 05/70] feat(optimize): fix tracking via recent vs baseline split Solves the problem where users who fixed an issue continued to see the finding for the remainder of the period. Findings now show visible progress or disappear entirely. Mechanism (no state file, no new I/O): - ToolCall and ApiCallMeta gain a `recent` boolean, set when the entry's timestamp falls inside a rolling 48-hour window. - Each session-based detector counts recent vs total occurrences. - computeTrend classifies each finding: active -- recent rate matches baseline improving -- recent rate under half of baseline (green arrow) resolved -- zero recent waste AND confirmed recent activity - Resolved findings are suppressed. Improving findings render with a green "improving down-arrow" badge next to the impact label. - When no recent activity exists, findings default to active so a user who simply paused is not told everything is fixed. Applies to the four session-based detectors: junk reads, duplicate reads, low read:edit ratio, cache bloat. The filesystem detectors (missing .claudeignore, bloated CLAUDE.md, unused MCP, ghost agents / skills / commands, bash limit) already self-heal on next run. 5 new tests cover computeTrend edge cases. 126 tests pass. --- src/dashboard.tsx | 8 ++- src/optimize.ts | 136 +++++++++++++++++++++++++++++++++++------ tests/optimize.test.ts | 53 ++++++++++++++++ 3 files changed, 178 insertions(+), 19 deletions(-) diff --git a/src/dashboard.tsx b/src/dashboard.tsx index 6587614..6157c31 100644 --- a/src/dashboard.tsx +++ b/src/dashboard.tsx @@ -459,9 +459,15 @@ function FindingPanel({ index, finding, costRate, width }: { index: number; find const costSaved = finding.tokensSaved * costRate const color = IMPACT_PANEL_COLORS[finding.impact] ?? DIM const label = finding.impact.charAt(0).toUpperCase() + finding.impact.slice(1) + const trendBadge = finding.trend === 'improving' ? ' improving \u2193' : '' return ( - {index}. {finding.title} {label} + + {index}. {finding.title} + + {label} + {trendBadge && {trendBadge}} + {finding.explanation} Savings: ~{formatTokens(finding.tokensSaved)} tokens (~{formatCost(costSaved)}) diff --git a/src/optimize.ts b/src/optimize.ts index 7cb0e61..84b18df 100644 --- a/src/optimize.ts +++ b/src/optimize.ts @@ -108,12 +108,15 @@ export type WasteAction = | { type: 'command'; label: string; text: string } | { type: 'file-content'; label: string; path: string; content: string } +export type Trend = 'active' | 'improving' + export type WasteFinding = { title: string explanation: string impact: Impact tokensSaved: number fix: WasteAction + trend?: Trend } export type OptimizeResult = { @@ -128,11 +131,13 @@ export type ToolCall = { input: Record sessionId: string project: string + recent?: boolean } export type ApiCallMeta = { cacheCreationTokens: number version: string + recent?: boolean } type ScanData = { @@ -149,6 +154,9 @@ type ScanData = { const FILE_READ_CONCURRENCY = 16 const RESULT_CACHE_TTL_MS = 60_000 +const RECENT_WINDOW_HOURS = 48 +const RECENT_WINDOW_MS = RECENT_WINDOW_HOURS * 60 * 60 * 1000 +const IMPROVING_THRESHOLD = 0.5 async function collectJsonlFiles(dirPath: string): Promise { const files = await readdir(dirPath).catch(() => []) @@ -202,10 +210,16 @@ function inRange(timestamp: string | undefined, range: DateRange | undefined): b return ts >= range.start && ts <= range.end } +function isRecent(timestamp: string | undefined, cutoff: number): boolean { + if (!timestamp) return false + return new Date(timestamp).getTime() >= cutoff +} + export async function scanJsonlFile( filePath: string, project: string, dateRange: DateRange | undefined, + recentCutoffMs = Date.now() - RECENT_WINDOW_MS, ): Promise { let content: string try { @@ -229,6 +243,7 @@ export async function scanJsonlFile( const ts = typeof entry.timestamp === 'string' ? entry.timestamp : undefined const withinRange = inRange(ts, dateRange) + const recent = isRecent(ts, recentCutoffMs) if (entry.cwd && typeof entry.cwd === 'string' && withinRange) cwds.push(entry.cwd) if (entry.version && typeof entry.version === 'string' && withinRange) versions.push(entry.version) @@ -256,7 +271,7 @@ export async function scanJsonlFile( const usage = msg?.usage as Record | undefined if (usage) { const cacheCreate = (usage.cache_creation_input_tokens as number) ?? 0 - if (cacheCreate > 0) apiCalls.push({ cacheCreationTokens: cacheCreate, version: lastVersion }) + if (cacheCreate > 0) apiCalls.push({ cacheCreationTokens: cacheCreate, version: lastVersion, recent }) } const blocks = msg?.content @@ -269,6 +284,7 @@ export async function scanJsonlFile( input: (block.input as Record) ?? {}, sessionId, project, + recent, }) } } @@ -358,15 +374,17 @@ export function loadMcpConfigs(projectCwds: Iterable): Map() let totalJunkReads = 0 + let recentJunkReads = 0 for (const call of calls) { if (!isReadTool(call.name)) continue const filePath = call.input.file_path as string | undefined if (!filePath || !JUNK_PATTERN.test(filePath)) continue totalJunkReads++ + if (call.recent) recentJunkReads++ for (const dir of JUNK_DIRS) { if (filePath.includes(`/${dir}/`)) { dirCounts.set(dir, (dirCounts.get(dir) ?? 0) + 1) @@ -377,6 +395,10 @@ export function detectJunkReads(calls: ToolCall[]): WasteFinding | null { if (totalJunkReads < MIN_JUNK_READS_TO_FLAG) return null + const hasRecentActivity = calls.some(c => c.recent) + const trend = sessionTrend(recentJunkReads, totalJunkReads, dateRange, hasRecentActivity) + if (trend === 'resolved') return null + const sorted = [...dirCounts.entries()].sort((a, b) => b[1] - a[1]) const dirList = sorted.slice(0, 3).map(([d, n]) => `${d}/ (${n}x)`).join(', ') const tokensSaved = totalJunkReads * AVG_TOKENS_PER_READ @@ -397,11 +419,12 @@ export function detectJunkReads(calls: ToolCall[]): WasteFinding | null { path: '.claudeignore', content: ignoreContent, }, + trend, } } -export function detectDuplicateReads(calls: ToolCall[]): WasteFinding | null { - const sessionFiles = new Map>() +export function detectDuplicateReads(calls: ToolCall[], dateRange?: DateRange): WasteFinding | null { + const sessionFiles = new Map>() for (const call of calls) { if (!isReadTool(call.name)) continue @@ -410,17 +433,22 @@ export function detectDuplicateReads(calls: ToolCall[]): WasteFinding | null { const key = `${call.project}:${call.sessionId}` if (!sessionFiles.has(key)) sessionFiles.set(key, new Map()) const fm = sessionFiles.get(key)! - fm.set(filePath, (fm.get(filePath) ?? 0) + 1) + const entry = fm.get(filePath) ?? { count: 0, recent: 0 } + entry.count++ + if (call.recent) entry.recent++ + fm.set(filePath, entry) } let totalDuplicates = 0 + let recentDuplicates = 0 const fileDupes = new Map() for (const fm of sessionFiles.values()) { - for (const [file, count] of fm) { - if (count <= 1) continue - const extra = count - 1 + for (const [file, entry] of fm) { + if (entry.count <= 1) continue + const extra = entry.count - 1 totalDuplicates += extra + if (entry.recent > 1) recentDuplicates += entry.recent - 1 const name = basename(file) fileDupes.set(name, (fileDupes.get(name) ?? 0) + extra) } @@ -428,6 +456,10 @@ export function detectDuplicateReads(calls: ToolCall[]): WasteFinding | null { if (totalDuplicates < MIN_DUPLICATE_READS_TO_FLAG) return null + const hasRecentActivity = calls.some(c => c.recent) + const trend = sessionTrend(recentDuplicates, totalDuplicates, dateRange, hasRecentActivity) + if (trend === 'resolved') return null + const worst = [...fileDupes.entries()] .sort((a, b) => b[1] - a[1]) .slice(0, 3) @@ -446,6 +478,7 @@ export function detectDuplicateReads(calls: ToolCall[]): WasteFinding | null { label: 'Point Claude at exact locations in your prompt, for example:', text: 'In lines -, look at the function.', }, + trend, } } @@ -599,12 +632,19 @@ export function detectBloatedClaudeMd(projectCwds: Set): WasteFinding | const READ_TOOL_NAMES = new Set(['Read', 'Grep', 'Glob', 'FileReadTool', 'GrepTool', 'GlobTool']) const EDIT_TOOL_NAMES = new Set(['Edit', 'Write', 'FileEditTool', 'FileWriteTool', 'NotebookEdit']) -export function detectLowReadEditRatio(calls: ToolCall[]): WasteFinding | null { +export function detectLowReadEditRatio(calls: ToolCall[], dateRange?: DateRange): WasteFinding | null { let reads = 0 let edits = 0 + let recentEdits = 0 + let recentReads = 0 for (const call of calls) { - if (READ_TOOL_NAMES.has(call.name)) reads++ - else if (EDIT_TOOL_NAMES.has(call.name)) edits++ + if (READ_TOOL_NAMES.has(call.name)) { + reads++ + if (call.recent) recentReads++ + } else if (EDIT_TOOL_NAMES.has(call.name)) { + edits++ + if (call.recent) recentEdits++ + } } if (edits < MIN_EDITS_FOR_RATIO) return null @@ -615,6 +655,14 @@ export function detectLowReadEditRatio(calls: ToolCall[]): WasteFinding | null { const extraReadsNeeded = Math.max(Math.round(edits * HEALTHY_READ_EDIT_RATIO) - reads, 0) const tokensSaved = extraReadsNeeded * AVG_TOKENS_PER_READ + let trend: Trend | 'resolved' = 'active' + if (recentEdits >= MIN_EDITS_FOR_RATIO) { + const recentRatio = recentReads / recentEdits + if (recentRatio >= HEALTHY_READ_EDIT_RATIO) trend = 'resolved' + else if (recentRatio > ratio * (1 / IMPROVING_THRESHOLD)) trend = 'improving' + } + if (trend === 'resolved') return null + return { title: 'Claude edits more than it reads', explanation: `Claude made ${reads} reads and ${edits} edits (ratio ${ratio.toFixed(1)}:1). A healthy ratio is ${HEALTHY_READ_EDIT_RATIO}+ reads per edit. Editing without reading leads to retries and wasted tokens.`, @@ -625,6 +673,7 @@ export function detectLowReadEditRatio(calls: ToolCall[]): WasteFinding | null { label: 'Add to your CLAUDE.md:', text: 'Before editing any file, read it first. Before modifying a function, grep for all callers. Research before you edit.', }, + trend, } } @@ -637,16 +686,24 @@ function computeBudgetAwareCacheBaseline(projects: ProjectSummary[]): number { return sorted[Math.floor(sorted.length * 0.25)] || 50_000 } -export function detectCacheBloat(apiCalls: ApiCallMeta[], projects: ProjectSummary[]): WasteFinding | null { +const CACHE_BLOAT_MULTIPLIER = 1.4 + +export function detectCacheBloat(apiCalls: ApiCallMeta[], projects: ProjectSummary[], dateRange?: DateRange): WasteFinding | null { if (apiCalls.length < MIN_API_CALLS_FOR_CACHE) return null const sorted = apiCalls.map(c => c.cacheCreationTokens).sort((a, b) => a - b) const median = sorted[Math.floor(sorted.length / 2)] const baseline = computeBudgetAwareCacheBaseline(projects) - const bloatThreshold = baseline * 1.4 + const bloatThreshold = baseline * CACHE_BLOAT_MULTIPLIER if (median < bloatThreshold) return null + const recentCalls = apiCalls.filter(c => c.recent) + const totalBloated = apiCalls.filter(c => c.cacheCreationTokens > bloatThreshold).length + const recentBloated = recentCalls.filter(c => c.cacheCreationTokens > bloatThreshold).length + const trend = sessionTrend(recentBloated, totalBloated, dateRange, recentCalls.length > 0) + if (trend === 'resolved') return null + const versionCounts = new Map() for (const call of apiCalls) { if (!call.version) continue @@ -682,6 +739,7 @@ export function detectCacheBloat(apiCalls: ApiCallMeta[], projects: ProjectSumma label: 'Check for recent Claude Code updates or heavy MCP/skill additions. As a workaround (not officially supported):', text: 'export ANTHROPIC_CUSTOM_HEADERS=\'User-Agent: claude-cli/2.1.98 (external, sdk-cli)\'', }, + trend, } } @@ -864,6 +922,46 @@ function urgencyScore(f: WasteFinding): number { return URGENCY_WEIGHTS[f.impact] * URGENCY_IMPACT_WEIGHT + normalizedTokens * URGENCY_TOKEN_WEIGHT } +type TrendInputs = { + recentCount: number + recentWindowMs: number + baselineCount: number + baselineWindowMs: number + hasRecentActivity: boolean +} + +export function computeTrend(inputs: TrendInputs): Trend | 'resolved' { + const { recentCount, recentWindowMs, baselineCount, baselineWindowMs, hasRecentActivity } = inputs + if (baselineCount === 0) return 'active' + if (recentCount === 0 && hasRecentActivity) return 'resolved' + if (!hasRecentActivity) return 'active' + const baselineRate = baselineCount / baselineWindowMs + const recentRate = recentCount / Math.max(recentWindowMs, 1) + if (recentRate < baselineRate * IMPROVING_THRESHOLD) return 'improving' + return 'active' +} + +function sessionTrend( + recentItemCount: number, + totalItemCount: number, + dateRange: DateRange | undefined, + hasRecentActivity: boolean, +): Trend | 'resolved' { + const now = Date.now() + const baselineCount = totalItemCount - recentItemCount + const thirtyDaysMs = 30 * 24 * 60 * 60 * 1000 + const periodStart = dateRange ? dateRange.start.getTime() : now - thirtyDaysMs + const recentStart = now - RECENT_WINDOW_MS + const baselineWindowMs = Math.max(recentStart - periodStart, 1) + return computeTrend({ + recentCount: recentItemCount, + recentWindowMs: RECENT_WINDOW_MS, + baselineCount, + baselineWindowMs, + hasRecentActivity, + }) +} + // ============================================================================ // Cost estimation // ============================================================================ @@ -910,10 +1008,10 @@ export async function scanAndDetect( const findings: WasteFinding[] = [] const syncDetectors: Array<() => WasteFinding | null> = [ - () => detectCacheBloat(apiCalls, projects), - () => detectLowReadEditRatio(toolCalls), - () => detectJunkReads(toolCalls), - () => detectDuplicateReads(toolCalls), + () => detectCacheBloat(apiCalls, projects, dateRange), + () => detectLowReadEditRatio(toolCalls, dateRange), + () => detectJunkReads(toolCalls, dateRange), + () => detectDuplicateReads(toolCalls, dateRange), () => detectUnusedMcp(toolCalls, projects, projectCwds), () => detectMissingClaudeignore(projectCwds), () => detectBloatedClaudeMd(projectCwds), @@ -967,14 +1065,16 @@ function renderFinding(n: number, f: WasteFinding, costRate: number): string[] { const lines: string[] = [] const costSaved = f.tokensSaved * costRate const impactLabel = f.impact.charAt(0).toUpperCase() + f.impact.slice(1) + const trendBadge = f.trend === 'improving' ? ' improving \u2193 ' : '' const savings = `~${formatTokens(f.tokensSaved)} tokens (~${formatCost(costSaved)})` - const titlePad = PANEL_WIDTH - f.title.length - impactLabel.length - 8 + const titlePad = PANEL_WIDTH - f.title.length - impactLabel.length - trendBadge.length - 8 const pad = titlePad > 0 ? ' ' + SEP.repeat(titlePad) + ' ' : ' ' lines.push(chalk.hex(DIM)(` ${SEP}${SEP}${SEP} `) + chalk.bold(`${n}. ${f.title}`) + chalk.hex(DIM)(pad) + chalk.hex(IMPACT_COLORS[f.impact])(impactLabel) + + (trendBadge ? chalk.hex(GREEN)(trendBadge) : '') + chalk.hex(DIM)(` ${SEP}${SEP}${SEP}`)) lines.push('') lines.push(wrap(f.explanation, PANEL_WIDTH - 4, ' ')) diff --git a/tests/optimize.test.ts b/tests/optimize.test.ts index fc2954d..5ebcab8 100644 --- a/tests/optimize.test.ts +++ b/tests/optimize.test.ts @@ -8,6 +8,7 @@ import { detectBloatedClaudeMd, detectMissingClaudeignore, computeHealth, + computeTrend, type ToolCall, type ApiCallMeta, type WasteFinding, @@ -256,3 +257,55 @@ describe('computeHealth', () => { expect(computeHealth([mockFinding('high'), mockFinding('high'), mockFinding('high'), mockFinding('high'), mockFinding('high')]).grade).toBe('F') }) }) + +describe('computeTrend', () => { + const window = 48 * 60 * 60 * 1000 + const baselineWindow = 5 * 24 * 60 * 60 * 1000 + + it('returns active when no recent activity detected', () => { + const trend = computeTrend({ + recentCount: 0, recentWindowMs: window, + baselineCount: 100, baselineWindowMs: baselineWindow, + hasRecentActivity: false, + }) + expect(trend).toBe('active') + }) + + it('returns resolved when recent activity exists but zero waste in it', () => { + const trend = computeTrend({ + recentCount: 0, recentWindowMs: window, + baselineCount: 100, baselineWindowMs: baselineWindow, + hasRecentActivity: true, + }) + expect(trend).toBe('resolved') + }) + + it('returns improving when recent rate is less than half of baseline rate', () => { + const trend = computeTrend({ + recentCount: 5, recentWindowMs: window, + baselineCount: 100, baselineWindowMs: baselineWindow, + hasRecentActivity: true, + }) + expect(trend).toBe('improving') + }) + + it('returns active when recent rate matches baseline rate', () => { + const recentRate = 100 / baselineWindow + const recentCount = Math.ceil(recentRate * window) + const trend = computeTrend({ + recentCount, recentWindowMs: window, + baselineCount: 100, baselineWindowMs: baselineWindow, + hasRecentActivity: true, + }) + expect(trend).toBe('active') + }) + + it('returns active when baseline is empty (new finding)', () => { + const trend = computeTrend({ + recentCount: 10, recentWindowMs: window, + baselineCount: 0, baselineWindowMs: baselineWindow, + hasRecentActivity: true, + }) + expect(trend).toBe('active') + }) +}) From 707d2faff137d921d0f61a5da7916e4bd4886a87 Mon Sep 17 00:00:00 2001 From: AgentSeal Date: Thu, 16 Apr 2026 06:59:07 -0700 Subject: [PATCH 06/70] feat(optimize): UX polish - Rename "ctx" column to "overhead" with wider padding for legibility in the By Project panel. - Name magic numbers for the project column widths. - Empty-state now includes a one-line description of what optimize does, so first-time users with no findings still understand the feature. --- src/dashboard.tsx | 8 +++++--- src/optimize.ts | 4 ++++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/dashboard.tsx b/src/dashboard.tsx index 6157c31..067158c 100644 --- a/src/dashboard.tsx +++ b/src/dashboard.tsx @@ -231,11 +231,13 @@ function shortProject(encoded: string): string { function ProjectBreakdown({ projects, pw, bw, budgets }: { projects: ProjectSummary[]; pw: number; bw: number; budgets?: Map }) { const maxCost = Math.max(...projects.map(p => p.totalCostUSD)) const hasBudgets = budgets && budgets.size > 0 - const nw = Math.max(8, pw - bw - (hasBudgets ? 31 : 23)) + const PROJECT_COL_BASE_WIDTH = 23 + const PROJECT_COL_WITH_OVERHEAD_WIDTH = 33 + const nw = Math.max(8, pw - bw - (hasBudgets ? PROJECT_COL_WITH_OVERHEAD_WIDTH : PROJECT_COL_BASE_WIDTH)) return ( - {''.padEnd(bw + 1 + nw)}{'cost'.padStart(8)}{'sess'.padStart(6)}{hasBudgets ? 'ctx'.padStart(8) : ''} + {''.padEnd(bw + 1 + nw)}{'cost'.padStart(8)}{'sess'.padStart(6)}{hasBudgets ? 'overhead'.padStart(10) : ''} {projects.slice(0, 8).map((project, i) => { const budget = budgets?.get(project.project) @@ -245,7 +247,7 @@ function ProjectBreakdown({ projects, pw, bw, budgets }: { projects: ProjectSumm {fit(shortProject(project.project), nw)} {formatCost(project.totalCostUSD).padStart(8)} {String(project.sessions.length).padStart(6)} - {hasBudgets && {(budget ? formatTokens(budget.total) : '-').padStart(8)}} + {hasBudgets && {(budget ? formatTokens(budget.total) : '-').padStart(10)}} ) })} diff --git a/src/optimize.ts b/src/optimize.ts index 84b18df..abb55fd 100644 --- a/src/optimize.ts +++ b/src/optimize.ts @@ -1124,6 +1124,10 @@ function renderOptimize( if (findings.length === 0) { lines.push(chalk.hex(GREEN)(' Nothing to fix. Your setup is lean.')) lines.push('') + lines.push(chalk.dim(' CodeBurn optimize scans your Claude Code sessions and config for')) + lines.push(chalk.dim(' token waste: junk directory reads, duplicate file reads, unused')) + lines.push(chalk.dim(' agents/skills/MCP servers, bloated CLAUDE.md, and more.')) + lines.push('') return lines.join('\n') } From b9dffc16ec0efd4e89532b2bd5f5f180d73f7dcd Mon Sep 17 00:00:00 2001 From: AgentSeal Date: Thu, 16 Apr 2026 07:09:20 -0700 Subject: [PATCH 07/70] chore(optimize): remove dead versions plumbing + name remaining magic numbers - ScanData.versions and ScanFileResult.versions were collected but never read in scanAndDetect. Per-call version lives on ApiCallMeta.version which is what detectCacheBloat actually uses. Dropped the unused aggregation path end-to-end. - Extract DEFAULT_CACHE_BASELINE_TOKENS, CACHE_BASELINE_QUANTILE, CACHE_VERSION_MIN_SAMPLES, CACHE_VERSION_DIFF_THRESHOLD as named module-scope constants. Honors the "no magic numbers" project rule across the full optimize engine. --- src/optimize.ts | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/src/optimize.ts b/src/optimize.ts index abb55fd..6acda03 100644 --- a/src/optimize.ts +++ b/src/optimize.ts @@ -144,7 +144,6 @@ type ScanData = { toolCalls: ToolCall[] projectCwds: Set apiCalls: ApiCallMeta[] - versions: Set userMessages: string[] } @@ -199,7 +198,6 @@ type ScanFileResult = { calls: ToolCall[] cwds: string[] apiCalls: ApiCallMeta[] - versions: string[] userMessages: string[] } @@ -224,12 +222,11 @@ export async function scanJsonlFile( let content: string try { content = await readFile(filePath, 'utf-8') - } catch { return { calls: [], cwds: [], apiCalls: [], versions: [], userMessages: [] } } + } catch { return { calls: [], cwds: [], apiCalls: [], userMessages: [] } } const calls: ToolCall[] = [] const cwds: string[] = [] const apiCalls: ApiCallMeta[] = [] - const versions: string[] = [] const userMessages: string[] = [] const sessionId = basename(filePath, '.jsonl') let lastVersion = '' @@ -246,7 +243,6 @@ export async function scanJsonlFile( const recent = isRecent(ts, recentCutoffMs) if (entry.cwd && typeof entry.cwd === 'string' && withinRange) cwds.push(entry.cwd) - if (entry.version && typeof entry.version === 'string' && withinRange) versions.push(entry.version) if (entry.type === 'user') { if (!withinRange) continue @@ -289,7 +285,7 @@ export async function scanJsonlFile( } } - return { calls, cwds, apiCalls, versions, userMessages } + return { calls, cwds, apiCalls, userMessages } } async function scanSessions(dateRange?: DateRange): Promise { @@ -297,7 +293,6 @@ async function scanSessions(dateRange?: DateRange): Promise { const allCalls: ToolCall[] = [] const allCwds = new Set() const allApiCalls: ApiCallMeta[] = [] - const allVersions = new Set() const allUserMessages: string[] = [] const tasks: Array<{ file: string; project: string }> = [] @@ -310,15 +305,14 @@ async function scanSessions(dateRange?: DateRange): Promise { } await runWithConcurrency(tasks, FILE_READ_CONCURRENCY, async ({ file, project }) => { - const { calls, cwds, apiCalls, versions, userMessages } = await scanJsonlFile(file, project, dateRange) + const { calls, cwds, apiCalls, userMessages } = await scanJsonlFile(file, project, dateRange) allCalls.push(...calls) for (const cwd of cwds) allCwds.add(cwd) allApiCalls.push(...apiCalls) - for (const v of versions) if (v) allVersions.add(v) allUserMessages.push(...userMessages) }) - return { toolCalls: allCalls, projectCwds: allCwds, apiCalls: allApiCalls, versions: allVersions, userMessages: allUserMessages } + return { toolCalls: allCalls, projectCwds: allCwds, apiCalls: allApiCalls, userMessages: allUserMessages } } // ============================================================================ @@ -677,17 +671,21 @@ export function detectLowReadEditRatio(calls: ToolCall[], dateRange?: DateRange) } } +const DEFAULT_CACHE_BASELINE_TOKENS = 50_000 +const CACHE_BASELINE_QUANTILE = 0.25 +const CACHE_BLOAT_MULTIPLIER = 1.4 +const CACHE_VERSION_MIN_SAMPLES = 5 +const CACHE_VERSION_DIFF_THRESHOLD = 10_000 + function computeBudgetAwareCacheBaseline(projects: ProjectSummary[]): number { const sessions = projects.flatMap(p => p.sessions) - if (sessions.length === 0) return 50_000 + if (sessions.length === 0) return DEFAULT_CACHE_BASELINE_TOKENS const cacheWrites = sessions.map(s => s.totalCacheWriteTokens).filter(n => n > 0) - if (cacheWrites.length < MIN_API_CALLS_FOR_CACHE) return 50_000 + if (cacheWrites.length < MIN_API_CALLS_FOR_CACHE) return DEFAULT_CACHE_BASELINE_TOKENS const sorted = cacheWrites.sort((a, b) => a - b) - return sorted[Math.floor(sorted.length * 0.25)] || 50_000 + return sorted[Math.floor(sorted.length * CACHE_BASELINE_QUANTILE)] || DEFAULT_CACHE_BASELINE_TOKENS } -const CACHE_BLOAT_MULTIPLIER = 1.4 - export function detectCacheBloat(apiCalls: ApiCallMeta[], projects: ProjectSummary[], dateRange?: DateRange): WasteFinding | null { if (apiCalls.length < MIN_API_CALLS_FOR_CACHE) return null @@ -713,7 +711,7 @@ export function detectCacheBloat(apiCalls: ApiCallMeta[], projects: ProjectSumma versionCounts.set(call.version, entry) } const versionAvgs = [...versionCounts.entries()] - .filter(([, d]) => d.count >= 5) + .filter(([, d]) => d.count >= CACHE_VERSION_MIN_SAMPLES) .map(([v, d]) => ({ version: v, avg: Math.round(d.total / d.count) })) .sort((a, b) => b.avg - a.avg) @@ -724,7 +722,7 @@ export function detectCacheBloat(apiCalls: ApiCallMeta[], projects: ProjectSumma if (versionAvgs.length >= 2) { const [high, ...rest] = versionAvgs const low = rest[rest.length - 1] - if (high.avg - low.avg > 10_000) { + if (high.avg - low.avg > CACHE_VERSION_DIFF_THRESHOLD) { versionNote = ` Version ${high.version} averages ${formatTokens(high.avg)} vs ${low.version} at ${formatTokens(low.avg)}.` } } From c02f63235ac4469a0961c18bf9ced0c0c6f202d2 Mon Sep 17 00:00:00 2001 From: AgentSeal Date: Thu, 16 Apr 2026 09:33:03 -0700 Subject: [PATCH 08/70] test(optimize): add 34 filesystem-mocking tests Covers previously untested detectors and helpers with real temp-dir fixtures (not stubs) to verify behavior against actual file I/O. New coverage: - detectMissingClaudeignore: project with/without junk dirs and .claudeignore, impact scaling. - detectBloatedClaudeMd: plain oversized file, @-import expansion, circular import safety, email/npm-scope @-token filtering. - loadMcpConfigs: project reads, colon-to-underscore normalization, malformed JSON tolerance. - detectUnusedMcp: 24-hour grace period, config vs invocation merge. - detectBashBloat: env var unset, configured under/over limit. - detectGhostCommands: path prefixes are not commands, tag parsing. - scanJsonlFile: missing file, tool_use parsing, malformed line skipping, date-range filter. - scanAndDetect: empty projects returns healthy result. - estimateContextBudget: system base, MCP tools, memory files. - discoverProjectCwd: empty dir, no jsonl, cwd extraction. Uses vi.mock to redirect os.homedir() to a disposable temp directory, so tests do not read the tester's real ~/.claude. 34 tests, <30ms wall time. Total suite now 160 tests. --- tests/optimize-fs.test.ts | 445 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 445 insertions(+) create mode 100644 tests/optimize-fs.test.ts diff --git a/tests/optimize-fs.test.ts b/tests/optimize-fs.test.ts new file mode 100644 index 0000000..a476042 --- /dev/null +++ b/tests/optimize-fs.test.ts @@ -0,0 +1,445 @@ +import { describe, it, expect, afterAll, beforeEach, vi } from 'vitest' +import { mkdtempSync, rmSync, mkdirSync, writeFileSync, utimesSync } from 'fs' +import { tmpdir } from 'os' +import { join } from 'path' + +vi.mock('os', async () => { + const actual = await vi.importActual('os') + const fs = await vi.importActual('fs') + const fakeHome = fs.mkdtempSync(actual.tmpdir() + '/codeburn-home-') + fs.mkdirSync(fakeHome + '/.claude', { recursive: true }) + process.env['CODEBURN_TEST_FAKE_HOME'] = fakeHome + return { ...actual, homedir: () => fakeHome } +}) + +const FAKE_HOME_FOR_MOCK = process.env['CODEBURN_TEST_FAKE_HOME']! + +import { + detectMissingClaudeignore, + detectBloatedClaudeMd, + detectUnusedMcp, + detectBashBloat, + detectGhostAgents, + detectGhostSkills, + detectGhostCommands, + loadMcpConfigs, + scanJsonlFile, + scanAndDetect, + type ToolCall, +} from '../src/optimize.js' +import { + estimateContextBudget, + discoverProjectCwd, +} from '../src/context-budget.js' + +// ============================================================================ +// Helpers for filesystem fixtures +// ============================================================================ + +const FIXTURE_ROOTS: string[] = [FAKE_HOME_FOR_MOCK] + +function makeFixtureRoot(): string { + const dir = mkdtempSync(join(tmpdir(), 'codeburn-test-')) + FIXTURE_ROOTS.push(dir) + return dir +} + +function writeFile(path: string, content: string): void { + mkdirSync(join(path, '..'), { recursive: true }) + writeFileSync(path, content) +} + +function touchOld(path: string, daysAgo: number): void { + const past = new Date(Date.now() - daysAgo * 24 * 60 * 60 * 1000) + utimesSync(path, past, past) +} + +afterAll(() => { + for (const dir of FIXTURE_ROOTS) { + rmSync(dir, { recursive: true, force: true }) + } +}) + +// ============================================================================ +// detectMissingClaudeignore +// ============================================================================ + +describe('detectMissingClaudeignore', () => { + it('flags a project with node_modules but no .claudeignore', () => { + const root = makeFixtureRoot() + const projectDir = join(root, 'myapp') + mkdirSync(join(projectDir, 'node_modules'), { recursive: true }) + const finding = detectMissingClaudeignore(new Set([projectDir])) + expect(finding).not.toBeNull() + expect(finding!.impact).toBe('medium') + }) + + it('does not flag when .claudeignore exists', () => { + const root = makeFixtureRoot() + const projectDir = join(root, 'myapp') + mkdirSync(join(projectDir, 'node_modules'), { recursive: true }) + writeFile(join(projectDir, '.claudeignore'), 'node_modules\n') + expect(detectMissingClaudeignore(new Set([projectDir]))).toBeNull() + }) + + it('does not flag project without junk dirs', () => { + const root = makeFixtureRoot() + const projectDir = join(root, 'myapp') + mkdirSync(join(projectDir, 'src'), { recursive: true }) + expect(detectMissingClaudeignore(new Set([projectDir]))).toBeNull() + }) + + it('escalates to high when three or more projects need it', () => { + const root = makeFixtureRoot() + const cwds = new Set() + for (let i = 0; i < 3; i++) { + const p = join(root, `proj-${i}`) + mkdirSync(join(p, 'node_modules'), { recursive: true }) + cwds.add(p) + } + const finding = detectMissingClaudeignore(cwds) + expect(finding!.impact).toBe('high') + }) +}) + +// ============================================================================ +// detectBloatedClaudeMd (including @-import expansion) +// ============================================================================ + +describe('detectBloatedClaudeMd', () => { + it('flags a CLAUDE.md with more than 200 lines', () => { + const root = makeFixtureRoot() + const projectDir = join(root, 'myapp') + mkdirSync(projectDir, { recursive: true }) + const content = Array.from({ length: 300 }, (_, i) => `line ${i}`).join('\n') + writeFile(join(projectDir, 'CLAUDE.md'), content) + const finding = detectBloatedClaudeMd(new Set([projectDir])) + expect(finding).not.toBeNull() + }) + + it('expands @-imports and counts transitive load', () => { + const root = makeFixtureRoot() + const projectDir = join(root, 'myapp') + mkdirSync(projectDir, { recursive: true }) + writeFile( + join(projectDir, 'CLAUDE.md'), + 'line 1\nline 2\n@./rules.md\n@./conventions.md\n', + ) + writeFile(join(projectDir, 'rules.md'), Array.from({ length: 120 }, (_, i) => `rule ${i}`).join('\n')) + writeFile(join(projectDir, 'conventions.md'), Array.from({ length: 120 }, (_, i) => `conv ${i}`).join('\n')) + const finding = detectBloatedClaudeMd(new Set([projectDir])) + expect(finding).not.toBeNull() + expect(finding!.explanation).toContain('2 @-imports') + }) + + it('does not flag a lean CLAUDE.md under 200 lines with no imports', () => { + const root = makeFixtureRoot() + const projectDir = join(root, 'myapp') + mkdirSync(projectDir, { recursive: true }) + writeFile(join(projectDir, 'CLAUDE.md'), 'just a few\nlines\nhere\n') + expect(detectBloatedClaudeMd(new Set([projectDir]))).toBeNull() + }) + + it('does not recurse infinitely on circular @-imports', () => { + const root = makeFixtureRoot() + const projectDir = join(root, 'myapp') + mkdirSync(projectDir, { recursive: true }) + writeFile(join(projectDir, 'CLAUDE.md'), '@./a.md\n') + writeFile(join(projectDir, 'a.md'), '@./b.md\n') + writeFile(join(projectDir, 'b.md'), '@./a.md\n') + expect(() => detectBloatedClaudeMd(new Set([projectDir]))).not.toThrow() + }) + + it('ignores @ tokens that are not paths (emails, npm scopes)', () => { + const root = makeFixtureRoot() + const projectDir = join(root, 'myapp') + mkdirSync(projectDir, { recursive: true }) + writeFile( + join(projectDir, 'CLAUDE.md'), + Array.from({ length: 250 }, (_, i) => + i === 10 ? '@user@example.com' : + i === 20 ? '@org/package' : + `line ${i}` + ).join('\n'), + ) + const finding = detectBloatedClaudeMd(new Set([projectDir])) + expect(finding).not.toBeNull() + // "with N @-imports" suffix appears only when non-zero imports were resolved + expect(finding!.explanation).not.toMatch(/with \d+ @-import/) + }) +}) + +// ============================================================================ +// loadMcpConfigs + detectUnusedMcp +// ============================================================================ + +describe('loadMcpConfigs', () => { + it('returns empty map when no configs exist', () => { + const root = makeFixtureRoot() + const servers = loadMcpConfigs([root]) + expect(servers.size).toBe(0) + }) + + it('reads servers from project .mcp.json', () => { + const root = makeFixtureRoot() + const projectDir = join(root, 'myapp') + mkdirSync(projectDir, { recursive: true }) + writeFile(join(projectDir, '.mcp.json'), JSON.stringify({ + mcpServers: { foo: { command: 'foo' }, bar: { command: 'bar' } }, + })) + const servers = loadMcpConfigs([projectDir]) + expect(servers.has('foo')).toBe(true) + expect(servers.has('bar')).toBe(true) + }) + + it('normalizes server names by replacing colons with underscores', () => { + const root = makeFixtureRoot() + const projectDir = join(root, 'myapp') + mkdirSync(projectDir, { recursive: true }) + writeFile(join(projectDir, '.mcp.json'), JSON.stringify({ + mcpServers: { 'plugin:context7:context7': { command: 'ctx' } }, + })) + const servers = loadMcpConfigs([projectDir]) + expect(servers.has('plugin_context7_context7')).toBe(true) + expect(servers.get('plugin_context7_context7')!.original).toBe('plugin:context7:context7') + }) + + it('handles malformed JSON without crashing', () => { + const root = makeFixtureRoot() + const projectDir = join(root, 'myapp') + mkdirSync(projectDir, { recursive: true }) + writeFile(join(projectDir, '.mcp.json'), '{ not valid json') + expect(() => loadMcpConfigs([projectDir])).not.toThrow() + expect(loadMcpConfigs([projectDir]).size).toBe(0) + }) +}) + +describe('detectUnusedMcp', () => { + it('flags servers configured but never called', () => { + const root = makeFixtureRoot() + const projectDir = join(root, 'myapp') + mkdirSync(projectDir, { recursive: true }) + writeFile(join(projectDir, '.mcp.json'), JSON.stringify({ + mcpServers: { ghost: { command: 'x' } }, + })) + const configFile = join(projectDir, '.mcp.json') + touchOld(configFile, 30) + const finding = detectUnusedMcp([], [], new Set([projectDir])) + expect(finding).not.toBeNull() + expect(finding!.explanation).toContain('ghost') + }) + + it('does not flag servers configured within 24 hours', () => { + const root = makeFixtureRoot() + const projectDir = join(root, 'myapp') + mkdirSync(projectDir, { recursive: true }) + writeFile(join(projectDir, '.mcp.json'), JSON.stringify({ + mcpServers: { freshly_added: { command: 'x' } }, + })) + expect(detectUnusedMcp([], [], new Set([projectDir]))).toBeNull() + }) + + it('does not flag servers that were called', () => { + const root = makeFixtureRoot() + const projectDir = join(root, 'myapp') + mkdirSync(projectDir, { recursive: true }) + writeFile(join(projectDir, '.mcp.json'), JSON.stringify({ + mcpServers: { used: { command: 'x' } }, + })) + touchOld(join(projectDir, '.mcp.json'), 30) + const calls: ToolCall[] = [ + { name: 'mcp__used__some_tool', input: {}, sessionId: 's1', project: 'p1' }, + ] + expect(detectUnusedMcp(calls, [], new Set([projectDir]))).toBeNull() + }) +}) + +// ============================================================================ +// detectBashBloat +// ============================================================================ + +describe('detectBashBloat', () => { + const originalEnv = process.env['BASH_MAX_OUTPUT_LENGTH'] + + beforeEach(() => { + delete process.env['BASH_MAX_OUTPUT_LENGTH'] + }) + + afterAll(() => { + if (originalEnv !== undefined) process.env['BASH_MAX_OUTPUT_LENGTH'] = originalEnv + }) + + it('flags when env var is unset (uses default 30K)', () => { + const finding = detectBashBloat() + expect(finding).not.toBeNull() + expect(finding!.impact).toBe('medium') + }) + + it('does not flag when env var is at recommended 15K', () => { + process.env['BASH_MAX_OUTPUT_LENGTH'] = '15000' + expect(detectBashBloat()).toBeNull() + }) + + it('does not flag when env var is below recommended', () => { + process.env['BASH_MAX_OUTPUT_LENGTH'] = '10000' + expect(detectBashBloat()).toBeNull() + }) + + it('flags when env var is above 15K', () => { + process.env['BASH_MAX_OUTPUT_LENGTH'] = '50000' + const finding = detectBashBloat() + expect(finding).not.toBeNull() + }) +}) + +// ============================================================================ +// detectGhostCommands (the pure-function ghost detector) +// ============================================================================ + +describe('detectGhostCommands', () => { + it('returns null when no commands are defined', async () => { + expect(await detectGhostCommands([])).toBeNull() + }) + + it('does not match /tmp or /usr or other path prefixes as command usage', async () => { + const messages = [ + 'check /tmp/debug.log', + 'look at /usr/local/bin', + 'rm -rf /var/cache', + ] + expect(await detectGhostCommands(messages)).toBeNull() + }) + + it('matches tags in user messages', async () => { + const messages = ['review'] + expect(await detectGhostCommands(messages)).toBeNull() + }) +}) + +// ============================================================================ +// scanJsonlFile +// ============================================================================ + +describe('scanJsonlFile', () => { + it('returns empty result for nonexistent file', async () => { + const result = await scanJsonlFile('/nonexistent/path.jsonl', 'p1', undefined) + expect(result.calls).toEqual([]) + expect(result.cwds).toEqual([]) + expect(result.apiCalls).toEqual([]) + expect(result.userMessages).toEqual([]) + }) + + it('parses tool_use blocks from assistant entries', async () => { + const root = makeFixtureRoot() + const filePath = join(root, 'session.jsonl') + const now = new Date().toISOString() + const lines = [ + JSON.stringify({ + type: 'assistant', + timestamp: now, + message: { + content: [{ type: 'tool_use', name: 'Read', input: { file_path: '/x/foo.ts' } }], + }, + }), + ] + writeFile(filePath, lines.join('\n')) + const result = await scanJsonlFile(filePath, 'p1', undefined) + expect(result.calls).toHaveLength(1) + expect(result.calls[0].name).toBe('Read') + }) + + it('skips malformed JSONL lines without crashing', async () => { + const root = makeFixtureRoot() + const filePath = join(root, 'session.jsonl') + writeFile(filePath, 'this is not json\n{broken\n{"type":"assistant","message":{"content":[]}}\n') + const result = await scanJsonlFile(filePath, 'p1', undefined) + expect(result.calls).toEqual([]) + }) + + it('respects date-range filter for assistant entries', async () => { + const root = makeFixtureRoot() + const filePath = join(root, 'session.jsonl') + const old = '2020-01-01T00:00:00Z' + const now = new Date().toISOString() + writeFile(filePath, [ + JSON.stringify({ + type: 'assistant', timestamp: old, + message: { content: [{ type: 'tool_use', name: 'Read', input: { file_path: '/old' } }] }, + }), + JSON.stringify({ + type: 'assistant', timestamp: now, + message: { content: [{ type: 'tool_use', name: 'Read', input: { file_path: '/new' } }] }, + }), + ].join('\n')) + const today = new Date() + const start = new Date(today.getFullYear(), today.getMonth(), today.getDate()) + const result = await scanJsonlFile(filePath, 'p1', { start, end: today }) + expect(result.calls).toHaveLength(1) + expect((result.calls[0].input as Record).file_path).toBe('/new') + }) +}) + +// ============================================================================ +// scanAndDetect (top-level integration) +// ============================================================================ + +describe('scanAndDetect', () => { + it('returns healthy result for empty projects', async () => { + const result = await scanAndDetect([]) + expect(result.findings).toEqual([]) + expect(result.healthScore).toBe(100) + expect(result.healthGrade).toBe('A') + expect(result.costRate).toBe(0) + }) +}) + +// ============================================================================ +// context-budget +// ============================================================================ + +describe('estimateContextBudget', () => { + it('returns only system base when project has no config', async () => { + const root = makeFixtureRoot() + const budget = await estimateContextBudget(root) + expect(budget.total).toBeGreaterThan(0) + expect(budget.mcpTools.count).toBe(0) + expect(budget.skills.count).toBe(0) + }) + + it('includes MCP tools from project .mcp.json', async () => { + const root = makeFixtureRoot() + writeFile(join(root, '.mcp.json'), JSON.stringify({ + mcpServers: { a: { command: 'x' }, b: { command: 'x' } }, + })) + const budget = await estimateContextBudget(root) + expect(budget.mcpTools.count).toBeGreaterThan(0) + }) + + it('includes memory file tokens from CLAUDE.md', async () => { + const root = makeFixtureRoot() + writeFile(join(root, 'CLAUDE.md'), 'Project context for Claude.\n') + const budget = await estimateContextBudget(root) + expect(budget.memory.count).toBeGreaterThan(0) + expect(budget.memory.tokens).toBeGreaterThan(0) + }) +}) + +describe('discoverProjectCwd', () => { + it('returns null for empty directory', async () => { + const root = makeFixtureRoot() + expect(await discoverProjectCwd(root)).toBeNull() + }) + + it('returns null for directory with no jsonl files', async () => { + const root = makeFixtureRoot() + writeFile(join(root, 'readme.txt'), 'hi') + expect(await discoverProjectCwd(root)).toBeNull() + }) + + it('extracts cwd from the first jsonl entry', async () => { + const root = makeFixtureRoot() + const entry = JSON.stringify({ type: 'assistant', cwd: '/Users/test/project', timestamp: new Date().toISOString() }) + writeFile(join(root, 'session.jsonl'), entry + '\n') + expect(await discoverProjectCwd(root)).toBe('/Users/test/project') + }) +}) From b9b2c7a900f7fbfd4953c33d3179b524d718769a Mon Sep 17 00:00:00 2001 From: AgentSeal Date: Thu, 16 Apr 2026 09:35:46 -0700 Subject: [PATCH 09/70] chore: remove dead ContextBudgetPanel and unused dateRange parameter - ContextBudgetPanel in dashboard.tsx was defined but never rendered after the per-project overhead column replaced it in Phase 1. - detectLowReadEditRatio accepted a dateRange parameter that was never used inside the function (trend is computed via recent-call flags on ToolCall). Verified with tsc --noUnusedLocals --noUnusedParameters: 0 errors. 160 tests pass. --- src/dashboard.tsx | 28 ---------------------------- src/optimize.ts | 4 ++-- 2 files changed, 2 insertions(+), 30 deletions(-) diff --git a/src/dashboard.tsx b/src/dashboard.tsx index 067158c..ac1c9eb 100644 --- a/src/dashboard.tsx +++ b/src/dashboard.tsx @@ -424,34 +424,6 @@ function PeriodTabs({ active, providerName, showProvider }: { active: Period; pr ) } -function ContextBudgetPanel({ budget, pw }: { budget: ContextBudget; pw: number }) { - const pct = ((budget.total / budget.modelContext) * 100).toFixed(1) - const available = budget.modelContext - budget.total - const items: Array<{ label: string; tokens: number; color: string }> = [ - { label: 'System base', tokens: budget.systemBase, color: '#5B9EF5' }, - { label: `MCP tools (${budget.mcpTools.count})`, tokens: budget.mcpTools.tokens, color: '#F55BE0' }, - { label: `Skills (${budget.skills.count})`, tokens: budget.skills.tokens, color: '#F5C85B' }, - { label: `Memory (${budget.memory.count})`, tokens: budget.memory.tokens, color: '#5BF5A0' }, - ] - const maxTokens = Math.max(...items.map(i => i.tokens)) - const bw = 6 - return ( - - {''.padEnd(bw + 20)}{'tokens'.padStart(8)} - {items.filter(i => i.tokens > 0).map(item => ( - - - {fit(item.label, 19)} - {formatTokens(item.tokens).padStart(8)} - - ))} - - Overhead: {formatTokens(budget.total)} ({pct}%) Free: {formatTokens(available)} - - - ) -} - function FindingAction({ action }: { action: WasteAction }) { const lines = action.type === 'file-content' ? action.content.split('\n') : action.type === 'command' ? action.text.split('\n') : [action.text] return (<>{action.label}{lines.map((line, i) => {line})}) diff --git a/src/optimize.ts b/src/optimize.ts index 6acda03..18c3666 100644 --- a/src/optimize.ts +++ b/src/optimize.ts @@ -626,7 +626,7 @@ export function detectBloatedClaudeMd(projectCwds: Set): WasteFinding | const READ_TOOL_NAMES = new Set(['Read', 'Grep', 'Glob', 'FileReadTool', 'GrepTool', 'GlobTool']) const EDIT_TOOL_NAMES = new Set(['Edit', 'Write', 'FileEditTool', 'FileWriteTool', 'NotebookEdit']) -export function detectLowReadEditRatio(calls: ToolCall[], dateRange?: DateRange): WasteFinding | null { +export function detectLowReadEditRatio(calls: ToolCall[]): WasteFinding | null { let reads = 0 let edits = 0 let recentEdits = 0 @@ -1007,7 +1007,7 @@ export async function scanAndDetect( const findings: WasteFinding[] = [] const syncDetectors: Array<() => WasteFinding | null> = [ () => detectCacheBloat(apiCalls, projects, dateRange), - () => detectLowReadEditRatio(toolCalls, dateRange), + () => detectLowReadEditRatio(toolCalls), () => detectJunkReads(toolCalls, dateRange), () => detectDuplicateReads(toolCalls, dateRange), () => detectUnusedMcp(toolCalls, projects, projectCwds), From 09139b1d920ba258fc336a6d1588196483e7e7c1 Mon Sep 17 00:00:00 2001 From: Travis Haley Date: Thu, 16 Apr 2026 09:57:06 -0600 Subject: [PATCH 10/70] feat: add --format json to report, today, and month commands Outputs full dashboard data as structured JSON to stdout, including: overview, daily breakdown, projects, models with token counts, activities with one-shot rates, core tools, MCP servers, and shell commands. Co-Authored-By: Claude Opus 4.6 (1M context) --- README.md | 39 ++++++++++---- src/cli.ts | 155 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 184 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index c3c26c8..2a4f6e9 100644 --- a/README.md +++ b/README.md @@ -44,20 +44,41 @@ npx codeburn ## Usage ```bash -codeburn # interactive dashboard (default: 7 days) -codeburn today # today's usage -codeburn month # this month's usage -codeburn report -p 30days # rolling 30-day window -codeburn report -p all # every recorded session -codeburn report --refresh 60 # auto-refresh every 60 seconds -codeburn status # compact one-liner (today + month) +codeburn # interactive dashboard (default: 7 days) +codeburn today # today's usage +codeburn month # this month's usage +codeburn report -p 30days # rolling 30-day window +codeburn report -p all # every recorded session +codeburn report --format json # full dashboard data as JSON +codeburn report --refresh 60 # auto-refresh every 60 seconds +codeburn status # compact one-liner (today + month) codeburn status --format json -codeburn export # CSV with today, 7 days, 30 days -codeburn export -f json # JSON export +codeburn export # CSV with today, 7 days, 30 days +codeburn export -f json # JSON export ``` Arrow keys switch between Today / 7 Days / 30 Days / Month / All Time. Press `q` to quit, `1` `2` `3` `4` `5` as shortcuts. The dashboard also shows average cost per session and the five most expensive sessions across all projects. +### JSON output + +`report`, `today`, and `month` support `--format json` to output the full dashboard data as structured JSON to stdout: + +```bash +codeburn report --format json # 7-day JSON report +codeburn today --format json # today's data as JSON +codeburn month --format json # this month as JSON +codeburn report -p 30days --format json # 30-day window +``` + +The JSON includes all dashboard panels: overview (cost, calls, sessions, cache hit %), daily breakdown, projects, models with token counts, activities with one-shot rates, core tools, MCP servers, and shell commands. Pipe to `jq` for filtering: + +```bash +codeburn report --format json | jq '.projects' +codeburn today --format json | jq '.overview.cost' +``` + +For the lighter `status --format json` (today + month totals only) or file-based exports (`export -f json`), see above. + ## Providers CodeBurn auto-detects which AI coding tools you use. If multiple providers have session data on disk, press `p` in the dashboard to toggle between them. diff --git a/src/cli.ts b/src/cli.ts index 2c5fcd1..8f7269e 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -2,6 +2,7 @@ import { Command } from 'commander' import { exportCsv, exportJson, type PeriodExport } from './export.js' import { loadPricing } from './models.js' import { parseAllSessions } from './parser.js' +import { getCostColumnHeader, convertCost } from './currency.js' import { renderStatusBar } from './format.js' import { installMenubar, renderMenubarFormat, type PeriodData, type ProviderCost, uninstallMenubar } from './menubar.js' import { CATEGORY_LABELS, type DateRange, type ProjectSummary, type TaskCategory } from './types.js' @@ -67,14 +68,150 @@ program.hook('preAction', async () => { await loadCurrency() }) +function buildJsonReport(projects: ProjectSummary[], period: string) { + const sessions = projects.flatMap(p => p.sessions) + const { code } = getCurrency() + + const totalCostUSD = projects.reduce((s, p) => s + p.totalCostUSD, 0) + const totalCalls = projects.reduce((s, p) => s + p.totalApiCalls, 0) + const totalSessions = projects.reduce((s, p) => s + p.sessions.length, 0) + const totalInput = sessions.reduce((s, sess) => s + sess.totalInputTokens, 0) + const totalOutput = sessions.reduce((s, sess) => s + sess.totalOutputTokens, 0) + const totalCacheRead = sessions.reduce((s, sess) => s + sess.totalCacheReadTokens, 0) + const totalCacheWrite = sessions.reduce((s, sess) => s + sess.totalCacheWriteTokens, 0) + const allInput = totalInput + totalCacheRead + totalCacheWrite + const cacheHitPercent = allInput > 0 ? Math.round((totalCacheRead / allInput) * 1000) / 10 : 0 + + // daily + const dailyMap: Record = {} + for (const sess of sessions) { + for (const turn of sess.turns) { + if (!turn.timestamp) { continue } + const day = turn.timestamp.slice(0, 10) + if (!dailyMap[day]) { dailyMap[day] = { cost: 0, calls: 0 } } + for (const call of turn.assistantCalls) { + dailyMap[day].cost += call.costUSD + dailyMap[day].calls += 1 + } + } + } + const daily = Object.entries(dailyMap).sort().map(([date, d]) => ({ + date, + cost: convertCost(d.cost), + calls: d.calls, + })) + + // projects + const projectList = projects.map(p => ({ + name: p.project, + path: p.projectPath, + cost: convertCost(p.totalCostUSD), + calls: p.totalApiCalls, + sessions: p.sessions.length, + })) + + // models + const modelMap: Record = {} + for (const sess of sessions) { + for (const [model, d] of Object.entries(sess.modelBreakdown)) { + if (!modelMap[model]) { modelMap[model] = { calls: 0, cost: 0, inputTokens: 0, outputTokens: 0, cacheReadTokens: 0, cacheWriteTokens: 0 } } + modelMap[model].calls += d.calls + modelMap[model].cost += d.costUSD + modelMap[model].inputTokens += d.tokens.inputTokens + modelMap[model].outputTokens += d.tokens.outputTokens + modelMap[model].cacheReadTokens += d.tokens.cacheReadInputTokens + modelMap[model].cacheWriteTokens += d.tokens.cacheCreationInputTokens + } + } + const models = Object.entries(modelMap) + .sort(([, a], [, b]) => b.cost - a.cost) + .map(([name, d]) => ({ name, cost: convertCost(d.cost), ...d, cost_usd: undefined })) + .map(({ cost_usd: _, ...rest }) => rest) + + // activities + const catMap: Record = {} + for (const sess of sessions) { + for (const [cat, d] of Object.entries(sess.categoryBreakdown)) { + if (!catMap[cat]) { catMap[cat] = { turns: 0, cost: 0, editTurns: 0, oneShotTurns: 0 } } + catMap[cat].turns += d.turns + catMap[cat].cost += d.costUSD + catMap[cat].editTurns += d.editTurns + catMap[cat].oneShotTurns += d.oneShotTurns + } + } + const activities = Object.entries(catMap) + .sort(([, a], [, b]) => b.cost - a.cost) + .map(([cat, d]) => ({ + category: CATEGORY_LABELS[cat as TaskCategory] ?? cat, + cost: convertCost(d.cost), + turns: d.turns, + editTurns: d.editTurns, + oneShotTurns: d.oneShotTurns, + oneShotRate: d.editTurns > 0 ? Math.round((d.oneShotTurns / d.editTurns) * 1000) / 10 : null, + })) + + // tools + const toolMap: Record = {} + const mcpMap: Record = {} + const bashMap: Record = {} + for (const sess of sessions) { + for (const [tool, d] of Object.entries(sess.toolBreakdown)) { + toolMap[tool] = (toolMap[tool] ?? 0) + d.calls + } + for (const [server, d] of Object.entries(sess.mcpBreakdown)) { + mcpMap[server] = (mcpMap[server] ?? 0) + d.calls + } + for (const [cmd, d] of Object.entries(sess.bashBreakdown)) { + bashMap[cmd] = (bashMap[cmd] ?? 0) + d.calls + } + } + + const sortedMap = (m: Record) => + Object.entries(m).sort(([, a], [, b]) => b - a).map(([name, calls]) => ({ name, calls })) + + return { + generated: new Date().toISOString(), + currency: code, + period, + overview: { + cost: convertCost(totalCostUSD), + calls: totalCalls, + sessions: totalSessions, + cacheHitPercent, + tokens: { + input: totalInput, + output: totalOutput, + cacheRead: totalCacheRead, + cacheWrite: totalCacheWrite, + }, + }, + daily, + projects: projectList, + models, + activities, + tools: sortedMap(toolMap), + mcpServers: sortedMap(mcpMap), + shellCommands: sortedMap(bashMap), + } +} + program .command('report', { isDefault: true }) .description('Interactive usage dashboard') .option('-p, --period ', 'Starting period: today, week, 30days, month, all', 'week') .option('--provider ', 'Filter by provider: all, claude, codex, cursor', 'all') + .option('--format ', 'Output format: tui, json', 'tui') .option('--refresh ', 'Auto-refresh interval in seconds', parseInt) .action(async (opts) => { - await renderDashboard(toPeriod(opts.period), opts.provider, opts.refresh) + const period = toPeriod(opts.period) + if (opts.format === 'json') { + await loadPricing() + const { range, label } = getDateRange(period) + const projects = await parseAllSessions(range, opts.provider) + console.log(JSON.stringify(buildJsonReport(projects, label), null, 2)) + return + } + await renderDashboard(period, opts.provider, opts.refresh) }) function buildPeriodData(label: string, projects: ProjectSummary[]): PeriodData { @@ -160,8 +297,16 @@ program .command('today') .description('Today\'s usage dashboard') .option('--provider ', 'Filter by provider: all, claude, codex, cursor', 'all') + .option('--format ', 'Output format: tui, json', 'tui') .option('--refresh ', 'Auto-refresh interval in seconds', parseInt) .action(async (opts) => { + if (opts.format === 'json') { + await loadPricing() + const { range, label } = getDateRange('today') + const projects = await parseAllSessions(range, opts.provider) + console.log(JSON.stringify(buildJsonReport(projects, label), null, 2)) + return + } await renderDashboard('today', opts.provider, opts.refresh) }) @@ -169,8 +314,16 @@ program .command('month') .description('This month\'s usage dashboard') .option('--provider ', 'Filter by provider: all, claude, codex, cursor', 'all') + .option('--format ', 'Output format: tui, json', 'tui') .option('--refresh ', 'Auto-refresh interval in seconds', parseInt) .action(async (opts) => { + if (opts.format === 'json') { + await loadPricing() + const { range, label } = getDateRange('month') + const projects = await parseAllSessions(range, opts.provider) + console.log(JSON.stringify(buildJsonReport(projects, label), null, 2)) + return + } await renderDashboard('month', opts.provider, opts.refresh) }) From fad21f3097208229b511b7ab13ca6335fe8e2b79 Mon Sep 17 00:00:00 2001 From: Travis Haley Date: Thu, 16 Apr 2026 13:08:46 -0600 Subject: [PATCH 11/70] fix: destructure cost before spread so convertCost isn't overwritten in models JSON output --- src/cli.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/cli.ts b/src/cli.ts index 8f7269e..c53a315 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -125,8 +125,7 @@ function buildJsonReport(projects: ProjectSummary[], period: string) { } const models = Object.entries(modelMap) .sort(([, a], [, b]) => b.cost - a.cost) - .map(([name, d]) => ({ name, cost: convertCost(d.cost), ...d, cost_usd: undefined })) - .map(({ cost_usd: _, ...rest }) => rest) + .map(([name, { cost, ...rest }]) => ({ name, ...rest, cost: convertCost(cost) })) // activities const catMap: Record = {} From 60712785d75a0f76ec971b80fd94d45a0717077d Mon Sep 17 00:00:00 2001 From: Travis Haley Date: Thu, 16 Apr 2026 13:10:05 -0600 Subject: [PATCH 12/70] style: remove section-label comments per repo convention --- src/cli.ts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/cli.ts b/src/cli.ts index c53a315..77a9a91 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -82,7 +82,6 @@ function buildJsonReport(projects: ProjectSummary[], period: string) { const allInput = totalInput + totalCacheRead + totalCacheWrite const cacheHitPercent = allInput > 0 ? Math.round((totalCacheRead / allInput) * 1000) / 10 : 0 - // daily const dailyMap: Record = {} for (const sess of sessions) { for (const turn of sess.turns) { @@ -101,7 +100,6 @@ function buildJsonReport(projects: ProjectSummary[], period: string) { calls: d.calls, })) - // projects const projectList = projects.map(p => ({ name: p.project, path: p.projectPath, @@ -110,7 +108,6 @@ function buildJsonReport(projects: ProjectSummary[], period: string) { sessions: p.sessions.length, })) - // models const modelMap: Record = {} for (const sess of sessions) { for (const [model, d] of Object.entries(sess.modelBreakdown)) { @@ -127,7 +124,6 @@ function buildJsonReport(projects: ProjectSummary[], period: string) { .sort(([, a], [, b]) => b.cost - a.cost) .map(([name, { cost, ...rest }]) => ({ name, ...rest, cost: convertCost(cost) })) - // activities const catMap: Record = {} for (const sess of sessions) { for (const [cat, d] of Object.entries(sess.categoryBreakdown)) { @@ -149,7 +145,6 @@ function buildJsonReport(projects: ProjectSummary[], period: string) { oneShotRate: d.editTurns > 0 ? Math.round((d.oneShotTurns / d.editTurns) * 1000) / 10 : null, })) - // tools const toolMap: Record = {} const mcpMap: Record = {} const bashMap: Record = {} From 7a061ea679faeabd696b3555a22bfaeeea3c062d Mon Sep 17 00:00:00 2001 From: Travis Haley Date: Thu, 16 Apr 2026 13:13:09 -0600 Subject: [PATCH 13/70] feat: add periodKey and topSessions to JSON output --- src/cli.ts | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/cli.ts b/src/cli.ts index 77a9a91..3a65da9 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -68,7 +68,7 @@ program.hook('preAction', async () => { await loadCurrency() }) -function buildJsonReport(projects: ProjectSummary[], period: string) { +function buildJsonReport(projects: ProjectSummary[], period: string, periodKey: string) { const sessions = projects.flatMap(p => p.sessions) const { code } = getCurrency() @@ -163,10 +163,16 @@ function buildJsonReport(projects: ProjectSummary[], period: string) { const sortedMap = (m: Record) => Object.entries(m).sort(([, a], [, b]) => b - a).map(([name, calls]) => ({ name, calls })) + const topSessions = projects + .flatMap(p => p.sessions.map(s => ({ project: p.project, sessionId: s.sessionId, date: s.firstTimestamp?.slice(0, 10) ?? null, cost: convertCost(s.totalCostUSD), calls: s.apiCalls }))) + .sort((a, b) => b.cost - a.cost) + .slice(0, 5) + return { generated: new Date().toISOString(), currency: code, period, + periodKey, overview: { cost: convertCost(totalCostUSD), calls: totalCalls, @@ -186,6 +192,7 @@ function buildJsonReport(projects: ProjectSummary[], period: string) { tools: sortedMap(toolMap), mcpServers: sortedMap(mcpMap), shellCommands: sortedMap(bashMap), + topSessions, } } @@ -202,7 +209,7 @@ program await loadPricing() const { range, label } = getDateRange(period) const projects = await parseAllSessions(range, opts.provider) - console.log(JSON.stringify(buildJsonReport(projects, label), null, 2)) + console.log(JSON.stringify(buildJsonReport(projects, label, period), null, 2)) return } await renderDashboard(period, opts.provider, opts.refresh) @@ -298,7 +305,7 @@ program await loadPricing() const { range, label } = getDateRange('today') const projects = await parseAllSessions(range, opts.provider) - console.log(JSON.stringify(buildJsonReport(projects, label), null, 2)) + console.log(JSON.stringify(buildJsonReport(projects, label, 'today'), null, 2)) return } await renderDashboard('today', opts.provider, opts.refresh) @@ -315,7 +322,7 @@ program await loadPricing() const { range, label } = getDateRange('month') const projects = await parseAllSessions(range, opts.provider) - console.log(JSON.stringify(buildJsonReport(projects, label), null, 2)) + console.log(JSON.stringify(buildJsonReport(projects, label, 'month'), null, 2)) return } await renderDashboard('month', opts.provider, opts.refresh) From 4154413e59fa5c3c05c79a85dce255a1b3a01ab5 Mon Sep 17 00:00:00 2001 From: AgentSeal Date: Thu, 16 Apr 2026 14:43:03 -0700 Subject: [PATCH 14/70] chore: DRY json report branches and drop unused import - extract Period type alias - hoist repeated json action body into runJsonReport helper - remove unused getCostColumnHeader import --- src/cli.ts | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/cli.ts b/src/cli.ts index 3a65da9..b47229f 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -2,7 +2,7 @@ import { Command } from 'commander' import { exportCsv, exportJson, type PeriodExport } from './export.js' import { loadPricing } from './models.js' import { parseAllSessions } from './parser.js' -import { getCostColumnHeader, convertCost } from './currency.js' +import { convertCost } from './currency.js' import { renderStatusBar } from './format.js' import { installMenubar, renderMenubarFormat, type PeriodData, type ProviderCost, uninstallMenubar } from './menubar.js' import { CATEGORY_LABELS, type DateRange, type ProjectSummary, type TaskCategory } from './types.js' @@ -51,7 +51,9 @@ function getDateRange(period: string): { range: DateRange; label: string } { } } -function toPeriod(s: string): 'today' | 'week' | '30days' | 'month' | 'all' { +type Period = 'today' | 'week' | '30days' | 'month' | 'all' + +function toPeriod(s: string): Period { if (s === 'today') return 'today' if (s === 'month') return 'month' if (s === '30days') return '30days' @@ -59,6 +61,13 @@ function toPeriod(s: string): 'today' | 'week' | '30days' | 'month' | 'all' { return 'week' } +async function runJsonReport(period: Period, provider: string): Promise { + await loadPricing() + const { range, label } = getDateRange(period) + const projects = await parseAllSessions(range, provider) + console.log(JSON.stringify(buildJsonReport(projects, label, period), null, 2)) +} + const program = new Command() .name('codeburn') .description('See where your AI coding tokens go - by task, tool, model, and project') @@ -206,10 +215,7 @@ program .action(async (opts) => { const period = toPeriod(opts.period) if (opts.format === 'json') { - await loadPricing() - const { range, label } = getDateRange(period) - const projects = await parseAllSessions(range, opts.provider) - console.log(JSON.stringify(buildJsonReport(projects, label, period), null, 2)) + await runJsonReport(period, opts.provider) return } await renderDashboard(period, opts.provider, opts.refresh) @@ -302,10 +308,7 @@ program .option('--refresh ', 'Auto-refresh interval in seconds', parseInt) .action(async (opts) => { if (opts.format === 'json') { - await loadPricing() - const { range, label } = getDateRange('today') - const projects = await parseAllSessions(range, opts.provider) - console.log(JSON.stringify(buildJsonReport(projects, label, 'today'), null, 2)) + await runJsonReport('today', opts.provider) return } await renderDashboard('today', opts.provider, opts.refresh) @@ -319,10 +322,7 @@ program .option('--refresh ', 'Auto-refresh interval in seconds', parseInt) .action(async (opts) => { if (opts.format === 'json') { - await loadPricing() - const { range, label } = getDateRange('month') - const projects = await parseAllSessions(range, opts.provider) - console.log(JSON.stringify(buildJsonReport(projects, label, 'month'), null, 2)) + await runJsonReport('month', opts.provider) return } await renderDashboard('month', opts.provider, opts.refresh) From 67c504a60ab53dcd436a82c96a9e1d7425468f45 Mon Sep 17 00:00:00 2001 From: Travis Haley Date: Thu, 16 Apr 2026 09:39:58 -0600 Subject: [PATCH 15/70] feat: add --project and --exclude filters for project-level filtering Adds two new repeatable flags to all commands (report, today, month, status, export): - --project : include only projects matching name (substring, case-insensitive) - --exclude : exclude projects matching name (substring, case-insensitive) Both flags can be specified multiple times to match multiple projects. Co-Authored-By: Claude Opus 4.6 (1M context) --- README.md | 14 ++++++++++++ src/cli.ts | 55 +++++++++++++++++++++++++++++++---------------- src/dashboard.tsx | 16 ++++++++------ src/parser.ts | 25 +++++++++++++++++++++ 4 files changed, 84 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index 2a4f6e9..246aeec 100644 --- a/README.md +++ b/README.md @@ -97,6 +97,20 @@ codeburn export --provider claude # export Claude data only The `--provider` flag works on all commands: `report`, `today`, `month`, `status`, `export`. +### Project filtering + +Filter results by project name (case-insensitive substring match). Both flags are repeatable: + +```bash +codeburn report --project myapp # show only projects matching "myapp" +codeburn report --exclude myapp # show everything except "myapp" +codeburn report --exclude myapp --exclude tests # exclude multiple projects +codeburn month --project api --project web # include multiple projects +codeburn export --project inventory # export only "inventory" project data +``` + +The `--project` and `--exclude` flags work on all commands and can be combined with `--provider`. + ### Supported providers | Provider | Data location | Status | diff --git a/src/cli.ts b/src/cli.ts index b47229f..79844f5 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -1,7 +1,7 @@ import { Command } from 'commander' import { exportCsv, exportJson, type PeriodExport } from './export.js' import { loadPricing } from './models.js' -import { parseAllSessions } from './parser.js' +import { parseAllSessions, filterProjectsByName } from './parser.js' import { convertCost } from './currency.js' import { renderStatusBar } from './format.js' import { installMenubar, renderMenubarFormat, type PeriodData, type ProviderCost, uninstallMenubar } from './menubar.js' @@ -61,10 +61,15 @@ function toPeriod(s: string): Period { return 'week' } -async function runJsonReport(period: Period, provider: string): Promise { +function collect(val: string, acc: string[]): string[] { + acc.push(val) + return acc +} + +async function runJsonReport(period: Period, provider: string, project: string[], exclude: string[]): Promise { await loadPricing() const { range, label } = getDateRange(period) - const projects = await parseAllSessions(range, provider) + const projects = filterProjectsByName(await parseAllSessions(range, provider), project, exclude) console.log(JSON.stringify(buildJsonReport(projects, label, period), null, 2)) } @@ -211,14 +216,16 @@ program .option('-p, --period ', 'Starting period: today, week, 30days, month, all', 'week') .option('--provider ', 'Filter by provider: all, claude, codex, cursor', 'all') .option('--format ', 'Output format: tui, json', 'tui') + .option('--project ', 'Show only projects matching name (repeatable)', collect, []) + .option('--exclude ', 'Exclude projects matching name (repeatable)', collect, []) .option('--refresh ', 'Auto-refresh interval in seconds', parseInt) .action(async (opts) => { const period = toPeriod(opts.period) if (opts.format === 'json') { - await runJsonReport(period, opts.provider) + await runJsonReport(period, opts.provider, opts.project, opts.exclude) return } - await renderDashboard(period, opts.provider, opts.refresh) + await renderDashboard(period, opts.provider, opts.refresh, opts.project, opts.exclude) }) function buildPeriodData(label: string, projects: ProjectSummary[]): PeriodData { @@ -265,15 +272,18 @@ program .description('Compact status output (today + week + month)') .option('--format ', 'Output format: terminal, menubar, json', 'terminal') .option('--provider ', 'Filter by provider: all, claude, codex, cursor', 'all') + .option('--project ', 'Show only projects matching name (repeatable)', collect, []) + .option('--exclude ', 'Exclude projects matching name (repeatable)', collect, []) .action(async (opts) => { await loadPricing() const pf = opts.provider + const fp = (p: ProjectSummary[]) => filterProjectsByName(p, opts.project, opts.exclude) if (opts.format === 'menubar') { const todayRange = getDateRange('today').range - const todayData = buildPeriodData('Today', await parseAllSessions(todayRange, pf)) - const weekData = buildPeriodData('7 Days', await parseAllSessions(getDateRange('week').range, pf)) - const thirtyDayData = buildPeriodData('30 Days', await parseAllSessions(getDateRange('30days').range, pf)) - const monthData = buildPeriodData('Month', await parseAllSessions(getDateRange('month').range, pf)) + const todayData = buildPeriodData('Today', fp(await parseAllSessions(todayRange, pf))) + const weekData = buildPeriodData('7 Days', fp(await parseAllSessions(getDateRange('week').range, pf))) + const thirtyDayData = buildPeriodData('30 Days', fp(await parseAllSessions(getDateRange('30days').range, pf))) + const monthData = buildPeriodData('Month', fp(await parseAllSessions(getDateRange('month').range, pf))) const todayProviders: ProviderCost[] = [] for (const p of await getAllProviders()) { const data = await parseAllSessions(todayRange, p.name) @@ -285,8 +295,8 @@ program } if (opts.format === 'json') { - const todayData = buildPeriodData('today', await parseAllSessions(getDateRange('today').range, pf)) - const monthData = buildPeriodData('month', await parseAllSessions(getDateRange('month').range, pf)) + const todayData = buildPeriodData('today', fp(await parseAllSessions(getDateRange('today').range, pf))) + const monthData = buildPeriodData('month', fp(await parseAllSessions(getDateRange('month').range, pf))) const { code, rate } = getCurrency() console.log(JSON.stringify({ currency: code, @@ -296,7 +306,7 @@ program return } - const monthProjects = await parseAllSessions(getDateRange('month').range, pf) + const monthProjects = fp(await parseAllSessions(getDateRange('month').range, pf)) console.log(renderStatusBar(monthProjects)) }) @@ -305,13 +315,15 @@ program .description('Today\'s usage dashboard') .option('--provider ', 'Filter by provider: all, claude, codex, cursor', 'all') .option('--format ', 'Output format: tui, json', 'tui') + .option('--project ', 'Show only projects matching name (repeatable)', collect, []) + .option('--exclude ', 'Exclude projects matching name (repeatable)', collect, []) .option('--refresh ', 'Auto-refresh interval in seconds', parseInt) .action(async (opts) => { if (opts.format === 'json') { - await runJsonReport('today', opts.provider) + await runJsonReport('today', opts.provider, opts.project, opts.exclude) return } - await renderDashboard('today', opts.provider, opts.refresh) + await renderDashboard('today', opts.provider, opts.refresh, opts.project, opts.exclude) }) program @@ -319,13 +331,15 @@ program .description('This month\'s usage dashboard') .option('--provider ', 'Filter by provider: all, claude, codex, cursor', 'all') .option('--format ', 'Output format: tui, json', 'tui') + .option('--project ', 'Show only projects matching name (repeatable)', collect, []) + .option('--exclude ', 'Exclude projects matching name (repeatable)', collect, []) .option('--refresh ', 'Auto-refresh interval in seconds', parseInt) .action(async (opts) => { if (opts.format === 'json') { - await runJsonReport('month', opts.provider) + await runJsonReport('month', opts.provider, opts.project, opts.exclude) return } - await renderDashboard('month', opts.provider, opts.refresh) + await renderDashboard('month', opts.provider, opts.refresh, opts.project, opts.exclude) }) program @@ -334,13 +348,16 @@ program .option('-f, --format ', 'Export format: csv, json', 'csv') .option('-o, --output ', 'Output file path') .option('--provider ', 'Filter by provider: all, claude, codex, cursor', 'all') + .option('--project ', 'Show only projects matching name (repeatable)', collect, []) + .option('--exclude ', 'Exclude projects matching name (repeatable)', collect, []) .action(async (opts) => { await loadPricing() const pf = opts.provider + const fp = (p: ProjectSummary[]) => filterProjectsByName(p, opts.project, opts.exclude) const periods: PeriodExport[] = [ - { label: 'Today', projects: await parseAllSessions(getDateRange('today').range, pf) }, - { label: '7 Days', projects: await parseAllSessions(getDateRange('week').range, pf) }, - { label: '30 Days', projects: await parseAllSessions(getDateRange('30days').range, pf) }, + { label: 'Today', projects: fp(await parseAllSessions(getDateRange('today').range, pf)) }, + { label: '7 Days', projects: fp(await parseAllSessions(getDateRange('week').range, pf)) }, + { label: '30 Days', projects: fp(await parseAllSessions(getDateRange('30days').range, pf)) }, ] if (periods.every(p => p.projects.length === 0)) { diff --git a/src/dashboard.tsx b/src/dashboard.tsx index 55c055b..6af5d3a 100644 --- a/src/dashboard.tsx +++ b/src/dashboard.tsx @@ -4,7 +4,7 @@ import React, { useState, useCallback, useEffect } from 'react' import { render, Box, Text, useInput, useApp, useWindowSize } from 'ink' import { CATEGORY_LABELS, type ProjectSummary, type TaskCategory } from './types.js' import { formatCost, formatTokens } from './format.js' -import { parseAllSessions } from './parser.js' +import { parseAllSessions, filterProjectsByName } from './parser.js' import { loadPricing } from './models.js' import { getAllProviders } from './providers/index.js' @@ -593,11 +593,13 @@ function DashboardContent({ projects, period, columns, activeProvider }: { proje ) } -function InteractiveDashboard({ initialProjects, initialPeriod, initialProvider, refreshSeconds }: { +function InteractiveDashboard({ initialProjects, initialPeriod, initialProvider, refreshSeconds, projectFilter, excludeFilter }: { initialProjects: ProjectSummary[] initialPeriod: Period initialProvider: string refreshSeconds?: number + projectFilter?: string[] + excludeFilter?: string[] }) { const { exit } = useApp() const [period, setPeriod] = useState(initialPeriod) @@ -629,10 +631,10 @@ function InteractiveDashboard({ initialProjects, initialPeriod, initialProvider, const reloadData = useCallback(async (p: Period, prov: string) => { setLoading(true) const range = getDateRange(p) - const data = await parseAllSessions(range, prov) + const data = filterProjectsByName(await parseAllSessions(range, prov), projectFilter, excludeFilter) setProjects(data) setLoading(false) - }, []) + }, [projectFilter, excludeFilter]) useEffect(() => { if (!refreshSeconds || refreshSeconds <= 0) return @@ -718,16 +720,16 @@ function StaticDashboard({ projects, period, activeProvider }: { projects: Proje ) } -export async function renderDashboard(period: Period = 'week', provider: string = 'all', refreshSeconds?: number): Promise { +export async function renderDashboard(period: Period = 'week', provider: string = 'all', refreshSeconds?: number, projectFilter?: string[], excludeFilter?: string[]): Promise { await loadPricing() const range = getDateRange(period) - const projects = await parseAllSessions(range, provider) + const projects = filterProjectsByName(await parseAllSessions(range, provider), projectFilter, excludeFilter) const isTTY = process.stdin.isTTY && process.stdout.isTTY if (isTTY) { const { waitUntilExit } = render( - + ) await waitUntilExit() } else { diff --git a/src/parser.ts b/src/parser.ts index 4055fea..429cb45 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -462,6 +462,31 @@ function cachePut(key: string, data: ProjectSummary[]) { sessionCache.set(key, { data, ts: now }) } +export function filterProjectsByName( + projects: ProjectSummary[], + include?: string[], + exclude?: string[], +): ProjectSummary[] { + let result = projects + if (include && include.length > 0) { + const patterns = include.map(s => s.toLowerCase()) + result = result.filter(p => { + const name = p.project.toLowerCase() + const path = p.projectPath.toLowerCase() + return patterns.some(pat => name.includes(pat) || path.includes(pat)) + }) + } + if (exclude && exclude.length > 0) { + const patterns = exclude.map(s => s.toLowerCase()) + result = result.filter(p => { + const name = p.project.toLowerCase() + const path = p.projectPath.toLowerCase() + return !patterns.some(pat => name.includes(pat) || path.includes(pat)) + }) + } + return result +} + export async function parseAllSessions(dateRange?: DateRange, providerFilter?: string): Promise { const key = cacheKey(dateRange, providerFilter) const cached = sessionCache.get(key) From d90042ec3cdbfc82c05d9201b0b57f45ee85f4de Mon Sep 17 00:00:00 2001 From: AgentSeal Date: Thu, 16 Apr 2026 15:44:39 -0700 Subject: [PATCH 16/70] fix: stop Top Sessions panel from truncating the calls column The TopSessions row layout summed to the full panel width without leaving room for the Box border (round) + paddingX, so Ink truncated the last 4 characters -- landing exactly on the calls column and producing rows like "$182.58 ..." with no calls value. Introduce PANEL_CHROME = 4 and subtract it from the name column so the row fits inside the panel's inner area. --- src/dashboard.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/dashboard.tsx b/src/dashboard.tsx index 55c055b..8b41399 100644 --- a/src/dashboard.tsx +++ b/src/dashboard.tsx @@ -132,6 +132,8 @@ function HBar({ value, max, width }: { value: number; max: number; width: number ) } +const PANEL_CHROME = 4 + function Panel({ title, color, children, width }: { title: string; color: string; children: React.ReactNode; width: number }) { return ( @@ -390,7 +392,7 @@ function TopSessions({ projects, pw, bw }: { projects: ProjectSummary[]; pw: num } const maxCost = top[0].totalCostUSD - const nw = Math.max(8, pw - bw - TOP_SESSIONS_COST_COL - TOP_SESSIONS_CALLS_COL - 1) + const nw = Math.max(8, pw - bw - TOP_SESSIONS_COST_COL - TOP_SESSIONS_CALLS_COL - 1 - PANEL_CHROME) return ( From 98c1e266d78bfc82deed9d6a4ff1c334a81f0611 Mon Sep 17 00:00:00 2001 From: AgentSeal Date: Thu, 16 Apr 2026 15:34:33 -0700 Subject: [PATCH 17/70] test: cover filterProjectsByName include/exclude semantics Adds unit tests for the project-filter helper: include OR semantics, exclude AND-negation, case-insensitive matching against both project name and projectPath, ordering (exclude applied after include), empty-string edge case, and input immutability. --- tests/parser-filter.test.ts | 82 +++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 tests/parser-filter.test.ts diff --git a/tests/parser-filter.test.ts b/tests/parser-filter.test.ts new file mode 100644 index 0000000..4c34722 --- /dev/null +++ b/tests/parser-filter.test.ts @@ -0,0 +1,82 @@ +import { describe, it, expect } from 'vitest' + +import { filterProjectsByName } from '../src/parser.js' +import type { ProjectSummary } from '../src/types.js' + +function makeProject(project: string, projectPath = project): ProjectSummary { + return { + project, + projectPath, + sessions: [], + totalCostUSD: 0, + totalApiCalls: 0, + } +} + +describe('filterProjectsByName', () => { + const projects = [ + makeProject('codeburn', '/Users/alice/codeburn'), + makeProject('AgentSeal', '/Users/alice/projects/AgentSeal'), + makeProject('dashboard', '/Users/alice/AgentSeal/dashboard'), + makeProject('sandbox', '/tmp/sandbox'), + ] + + it('returns all projects when no filters given', () => { + expect(filterProjectsByName(projects)).toEqual(projects) + expect(filterProjectsByName(projects, [], [])).toEqual(projects) + expect(filterProjectsByName(projects, undefined, undefined)).toEqual(projects) + }) + + it('include matches project name (case-insensitive substring)', () => { + const result = filterProjectsByName(projects, ['codeburn']) + expect(result.map(p => p.project)).toEqual(['codeburn']) + }) + + it('include is case-insensitive', () => { + const result = filterProjectsByName(projects, ['AGENTSEAL']) + expect(result.map(p => p.project).sort()).toEqual(['AgentSeal', 'dashboard']) + }) + + it('include matches substring in path when name does not match', () => { + const result = filterProjectsByName(projects, ['alice/projects']) + expect(result.map(p => p.project)).toEqual(['AgentSeal']) + }) + + it('include uses OR semantics across patterns', () => { + const result = filterProjectsByName(projects, ['codeburn', 'sandbox']) + expect(result.map(p => p.project).sort()).toEqual(['codeburn', 'sandbox']) + }) + + it('exclude removes matching projects (AND-negation across patterns)', () => { + const result = filterProjectsByName(projects, undefined, ['codeburn', 'sandbox']) + expect(result.map(p => p.project).sort()).toEqual(['AgentSeal', 'dashboard']) + }) + + it('exclude matches path substring', () => { + const result = filterProjectsByName(projects, undefined, ['/tmp']) + expect(result.map(p => p.project)).not.toContain('sandbox') + }) + + it('exclude is applied after include', () => { + const result = filterProjectsByName(projects, ['AgentSeal'], ['dashboard']) + expect(result.map(p => p.project)).toEqual(['AgentSeal']) + }) + + it('returns empty array when no project matches include', () => { + expect(filterProjectsByName(projects, ['does-not-exist'])).toEqual([]) + }) + + it('empty-string pattern matches every project', () => { + const resultInclude = filterProjectsByName(projects, ['']) + expect(resultInclude).toHaveLength(projects.length) + const resultExclude = filterProjectsByName(projects, undefined, ['']) + expect(resultExclude).toEqual([]) + }) + + it('does not mutate the input array', () => { + const input = [makeProject('a'), makeProject('b')] + const snapshot = [...input] + filterProjectsByName(input, ['a'], ['b']) + expect(input).toEqual(snapshot) + }) +}) From d15532af0bd760770745475dcf060746629743dd Mon Sep 17 00:00:00 2001 From: AgentSeal Date: Thu, 16 Apr 2026 15:34:38 -0700 Subject: [PATCH 18/70] fix: apply --project/--exclude to menubar per-provider today totals The menubar status output computes per-provider today costs by iterating all providers after the main period blocks. That loop bypassed the project filter, so --project/--exclude affected the main totals but not the provider breakdown shown below them. --- src/cli.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cli.ts b/src/cli.ts index 79844f5..3cfe752 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -286,7 +286,7 @@ program const monthData = buildPeriodData('Month', fp(await parseAllSessions(getDateRange('month').range, pf))) const todayProviders: ProviderCost[] = [] for (const p of await getAllProviders()) { - const data = await parseAllSessions(todayRange, p.name) + const data = fp(await parseAllSessions(todayRange, p.name)) const cost = data.reduce((s, proj) => s + proj.totalCostUSD, 0) if (cost > 0) todayProviders.push({ name: p.displayName, cost }) } From 3ea2c0b25555062b118d32f0999866cafa38c48b Mon Sep 17 00:00:00 2001 From: AgentSeal Date: Thu, 16 Apr 2026 15:55:29 -0700 Subject: [PATCH 19/70] chore: release 0.6.1 -- JSON output, project filters, claude-opus-4-7, Top Sessions fix --- CHANGELOG.md | 27 +++++++++++++++++++++++++++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 34e4b46..bd0b560 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,32 @@ # Changelog +## 0.6.1 - 2026-04-16 + +### Added +- **JSON output on `report`, `today`, `month`.** `--format json` writes the + full dashboard (overview, daily, projects, models, activities, tools, MCP + servers, shell commands, top sessions) to stdout. Contributed by @mallek. +- **Project filters.** `--project ` and `--exclude ` on all + commands (`report`, `today`, `month`, `status`, `export`). Case-insensitive + substring match against project name and path. Both flags are repeatable. + Contributed by @mallek. +- **claude-opus-4-7 model mapping and pricing.** Displays as `Opus 4.7` with + the same Opus pricing as 4.6 and a 6x fast multiplier. Contributed by @mallek. +- **Unit tests for `filterProjectsByName`** covering include/exclude + semantics, case-insensitivity, path matching, and input immutability. + +### Fixed +- **Top Sessions panel truncating the calls column.** Row width filled the + full panel width without leaving room for the border and padding, so Ink + truncated the last 4 characters -- landing exactly on the calls column and + producing rows like `$182.58 ...` with no value. +- **SwiftBar custom plugin directory** now honoured when installing the + menubar widget. Reads the configured path from SwiftBar's defaults before + falling back to the standard location. Contributed by @Galeas. +- **`status --format menubar` per-provider today totals** now respect + `--project`/`--exclude`. The main period blocks already did, the provider + breakdown loop was the one spot that bypassed the filter. + ## 0.6.0 - 2026-04-16 ### Added diff --git a/package-lock.json b/package-lock.json index 282a31d..d40c129 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "codeburn", - "version": "0.6.0", + "version": "0.6.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "codeburn", - "version": "0.6.0", + "version": "0.6.1", "license": "MIT", "dependencies": { "chalk": "^5.4.1", diff --git a/package.json b/package.json index 2f91219..35ad388 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "codeburn", - "version": "0.6.0", + "version": "0.6.1", "description": "See where your AI coding tokens go - by task, tool, model, and project", "type": "module", "main": "./dist/cli.js", From 3bd3c0d7b4e1bffa072380ed35a5090780a6eae9 Mon Sep 17 00:00:00 2001 From: AgentSeal Date: Thu, 16 Apr 2026 16:09:19 -0700 Subject: [PATCH 20/70] chore(optimize): extract trend period magic number to named constant --- src/optimize.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/optimize.ts b/src/optimize.ts index 18c3666..532ec19 100644 --- a/src/optimize.ts +++ b/src/optimize.ts @@ -155,6 +155,8 @@ const FILE_READ_CONCURRENCY = 16 const RESULT_CACHE_TTL_MS = 60_000 const RECENT_WINDOW_HOURS = 48 const RECENT_WINDOW_MS = RECENT_WINDOW_HOURS * 60 * 60 * 1000 +const DEFAULT_TREND_PERIOD_DAYS = 30 +const DEFAULT_TREND_PERIOD_MS = DEFAULT_TREND_PERIOD_DAYS * 24 * 60 * 60 * 1000 const IMPROVING_THRESHOLD = 0.5 async function collectJsonlFiles(dirPath: string): Promise { @@ -947,8 +949,7 @@ function sessionTrend( ): Trend | 'resolved' { const now = Date.now() const baselineCount = totalItemCount - recentItemCount - const thirtyDaysMs = 30 * 24 * 60 * 60 * 1000 - const periodStart = dateRange ? dateRange.start.getTime() : now - thirtyDaysMs + const periodStart = dateRange ? dateRange.start.getTime() : now - DEFAULT_TREND_PERIOD_MS const recentStart = now - RECENT_WINDOW_MS const baselineWindowMs = Math.max(recentStart - periodStart, 1) return computeTrend({ From f9587568617738b6f20118471dd86d15b0d5d99e Mon Sep 17 00:00:00 2001 From: AgentSeal Date: Thu, 16 Apr 2026 16:20:53 -0700 Subject: [PATCH 21/70] chore(optimize): name preview-count literals and drop punctuation dashes Rename slice(0, N) and length - N literals used in waste-finding preview strings to GHOST_NAMES_PREVIEW, GHOST_CLEANUP_COMMANDS_LIMIT, TOP_ITEMS_PREVIEW, MISSING_IGNORE_PATHS_PREVIEW, JUNK_DIRS_IGNORE_PREVIEW. Drop the punctuation double-hyphen from the config-health header. --- src/optimize.ts | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/src/optimize.ts b/src/optimize.ts index 532ec19..fa8ff8e 100644 --- a/src/optimize.ts +++ b/src/optimize.ts @@ -96,6 +96,12 @@ const JUNK_PATTERN = new RegExp(`/(?:${JUNK_DIRS.join('|')})/`) const SHELL_PROFILES = ['.zshrc', '.bashrc', '.bash_profile', '.profile'] +const TOP_ITEMS_PREVIEW = 3 +const MISSING_IGNORE_PATHS_PREVIEW = 2 +const JUNK_DIRS_IGNORE_PREVIEW = 8 +const GHOST_NAMES_PREVIEW = 5 +const GHOST_CLEANUP_COMMANDS_LIMIT = 10 + // ============================================================================ // Types // ============================================================================ @@ -396,7 +402,7 @@ export function detectJunkReads(calls: ToolCall[], dateRange?: DateRange): Waste if (trend === 'resolved') return null const sorted = [...dirCounts.entries()].sort((a, b) => b[1] - a[1]) - const dirList = sorted.slice(0, 3).map(([d, n]) => `${d}/ (${n}x)`).join(', ') + const dirList = sorted.slice(0, TOP_ITEMS_PREVIEW).map(([d, n]) => `${d}/ (${n}x)`).join(', ') const tokensSaved = totalJunkReads * AVG_TOKENS_PER_READ const detected = sorted.map(([d]) => d) @@ -458,7 +464,7 @@ export function detectDuplicateReads(calls: ToolCall[], dateRange?: DateRange): const worst = [...fileDupes.entries()] .sort((a, b) => b[1] - a[1]) - .slice(0, 3) + .slice(0, TOP_ITEMS_PREVIEW) .map(([name, n]) => `${name} (${n + 1}x)`) .join(', ') @@ -542,9 +548,9 @@ export function detectMissingClaudeignore(projectCwds: Set): WasteFindin if (missing.length === 0) return null const shortPaths = missing.map(shortHomePath) - const display = shortPaths.length <= 3 + const display = shortPaths.length <= MISSING_IGNORE_PATHS_PREVIEW + 1 ? shortPaths.join(', ') - : `${shortPaths.slice(0, 2).join(', ')} + ${shortPaths.length - 2} more` + : `${shortPaths.slice(0, MISSING_IGNORE_PATHS_PREVIEW).join(', ')} + ${shortPaths.length - MISSING_IGNORE_PATHS_PREVIEW} more` const tokensSaved = missing.length * ESTIMATED_READS_PER_MISSING_IGNORE * AVG_TOKENS_PER_READ @@ -557,7 +563,7 @@ export function detectMissingClaudeignore(projectCwds: Set): WasteFindin type: 'file-content', label: 'Create .claudeignore in each project root:', path: '.claudeignore', - content: JUNK_DIRS.slice(0, 8).join('\n'), + content: JUNK_DIRS.slice(0, JUNK_DIRS_IGNORE_PREVIEW).join('\n'), }, } } @@ -607,7 +613,7 @@ export function detectBloatedClaudeMd(projectCwds: Set): WasteFinding | const totalExtraLines = sorted.reduce((s, b) => s + (b.expandedLines - CLAUDEMD_HEALTHY_LINES), 0) const tokensSaved = totalExtraLines * CLAUDEMD_TOKENS_PER_LINE - const list = sorted.slice(0, 3).map(b => { + const list = sorted.slice(0, TOP_ITEMS_PREVIEW).map(b => { const importNote = b.imports > 0 ? ` with ${b.imports} @-import${b.imports > 1 ? 's' : ''}` : '' return `${b.path} (${b.expandedLines} lines${importNote})` }).join(', ') @@ -778,7 +784,7 @@ export async function detectGhostAgents(calls: ToolCall[]): Promise 5 ? `, +${ghosts.length - 5} more` : '') + const list = ghosts.slice(0, GHOST_NAMES_PREVIEW).join(', ') + (ghosts.length > GHOST_NAMES_PREVIEW ? `, +${ghosts.length - GHOST_NAMES_PREVIEW} more` : '') return { title: `${ghosts.length} custom agent${ghosts.length > 1 ? 's' : ''} you never use`, @@ -788,7 +794,7 @@ export async function detectGhostAgents(calls: ToolCall[]): Promise 1 ? 's' : ''}:`, - text: ghosts.slice(0, 10).map(name => `mv ~/.claude/agents/${name}.md ~/.claude/agents/.archived/`).join('\n'), + text: ghosts.slice(0, GHOST_CLEANUP_COMMANDS_LIMIT).map(name => `mv ~/.claude/agents/${name}.md ~/.claude/agents/.archived/`).join('\n'), }, } } @@ -808,7 +814,7 @@ export async function detectGhostSkills(calls: ToolCall[]): Promise 5 ? `, +${ghosts.length - 5} more` : '') + const list = ghosts.slice(0, GHOST_NAMES_PREVIEW).join(', ') + (ghosts.length > GHOST_NAMES_PREVIEW ? `, +${ghosts.length - GHOST_NAMES_PREVIEW} more` : '') return { title: `${ghosts.length} skill${ghosts.length > 1 ? 's' : ''} you never use`, @@ -818,7 +824,7 @@ export async function detectGhostSkills(calls: ToolCall[]): Promise 1 ? 's' : ''}:`, - text: ghosts.slice(0, 10).map(name => `mv ~/.claude/skills/${name} ~/.claude/skills/.archived/`).join('\n'), + text: ghosts.slice(0, GHOST_CLEANUP_COMMANDS_LIMIT).map(name => `mv ~/.claude/skills/${name} ~/.claude/skills/.archived/`).join('\n'), }, } } @@ -840,7 +846,7 @@ export async function detectGhostCommands(userMessages: string[]): Promise 5 ? `, +${ghosts.length - 5} more` : '') + const list = ghosts.slice(0, GHOST_NAMES_PREVIEW).join(', ') + (ghosts.length > GHOST_NAMES_PREVIEW ? `, +${ghosts.length - GHOST_NAMES_PREVIEW} more` : '') return { title: `${ghosts.length} slash command${ghosts.length > 1 ? 's' : ''} you never use`, @@ -850,7 +856,7 @@ export async function detectGhostCommands(userMessages: string[]): Promise 1 ? 's' : ''}:`, - text: ghosts.slice(0, 10).map(name => `mv ~/.claude/commands/${name}.md ~/.claude/commands/.archived/`).join('\n'), + text: ghosts.slice(0, GHOST_CLEANUP_COMMANDS_LIMIT).map(name => `mv ~/.claude/commands/${name}.md ~/.claude/commands/.archived/`).join('\n'), }, } } @@ -1108,7 +1114,7 @@ function renderOptimize( ): string { const lines: string[] = [] lines.push('') - lines.push(` ${chalk.bold.hex(ORANGE)('CodeBurn -- config health')}${chalk.dim(' ' + periodLabel)}`) + lines.push(` ${chalk.bold.hex(ORANGE)('CodeBurn config health')}${chalk.dim(' ' + periodLabel)}`) lines.push(chalk.hex(DIM)(' ' + SEP.repeat(PANEL_WIDTH))) const issueSuffix = findings.length > 0 ? `, ${findings.length} issue${findings.length > 1 ? 's' : ''}` : '' From 40b7de6841c6084fcd352abdb1080ecaa19e27b9 Mon Sep 17 00:00:00 2001 From: AgentSeal Date: Thu, 16 Apr 2026 16:27:33 -0700 Subject: [PATCH 22/70] docs: add optimize section with screenshot and command reference Sits between 'Reading the dashboard' (what the numbers mean) and 'How it reads data' (where the data comes from) so the feature lands as the natural next step: here is how to act on the patterns you saw. --- README.md | 32 ++++++++++++++++++++++++++++++++ assets/optimize.jpg | Bin 0 -> 616135 bytes 2 files changed, 32 insertions(+) create mode 100644 assets/optimize.jpg diff --git a/README.md b/README.md index 246aeec..5eaf2c4 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,8 @@ codeburn status # compact one-liner (today + month) codeburn status --format json codeburn export # CSV with today, 7 days, 30 days codeburn export -f json # JSON export +codeburn optimize # find waste, get copy-paste fixes +codeburn optimize -p week # scope the scan to last 7 days ``` Arrow keys switch between Today / 7 Days / 30 Days / Month / All Time. Press `q` to quit, `1` `2` `3` `4` `5` as shortcuts. The dashboard also shows average cost per session and the five most expensive sessions across all projects. @@ -206,6 +208,36 @@ CodeBurn surfaces the data, you read the story. A few patterns worth knowing: These are starting points, not verdicts. A 60% cache hit on a single experimental session is fine. A persistent 60% cache hit across weeks of work is a config issue. +## Optimize + +Once you know what to look for, `codeburn optimize` scans your sessions and your `~/.claude/` setup for the most common waste patterns and hands back exact, copy-paste fixes. It never writes to your files. + +

+ CodeBurn optimize output +

+ +```bash +codeburn optimize # scan the last 30 days +codeburn optimize -p today # today only +codeburn optimize -p week # last 7 days +codeburn optimize --provider claude # restrict to one provider +``` + +**What it detects** + +- Files Claude re-reads across sessions (same content, same context, over and over) +- Low Read:Edit ratio (editing without reading leads to retries and wasted tokens) +- Projects missing a `.claudeignore` (Claude wanders into `node_modules`, `.git`, build dirs) +- Wasted bash output (uncapped `BASH_MAX_OUTPUT_LENGTH`, trailing noise) +- Unused MCP servers still paying their tool-schema overhead every session +- Ghost agents, skills, and slash commands defined in `~/.claude/` but never invoked +- Bloated `CLAUDE.md` files (with `@-import` expansion counted) +- Cache creation overhead and junk directory reads + +Each finding shows the estimated token and dollar savings plus a ready-to-paste fix: a `CLAUDE.md` line, a `.claudeignore` template, an environment variable, or a `mv` command to archive unused items. Findings are ranked by urgency (impact weighted against observed waste) and rolled up into an A-F setup health grade. Repeat runs classify each finding as new, improving, or resolved against a 48-hour recent window. + +You can also open it inline from the dashboard: press `o` when a finding count appears in the status bar, `b` to return. + ## How it reads data **Claude Code** stores session transcripts as JSONL at `~/.claude/projects//.jsonl`. Each assistant entry contains model name, token usage (input, output, cache read, cache write), tool_use blocks, and timestamps. diff --git a/assets/optimize.jpg b/assets/optimize.jpg new file mode 100644 index 0000000000000000000000000000000000000000..9d8939d85cf138e0b866db32d4ecf2b62b1a26c3 GIT binary patch literal 616135 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 KVr!YPU$NeSxgMzJ-V|S#!%PJNp?$`m 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≺J#Ii)M+{!pq>9iY7 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

_lho-54hNBs^ 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ΝA&s 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

&ljtDEk!~D9X0cgvMh_`rY)b!nilHh9 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 |LEp#Fs(S;nyyWzgmkrt7G6^;6cjt;&jvT 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

vH*k5O2;dj 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%0D@h_TOsgyh5h_S`=z4ebbN@x)EmQD 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

7fH2IszC`9AmlSG2J+KsjkvCRbpo(+fIQ5n>|L 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 os@bUH)xI;;Eg>0&{9sTf|49HqQ3Qb%isGj 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 $Avhj_Q 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 o#;&^IH#F$~03kgW7-%x@_ Date: Thu, 16 Apr 2026 16:31:19 -0700 Subject: [PATCH 23/70] chore: release 0.7.0 -- codeburn optimize New top-level command plus in-TUI view for finding token waste and getting copy-paste fixes. 11 detectors, A-F setup health grade, recent-vs-baseline trend tracking, per-project context budget column. 198 tests. --- CHANGELOG.md | 35 +++++++++++++++++++++++++++++++++++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bd0b560..aa90735 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,40 @@ # Changelog +## 0.7.0 - 2026-04-16 + +### Added +- **`codeburn optimize` command.** Scans your sessions and your `~/.claude/` + setup for 11 common waste patterns and hands back exact copy-paste fixes. + Detection-only, never writes to user files. Supports `--period` (today, + week, 30days, month, all) and `--provider` (all, claude, codex, cursor). +- **Setup health grade (A-F).** Urgency-weighted rollup of all findings, with + impact scored against observed waste so the most expensive issues rank + first. High findings penalise more, medium less, low least. +- **Trend tracking.** Repeat runs classify each finding as new, improving, + or resolved against a 48-hour recent window, so fixed issues disappear + instead of lingering as noise. +- **11 detectors:** files Claude re-reads across sessions, low Read:Edit + ratio, projects missing `.claudeignore`, uncapped `BASH_MAX_OUTPUT_LENGTH`, + unused MCP servers, ghost agents, ghost skills, ghost slash commands, + bloated `CLAUDE.md` files (with `@-import` expansion counted), cache + creation overhead, and junk directory reads. +- **Copy-paste fixes.** Each finding comes with a ready-to-paste remedy: a + `CLAUDE.md` line, a `.claudeignore` template, an environment variable, or + a `mv` command to archive unused items. +- **In-TUI optimize view.** Press `o` in the dashboard when the status bar + shows a finding count, `b` to return. Same engine as the standalone + command, scoped to the current period and provider. +- **Per-project context budget column.** By Project panel now shows the + estimated per-session context overhead for each project (system prompt + + tools + `CLAUDE.md` + skills). +- **34 filesystem-mocking tests.** Tmpdir fixtures with `os.homedir` mocked + via `vi.mock` cover the detector surface end to end. Total suite: 198 + tests across 13 files. + +### Performance +- **mtime pre-filter + parallel reads + 60s result cache** cut a cold scan + from 12-17s to 6-7s on a 10k-session history. + ## 0.6.1 - 2026-04-16 ### Added diff --git a/package-lock.json b/package-lock.json index d40c129..e9a6b9c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "codeburn", - "version": "0.6.1", + "version": "0.7.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "codeburn", - "version": "0.6.1", + "version": "0.7.0", "license": "MIT", "dependencies": { "chalk": "^5.4.1", diff --git a/package.json b/package.json index 35ad388..15cb1bf 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "codeburn", - "version": "0.6.1", + "version": "0.7.0", "description": "See where your AI coding tokens go - by task, tool, model, and project", "type": "module", "main": "./dist/cli.js", From 276b14adea8ece2f0bc2f5443233738083cf3430 Mon Sep 17 00:00:00 2001 From: Jonathan Date: Fri, 17 Apr 2026 07:29:14 +0100 Subject: [PATCH 24/70] fix: prepend install-time node bin dir to menubar plugin PATH SwiftBar/xbar launch plugins with a minimal environment. If an older system Node (e.g. v18.x from Homebrew) appears earlier on PATH than the NVM-managed Node used to install codeburn, the plugin silently fails because string-width uses the /v regex flag (requires Node >= 20.11). Resolve the node binary directory at install time via process.execPath and prepend it to PATH in the generated plugin script. Also explicitly set HOME, which SwiftBar does not always inherit. Fixes #63 --- src/menubar.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/menubar.ts b/src/menubar.ts index a5abb5d..ca402a9 100644 --- a/src/menubar.ts +++ b/src/menubar.ts @@ -71,6 +71,11 @@ function getCodeburnBin(): string { function generatePlugin(bin: string): string { const home = homedir() + // Resolve the directory of the node binary used at install time so the + // plugin uses the same Node version codeburn was installed with — even + // when SwiftBar/xbar launch with a minimal PATH that finds an older + // system Node first. Fixes #63. + const nodeBinDir = join(process.execPath, '..') return `#!/bin/bash # CodeBurn # v0.1.0 @@ -81,7 +86,8 @@ function generatePlugin(bin: string): string { # https://github.com/agentseal/codeburn # node -export PATH="/usr/local/bin:/opt/homebrew/bin:$HOME/.local/bin:$HOME/.npm-global/bin:$PATH" +export HOME="${home}" +export PATH="${nodeBinDir}:$HOME/.local/bin:$HOME/.npm-global/bin:/opt/homebrew/bin:/usr/local/bin:$PATH" ${bin} status --format menubar 2>/dev/null || echo "-- | sfimage=flame.fill" ` From bd71377fdd19a10d532b3c2e6aa88ca4fdbc9739 Mon Sep 17 00:00:00 2001 From: Ninym Date: Fri, 17 Apr 2026 08:26:03 +0200 Subject: [PATCH 25/70] docs(optimize): remove references to non-existent .claudeignore Claude Code does not document or implement a .claudeignore feature. The junk-reads detector's fix is now a CLAUDE.md instruction asking Claude to avoid generated/dependency directories. The separate detectMissingClaudeignore finding and its tests are removed; checking for the presence of a non-existent file has no signal. Closes #61. --- src/optimize.ts | 53 ++++----------------------------------- tests/optimize-fs.test.ts | 43 ------------------------------- tests/optimize.test.ts | 20 ++++----------- 3 files changed, 10 insertions(+), 106 deletions(-) diff --git a/src/optimize.ts b/src/optimize.ts index fa8ff8e..fec40d5 100644 --- a/src/optimize.ts +++ b/src/optimize.ts @@ -32,7 +32,6 @@ const TOKENS_PER_SKILL_DEF = 80 const TOKENS_PER_COMMAND_DEF = 60 const CLAUDEMD_TOKENS_PER_LINE = 13 const BASH_TOKENS_PER_CHAR = 0.25 -const ESTIMATED_READS_PER_MISSING_IGNORE = 10 // ============================================================================ // Detector thresholds @@ -52,7 +51,6 @@ const LOW_RATIO_HIGH_THRESHOLD = 2 const LOW_RATIO_MEDIUM_THRESHOLD = 3 const MIN_API_CALLS_FOR_CACHE = 10 const CACHE_EXCESS_HIGH_THRESHOLD = 15000 -const MISSING_IGNORE_HIGH_THRESHOLD = 3 const UNUSED_MCP_HIGH_THRESHOLD = 3 const GHOST_AGENTS_HIGH_THRESHOLD = 5 const GHOST_AGENTS_MEDIUM_THRESHOLD = 2 @@ -97,8 +95,6 @@ const JUNK_PATTERN = new RegExp(`/(?:${JUNK_DIRS.join('|')})/`) const SHELL_PROFILES = ['.zshrc', '.bashrc', '.bash_profile', '.profile'] const TOP_ITEMS_PREVIEW = 3 -const MISSING_IGNORE_PATHS_PREVIEW = 2 -const JUNK_DIRS_IGNORE_PREVIEW = 8 const GHOST_NAMES_PREVIEW = 5 const GHOST_CLEANUP_COMMANDS_LIMIT = 10 @@ -408,18 +404,17 @@ export function detectJunkReads(calls: ToolCall[], dateRange?: DateRange): Waste const detected = sorted.map(([d]) => d) const commonDefaults = ['node_modules', '.git', 'dist', '__pycache__'] const extras = commonDefaults.filter(d => !dirCounts.has(d)).slice(0, Math.max(0, 6 - detected.length)) - const ignoreContent = [...detected, ...extras].join('\n') + const dirsToAvoid = [...detected, ...extras].join(', ') return { title: 'Claude is reading build/dependency folders', - explanation: `Claude read into ${dirList} (${totalJunkReads} reads). These are generated or dependency directories, not your code. A .claudeignore tells Claude to skip them.`, + explanation: `Claude read into ${dirList} (${totalJunkReads} reads). These are generated or dependency directories, not your code. Tell Claude in CLAUDE.md to avoid them.`, impact: totalJunkReads > JUNK_READS_HIGH_THRESHOLD ? 'high' : totalJunkReads > JUNK_READS_MEDIUM_THRESHOLD ? 'medium' : 'low', tokensSaved, fix: { - type: 'file-content', - label: 'Create .claudeignore in your project root:', - path: '.claudeignore', - content: ignoreContent, + type: 'paste', + label: 'Append to your project CLAUDE.md:', + text: `Do not read or search files under these directories unless I explicitly ask: ${dirsToAvoid}.`, }, trend, } @@ -531,43 +526,6 @@ export function detectUnusedMcp( } } -export function detectMissingClaudeignore(projectCwds: Set): WasteFinding | null { - const missing: string[] = [] - - for (const cwd of projectCwds) { - if (!existsSync(cwd)) continue - if (existsSync(join(cwd, '.claudeignore'))) continue - for (const dir of JUNK_DIRS) { - if (existsSync(join(cwd, dir))) { - missing.push(cwd) - break - } - } - } - - if (missing.length === 0) return null - - const shortPaths = missing.map(shortHomePath) - const display = shortPaths.length <= MISSING_IGNORE_PATHS_PREVIEW + 1 - ? shortPaths.join(', ') - : `${shortPaths.slice(0, MISSING_IGNORE_PATHS_PREVIEW).join(', ')} + ${shortPaths.length - MISSING_IGNORE_PATHS_PREVIEW} more` - - const tokensSaved = missing.length * ESTIMATED_READS_PER_MISSING_IGNORE * AVG_TOKENS_PER_READ - - return { - title: `Add .claudeignore to ${missing.length} project${missing.length > 1 ? 's' : ''}`, - explanation: `${missing.length} project${missing.length > 1 ? 's have' : ' has'} build/dependency folders (node_modules, .git, etc.) but no .claudeignore: ${display}. Without it, Claude can wander into them.`, - impact: missing.length >= MISSING_IGNORE_HIGH_THRESHOLD ? 'high' : 'medium', - tokensSaved, - fix: { - type: 'file-content', - label: 'Create .claudeignore in each project root:', - path: '.claudeignore', - content: JUNK_DIRS.slice(0, JUNK_DIRS_IGNORE_PREVIEW).join('\n'), - }, - } -} - function expandImports(filePath: string, seen: Set, depth: number): { totalLines: number; importedFiles: number } { if (depth > MAX_IMPORT_DEPTH || seen.has(filePath)) return { totalLines: 0, importedFiles: 0 } seen.add(filePath) @@ -1018,7 +976,6 @@ export async function scanAndDetect( () => detectJunkReads(toolCalls, dateRange), () => detectDuplicateReads(toolCalls, dateRange), () => detectUnusedMcp(toolCalls, projects, projectCwds), - () => detectMissingClaudeignore(projectCwds), () => detectBloatedClaudeMd(projectCwds), () => detectBashBloat(), ] diff --git a/tests/optimize-fs.test.ts b/tests/optimize-fs.test.ts index a476042..e43f66b 100644 --- a/tests/optimize-fs.test.ts +++ b/tests/optimize-fs.test.ts @@ -15,7 +15,6 @@ vi.mock('os', async () => { const FAKE_HOME_FOR_MOCK = process.env['CODEBURN_TEST_FAKE_HOME']! import { - detectMissingClaudeignore, detectBloatedClaudeMd, detectUnusedMcp, detectBashBloat, @@ -60,48 +59,6 @@ afterAll(() => { } }) -// ============================================================================ -// detectMissingClaudeignore -// ============================================================================ - -describe('detectMissingClaudeignore', () => { - it('flags a project with node_modules but no .claudeignore', () => { - const root = makeFixtureRoot() - const projectDir = join(root, 'myapp') - mkdirSync(join(projectDir, 'node_modules'), { recursive: true }) - const finding = detectMissingClaudeignore(new Set([projectDir])) - expect(finding).not.toBeNull() - expect(finding!.impact).toBe('medium') - }) - - it('does not flag when .claudeignore exists', () => { - const root = makeFixtureRoot() - const projectDir = join(root, 'myapp') - mkdirSync(join(projectDir, 'node_modules'), { recursive: true }) - writeFile(join(projectDir, '.claudeignore'), 'node_modules\n') - expect(detectMissingClaudeignore(new Set([projectDir]))).toBeNull() - }) - - it('does not flag project without junk dirs', () => { - const root = makeFixtureRoot() - const projectDir = join(root, 'myapp') - mkdirSync(join(projectDir, 'src'), { recursive: true }) - expect(detectMissingClaudeignore(new Set([projectDir]))).toBeNull() - }) - - it('escalates to high when three or more projects need it', () => { - const root = makeFixtureRoot() - const cwds = new Set() - for (let i = 0; i < 3; i++) { - const p = join(root, `proj-${i}`) - mkdirSync(join(p, 'node_modules'), { recursive: true }) - cwds.add(p) - } - const finding = detectMissingClaudeignore(cwds) - expect(finding!.impact).toBe('high') - }) -}) - // ============================================================================ // detectBloatedClaudeMd (including @-import expansion) // ============================================================================ diff --git a/tests/optimize.test.ts b/tests/optimize.test.ts index 5ebcab8..698a18f 100644 --- a/tests/optimize.test.ts +++ b/tests/optimize.test.ts @@ -6,7 +6,6 @@ import { detectLowReadEditRatio, detectCacheBloat, detectBloatedClaudeMd, - detectMissingClaudeignore, computeHealth, computeTrend, type ToolCall, @@ -77,13 +76,14 @@ describe('detectJunkReads', () => { expect(detectJunkReads(calls)).toBeNull() }) - it('builds .claudeignore content from detected + common extras', () => { + it('suggests CLAUDE.md advice listing detected and common junk dirs', () => { const calls = Array.from({ length: 5 }, () => call('Read', { file_path: '/x/node_modules/a.js' })) const finding = detectJunkReads(calls)! - expect(finding.fix.type).toBe('file-content') - if (finding.fix.type === 'file-content') { - expect(finding.fix.content).toContain('node_modules') + expect(finding.fix.type).toBe('paste') + if (finding.fix.type === 'paste') { + expect(finding.fix.text).toContain('node_modules') } + expect(finding.fix.label).toContain('CLAUDE.md') }) }) @@ -207,16 +207,6 @@ describe('detectBloatedClaudeMd', () => { }) }) -describe('detectMissingClaudeignore', () => { - it('returns null for empty set', () => { - expect(detectMissingClaudeignore(new Set())).toBeNull() - }) - - it('returns null for non-existent cwds', () => { - expect(detectMissingClaudeignore(new Set(['/does/not/exist']))).toBeNull() - }) -}) - describe('computeHealth', () => { it('returns A with 100 for no findings', () => { const { score, grade } = computeHealth([]) From e890d9bfc32dd0fa237d8d223670d48ffd16cbe5 Mon Sep 17 00:00:00 2001 From: Ninym Date: Fri, 17 Apr 2026 07:29:37 +0200 Subject: [PATCH 26/70] test(security): add failing test for HIGH-1 prototype pollution Three PoC fixtures (tool name, bash command, model name) reproduce the audit's HIGH-1 attack. Tests assert Object.prototype.calls stays undefined after parsing. They fail against current parser.ts -- Task 3 will close the pollution sink with Object.create(null). --- tests/fixtures/security/proto-bash.jsonl | 1 + tests/fixtures/security/proto-model.jsonl | 1 + tests/fixtures/security/proto-tool.jsonl | 1 + tests/security/prototype-pollution.test.ts | 77 ++++++++++++++++++++++ 4 files changed, 80 insertions(+) create mode 100644 tests/fixtures/security/proto-bash.jsonl create mode 100644 tests/fixtures/security/proto-model.jsonl create mode 100644 tests/fixtures/security/proto-tool.jsonl create mode 100644 tests/security/prototype-pollution.test.ts diff --git a/tests/fixtures/security/proto-bash.jsonl b/tests/fixtures/security/proto-bash.jsonl new file mode 100644 index 0000000..8e6b5e7 --- /dev/null +++ b/tests/fixtures/security/proto-bash.jsonl @@ -0,0 +1 @@ +{"type":"assistant","sessionId":"security-test","timestamp":"2026-04-16T00:00:00Z","message":{"id":"pwn-bash","type":"message","role":"assistant","model":"claude-opus-4-6","content":[{"type":"tool_use","id":"b1","name":"Bash","input":{"command":"/x/__proto__"}}],"usage":{"input_tokens":1,"output_tokens":1}}} diff --git a/tests/fixtures/security/proto-model.jsonl b/tests/fixtures/security/proto-model.jsonl new file mode 100644 index 0000000..0aabf71 --- /dev/null +++ b/tests/fixtures/security/proto-model.jsonl @@ -0,0 +1 @@ +{"type":"assistant","sessionId":"security-test","timestamp":"2026-04-16T00:00:00Z","message":{"id":"pwn-model","type":"message","role":"assistant","model":"__proto__","content":[{"type":"text","text":"x"}],"usage":{"input_tokens":1,"output_tokens":1}}} diff --git a/tests/fixtures/security/proto-tool.jsonl b/tests/fixtures/security/proto-tool.jsonl new file mode 100644 index 0000000..a93a853 --- /dev/null +++ b/tests/fixtures/security/proto-tool.jsonl @@ -0,0 +1 @@ +{"type":"assistant","sessionId":"security-test","timestamp":"2026-04-16T00:00:00Z","message":{"id":"pwn-tool","type":"message","role":"assistant","model":"claude-opus-4-6","content":[{"type":"tool_use","id":"t1","name":"__proto__","input":{}}],"usage":{"input_tokens":1,"output_tokens":1}}} diff --git a/tests/security/prototype-pollution.test.ts b/tests/security/prototype-pollution.test.ts new file mode 100644 index 0000000..6b6075c --- /dev/null +++ b/tests/security/prototype-pollution.test.ts @@ -0,0 +1,77 @@ +import { describe, it, expect, afterEach, beforeEach } from 'vitest' +import { mkdtemp, mkdir, cp, rm } from 'fs/promises' +import { tmpdir } from 'os' +import { join } from 'path' + +import { parseAllSessions } from '../../src/parser.js' +import type { DateRange } from '../../src/types.js' + +// Fixtures carry timestamp 2026-04-16T00:00:00Z. The range below must stay +// wide enough to include that date; if the fixtures move, move FIXTURE_DAY too. +const FIXTURE_DAY = Date.UTC(2026, 3, 16) // month index 3 = April (Date.UTC is 0-indexed) +const RANGE_BEFORE_MS = FIXTURE_DAY - 24 * 60 * 60 * 1000 +const RANGE_AFTER_MS = FIXTURE_DAY + 24 * 60 * 60 * 1000 +const PROJECT_NAME = 'codeburn-poc-testing' + +function makeRange(offsetMs: number): DateRange { + return { + start: new Date(RANGE_BEFORE_MS + offsetMs), + end: new Date(RANGE_AFTER_MS + offsetMs), + } +} + +// Hermeticity note: the Claude provider also scans a fixed Desktop sessions +// dir independent of CLAUDE_CONFIG_DIR. The narrow dateRange above excludes +// any real sessions in practice, but these tests are not strictly isolated +// on a machine with April 2026 Claude Desktop activity. A stricter fix +// belongs in a follow-up to discoverSessions itself. + +describe('HIGH-1 prototype pollution via unchecked bracket-assign', () => { + const tmpDirs: string[] = [] + let originalConfigDir: string | undefined + + beforeEach(() => { + originalConfigDir = process.env['CLAUDE_CONFIG_DIR'] + }) + + afterEach(async () => { + delete (Object.prototype as Record).calls + if (originalConfigDir === undefined) { + delete process.env['CLAUDE_CONFIG_DIR'] + } else { + process.env['CLAUDE_CONFIG_DIR'] = originalConfigDir + } + while (tmpDirs.length > 0) { + const d = tmpDirs.pop() + if (d) await rm(d, { recursive: true, force: true }) + } + }) + + async function setupPoc(fixture: string): Promise { + const base = await mkdtemp(join(tmpdir(), 'codeburn-sec-')) + tmpDirs.push(base) + const projectDir = join(base, 'projects', PROJECT_NAME) + await mkdir(projectDir, { recursive: true }) + await cp(join(__dirname, '..', 'fixtures', 'security', fixture), join(projectDir, 'pwn.jsonl')) + process.env['CLAUDE_CONFIG_DIR'] = base + return base + } + + it('does not pollute Object.prototype when session contains tool_use name "__proto__"', async () => { + await setupPoc('proto-tool.jsonl') + await expect(parseAllSessions(makeRange(0), 'claude')).resolves.not.toThrow() + expect(({} as Record).calls).toBeUndefined() + }) + + it('does not pollute Object.prototype when bash command basename is "__proto__"', async () => { + await setupPoc('proto-bash.jsonl') + await expect(parseAllSessions(makeRange(1), 'claude')).resolves.not.toThrow() + expect(({} as Record).calls).toBeUndefined() + }) + + it('does not pollute Object.prototype when model name is "__proto__"', async () => { + await setupPoc('proto-model.jsonl') + await expect(parseAllSessions(makeRange(2), 'claude')).resolves.not.toThrow() + expect(({} as Record).calls).toBeUndefined() + }) +}) From 5b810161e743f07e3623db99383e7249a847c211 Mon Sep 17 00:00:00 2001 From: Ninym Date: Fri, 17 Apr 2026 07:55:32 +0200 Subject: [PATCH 27/70] fix(parser): block prototype pollution via Object.create(null) Initialize the four breakdown maps (model, tool, mcp, bash) with null prototype so attacker-controlled keys named __proto__ create own properties on the map instead of mutating Object.prototype. Closes the HIGH-1 finding from the 2026-04-16 external security audit. --- src/parser.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/parser.ts b/src/parser.ts index 429cb45..6b39fc8 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -168,10 +168,10 @@ function buildSessionSummary( project: string, turns: ClassifiedTurn[], ): SessionSummary { - const modelBreakdown: SessionSummary['modelBreakdown'] = {} - const toolBreakdown: SessionSummary['toolBreakdown'] = {} - const mcpBreakdown: SessionSummary['mcpBreakdown'] = {} - const bashBreakdown: SessionSummary['bashBreakdown'] = {} + const modelBreakdown: SessionSummary['modelBreakdown'] = Object.create(null) + const toolBreakdown: SessionSummary['toolBreakdown'] = Object.create(null) + const mcpBreakdown: SessionSummary['mcpBreakdown'] = Object.create(null) + const bashBreakdown: SessionSummary['bashBreakdown'] = Object.create(null) const categoryBreakdown: SessionSummary['categoryBreakdown'] = {} as SessionSummary['categoryBreakdown'] let totalCost = 0 From 0ab66f6fe9e8c1006b059a094018750049b47c2e Mon Sep 17 00:00:00 2001 From: Ninym Date: Fri, 17 Apr 2026 07:57:19 +0200 Subject: [PATCH 28/70] test(fs-utils): add failing test for bounded read helper Tests the to-be-built readSessionFile helper: under-cap fast path, at-threshold stream path, over-cap null+skip, verbose stderr warning, and stat-failure graceful fallback. Fails against missing module -- Task 5 will implement src/fs-utils.ts to flip GREEN. --- tests/fs-utils.test.ts | 63 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 tests/fs-utils.test.ts diff --git a/tests/fs-utils.test.ts b/tests/fs-utils.test.ts new file mode 100644 index 0000000..7c5f38b --- /dev/null +++ b/tests/fs-utils.test.ts @@ -0,0 +1,63 @@ +import { describe, it, expect, afterEach, vi } from 'vitest' +import { mkdtemp, writeFile, rm } from 'fs/promises' +import { tmpdir } from 'os' +import { join } from 'path' + +import { + MAX_SESSION_FILE_BYTES, + STREAM_THRESHOLD_BYTES, + readSessionFile, +} from '../src/fs-utils.js' + +describe('readSessionFile', () => { + const tmpDirs: string[] = [] + + afterEach(async () => { + delete process.env.CODEBURN_VERBOSE + while (tmpDirs.length > 0) { + const d = tmpDirs.pop() + if (d) await rm(d, { recursive: true, force: true }) + } + }) + + async function tmpPath(content: string | Buffer): Promise { + const base = await mkdtemp(join(tmpdir(), 'codeburn-fs-')) + tmpDirs.push(base) + const p = join(base, 'x.jsonl') + await writeFile(p, content) + return p + } + + it('returns content for small files via readFile fast path', async () => { + const p = await tmpPath('hello\nworld\n') + expect(await readSessionFile(p)).toBe('hello\nworld\n') + }) + + it('returns content for files at the stream threshold via stream path', async () => { + const p = await tmpPath(Buffer.alloc(STREAM_THRESHOLD_BYTES, 'a')) + const got = await readSessionFile(p) + expect(got).not.toBeNull() + expect(got!.length).toBe(STREAM_THRESHOLD_BYTES) + }) + + it('returns null and skips files over the cap', async () => { + const p = await tmpPath(Buffer.alloc(MAX_SESSION_FILE_BYTES + 1, 'b')) + expect(await readSessionFile(p)).toBeNull() + }) + + it('emits stderr warning under CODEBURN_VERBOSE=1 for skipped file', async () => { + process.env.CODEBURN_VERBOSE = '1' + const p = await tmpPath(Buffer.alloc(MAX_SESSION_FILE_BYTES + 1, 'c')) + const spy = vi.spyOn(process.stderr, 'write').mockImplementation(() => true) + await readSessionFile(p) + expect(spy).toHaveBeenCalled() + const msg = (spy.mock.calls[0][0] as string) + expect(msg).toContain('codeburn') + expect(msg).toContain('oversize') + spy.mockRestore() + }) + + it('returns null on stat failure without throwing', async () => { + expect(await readSessionFile('/nonexistent/path/x.jsonl')).toBeNull() + }) +}) From 82c3125638378aac68cbe5a401e1253c4689ba46 Mon Sep 17 00:00:00 2001 From: Ninym Date: Fri, 17 Apr 2026 07:59:11 +0200 Subject: [PATCH 29/70] feat(fs-utils): bounded session-file read helper Adds readSessionFile / readSessionFileSync / readSessionLines with a 128 MB hard cap and 8 MB streaming threshold. Verbose mode (CODEBURN_VERBOSE=1) logs skipped and failed reads to stderr. Prepares the MEDIUM-1 migration of all provider read paths. --- src/fs-utils.ts | 93 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 src/fs-utils.ts diff --git a/src/fs-utils.ts b/src/fs-utils.ts new file mode 100644 index 0000000..49eff20 --- /dev/null +++ b/src/fs-utils.ts @@ -0,0 +1,93 @@ +import { readFile, stat } from 'fs/promises' +import { readFileSync, statSync, createReadStream } from 'fs' +import { createInterface } from 'readline' + +// Hard cap well below V8's 512 MB string limit even with split('\n') doubling. +// Stream threshold chosen as empirical breakeven between readFile+split peak +// memory and createReadStream+readline overhead for typical session files. +export const MAX_SESSION_FILE_BYTES = 128 * 1024 * 1024 +export const STREAM_THRESHOLD_BYTES = 8 * 1024 * 1024 + +function verbose(): boolean { + return process.env.CODEBURN_VERBOSE === '1' +} + +function warn(msg: string): void { + if (verbose()) process.stderr.write(`codeburn: ${msg}\n`) +} + +async function readViaStream(filePath: string): Promise { + const chunks: string[] = [] + const stream = createReadStream(filePath, { encoding: 'utf-8' }) + const rl = createInterface({ input: stream, crlfDelay: Infinity }) + for await (const line of rl) chunks.push(line) + return chunks.join('\n') +} + +export async function readSessionFile(filePath: string): Promise { + let size: number + try { + size = (await stat(filePath)).size + } catch (err) { + warn(`stat failed for ${filePath}: ${(err as NodeJS.ErrnoException).code ?? 'unknown'}`) + return null + } + + if (size > MAX_SESSION_FILE_BYTES) { + warn(`skipped oversize file ${filePath} (${size} bytes > cap ${MAX_SESSION_FILE_BYTES})`) + return null + } + + try { + if (size >= STREAM_THRESHOLD_BYTES) return await readViaStream(filePath) + return await readFile(filePath, 'utf-8') + } catch (err) { + warn(`read failed for ${filePath}: ${(err as NodeJS.ErrnoException).code ?? 'unknown'}`) + return null + } +} + +export function readSessionFileSync(filePath: string): string | null { + let size: number + try { + size = statSync(filePath).size + } catch (err) { + warn(`stat failed for ${filePath}: ${(err as NodeJS.ErrnoException).code ?? 'unknown'}`) + return null + } + + if (size > MAX_SESSION_FILE_BYTES) { + warn(`skipped oversize file ${filePath} (${size} bytes > cap ${MAX_SESSION_FILE_BYTES})`) + return null + } + + try { + return readFileSync(filePath, 'utf-8') + } catch (err) { + warn(`read failed for ${filePath}: ${(err as NodeJS.ErrnoException).code ?? 'unknown'}`) + return null + } +} + +export async function* readSessionLines(filePath: string): AsyncGenerator { + let size: number + try { + size = (await stat(filePath)).size + } catch (err) { + warn(`stat failed for ${filePath}: ${(err as NodeJS.ErrnoException).code ?? 'unknown'}`) + return + } + + if (size > MAX_SESSION_FILE_BYTES) { + warn(`skipped oversize file ${filePath} (${size} bytes > cap ${MAX_SESSION_FILE_BYTES})`) + return + } + + const stream = createReadStream(filePath, { encoding: 'utf-8' }) + const rl = createInterface({ input: stream, crlfDelay: Infinity }) + try { + for await (const line of rl) yield line + } catch (err) { + warn(`stream read failed for ${filePath}: ${(err as NodeJS.ErrnoException).code ?? 'unknown'}`) + } +} From ee738a1b26d3cd8e538ee53cb2f1b679c3529725 Mon Sep 17 00:00:00 2001 From: Ninym Date: Fri, 17 Apr 2026 08:05:28 +0200 Subject: [PATCH 30/70] fix(parser): use bounded readSessionFile helper Replaces the unbounded readFile in parseSessionFile with the 128 MB-capped helper from src/fs-utils. Addresses MEDIUM-1 for the Claude provider hot path. Verbose-mode stderr output replaces the previous silent catch, closing LOW-1 as a side effect. --- src/parser.ts | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/parser.ts b/src/parser.ts index 6b39fc8..5ba0da9 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -1,5 +1,6 @@ -import { readdir, readFile } from 'fs/promises' +import { readdir } from 'fs/promises' import { basename, join } from 'path' +import { readSessionFile } from './fs-utils.js' import { calculateCost, getShortModelName } from './models.js' import { discoverAllSessions, getProvider } from './providers/index.js' import type { ParsedProviderCall } from './providers/types.js' @@ -265,12 +266,8 @@ async function parseSessionFile( seenMsgIds: Set, dateRange?: DateRange, ): Promise { - let content: string - try { - content = await readFile(filePath, 'utf-8') - } catch { - return null - } + const content = await readSessionFile(filePath) + if (content === null) return null const lines = content.split('\n').filter(l => l.trim()) const entries: JournalEntry[] = [] From 1de0baf3295b30971714408076399fa9f899cecc Mon Sep 17 00:00:00 2001 From: Ninym Date: Fri, 17 Apr 2026 08:07:57 +0200 Subject: [PATCH 31/70] fix(codex): use bounded readSessionFile helper Both Codex session read paths (first-line meta and full-session parse) now pass through the 128 MB-capped helper. MEDIUM-1 coverage for the Codex provider. --- src/providers/codex.ts | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/src/providers/codex.ts b/src/providers/codex.ts index bf64e52..01d48b7 100644 --- a/src/providers/codex.ts +++ b/src/providers/codex.ts @@ -1,7 +1,8 @@ -import { readdir, readFile, stat } from 'fs/promises' +import { readdir, stat } from 'fs/promises' import { basename, join } from 'path' import { homedir } from 'os' +import { readSessionFile } from '../fs-utils.js' import { calculateCost } from '../models.js' import type { Provider, SessionSource, SessionParser, ParsedProviderCall } from './types.js' @@ -65,10 +66,11 @@ function sanitizeProject(cwd: string): string { } async function readFirstLine(filePath: string): Promise { + const content = await readSessionFile(filePath) + if (content === null) return null + const line = content.split('\n')[0] + if (!line?.trim()) return null try { - const content = await readFile(filePath, 'utf-8') - const line = content.split('\n')[0] - if (!line?.trim()) return null return JSON.parse(line) as CodexEntry } catch { return null @@ -139,13 +141,8 @@ function resolveModel(info: CodexEntry['payload'], sessionModel?: string): strin function createParser(source: SessionSource, seenKeys: Set): SessionParser { return { async *parse(): AsyncGenerator { - let content: string - try { - content = await readFile(source.path, 'utf-8') - } catch { - return - } - + const content = await readSessionFile(source.path) + if (content === null) return const lines = content.split('\n').filter(l => l.trim()) let sessionModel: string | undefined let sessionId = '' From 9f6827d52834473b24adc4e70e1650e01409cfdf Mon Sep 17 00:00:00 2001 From: Ninym Date: Fri, 17 Apr 2026 08:08:26 +0200 Subject: [PATCH 32/70] fix(copilot): use bounded readSessionFile helper Events JSONL and workspace.yaml reads now pass through the 128 MB-capped helper. The workspace.yaml path stays non-fatal: a null read skips cwd derivation but still pushes the session with sessionId as the fallback project label. MEDIUM-1 coverage for the Copilot provider. --- src/providers/copilot.ts | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/src/providers/copilot.ts b/src/providers/copilot.ts index 9cb7983..f32738f 100644 --- a/src/providers/copilot.ts +++ b/src/providers/copilot.ts @@ -1,7 +1,8 @@ -import { readdir, readFile, stat } from 'fs/promises' +import { readdir, stat } from 'fs/promises' import { basename, dirname, join } from 'path' import { homedir } from 'os' +import { readSessionFile } from '../fs-utils.js' import { calculateCost } from '../models.js' import type { Provider, SessionSource, SessionParser, ParsedProviderCall } from './types.js' @@ -85,13 +86,8 @@ function parseCwd(yaml: string): string | null { function createParser(source: SessionSource, seenKeys: Set): SessionParser { return { async *parse(): AsyncGenerator { - let content: string - try { - content = await readFile(source.path, 'utf-8') - } catch { - return - } - + const content = await readSessionFile(source.path) + if (content === null) return const sessionId = basename(dirname(source.path)) const lines = content.split('\n').filter(l => l.trim()) let currentModel = '' @@ -177,11 +173,11 @@ async function discoverSessionsInDir(sessionStateDir: string): Promise Date: Fri, 17 Apr 2026 08:08:54 +0200 Subject: [PATCH 33/70] fix(pi): use bounded readSessionFile helper Both Pi session read paths (first-entry meta and full-session parse) now pass through the 128 MB-capped helper. MEDIUM-1 coverage for the Pi provider. --- src/providers/pi.ts | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/src/providers/pi.ts b/src/providers/pi.ts index 4fb42cf..92af213 100644 --- a/src/providers/pi.ts +++ b/src/providers/pi.ts @@ -1,7 +1,8 @@ -import { readdir, readFile, stat } from 'fs/promises' +import { readdir, stat } from 'fs/promises' import { basename, join } from 'path' import { homedir } from 'os' +import { readSessionFile } from '../fs-utils.js' import { calculateCost } from '../models.js' import { extractBashCommands } from '../bash-utils.js' import type { Provider, SessionSource, SessionParser, ParsedProviderCall } from './types.js' @@ -56,10 +57,11 @@ function getPiSessionsDir(override?: string): string { } async function readFirstEntry(filePath: string): Promise { + const content = await readSessionFile(filePath) + if (content === null) return null + const line = content.split('\n')[0] + if (!line?.trim()) return null try { - const content = await readFile(filePath, 'utf-8') - const line = content.split('\n')[0] - if (!line?.trim()) return null return JSON.parse(line) as PiEntry } catch { return null @@ -108,13 +110,8 @@ async function discoverSessionsInDir(sessionsDir: string): Promise): SessionParser { return { async *parse(): AsyncGenerator { - let content: string - try { - content = await readFile(source.path, 'utf-8') - } catch { - return - } - + const content = await readSessionFile(source.path) + if (content === null) return const lines = content.split('\n').filter(l => l.trim()) let sessionId = basename(source.path, '.jsonl') let pendingUserMessage = '' From 1bdbac49270880d241952c13801cceedbd81f786 Mon Sep 17 00:00:00 2001 From: Ninym Date: Fri, 17 Apr 2026 08:09:25 +0200 Subject: [PATCH 34/70] fix(context-budget): use bounded readSessionFile helper Config JSON, CLAUDE.md scans, and session-discovery reads now pass through the 128 MB-capped helper. JSON.parse remains wrapped in try/catch to preserve the previous 'null on malformed JSON' contract. MEDIUM-1 coverage for the context-budget module. --- src/context-budget.ts | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/src/context-budget.ts b/src/context-budget.ts index 3db8e95..b5c72d6 100644 --- a/src/context-budget.ts +++ b/src/context-budget.ts @@ -1,8 +1,10 @@ -import { readdir, readFile } from 'fs/promises' +import { readdir } from 'fs/promises' import { existsSync } from 'fs' import { join } from 'path' import { homedir } from 'os' +import { readSessionFile } from './fs-utils.js' + const CHARS_PER_TOKEN = 4 const SYSTEM_BASE_TOKENS = 10400 const TOOL_TOKENS_OVERHEAD = 400 @@ -23,9 +25,9 @@ function estimateTokens(text: string): number { async function readConfigFile(path: string): Promise | null> { if (!existsSync(path)) return null - try { - return JSON.parse(await readFile(path, 'utf-8')) - } catch { return null } + const raw = await readSessionFile(path) + if (raw === null) return null + try { return JSON.parse(raw) } catch { return null } } async function countMcpTools(projectPath?: string): Promise { @@ -91,10 +93,9 @@ async function scanMemoryFiles(projectPath?: string): Promise } export async function discoverProjectCwd(sessionDir: string): Promise { + let files: string[] try { - const files = (await readdir(sessionDir)).filter(f => f.endsWith('.jsonl')) - if (files.length === 0) return null - const content = await readFile(join(sessionDir, files[0]), 'utf-8') - for (const line of content.split('\n')) { - if (!line.trim()) continue - try { - const entry = JSON.parse(line) - if (entry.cwd && typeof entry.cwd === 'string') return entry.cwd - } catch { continue } - } + files = (await readdir(sessionDir)).filter(f => f.endsWith('.jsonl')) } catch { return null } + if (files.length === 0) return null + const content = await readSessionFile(join(sessionDir, files[0])) + if (content === null) return null + for (const line of content.split('\n')) { + if (!line.trim()) continue + try { + const entry = JSON.parse(line) + if (entry.cwd && typeof entry.cwd === 'string') return entry.cwd + } catch { continue } + } return null } From 216782391a2a755435dc009a4c36e621ee7a3aa8 Mon Sep 17 00:00:00 2001 From: Ninym Date: Fri, 17 Apr 2026 08:10:20 +0200 Subject: [PATCH 35/70] fix(optimize): use bounded read helpers All four read paths in the optimizer (async session scan + three sync config/import/profile scans) now pass through the 128 MB-capped helpers. JSON.parse in readJsonFile stays wrapped in try/catch. MEDIUM-1 coverage for the optimize module. --- src/optimize.ts | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/optimize.ts b/src/optimize.ts index fa8ff8e..433cb99 100644 --- a/src/optimize.ts +++ b/src/optimize.ts @@ -1,9 +1,10 @@ import chalk from 'chalk' -import { readdir, readFile, stat } from 'fs/promises' -import { existsSync, readFileSync, statSync } from 'fs' +import { readdir, stat } from 'fs/promises' +import { existsSync, statSync } from 'fs' import { basename, join } from 'path' import { homedir } from 'os' +import { readSessionFile, readSessionFileSync } from './fs-utils.js' import { discoverAllSessions } from './providers/index.js' import type { DateRange, ProjectSummary } from './types.js' import { formatCost } from './currency.js' @@ -227,10 +228,8 @@ export async function scanJsonlFile( dateRange: DateRange | undefined, recentCutoffMs = Date.now() - RECENT_WINDOW_MS, ): Promise { - let content: string - try { - content = await readFile(filePath, 'utf-8') - } catch { return { calls: [], cwds: [], apiCalls: [], userMessages: [] } } + const content = await readSessionFile(filePath) + if (content === null) return { calls: [], cwds: [], apiCalls: [], userMessages: [] } const calls: ToolCall[] = [] const cwds: string[] = [] @@ -328,7 +327,9 @@ async function scanSessions(dateRange?: DateRange): Promise { // ============================================================================ function readJsonFile(path: string): Record | null { - try { return JSON.parse(readFileSync(path, 'utf-8')) } catch { return null } + const raw = readSessionFileSync(path) + if (raw === null) return null + try { return JSON.parse(raw) } catch { return null } } function shortHomePath(absPath: string): string { @@ -571,8 +572,8 @@ export function detectMissingClaudeignore(projectCwds: Set): WasteFindin function expandImports(filePath: string, seen: Set, depth: number): { totalLines: number; importedFiles: number } { if (depth > MAX_IMPORT_DEPTH || seen.has(filePath)) return { totalLines: 0, importedFiles: 0 } seen.add(filePath) - let content: string - try { content = readFileSync(filePath, 'utf-8') } catch { return { totalLines: 0, importedFiles: 0 } } + const content = readSessionFileSync(filePath) + if (content === null) return { totalLines: 0, importedFiles: 0 } let totalLines = content.split('\n').length let importedFiles = 0 @@ -865,11 +866,10 @@ function readShellProfileLimit(): number | null { for (const profile of SHELL_PROFILES) { const path = join(homedir(), profile) if (!existsSync(path)) continue - try { - const content = readFileSync(path, 'utf-8') - const match = content.match(/^\s*export\s+BASH_MAX_OUTPUT_LENGTH\s*=\s*['"]?(\d+)['"]?/m) - if (match) return parseInt(match[1], 10) - } catch { continue } + const content = readSessionFileSync(path) + if (content === null) continue + const match = content.match(/^\s*export\s+BASH_MAX_OUTPUT_LENGTH\s*=\s*['"]?(\d+)['"]?/m) + if (match) return parseInt(match[1], 10) } return null } From 71461fb352850df5974c2e515ba03e5e536ba50f Mon Sep 17 00:00:00 2001 From: Ninym Date: Fri, 17 Apr 2026 08:10:52 +0200 Subject: [PATCH 36/70] test(security): add failing test for MEDIUM-2 menubar injection Three cases (pipe-in-model, ANSI-in-model, pipe-in-category) reproduce the audit's SwiftBar directive-separator attack. Tests fail against current menubar.ts -- Task 13 will close with an allowlist sanitizer. --- tests/security/menubar-injection.test.ts | 47 ++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 tests/security/menubar-injection.test.ts diff --git a/tests/security/menubar-injection.test.ts b/tests/security/menubar-injection.test.ts new file mode 100644 index 0000000..d8de96d --- /dev/null +++ b/tests/security/menubar-injection.test.ts @@ -0,0 +1,47 @@ +import { describe, it, expect } from 'vitest' + +import { renderMenubarFormat, type PeriodData } from '../../src/menubar.js' + +const ESC = '\u001b' + +function period(name: string): PeriodData { + return { + label: 'x', + cost: 0.01, + calls: 1, + inputTokens: 1, + outputTokens: 1, + cacheReadTokens: 0, + cacheWriteTokens: 0, + categories: [{ name, cost: 0.01, turns: 1, editTurns: 0, oneShotTurns: 1 }], + models: [{ name, cost: 0.01, calls: 1 }], + } +} + +function linesWithToken(output: string, token: string): string[] { + return output.split('\n').filter(l => l.includes(token)) +} + +describe('MEDIUM-2 menubar directive separator injection', () => { + it('strips pipe separators from model names', () => { + const p = period('foo | href=https://attacker.example/pwn') + const out = renderMenubarFormat(p, p, p, p) + for (const line of linesWithToken(out, 'foo')) { + expect(line.split('|').length).toBeLessThanOrEqual(2) + } + }) + + it('strips ANSI escapes from model names', () => { + const p = period(`foo${ESC}[31mMODEL${ESC}[0m`) + const out = renderMenubarFormat(p, p, p, p) + expect(out).not.toContain(ESC) + }) + + it('strips pipe separators from category names', () => { + const p = period('cat | color=red') + const out = renderMenubarFormat(p, p, p, p) + for (const line of linesWithToken(out, 'cat')) { + expect(line.split('|').length).toBeLessThanOrEqual(2) + } + }) +}) From 646635c262c4b9215113fefc4fa2292d6e28c35f Mon Sep 17 00:00:00 2001 From: Ninym Date: Fri, 17 Apr 2026 08:11:32 +0200 Subject: [PATCH 37/70] fix(menubar): sanitize SwiftBar labels via allowlist Replaces any character outside [A-Za-z0-9 ._/-] with ? in model and category labels and truncates to 14 chars before padEnd. Closes the MEDIUM-2 finding from the 2026-04-16 audit: an attacker-controlled JSONL with a crafted model name no longer injects SwiftBar directives or ANSI escapes. --- src/menubar.ts | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/src/menubar.ts b/src/menubar.ts index a5abb5d..51d7e41 100644 --- a/src/menubar.ts +++ b/src/menubar.ts @@ -10,6 +10,16 @@ const PLUGIN_REFRESH = '5m' const SWIFTBAR_PREFERENCES_DOMAIN = 'com.ameba.SwiftBar' const SWIFTBAR_PLUGIN_DIRECTORY_KEY = 'PluginDirectory' +const MENUBAR_LABEL_MAX_LENGTH = 14 +const MENUBAR_LABEL_ALLOWLIST = /[^A-Za-z0-9 ._/-]/g + +// SwiftBar/xbar parse `|` as the metadata separator and interpret ANSI escapes +// on some paths. Replace anything outside a conservative allowlist with `?` +// and truncate before padEnd. +function sanitizeMenubarLabel(name: string): string { + return name.replace(MENUBAR_LABEL_ALLOWLIST, '?').slice(0, MENUBAR_LABEL_MAX_LENGTH) +} + function getSwiftBarPluginDir(): string { return join(homedir(), 'Library', 'Application Support', 'SwiftBar', 'plugins') } @@ -138,7 +148,7 @@ export function renderMenubarFormat( lines.push(`Activity - Today | size=12 color=#FF8C42`) for (const cat of today.categories.slice(0, 8)) { const bar = miniBar(cat.cost, maxCat) - const name = cat.name.padEnd(14) + const name = sanitizeMenubarLabel(cat.name).padEnd(14) lines.push(`${bar} ${name} ${formatCost(cat.cost).padStart(8)} ${String(cat.turns).padStart(4)} turns | font=Menlo size=11`) } lines.push('---') @@ -148,7 +158,7 @@ export function renderMenubarFormat( for (const model of today.models.slice(0, 5)) { if (model.name === '') continue const bar = miniBar(model.cost, maxModel) - const name = model.name.padEnd(14) + const name = sanitizeMenubarLabel(model.name).padEnd(14) lines.push(`${bar} ${name} ${formatCost(model.cost).padStart(8)} ${String(model.calls).padStart(5)} calls | font=Menlo size=11`) } @@ -164,7 +174,7 @@ export function renderMenubarFormat( lines.push(`--Activity | size=12 color=#FF8C42`) for (const cat of week.categories.slice(0, 8)) { const bar = miniBar(cat.cost, weekMaxCat) - const name = cat.name.padEnd(14) + const name = sanitizeMenubarLabel(cat.name).padEnd(14) lines.push(`--${bar} ${name} ${formatCost(cat.cost).padStart(8)} ${String(cat.turns).padStart(4)} turns | font=Menlo size=11`) } lines.push(`-----`) @@ -172,7 +182,7 @@ export function renderMenubarFormat( for (const model of week.models.slice(0, 5)) { if (model.name === '') continue const bar = miniBar(model.cost, weekMaxModel) - const name = model.name.padEnd(14) + const name = sanitizeMenubarLabel(model.name).padEnd(14) lines.push(`--${bar} ${name} ${formatCost(model.cost).padStart(8)} ${String(model.calls).padStart(5)} calls | font=Menlo size=11`) } @@ -182,7 +192,7 @@ export function renderMenubarFormat( lines.push(`--Activity | size=12 color=#FF8C42`) for (const cat of thirtyDays.categories.slice(0, 8)) { const bar = miniBar(cat.cost, tdMaxCat) - const name = cat.name.padEnd(14) + const name = sanitizeMenubarLabel(cat.name).padEnd(14) lines.push(`--${bar} ${name} ${formatCost(cat.cost).padStart(8)} ${String(cat.turns).padStart(4)} turns | font=Menlo size=11`) } lines.push(`-----`) @@ -190,7 +200,7 @@ export function renderMenubarFormat( for (const model of thirtyDays.models.slice(0, 5)) { if (model.name === '') continue const bar = miniBar(model.cost, tdMaxModel) - const name = model.name.padEnd(14) + const name = sanitizeMenubarLabel(model.name).padEnd(14) lines.push(`--${bar} ${name} ${formatCost(model.cost).padStart(8)} ${String(model.calls).padStart(5)} calls | font=Menlo size=11`) } @@ -200,7 +210,7 @@ export function renderMenubarFormat( lines.push(`--Activity | size=12 color=#FF8C42`) for (const cat of month.categories.slice(0, 8)) { const bar = miniBar(cat.cost, monthMaxCat) - const name = cat.name.padEnd(14) + const name = sanitizeMenubarLabel(cat.name).padEnd(14) lines.push(`--${bar} ${name} ${formatCost(cat.cost).padStart(8)} ${String(cat.turns).padStart(4)} turns | font=Menlo size=11`) } lines.push(`-----`) @@ -208,7 +218,7 @@ export function renderMenubarFormat( for (const model of month.models.slice(0, 5)) { if (model.name === '') continue const bar = miniBar(model.cost, monthMaxModel) - const name = model.name.padEnd(14) + const name = sanitizeMenubarLabel(model.name).padEnd(14) lines.push(`--${bar} ${name} ${formatCost(model.cost).padStart(8)} ${String(model.calls).padStart(5)} calls | font=Menlo size=11`) } From 8f5927153e04c96b75c425237023e76cabacd1ac Mon Sep 17 00:00:00 2001 From: Ninym Date: Fri, 17 Apr 2026 08:12:09 +0200 Subject: [PATCH 38/70] feat(cli): add --verbose flag for stderr warnings Sets CODEBURN_VERBOSE=1 via commander preAction, which the fs-utils helpers check before emitting stderr lines on skipped or failed reads. Closes LOW-1 from the 2026-04-16 audit. --- src/cli.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/cli.ts b/src/cli.ts index c1d2308..342a9f2 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -78,8 +78,12 @@ const program = new Command() .name('codeburn') .description('See where your AI coding tokens go - by task, tool, model, and project') .version(version) + .option('--verbose', 'print warnings to stderr on read failures and skipped files') -program.hook('preAction', async () => { +program.hook('preAction', async (thisCommand) => { + if (thisCommand.opts<{ verbose?: boolean }>().verbose) { + process.env['CODEBURN_VERBOSE'] = '1' + } await loadCurrency() }) From d5ecedb1887a10a12b616b5b8d0e0ffefef6d620 Mon Sep 17 00:00:00 2001 From: Ninym Date: Fri, 17 Apr 2026 08:36:24 +0200 Subject: [PATCH 39/70] chore(git): ignore local .claude/ directory Prevents agent-scratchpad files under .claude/ from being accidentally staged by tooling. Matches the existing pattern for docs/superpowers/. --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index bc8b930..110cddd 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,7 @@ Thumbs.db # Planning artifacts (internal, not shipped) docs/superpowers/ +.claude/ # Config / secrets .env From 09cea9bc7964e2e6e82cce7e67f1ba11a122a301 Mon Sep 17 00:00:00 2001 From: AgentSeal Date: Fri, 17 Apr 2026 05:08:37 -0700 Subject: [PATCH 40/70] chore: release 0.7.1 security hardening --- CHANGELOG.md | 12 ++++++++++++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aa90735..0e49607 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ # Changelog +## 0.7.1 - 2026-04-17 + +### Security +- **External security audit closed.** 1 HIGH, 2 MEDIUM, and 1 LOW finding fixed. Threat model: a compromised third-party AI CLI with write access to `~/.claude/projects/` dropping malicious session JSONL. +- **Prototype pollution blocked.** Breakdown maps in `parser.ts` (model, tool, MCP, bash) now use `Object.create(null)` so attacker-controlled keys like `__proto__` create own properties instead of mutating `Object.prototype`. Credit: @lfl1337 (PR #67). +- **Bounded session-file reads.** New `src/fs-utils.ts` helper caps reads at 128 MB and switches to stream-based parsing above 8 MB. Applied to 13 reachable read sites across parser, Codex, Copilot, Pi, context-budget, and optimize. Credit: @lfl1337 (PR #67). +- **Menubar label sanitizer.** SwiftBar directive-separator (`|`) and ANSI escape injection via crafted model or category names is now prevented by an allowlist (`[A-Za-z0-9 ._/-]`) plus 14-character truncation. Credit: @lfl1337 (PR #67). + +### Added +- **`--verbose` flag.** Global CLI option that prints warnings to stderr on skipped (oversize) or failed session-file reads. Silent by default. Credit: @lfl1337 (PR #67). +- **11 new security tests.** `tests/security/prototype-pollution.test.ts`, `tests/security/menubar-injection.test.ts`, `tests/fs-utils.test.ts`. Total suite: 209 tests. + ## 0.7.0 - 2026-04-16 ### Added diff --git a/package-lock.json b/package-lock.json index e9a6b9c..c4ffcb6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "codeburn", - "version": "0.7.0", + "version": "0.7.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "codeburn", - "version": "0.7.0", + "version": "0.7.1", "license": "MIT", "dependencies": { "chalk": "^5.4.1", diff --git a/package.json b/package.json index 15cb1bf..06932e4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "codeburn", - "version": "0.7.0", + "version": "0.7.1", "description": "See where your AI coding tokens go - by task, tool, model, and project", "type": "module", "main": "./dist/cli.js", From 69268a9e91648f1261587488637ab9010203e2c4 Mon Sep 17 00:00:00 2001 From: AgentSeal Date: Fri, 17 Apr 2026 05:24:16 -0700 Subject: [PATCH 41/70] docs: remove .claudeignore references from README --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 5eaf2c4..151a090 100644 --- a/README.md +++ b/README.md @@ -227,14 +227,13 @@ codeburn optimize --provider claude # restrict to one provider - Files Claude re-reads across sessions (same content, same context, over and over) - Low Read:Edit ratio (editing without reading leads to retries and wasted tokens) -- Projects missing a `.claudeignore` (Claude wanders into `node_modules`, `.git`, build dirs) - Wasted bash output (uncapped `BASH_MAX_OUTPUT_LENGTH`, trailing noise) - Unused MCP servers still paying their tool-schema overhead every session - Ghost agents, skills, and slash commands defined in `~/.claude/` but never invoked - Bloated `CLAUDE.md` files (with `@-import` expansion counted) - Cache creation overhead and junk directory reads -Each finding shows the estimated token and dollar savings plus a ready-to-paste fix: a `CLAUDE.md` line, a `.claudeignore` template, an environment variable, or a `mv` command to archive unused items. Findings are ranked by urgency (impact weighted against observed waste) and rolled up into an A-F setup health grade. Repeat runs classify each finding as new, improving, or resolved against a 48-hour recent window. +Each finding shows the estimated token and dollar savings plus a ready-to-paste fix: a `CLAUDE.md` line, an environment variable, or a `mv` command to archive unused items. Findings are ranked by urgency (impact weighted against observed waste) and rolled up into an A-F setup health grade. Repeat runs classify each finding as new, improving, or resolved against a 48-hour recent window. You can also open it inline from the dashboard: press `o` when a finding count appears in the status bar, `b` to return. From 495a25433838ca577f92fe83ca383c31adfb61b4 Mon Sep 17 00:00:00 2001 From: Resham Joshi Date: Fri, 17 Apr 2026 16:55:56 -0700 Subject: [PATCH 42/70] feat(mac): native Swift menubar app + one-command install Introduces mac/ with a native SwiftUI menubar app that replaces the previous SwiftBar plugin entirely. Install via `npx codeburn menubar`, which downloads the .app from GitHub Releases, strips Gatekeeper quarantine, and drops it into ~/Applications. Highlights - mac/ SwiftUI app: agent tabs, Today/7/30/Month/All period switcher, Trend/Forecast/Pulse/Stats/Plan insights, activity + model breakdowns, optimize findings, CSV/JSON export, Star-on-GitHub banner, live 60s refresh, instant currency switching with offline FX cache. - Security: CodeburnCLI argv-based spawn (no shell interpretation), SafeFile symlink guards + O_NOFOLLOW writes, FX rate clamping to [0.0001, 1_000_000], keychain filtered to account == "default", removed byte-window credential log, in-flight refresh guard, POSIX flock on config.json writes, TerminalLauncher validates argv before AppleScript interpolation. - Performance: shared static NumberFormatter (thousands of allocations per popover redraw eliminated), concurrent pipe drain with 20 MB cap + 60s timeout in DataClient, Observation-tracked reactive UI, 5-min payload cache keyed on (period, provider). - CLI: new `codeburn menubar` subcommand that downloads + installs + launches the .app (no clone, no build). New `status --format menubar-json` payload builder. `export` rewritten to produce a folder of one-table-per-file CSVs with a `.codeburn-export` marker so arbitrary -o paths cannot be silently deleted. - Removed: src/menubar.ts (SwiftBar plugin generator), install-menubar / uninstall-menubar subcommands, `status --format menubar` directive output, tests/menubar.test.ts, tests/security/menubar-injection.test.ts. - Release: .github/workflows/release-menubar.yml builds universal binary, assembles .app, ad-hoc signs, zips, uploads on mac-v* tag push. Runs on the free macos-latest runner. Tests - 230 TypeScript tests pass - 10 Swift CapacityEstimator tests pass - TypeScript typecheck clean - Swift release build clean --- .github/workflows/release-menubar.yml | 70 + README.md | 11 +- assets/menubar.png | Bin 304605 -> 307483 bytes mac/.gitignore | 6 + mac/Package.swift | 29 + mac/README.md | 88 ++ mac/Scripts/package-app.sh | 103 ++ mac/Sources/CodeBurnMenubar/AppStore.swift | 307 +++++ mac/Sources/CodeBurnMenubar/CodeBurnApp.swift | 182 +++ .../CodeBurnMenubar/CurrencyState.swift | 209 +++ .../Data/CapacityEstimator.swift | 127 ++ .../CodeBurnMenubar/Data/DataClient.swift | 107 ++ .../CodeBurnMenubar/Data/MenubarPayload.swift | 123 ++ .../Data/SubscriptionClient.swift | 306 +++++ .../Data/SubscriptionSnapshotStore.swift | 102 ++ .../Data/SubscriptionUsage.swift | 46 + .../Security/CodeburnCLI.swift | 59 + .../CodeBurnMenubar/Security/SafeFile.swift | 128 ++ .../Security/TerminalLauncher.swift | 40 + mac/Sources/CodeBurnMenubar/Theme/Theme.swift | 32 + .../Views/ActivitySection.swift | 87 ++ .../CodeBurnMenubar/Views/AgentTabStrip.swift | 92 ++ .../Views/FindingsSection.swift | 290 ++++ .../Views/HeatmapSection.swift | 1219 +++++++++++++++++ .../CodeBurnMenubar/Views/HeroSection.swift | 55 + .../Views/MenuBarContent.swift | 401 ++++++ .../CodeBurnMenubar/Views/ModelsSection.swift | 97 ++ .../Views/PeriodSegmentedControl.swift | 36 + .../Views/SectionCaption.swift | 85 ++ .../CodeBurnMenubar/Views/SparklineView.swift | 99 ++ .../CapacityEstimatorTests.swift | 158 +++ src/cli.ts | 217 ++- src/currency.ts | 25 +- src/daily-cache.ts | 118 ++ src/day-aggregator.ts | 142 ++ src/export.ts | 310 +++-- src/menubar-installer.ts | 173 +++ src/menubar-json.ts | 182 +++ src/menubar.ts | 334 ----- src/parser.ts | 17 +- tests/daily-cache.test.ts | 189 +++ tests/day-aggregator.test.ts | 258 ++++ tests/export.test.ts | 11 +- tests/menubar-json.test.ts | 234 ++++ tests/menubar.test.ts | 57 - tests/security/menubar-injection.test.ts | 47 - 46 files changed, 6433 insertions(+), 575 deletions(-) create mode 100644 .github/workflows/release-menubar.yml create mode 100644 mac/.gitignore create mode 100644 mac/Package.swift create mode 100644 mac/README.md create mode 100755 mac/Scripts/package-app.sh create mode 100644 mac/Sources/CodeBurnMenubar/AppStore.swift create mode 100644 mac/Sources/CodeBurnMenubar/CodeBurnApp.swift create mode 100644 mac/Sources/CodeBurnMenubar/CurrencyState.swift create mode 100644 mac/Sources/CodeBurnMenubar/Data/CapacityEstimator.swift create mode 100644 mac/Sources/CodeBurnMenubar/Data/DataClient.swift create mode 100644 mac/Sources/CodeBurnMenubar/Data/MenubarPayload.swift create mode 100644 mac/Sources/CodeBurnMenubar/Data/SubscriptionClient.swift create mode 100644 mac/Sources/CodeBurnMenubar/Data/SubscriptionSnapshotStore.swift create mode 100644 mac/Sources/CodeBurnMenubar/Data/SubscriptionUsage.swift create mode 100644 mac/Sources/CodeBurnMenubar/Security/CodeburnCLI.swift create mode 100644 mac/Sources/CodeBurnMenubar/Security/SafeFile.swift create mode 100644 mac/Sources/CodeBurnMenubar/Security/TerminalLauncher.swift create mode 100644 mac/Sources/CodeBurnMenubar/Theme/Theme.swift create mode 100644 mac/Sources/CodeBurnMenubar/Views/ActivitySection.swift create mode 100644 mac/Sources/CodeBurnMenubar/Views/AgentTabStrip.swift create mode 100644 mac/Sources/CodeBurnMenubar/Views/FindingsSection.swift create mode 100644 mac/Sources/CodeBurnMenubar/Views/HeatmapSection.swift create mode 100644 mac/Sources/CodeBurnMenubar/Views/HeroSection.swift create mode 100644 mac/Sources/CodeBurnMenubar/Views/MenuBarContent.swift create mode 100644 mac/Sources/CodeBurnMenubar/Views/ModelsSection.swift create mode 100644 mac/Sources/CodeBurnMenubar/Views/PeriodSegmentedControl.swift create mode 100644 mac/Sources/CodeBurnMenubar/Views/SectionCaption.swift create mode 100644 mac/Sources/CodeBurnMenubar/Views/SparklineView.swift create mode 100644 mac/Tests/CodeBurnMenubarTests/CapacityEstimatorTests.swift create mode 100644 src/daily-cache.ts create mode 100644 src/day-aggregator.ts create mode 100644 src/menubar-installer.ts create mode 100644 src/menubar-json.ts delete mode 100644 src/menubar.ts create mode 100644 tests/daily-cache.test.ts create mode 100644 tests/day-aggregator.test.ts create mode 100644 tests/menubar-json.test.ts delete mode 100644 tests/menubar.test.ts delete mode 100644 tests/security/menubar-injection.test.ts diff --git a/.github/workflows/release-menubar.yml b/.github/workflows/release-menubar.yml new file mode 100644 index 0000000..df8fd31 --- /dev/null +++ b/.github/workflows/release-menubar.yml @@ -0,0 +1,70 @@ +name: Release macOS Menubar + +# Triggers on a `mac-v*` tag push (e.g. `git tag mac-v0.8.0 && git push origin mac-v0.8.0`), +# or manually via the Actions tab. Runs entirely on the free macos-latest runner -- no Apple +# Developer Program membership, no signing certificates, no secrets required. The bundle ships +# ad-hoc signed; `npx codeburn menubar` strips the download quarantine flag on install so +# Gatekeeper stays quiet. +on: + push: + tags: + - 'mac-v*' + workflow_dispatch: + inputs: + version: + description: 'Version label for the bundle (e.g. v0.8.0 or dev-preview)' + required: true + default: 'dev-preview' + +permissions: + contents: write # Needed to create the release + upload assets. + +jobs: + build: + runs-on: macos-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Resolve version label + id: version + run: | + if [[ "${GITHUB_REF}" == refs/tags/mac-v* ]]; then + echo "value=${GITHUB_REF#refs/tags/mac-}" >> "$GITHUB_OUTPUT" + else + echo "value=${{ github.event.inputs.version }}" >> "$GITHUB_OUTPUT" + fi + + - name: Show Swift toolchain + run: swift --version + + - name: Build + bundle + zip + run: mac/Scripts/package-app.sh "${{ steps.version.outputs.value }}" + + - name: Upload artifact (for manual runs) + if: github.event_name == 'workflow_dispatch' + uses: actions/upload-artifact@v4 + with: + name: CodeBurnMenubar-${{ steps.version.outputs.value }} + path: mac/.build/dist/CodeBurnMenubar-*.zip + if-no-files-found: error + + - name: Create / update GitHub Release + if: startsWith(github.ref, 'refs/tags/mac-v') + uses: softprops/action-gh-release@v2 + with: + tag_name: ${{ github.ref_name }} + name: Menubar ${{ steps.version.outputs.value }} + body: | + Install with: + + ``` + npx codeburn menubar + ``` + + Unsigned build. The installer clears Gatekeeper quarantine on download, so the + app launches without warnings. Direct-download users from this page may see + "cannot verify developer" -- right-click → Open once to dismiss it, or use the + npx command above. + files: mac/.build/dist/CodeBurnMenubar-*.zip + fail_on_unmatched_files: true diff --git a/README.md b/README.md index 151a090..4b6e167 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ CodeBurn TUI dashboard

-By task type, tool, model, MCP server, and project. Supports **Claude Code**, **Codex** (OpenAI), **Cursor**, **OpenCode**, **Pi**, and **GitHub Copilot** with a provider plugin system. Tracks one-shot success rate per activity type so you can see where the AI nails it first try vs. burns tokens on edit/test/fix retries. Interactive TUI dashboard with gradient charts, responsive panels, and keyboard navigation. macOS menu bar widget via SwiftBar. CSV/JSON export. +By task type, tool, model, MCP server, and project. Supports **Claude Code**, **Codex** (OpenAI), **Cursor**, **OpenCode**, **Pi**, and **GitHub Copilot** with a provider plugin system. Tracks one-shot success rate per activity type so you can see where the AI nails it first try vs. burns tokens on edit/test/fix retries. Interactive TUI dashboard with gradient charts, responsive panels, and keyboard navigation. Native macOS menubar app in `mac/`. CSV/JSON export. Works by reading session data directly from disk. No wrapper, no proxy, no API keys. Pricing from LiteLLM (auto-cached, all models supported). @@ -156,14 +156,13 @@ The menu bar widget includes a currency picker with 17 common currencies. For an ## Menu Bar -CodeBurn SwiftBar menu bar widget +CodeBurn macOS menubar app ```bash -codeburn install-menubar # install SwiftBar/xbar plugin -codeburn uninstall-menubar # remove it +npx codeburn menubar ``` -Requires [SwiftBar](https://github.com/swiftbar/SwiftBar) (`brew install --cask swiftbar`). Shows today's cost in the menu bar with a flame icon. Dropdown shows activity breakdown, model costs, token stats, per-provider cost breakdown, and a currency picker. Refreshes every 5 minutes. +One command: downloads the latest `.app`, installs into `~/Applications`, and launches it. Re-run with `--force` to reinstall. Native Swift + SwiftUI app lives in `mac/` (see `mac/README.md` for build details). Shows today's cost with a flame icon, opens a popover with agent tabs, period switcher (Today / 7 Days / 30 Days / Month / All), Trend / Forecast / Pulse / Stats / Plan insights, activity and model breakdowns, optimize findings, and CSV/JSON export. Refreshes live via FSEvents plus a 60-second poll. ## What it tracks @@ -269,7 +268,7 @@ src/ classifier.ts 13-category task classifier types.ts Type definitions format.ts Text rendering (status bar) - menubar.ts SwiftBar plugin generator + menubar-json.ts Payload builder consumed by the native macOS menubar app in mac/ export.ts CSV/JSON multi-period export config.ts Config file management (~/.config/codeburn/) currency.ts Currency conversion, exchange rates, Intl formatting diff --git a/assets/menubar.png b/assets/menubar.png index 1f93d4dcde5953733fcafa858d6e0215f3d615d7..1ad264aa0588e9e4a9d3cc680f82608a28f3b672 100644 GIT binary patch literal 307483 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%0D~&Aq6o9P zSqK=uOt~XU9F8Ng|%-w~!dQn{-l9tUzgN~zDy4VWid$D&L`)R*&?D&GOyjx7& zl_@p_C4nDz?^@%o?(SP z$R~a61dvURg%=?Cr3DtO*BuSOXe%!@~Joc!2#y z>({PhM6?5A88N|QT`>iSh>C~XTNrvV60RHWzx^C%3eCfC>=nYX5Xn{digi^DsL6dn=22{*$onR2s!)Ru1717b~69=gC;8QI5AV>kD9&BDc z!zhP?hEq5kNl&0+1JB2 z-nkD)0!Q)u08R*_A)K;`ta0J%zrsw~i2Fu#!|ePyMm|_@!dlVwo7f?Hd=Q@F*zQ>z z2~Dv{wTH;Lb8KMcPNI=lqo+nvk40KP z+x?UHSfwo<*T51!x4J~bu81zIjUslKr${Y~G%R_#3S;EeR9;GNHP2@ZhHKtQO)9%L zDOw<45Hq~G7E+ULdaO=z57X@2ghp$kqawVzY!q4b!(^=_?|4d6k>0J5k>4OG-34p0 zxeWn{p1LxEp&{V~0IpoUH7xe8{|rpi0xw}2z86VrHd!l+y5LC;u!J&)V6$1IX6s?< zY!=gSGhK{y7;=U^qH}Oe+|YW4Z96B}ibKc6HKHMA)n@z5gw5Ten3}`)gMNiaH+0}9 z7?jXM$Tl;562jX z`&F}(UPvm%erW=&JDV7JZV>E9tZ4Tpm$xBOu@o^8-sHbJNYr-`nZ_NRk(Xjv57RO+ z7ib?J!imr}8T^>))kZyV*OHz#de5YeAA-Y&47Y6eZP*R}^0xr^qi<#Hp^7c$@#yG;fO&3y< znCc}Yh){80ixk{FyFTrx)}YO zA#AUUgm>FGd3AYp0eR#?*oU_qU|1$Cl1{I?VeDH#%CxUW@Ona)N07EF_ChEk3P~~T z5U#6a@Q0eTk zU&|qwa}m`Qr5R+@oqUnkbd2IiakUkRl$2(&TG|s8k2kF#MtO|LT3#TW3M3sm6^9U; z8OF&cXx%GUWm~Sql<|I5I=oDlOFCbSE*{q~!%PTBUT}uf57v+;l*cvD4-hVyaX`bY z*mNiiGMK{ws7%*}{}?H8WCW)L=fE^tJvbxTABsQ)9+cPRUecpO>`6ThJqakl7w7G_ zK0xx)RaroKhPghjIh`Xa?qm;Hu;FB8kdk3%6WJ3^cCg@djEzWiK0}-@)Pa*(49nNn z!}9!cc>LfQ()_>?f$98c5S9@>cZ8_B!!w3_vlF>dRXa27KI`BV%C6^SSgm-MAduuG zp-nJXQz=^*Wxr_sQPb6xVw-a7?NNIPUGly={#=DawSR$grf6}(UR84H5=|3kTq@gI zo;#zM8!OT&C+Y>W3}n)qdP|TtYLiytQP_Bjc3xsG!k_Zc_7pN&;|s=0SHhkPnPl(7 zG|V4o`>#qD+Xq=ybLmXx5FOpabDvM!Qx17#0D+MW)`jFyy6SCXumOM4apc54=Cs>6 z=HEI9V&HIy-MfI-bFy&0vJo#}ZHPOW*qvrq&R>0N~?~5I}$gr92~IAIEi{ zAw&-gIbg(a3Rx5Ou>P~qUk-?c2zRfqV9t;M4N#8J&^#8UI`D2oM9&>z;pu?cRWaYU z4R6PTkXYvMtdC%YZWk~%sJ^O}*Y&zD9Hc6Ol->35UejqLb+bhmvG^(^(UR%xPc5}a z@MUDA5*y|uo#iV9oizw_HK_vYs;EnA$^E3?8(qE>1SE;M&Bs7(qO=mcAfkW!yZ+4jn zmExQ@L_+gBFvJ=^PgflbbuSSU889+VoDc%qdg6fKY~UkEcg{L^&Kb7NQ&`!f7_9Uj zzJq;0a8U!y_r3pMC)|DcFkHW}9JY}MZhmbEM|Lv{LKjhS*hjQ`h*8a1*nfT)u#XiX zd{~@H*`eejcVT1PaWcu2utP{(4S{W&(w7Hc$N-RDA zYCcETI`!vhqzURc6l%CyVAV*%4VKd6j!7BJ8L?*ciixkDCPG=F%;r^wDxIe{JDU0 zoNeZ!3UPBdMVk(WqZ+QAb}{myFE~Tc0;zfkNF$DS4pyk)j8k=RMC=jn8D+RYZ|mM6 zhD2}-5PThB*Q-Z&!bkt;nM|=^NEDthHXNbb9nAa9!Wk{SvJmFhLRjCxA$P=K6vUAb zj{x6#ItWMm90}nI1@AZu0owtqaDMa!seH8Ud3i!j#9G>yFLn^a@*VQ*fbX@C`A zEyFietSGcadat=OjEo zcp45d4C`X=&@2|D!VsZ(Fb4i446$)(4^eZw7y%t@?qXfⅅiNlvL>&U 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%0AXS|uD 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 viuilbEX|(3E(c|}Lva85* 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

    M>P_s zrsP_Jh;midtYn(zD3h+eBtvT3VP2`utif!lOi5QPIR)J{ywD?4lUfGlOe*vwFC*W< z5-VjK(`AKi?ZblcG;LlasGLxFnEl8pZ5bOXsp7+Ee1h zdj4n!I%*CqW-a@#xu`XM;WO7Msj_xSSU{tU`DUq#45G~`r*JxY$ab1K+P)9Tfbt=SF;8g6BCm03m2LN`?X04ECy?8nJ0VrGspZL%VGXrCw;)Dyn06YUjP$6A8UTmBn{{XfRSq&@d@|l*z zQZO`Nv35LQ*J>oG6_jgCdS`j%D6Wfcn38W_cV{EnRHVsegwZoaG4^SED>LoDvf)|Z zc;qlenwQZ4dq9N0GAW8SUY0c-OcUC^*^Vg^_%IEEcLmMzQ+4a7DsZr*G5IeSsghMj z(O#b11Oubw*}3pKn1>$xFR@lGJ<6d&b;zecC|zP5qF~i1@0IZ+MHKgC;#k%{*h41e z3+q{qJ`kfvNjI8t*#O>`L{FKzg}{i)HOZE8E(yC#rKc)7U_2)PIE>3GITAcQ3*hSM zaHb}kJnti#C&H-St1{mo)nA8btQ`^}Wc!Ho`=O$(3ZMmaucHfAR%_rA)g|>Q(7)wwCPV(bxPk18> zF$^mrt(?GfECefV^^s=x0l4vo8-?|;I_@Go1Y@s@J*b5X7GQlqY{(d~>?jR`$9=72 z`{6O1Bm^+d43ur`8MSa_u2?=5=FH>d3OFJaakWWVnF1{q(`j6X_jJB)k(lieRQkNZu@s{nZ_}c|(C6+^I}^)C{0ZSJ@;7M)Sr(G`s0KS%yDG zvOIPB_EKAk9~IMof8?S9a=DUEty0rb7SZInS0D4#8uz5@rSo7C)hKKeBC55*~Opvp^=)a0NS<>@$O%=6_SL=CMl}BXi;JGMI^s*+=v*P_|bTtgq@c|g;Kuluqsin&o%Y=yQZ@3;CD?R|B z`B?YwpNM*xk`55NWkVS1W5D8{9y$$i5`j(LQWmeVATD}bq{+8h1_~j|Z@3&3MqY|W zi!4bZEwP5eV;=d4@QHUH7v|%guw__0mtUgYci29>nt$}ddL zXMSxfRmSP?n3#tuBDuQ!VF&LoM6QKs$36Ew5Wa|D8*i4H=~tOBUr!Nh`Jgv7u8Zcy zRpvwQcpHAa%nz?U?!Q{^t#w_Cax|N1*^l~$m@w&ju^S(K%5vUA&3Et|*=0q<2MpsG zjb){^1*%N*XU_26H`D8Jp5JWD)B**Jg*N>O#BX&rmdJ9^=2DeYTghU|_%;Vo{}-|b z?L2>iHWUi*EtTvSQFNJfbKNj3TV7N>)DJUI>v^a~y7U^oRlhNvGlC=C2{d5FkEw%F zlfg;0Jn7|OI!fxmB~x747Pr9@cEm7FEX5A;{I<-Q%aJ)wl^6=ku?^J}UY(kY@*LdL z=Ofn0*PX9Aq1(k?))Z!&50CQ)HWs{<#cE~6rfKw?u!8!;GAzHe6#G~$4gbW}AIq?< zy}V~7Lw}gr!FR1-9KW&g0dIJfA|T1$L@3h<{_199qw|Gid0d7GdGh4~h1-;c7S=V^ z3AwtUBtsm1xR^vbL$qv$p~PiXXFpo4D?1{&tj_@}j1=n+xy~}NOWM^!woRy z2av0Z%Zh$q&Uuk?CqLHSJ7Zv>#eyWfA!Sh$NpKJ>?|o<9%UPLe#yf49NXUSPldmL< zQ|1F$9AJ4EBgb~Jy;g!;lZ*5yuj_{Q_67kS*$w=UPr&*J(zc%4?(YrD5u0w@)6Pu@=~5 z3-;rIjO6VrtPH8Eu?$+J^XJVC+ikOTxa_KHFwAxu>?q(Xr=JzJeau#2r^jy_7Ol20 z?6=46;bqS~G@O6&AH&o3-UAQkCd2u^za)I@3ty4d;3@U2r|uJ;`;4cBO*h;iT!Y@p z$>08NxaiW$!p0k{7e4d8hoh9Uh_T4MI>IKgZFMaEK9E|m6TWC8thRZ63xCa+6319s7nc=X5 z_79KTVl!z=_RjwOF z7N7XSDY6gQ9LT-_vU~2lBUap>7cNKJe*Wv<3Rk1f9B%#ed;c@sfGuCPe$2`@;D z+=wGMRe+#Wh)hjL<$XIH0`pkUOeoP-a!jVAW{G||@uY{BJ>*ri1z^4aU>K%6+z%}y zDImW6LRQq8R4lgw7or z3v=glk#y{pi1%@)v8XK{NsZx0_b_@+b8$Z#9l>)ejO2|m=5T_9ygdwI_CnZ`xEIsd zAHWjkKcrn_rbMPJ; zebaZ&R8~G?1ts>e9qK=VK$f-x@3D`5lnf)@{P){L_uG$tML1~Ry~8=@|2BN{dp{1l zY`<+d{_V$#(3)$k5muMBctZH9wZ)V74F4Y6;<#g84cRA!UtRS3aLRYS8@AYFZv7e4>ZZwLC&c39gOuP&3WGcbP7aPri zv)O{^3ueNn!e?-b|6qu=sNci*qf`C_*Yu~vw(zO1)=4we>vW3I=#wNM=#K+yW2NdR z&Vv0=Ob+nQ;LlDzgPxkT7&TLR#{ci?- z3Cs9Qi=#H^g>ila`&ZlycmzWyU#|S;C_v47+i~B=(}Xss)$k-zAETUhju3^JgrZiob2yNSWg%MxrqMB!VVJ*&c(Yc%_Kmn|1s5NbjuN*f<`VE& zco30FdO#DLHxG6?*mID>h%Dzke^Ke7I4j+JtNx1Lc*70D%%3y}DQ_rjy3vLrauYD? zU=S8*hkUb%hjek(q@`zxnUChmF@? zH)GBHn4WXNMd8e|&rSS0?z$)C`)8=c6qabKH>v-)^R95|6<3Arw%$sD)kjV`1(Qjx zLr-WU5r51hw+JVH^nHbbb=T2$AThT^2-hI6u`RZF)FWkL2g~Zij7-=dezT1>!tkF4 zt6OE(A${~75!J)*8cMi3+SvZa=b*^KPMd()Pi~}4DGr=oQzgGFnMj)<(u|JVZ_HAs zQOi8h#)0=StBHP=wlmheu(Z%)#F(ldrEIA;do3a*G-<2#Bv{O7k_(9+m6l~yThek# za{Ng50OXBm&bR$25hnrA|EYB;lC=w4?@@Ha^fBLhcu5cFqI-r7?HJRl zX|20OCXs5a(?nK{OJ(rDw_*WxD(b9S^HMd!m9cV>JpW%X4kF?VIxc+vJ%*q(j!w`T z7=aoaP6IdHit^-&{FawF7oG-zz37S{DM{WwQ z`{G;2i5Bv{RJ@?rE911nsVVfM5C%ERjZ0=AgW*8V<-mhAtZ1Q?Ljm=pPOBzu@$lt* z)5=uJUwiZ4&?TG<&)jdH@Y7#ifK@e?i|jnCHFe1TPmx|9gA#|Wcsv5bdY4^wt=Q&G zowMogz5l`R+e8!E@%tt;1K6u@H~nKhx(SH?bsWmkDD>z$uSf*+jwKiHK)as zoPCqY8m=rt_)ve%Yoq$K{K|Sx%D3ID5|f$iM<%z?jN9c;P4{KXGtGJC)RJD)l9%sF z3q6{5SAX){(~^2~w<3rQe3%!6sSimYWjscR6`?4~m)q%$OidgTSyyVe)qzQ1X1vqU zw$dUa8j-e1_02+(qaECb?B_?JUkZBn5LNuh;uSO+E2wR>4CqvqAu-pcrZc3 z1e0;3L9)q&%BP~qIzr9@o6M2QLgs2t0r`GSg-M7798o5cWkGYq2-(IS@nRZ(6Nn+4 zWj=`x4tJR!LV&^)K@9sr7XLZri;Jo=@*r4o4-o)(5g_4A3|Z9z1)aGE*-->B{u;s` zpI=c66V93EdstxxT{Q%#5jcWSCBur7n5sC1p4R9zrYSh0}igv#{RUYlgir zf#BDeSimpB1%J2{&$G4*{|Wxj&@0;c@sAD9*zZZ1|xan3)1m$ypqU5-CYCl1Zhg(tB)vBvH*o5#Om&VYF5fuPaC)geH)a z#gq|N>$lX@d1&?~Qw1j3Gm|H< zzAW~@;>14$6-1>lId^3WI}q-o(il&?;**jk3Fjpfm(!?AncD z$ZrTnmoLL?julJ7TtrFEPUB<@uCzWhIV{F`wIO)MgBh(Jn=p}$9aG=D#`^kMKa?rf zoKSEKrmFL}x_TD!2owFrbPtLHD!z!XqgwK8B^zb1} z+<4XVpDi{Ryf)u>1NkKpm5Xo8ufX_h+ri;kSze##2l{D()7THhB#DsJFkjD9jaiBUeTj`$!%IusglkT<&0`N_+2gOh9EXyttp?`!ly0M#eBA)CI6X4 zy!@2UeuDIV zp=}&Ten=IWq$HW z$q>>)J}WJHaPD}%I0`q6nSGo^&KHD7N9W1pHcmVn#)(>vd*EWMpfq#OgWzG63q&Z1 zKj>Sn^9Pri;go}TSNeVDTt%DuvNQqV&dkH)ktmF!h zKEDDl%)S^m?k7M0C=7>j_hU?(#6rA0ydDPIH5RQF7Ngh0`v0qr)iIr(y%lzMSMA7N zx3z}ppG8`U$3O%fHDUDH>l{#q|N zzT|YctVdXb*vMPvRTkjfE(aeJe*TFQ!c$-M8W9`fT1&WpjE`VhKXiJ=F!VPEOE8V$ z#b2&H%UdxYGt9wei`*Y^iUA3Yfblu>tT4RB9u+Gs5t6OL-~=YubCO{_kmxrbfQ6NK z*9s9*E*x~@Xh44W0LuWyu*s1@&K%?v_6L?c2zu_RP!qrARkdP$_0-T-K9pu<6*=qbx>go_TJW@7ZL@7iYIaAR&@WX~&lafOvRkUc!+C zDqgKpk~3lY^?azf=CkvjX9kp;F-A`sz^b`+dDnExm>(h^0h+X+E0Po=EweP|1DN_& zetOxGqou45Wfr2Ng}=fAQ*ItASA5b5t9)eezD0FjpOl@TEPg7OnggPdYDc1c2ia+N zI*?8HlraM)!g68?u|_CTztzb<6YrCX=A;mrXsWc>M+w+jPg0hIniQ}iQD>woG%fZZ zMSfq*3#OP@ffzF~&S5~r6a*+fFhVCQjG<>mef&YscVao3G>VSUJ(d=!E@z(B=kTzu|DF8@vP%WXhpXoznm*DWcP z5gb^>AqEm9LrS^;K+1d-`RRGT#jxLBB^V_omT6I8tbx*1m9L#NV*}~S!UMrwi=1=* zZ^9*i(YEL(ODl@e8?(9SQ`3<>^4w;AP@JB{sNIY-)uqcnv$EHjw(2?4CVt~aDJ>y4 zOueRg&06c|H-lHawHs?e=k=3W$+>bK)LvmDPqBjHLr<|lqOJAlw_@o z>Go-fiyW(rW4f#tPx*GfQB9%3g_;5uOPMc0D;JY~%Lt1>kcVqivm}iQc2>b$;)+=D z(Ss#8ajy#`OjU<0uODx@%okQ?QHa-Et(xU@M2wZK@(GhNhLF@?o|up+gIY*Cqjo|w zhD!69)iOL2AL2GsAaSAec?i7`+=`I2Uh1;c*h? zQw-sUF?(Qm_=JlTy4h2rJx=D6YC)+k#YBVoOGzvqWpT_f}RDR_Uo{dW9ek=G7!hmKj(6a|(ciJ+> zY#j26S26G178T}4)YssfoeF2MS+${;vTf(oyz^Ib(APkZ0grRAR;AI^;Bgu-;6`FPL{v+_Y+btDo2sURSh z=xX~BZ4~^X&>|LP$Z3T-zDT!%TJ(C7*Fkw-_P8?N3`AM3^di%}hK778?936L`7B^G-bf=V+T&5CAe<`NG1Qd>O7#kHH!CAQS*OIgBGd*!p{ z*~@ypl+L<5r>r$O#CfdNU1LW67MKp14LE_FrOHVhO$RF$5(1&6_)p z=la~zeg#&l<=hEOS6?xVo|oEMi3KY#3`mvuh$&fejv2!wI^j~mP$B2WOI#Byon!Dp ze~H70=-zRtPqrtHbr^yJLzs#5{u(HA|cZ&79#Ag5UzG%e`;6he+?_jOSvbjO5WQUWuX^6aQN@v`+Q7lkU>0wla% z07VmFJy?@hsmMX1W#eYwGrhmZS-P3adOUA%s#$NB@H*S_Cat{wI%-5IuP0Wo?>1{C z4Z1{~UKe^E^lmHxD_tdKlXyOd;{ga($7jh#E-P{8pn)2IkbP(an_o>-lVWGbxt8uSB^spy zR20;WDA2-bbF-p(Yt#_!xgL~#RaL)!(JfEBY5+z5s}8XOLQstav!vn zkM`eP9s#T`iqfcA==g|5v*+Py2txvLsVaNXmNRW7PpFPn*fK|why%JT*({c_q$;I? z3cX1q{vjMqXHdi=%MM7C#s!@QiAB z7;%EJ1}MfGF26L78}#D271lgw@IjoJz&^iAF=_`4wMmLsr9?d=5&p{z4VaTj5pl8w z0D7%P53DL2f|E@ff#Z8u!y}m0fnFA#iAj%&J*%;~^TUGGSA%i!86VB62unVyDz?!? zjWAT9%PPU^Ad}??YG9ix6m2^6hR`8aoDr2UIn|r&TCrzZ%Tl^YGo$KL$#3909j_co zYEq^GT@Ybs>}T za@JVlVLdM`DU~&dd}OsgRx8j=G;&BtBvm7yCSjx+Q|cuOh$xh>mJzzw2%E+;1BqQL zF+iU*$+zIZBU?@O0#cSg56UauOVn;>YmOrVJ*=5RCzAD8j!XdYpKV2v8g6PRQS(U4 zN7Q8mFBoZMjSbi@ZF9_&t4CHUHF<9pktrsTDI&|Fv0Ro{FK3nWHJ8;F&DY6yoB@b3 z1^90S9UD$j$8z$5;n?z~+o$2uryS zW3mKIaW*<%OdXmAO@a~?K>?<%a}B2%M8dK0`55lw12jys;Ii(Rj>wmZ=iqJRMGM!I z*&V{<2W2&hq*!s#^{5)c$d)FY5vnxtO;2g9LKnp(DpdX5EDnpu1ysqAWO8Ov$+3i} zt{0o3$W@s(zHxrlpqAfRVA8&zuil)R1ssW~Ay)JS|pyaIL)}pI1&( zOQzKNqFAX{oG_&G2&6_(5(QuwJSog_g*xNUA{EuO{uX&c)T#z3LULIJvR7J8YEwq( z?dWcvh({fTjh2F)|H7o;G9~5Obc!3MI3e9BFrN39`ApAJH3sFvrrpzOT-H@`lwMty zqEtCf&a%!K%W^5cHP@aW=QiLSUBrwLtT)RIXt@N_1g57m#^_#o*jEvFPH*Q5N&JG% z$2+2Y7i)BcyD%~svDNW^8ZZ8i;e{*?<*}#5u9~c20B5+!AZHnJY*E&6Lbr}lbIyD` zI9q_XjxjDdh6iQi*dTEd(U8;HCowgV-8r4efqJq_#)g)fSPj`kKF@N52u{oVY@#Bs z!et4Q>Io>}MXA$bfnuT6LORp6o_yhyay5>c+i0ZosCji+QTem9#u6ngHC%}@YBLoa zKAKh?rLzsFPjS8Mbt9aOtO~ha+7#GCfs{tNG*A>?UPKs8XlNnJYk|qNzvWUdZVZ z1x=Zx*NfqT;{CiJMIdSNz7^V5@<{>9*v=j!Z=B-JU^Fs=b!G89iYpy4HpujK%qnM> z3FCC&V-G9DmLdGft{>1ay5T14VTJ~R6CxQGu;mv_R;l2U?082CbNUc)@WSZ?cwE~F z!Hvtck6<}>cFl(IFpTr(F$+;-xs5${b>!Yq+?IU=bLZ{Xhx!gZzNS78KvhiDwT$m| zX!Am%pO6R>JrK}L{V%6o7fVU^^|vo^cC^H1y3Z-bw}j;__2@zKy<`XRs+S$rowekg zNk!|)iDn%YnE+9+sYw}a^cGqq8K+%4sfNH6D4>!?n+_qRT33x}=R-?W?d--ZlCkurdftDv*K9dH?O+;c2~XH<4L8BvYY@OL}{-Og@F{ zgiVS8F=EbXtuiLrYRUMQZ!_C;W{Tu`s?0JaOzGacN~;v*JTpc_VUe6 zPYc0}Z!M>TSt)7*DP8jpmEfHjfEAxElL+mlMOv&=<^LOoZ-?50lGpEI(iSOYYK{Lp z<mlVb=?yL5ZWc8vGZ5cZ`t8+ucZUoay|O21Uf zWX)pxIW=mH&Pp@KG?528(ggfYWSh}+7Di6^f>pA7i=tAm+v_Y8un>XHl6R(pn=z-| zNLf{saTrhv{aQhMmYB-eEQ$l@aek`VrcAoV6ILBRn-<~8!WyaSk;L{UWKmfAqzHmz9QC|cZj@mJ%utUT75O|t|A;39k2E+)= zbr@r?0&fL3?!~_$Ea%5SHo^!;8KiuyHM#=JS^$Lw^ssi_@M;Jwb734iG)`b>a0U|w zvGwru1c&{wRudxA41yIGx}Aa(!+f>{gR&MNr?=1LJ|yGl-eGZESqxU+!IEJ>8n%kk z1Ll#~kyu8sw3A_gS{0S{5^_ef3YY68>tL&#?PuQbBGSpW2o@wl3qmPw-gKwV zRwu|XwIK@BG?oqT6?$4NV>pj7S{K&%Oxxs?+Dlq*J@E!aH4!Y7+#MkYEYnol%F-oW z(fm}p=b9!_oDf#>wjwenNk__L8F4--t^iUb)95i@>-Fkd^7?~28A%A$%1>`2u_co^ z=0nLJtW?T+PfCuJ43W=LI*r~S;6>nZAPF3z#)S~x3vsCSY{RScc}18{#;MDu&-lGl zv#O{{mn$-BSnr3uB=4jo=Thn$cYqO_?(;auEa~eBj{Cezr!i4<2{Vt4wrG` zT!*PiOlL=M;w~ZVEMcJ~OwPc2R$FiL2=t=Hv98<-d6#M)0uG;2@qw2_O)j-055cg# zFt)rOLx7@3vdJQN6Wm>Rnse7V!-Ffg>q9ZFn9J}8wBVUgpM+u7hzC=4E2R)Wih^hK z&Wox9@lBkFWyS<7OCw1$S##|GOI9F(nU zE$ksV@4%T@H4ZS36F(-k}FcBT%0gz?~#cmp7>!3>(omQmZyHZ8uL{T8m@JD zjs+81^=ykdN^v3uw+BI>Km?kS>FYDt{)0h`WDdTun*nkPv3jb@ZF#NGTeggPLgGq zdC8%NU}ccy;k2Lplxm8DI@K>3pe=YTG`-A_XFg@$@Q6(|5duTXtyrq*va7ENH{SX; z`PGw=sg*OSR}MxG-glqy?=N{tc=qdFA0Ax1IG(5MP4=7Z*`hx~ouwKFP)%~^wrs1~ zHlVbe{(f%CC`Gv{oH5Krr!o-~D|m;MX16zU!y`yDRLL(S`;eT*xM5 zA2V^s4n98OL<)A0xJ?!B?lQF<54P9?bU_Ls0%BoxdEu8Y zbB&^FH;mA?5}PT`AR?~Bkl@f1W(y=b$J9>EXDs^YGhkFi3sj+h<6yqJC{2qG%|WNa;S3Q-F9Sk?z>k z$ZbEq|G7_xFPwH}_}ce=sA~Pi4*cUEy;V5jxVOmm8xJhOB98dC=Z;SZPkG|5;n)v- zL^fpn=v$8sJ7RCB`yPBy$~$0F!>2!K&+v+O{ukPBIz0PnPsL=F$#CM=zm;6yaNTvo z%b#;-_{n+a3(ePX_0?7j-}~%m!WU2bPB``ZKS(lzX7=21$FTbowwG1dxlF(PFu3H3 zE5bWI_VJ?K2i0k~1qjAtIEQjxViVgJR{cIP`u%+qS%nl0AHV3cxV(DW;i>m+Ot4)J zHC>U)HH<1ZWPRfzm%I|Ks7y0y)m5XFTK}*T=~|G`tX2fISP@la`KfoIl2(+O^(ff0 zE|~MtH!BXLC$@86nLhQFDrHPxb>f={A*bjpZH_BNxm_BYQYM|#@>;4TS~Y`6oWE6> zzVZiBDeZMzzC=(9{GomUlvg8XlrP1u4`Wk!K7}9o^3w(Zf%_xM4{Pi+j~qkBzf#3ztI4Hd4 z`GS^hU(K(Aj{+I^Dppj2u&}=n5`148-L}*Can-! zW8Qzf+$7)s#$&=`AGKw8>D&J^ z9RKDwhNa7vht(D?2#jRuJFwt{v@3B^IwXQtv25*yzWIWklxTzY}ELhOaBy3 zIOSB)bLjs2g;yN@91MqD9d_S-yYQW}e-@s$=MzQlMTZ<54%q97;mEfgCuRL$Tg(fO zd(m|`J(knYK0D0EO2fuG`+^I@ z(Jy#j*zPe~g+Bww0W28HNzJ^@P5I(@Q`PQr|q?8c=6lb9v-#%=BV2d zv2M#zw@bq(Px&e?lHP%Yf#&=_`~gFNw}zA6|Gx0#U3W>rio=D6A9!HcY{L!0)i>P~ zzI^%_;i5nN3ATsAVNX9GJoli3!g^S3|F%2s2wy(q%4XDe*cI3sCeT`UL5w?X(wsV%dWXPeD0gy3RmB7V>opGr-qk3=Q-jZ>&bm^ z&cFB%;p1QWa%xMn)i33lv1_UILW>Ig^_TD+%01Q~S%$eLLMiRMEK5mWGVPj{oNS|A zCiAlvXegD4t1@-E4W7W6nR8hymDXxKx0$CFN|=-j9!+pUwY6&rH}5Phxms%S%!@X3 zKUz~;n*>pVT2YN{61_E4o^*jLSm|wKLe|914-?ZKnsQ0gP=m~jc5DKdTf%A;QwUBg zF~5P2oH*Nj3OD)*1gLwRF(gE)*~$qY5&-n+AgfM`s(51 zZ+|PE)odJ2IrDqr7r*@-o)zsC-u*i6Y&jFwUVV}5ILsUK$)}$gF8=dn2y{Odhc3J7 z8Vt9^VZh|#4E)$kO27Ku#Yl7AAHcJk=Nxlv_^(f&7_PhJZ?YlcixF7f@#>=jdt3CA zHZHm1N|FEhZ+;^aUG_tO;<3fX8;31X|DRp(o7B@120oT!^RjRLkbyCT%MjQ&45)Q` zo7C+qXP$++U4**rjk+Bjy`pdRpQuP5x1y)TK=jB>H$zWxRD#xOQLiyha^Pim z`T$F|+TiD`td&ZN(yHj`w%>XRKuq^z=3(Fd3Rhx*JRX|DmSogsdOr*_J~ASci`gz; zHW5~!^T7EG+6m)m7FJtF0MkcEnE!_-AP17W z@4G*|?V~41Z|NuJT@cRv%n1_k*d66FsCS<5>2Sd%mx|hX=-oVR&pqVVz1eyD$4&^h za-S?5*P>VS+9RHi2@}_Za}YS{W5adV5z_5<-c_?wnG-JF@PQA9qYgVXJav!VB|wt- z`^zp5ANcI&!~J-Ub=ST3g+Kh|im>l)yM|AH^;85j4O;AR)dzP1=Fs44k9a}!>%y=v zh7kEY=v^m#5_S8dh-lsRjKiV&L!#gL;DisZy1)K9>!8QBm+1NYx4$htS=RBrZ+Ja^ z3~Vp$LMA7@{OuqA3~&0-@nZkMCETT0t$gAg$4QUuU7v(cf4D?+{S91aD>%Maj_bf`Z%DEe z+K7ojZYz>u{n;R!PA z`0+2DBJi`%zcB2IXGc42`#1?|S6+7=g68c`mHOA_340?vuDbEYgunKto27TP34FUA zy*t*$>d^Yj7>La`+E6B4`~!h$PXrMjC%)&uB(;ytHrgnhe)c)xd%ySvCW-6~+>T-C z@@3(N=l&|3gyB0qhS264B0GbbkGGg8QmccKHePQ%`6YIB7G)$2B;KKQ)yes8p>BCEz+=FIa=w?#LzY-Vuo}Z7CU$+7rAo93|FRD z3I$6r%kM!9@jZZGghw93E8x&F%n)3Ru|`Zy9qf6rcX#kUPbzw6t1nzFeDQkY@JMf`OGuX-JcG} zzx6F)!TbgAM13Z}{N@h{&L%DV-dKawt^dq{nnSmC5X<0r?*k7QDW>rPsHm;Q4yc{; zlAZl7bZN8cslXSO)$^Bes;=QEZ28U<-!p#sqpnVT#bDbu|H^B)@V$~(UhPyVQ99qn z%Qm$QsdIp1Kv*wL88XrQ3LV^%FHJsx>p2*>r%GrQ25d%SuJJIv?DZb-7x(pfKym-;E z+r>Sp_`)yew=)7_Rys!Tz!=4BEJPA!xtOhp&@P4phY;wvxGlA?ry~!>-~B zRfMU}qo^(lS#Dg$CQA-fLBzD`+hBskGxyymiSgy-pZxm#urqod&p-G8c`xbqyY9xs zgu}!04mu!w>qkEoE$gkl7G~oe9WK87FJYhEc9EHS7ybG2@Rw_@lVI?+SG)}GEuACJ zr=GRnzTr|#j$n{ThjV=y##`BVoOEzGa(#k&I)(lbFcJL7(~DEgCB*(nAovDCT=jmatPB74j1y-*FjI-8z*%#{PLoU zQVSYJPBIF7_lo#^@I2@**IXMo(~xy|+bfO=-@!Xs3+B%c&upukDMHF&L$>c+43Ba$ z3ZDzHKL7o-uL+97iMv1H3E`cueJzIRE<}%S+whEi_6;9B`D8iw|M99 zRl`UPN=0h(002M$NklPPl?OaO0D>UFJ6)2sz}3J1qt0M&Lo$00Wq96 zgJ)VClbc45ibI8bXO|;p=$kO8AP6BgJ!Yp}-@|u#*!AL47aXT!_lyhJvd=Pw$RsXc z=x=lmW&+B#Ao`0fdVxW|DVbfySy>$BnY)%*ZwutTC2n& za&W2)R7&%g5T`$K_8o`T_Si|ETk+Y|6L;7i59rShA3yHRm^iUCy!(U`$!{HNO z{u%<#@56l$JSZ>!?z7v@7~XrLOt9D#!;U}t)p_Adm}DVApUs0~F`oGxh+xHD*4gLt z85#UQ`>HJ>^x&_PdGKqGopuOM*?sqL(zi}S-L8`%#Qpc$LuLdr2)yqzCrVH=IZOA# z#FfW9;t}$^XxHr?FYiVD4iic^d+=I38|1-fg#1Oc_s%=ZQ0bPKcyZRxe~xqTqrhqJ z?EP_u-T`~<9XLbrE0_TBtKa=TJZ`J4Fa`dxGVy~xEkxja>YjT_AiVUie~o_cD1M*% zz3+$LVp0cZGE&zr@P$35<3IO#JQuqeFIhh}Y`^u^a^4Po+Wrz$S+5U%?j+GCjy68n zUjL#asvg|J;7EGhMAwwMT-B3o{H04q$`yf3qgUeXMFF?78Xm`>-ioH4hjz?HLqBXA z-^Bztnh`nI?SGaX1Wi32=kwh*Jg1Z>OCHC3lN$p|4V**T$EC~Si7{WX}hw)IZi zVdMnQq%azV+Z1|Q90tUsiBZmjK+KW&gSf*^4q^sJR@m79bwG;0VNjczp3q%}UwrIw z;L!wnQb^c6o58}g3?O_)MKHT?9J*nzN_txeVAEV?3Eel|xY(m~4m4idyQUPmYqmoEd;14n$zxdw&5L{ z*&e>={iMQ6v0HDuA8k5nT2rUj)#Os%BWith*<;(aiA2H51utD|?p@A0YMkh7W1BI@ z(<~VH-tKYG)5G^a@tJVwYhEHhe#fx6qKw?h+;Q}*I7<-2eliJzK?A)ku1CuWU5rHx zXnZ%6ac7hdy7+=G0}Wpe=CdlUWWnWs}hNQa&Ifg1;Ox%=_ zH;-YyqlJIkKP!J(`9PKK9u^4DN>=~6!P?5A8Li{QTVT*g3|w5Y)Q0wG#kDX>d_gTA zr59Ebi6}PN8l+5vNrdpvJMRI}+lsvS<;y{gvRTeFY3k)8CqYvNR&*ApP!gFpdj^0O z9i@@hl9w`-yttarhg6)w#s{2Mr7gt#VsB>p)k=(N{xIdM3H3oA$unP#Z*pyA!PWo+ zKE$+ETl+Oz^``Hk>M^^f&&oxL?>vv8c&!$^o(0OaYp$u$LV>R_G}WuVGBOkGmAL+X zlz3X2{n6%csfCEySyG+6!}ZthZOz`2N%v{1=sri!8b?FayueKt*O1H_XU7DwVThd@ z9DGW}(KpVS;K&(54$@)#u*MHm=`>-rbpm?UjX=YPx10fpCtG0|?rGC_XNSRy zeGiglX*on3w^h!{}MjDXy5yH3k8pMSjR3 zzj9Gb6jUO%gFyyJD~Y5GqK?Jv2ma>^(#>otb-)JGD+IGG8k%?oZK#r(8kpQlfGm$TM)=A)&`w^F;u zT$HHj-NKne$y}-w=zXdR znr-zp4Vh;-IZPqtQvs2INyF zu>nOK`kO&FjN^H-%`oP>PfPGY5Sokkf`Jx8eCrq!Con=N{89AIhOjXsBPCB5AD%H# zK~#)^D3xJU*7}eUofYPwAJktSs?TVuSFP|j$xOKF`kNWtaWrKGS1O2#N^C2nm1y-d zf6Q(MYiMRU+Ax--UQ}w}36K%73@(aNkPip}lVOl!d)T4BMXl67bvhk5>r1t9T$(qz zg1pKF+T*h^{;k?U4bCT50n0jWe-on4B)j14{MMULmx=-DZI)(LpN1W$(G(?8$`n#Y zHF&}7Sun|7AZpDx=G0E6nY2;7L_eQQ#&j_4((f^vZ5(UA0Idhguq1ibmex7rApd|oe62KOKaBJ_*U=>d&5W;|9J9b=~lGX@dRIO0Ey z5jw^n4*#)J#7+=~2Ny^LV^3%bD^E3lAQ;Xc_~7>fCur>ZUcbb5s3 zB@8pW^r35jJyTM<*XBwJ+`Yi25UP8?da#^RZB7hEqZg$OPx1NQ`f_bb+~7BIF9&Vr zRH3*ihyW=D^%^wa#5XadIGk4oGOt)qYRY%ZmRN@?8UMnP+0+_XJxH~Dw{eq=h)O_o zkXFIE^*uCB(`Qm-+8sJV7}7&r7#ZU;Dt$Fdh6U02VNDrZ(C?9hgL4vJfR{CBv5@-2 z@}<}*7=13TE5{)_IqfqX7KAW^4I&eTSYOU1;M8;~MMqA0QX`mkCM|)R9$zM2Y0=Dj zQCO64CeHMr(|S-}{q@MLobDkJo!dEMBC9>g0%ooq*G09vk~dfD?2;XbPQ_j!%BdJL z-gcYLgeMc=8lM^w?QA^ANY)3a1~cl*4yBx_X>%t#P&lU07LwP|hh3_s6FmhYpeM## z?~(6a;X<%Bmqlxi7wg6IIL&9Y-Iz0_PoqFV_Nb{@rF$dVq#P{?N1wcF0@EKr3Fbrx z%Qh5dF}t1tA*!%Z6tYOlC4SW3!%UL-mu1YjI+a{2>=~vY_AF3B2DWA|+EZ^AQ*J4+ zMVmCqkveu@Rv^X%QZ&;k9#}}sLKV*jxM;5Jy z^=D;VkVAEN=7bMKK)jsAVLe1bjxCO0EKv?Td>ZHK76?dFD-ndCMAv!3%UcLUva2KF z5odHw;bECPNJE61T#3~!k;Z)1X&j<@ zA6}m!9WAQ`Gt-&tZ^KYNH5+y6bVr*el?`P~E!`;ha&8uCvR*ILOL>;a?N#HwE{`8D zZ|XYLkU>xMq`D9cx+IFSz= z@PI)N44W^`5eBEEGvLg{BCb?0jR3=Y7H9Gi$klSWy2Utl1?H6XY0TiDB3UwnZzQA3 z#z_@Zc-Y0&bf>TY?n;bL4$mw^BxMiGT8pXWW7EW%X_9$b?T6uWRaJU9-};41os0t2 zESU1ak)_fJG4(hyN=kwi_A)(csPbre=bepO^@^VCt+ zBq3^YWsYCDij+iWm#GcSPP&Qq`h32wY00bglyz&t`d>AU&1@-KYi8L5EN#QI&>D)f z{9txlbQ;NYXO+eoFf~C_)KARt{ct6}TYJ=JfL8Ub#L~d5OWN7tJCwtWF?ca}49~B| z@CXT!1-Bstp^=5SDDaIz>|h6okE3Mn1Y!`sN2E7>2=_8Vc z14hJ7q)A>m5B-xTgbMA%B#k|+h)fie8+j7aOsz|uuRyabicWm^UX7`!>@_^67_b%0 zq+<%MziC9O$VG+zlw@uGM%%PtzE~R1r1+9)l`B@P0ZsLW?48zndZU%Qs;9~;4ACU$fXUu1Jd^t2|Xu(Jp5ft;|1 zFoh1!kZdb7jr%a=xQ6Jx_uq>RfEUg~FN$+A@bHTfkK5H_ULj-JB$(+dJ6ld6nx8)-vt+j2Nue5VE~ALd*OQVvZa($mmyRKO3}mf;saI^ z>&Q@u67fhGBlJjTgYBVaAl9nbNG8Xn;EPQQ5psdgyc& z5xD|d6#7^tJL8?&f?g{zi6)*D z?;iB7X0YPWyfBFcs#(9$wKiOY2^QGJ5j~?ZcGd95H;QFgZw8SN(+N35xB@GkBSvXA zjTtDK#OAXK_ z>|pEfNrVzS%G_coSCY#cMUSS=k+!#_htq54s_%n27PjZ zqMkxsQIHd<=ThnNlh96X1#LRp4lwa1zMIk|WAt`Q-TDfSDKR3Htz3aeLo1hI1P}8V zFoS%Ab0m0Y!}BY?+shSprl%L9h%G`eEXR1nz4sO^#D>4v;+_-uMyG~XhVcdR^a42u^p3lqzLg8_Nr3k*)c zpwF@-6LRXm-T>u{!Ox;WQUwdDRoA8c_zqfSDM>S4Lo!=o2QPYUy`>b{4EKC40YwoS52CSpxV32RYQ0!&PSC9g$T zNQUY&u2YDYb_$j&5M|mO*=Nai%IuC<5Iw%1z5+W~!I@V9al7<;fSN>O4QtF>7Oq}4eDNdvq;sY%X`*HRjpG)!OEd1l^U<}# z*yD1p38xr7yIMJcXo?;ggBTRjM>wjLlYCK6p`?m-WeQYL5ams=!UmtaX&|+QY*j@C zYHBGc8LiR{HwyFs1yNXQsmsul4L6h$J5Hwx+Hk0@@Mmz$2R)u>Bn#QW&)+Voz4-Sy~!|BLrRw_kI9m=$wkek$Qe?<`ss24 z<;5IJoJfJ0e|W^iIKX#wN4P=~mf{=3y?6){Eu>?E7{q%sx0B+O4DR0k=uNi>>#ngT zCSw2x+0hxiIXr=3K%L_rFm^Z}U_7(JFdiZodQ=!1L{DiNORh5tPV=2(31-7#>0<8c zNE}wKfT6KDFh~rC#1Nmx#;3#bCAz1PcE`kTZFu=*-`yO(2`I(oI$ryt=Ss>lD|j1r z@BQtim!<9INpBoc5obBR|KE?sb`y^afBx$=;f){osDlz@XUma0E|J=|XFlag;n1g0jb$vsRB#G(gXI=kotDW-5+^;!(p(AsW4{y_eudbT+gHB^RbKiVV> zlLM~)tTj5v)es&KAMngdmZrt1Tikkz8~w5y!?gq1R&x-3$q3hkT4BU-oawTV{D>h zQ+Q}b98}4WVwgLG;D?vL(4CV5xU#ZkDK=MyQ7Y%$Kli}>rLYt$WsGBGUd|Lb>hOOH zZ+QPlu#@f03bYn7Wij1;>#eY9;CA8Mi!KgdI^%m4m&JBpT7V7G{CRjV$XSuJE%sMk zmnctlFg=OjY#Yy!3YcCx1<64*>vR-AM<=iV#DCO-D10I8iW58BrE3 zHyvo2Dky{6DuncOCsL(j);=Ufv&!gzJ1;%oc2H5dla$gg2KPZMOL?9bNP` z{lG?FO{#2OqqfPm(aMTby42Su^Dxp{405&QBV%< zfi!{ly!^55+H0aXBRlxs^!L9feZ;WW#`ggHo=M!>%9p(^ZoJ5?=+hx>0nd?+A*iyg zbj4spXsxVNr1_i{uKBI`kB_J1~_xqSDQ?;*~{3mb5`i-Vg7f zrw^iM)iK^`aOU{aGZ`Fe`O@=bRgwqWMp&m^0P0y0pcOMflw za4t)fFRr>DwY{=T8@+XVFG|^-r7oqUcdG1UbePIUa&7<}13)?qN?WNoKh-Mlhlofh zGFV~pT0U|@ykRd(_B=$)8OJ?%^9?o(kKA}O83r7}vP=_@n^?9K?SU>8h5|YNfg(_b zix7cnm@_p{=JHD;0MQUaknkC|I0KO5ihS3K?_lWyw?J_EJ1=|$I{q=}q3?z5iW&IS zeJJTT_ytfK0${dr#;5~-!qctNzla@m4@Yn7QCn;#^ha&JX?XpSFTgIckH)?%b>Od+Sjz!Oq3o zVaRkQoO9uC!wJ|G*q)7v0{Q6G7O`@D+be6UbE*ODiA>a1LtMF+F9usROuOwaU0rnZ zp)_cpYRf zIs1I}daxf>wS^X^T1d52-?F*&aOje&*-pGE?%_d;O_I7LO`ru4?_=y`@%tiE*AbNX zScy{d@-I3+BY4EL=AwmR-PP9!OBO$fxehDX*$NZbUyv(VAOr!7P7=FkW0-j%%O!C* zP;7JdAC|hn+JCZIF2)hr`xpmpK32R~fa!$u=FJUr=3poe6E8-=XVl|r7TWz|R}WJZ zXO<(daYI8Hg|6$f0NW&1PnSbp4ATS`ynroZ17)>wUE`1sr39Jbha zBLt{3WNZ5)4|zs-;j<1x{#pc_Ka2F2&irop-Y?I^N*&{2t<@KWT^|3q@Pl)Ig`vT- z!alq19Nzl!mxR0TyD$9DH@_`IjUPDn_2ChlZWJEdtaHOva@JKFi4uf}~T` zsXZqv_I)`T^0t!>;2O5Ptk0_+Q4?K?nvpbdnYZdWwZ)$}`ZI^+e0ZB(`HW^x^(fZz zMT)lI7f%1Y&Qj0ATPkZcxb7A?o=YArEM@fijIte&K~)mh8{1*0gPh&rkKKoQw0qW0 zrL`7|Eu=QD283y2i31(>+LRYG%JGh@X{*m3UpeNjTE2of=`N1aWdsg=reRF3kWoAN z-cE)2h#PCnpNmNpL*bsg?+SO_bqC(Dx;NZ+?>%AZvc-rWn3+DbGAv)V1hWAVOk}SS z_RUx^`N^o&V@Tt~3&bfI-kZS%4+?Ok(J-oyKsB+PGdlPl7P@L!?`aZ4a9o9*OExij zmPf9XL`*vwc2(Gyib5@U27%qS-!?2-upn?dcZ1G`gWNbWcjCG^DlV{zxw-cl_|i79z7A>_`Tm9p7*q;hI{TmB0MIPJn+!* z@O?k^Gssxk8_q7CXSd1m6TkXv;p6vwI{ek0cZRqA{LhA)u00HTY_GLXMT^(eCx%rB z6l5pw1l2@^SG8S{b6BZZ$Te6RB$C`1B|`f5R#Y3{1k{*r3MyHO@`D7Lk%xIUOe#6U zQtn62`=?a9n11G1>|;-{KCidlOV%ZFYKfk6Q>~5L??=)sOXKOa?PhpG-KP?v1{)s- zIP)kPB5j24BiJ5Qe;Qa2%sI72G4Fvff!p|Tt!kSaoFfl{KJDH$8y0XQFvG;+c?2ZL zaAt~ehXbG`%-Hc7&(Rh_4HmzUFrhoBGhk5=i(eRi=|;6wMuLSjmP0aVKx`Y?7W}$z zV+aR)(BTNiZtKYI*oM3uoDq~6NUgHg9P(!2#ojQxc-grT%nJ{lI1xVh$$tn>ebOxw ztbXP{{+0xYZ~5A<5y9{L#+L{F*>U4F*P!U^N||+~9etP&@ze4Pp7{(>`wu_%207cy z^;qzG+h4pVyyGwbI=u9SF9?)dT3L}1*{@&(X8K2tAD8k&2!>qmVp2%^qO7RaY_n0G z>Cq^eOs7-WkhG1NPE+aQc|ZE)8n{sf@zoqQ|0+r&J`0V8K}ACRsnxKxPzV*=$G6(k z#$Lla?QgcV)UD7eq~uPn?|aXele{nGy5uCCHqUET%cd-_kQFf;VC!W6kh)QKOhMb9AzHdzaQ!7=Vc-A*Z$xS!oUB$-wU@v<`rN4 zGOTTVxlAwG8^$-mUnogep7{`6$xf!75i=a&G-6F5SIBCmy|PZ>u8{?0OB*%)%-{u7 z%$C{hw`J1f8!T}>QpxK>_j;vVA5O{Z!y#@dU)pNdMbrM&tLxa;p2CII=tphZ)!dRH9!k6 zfBS(Cgy%o)Y2gju_3hz3NRW8e?YD=odhv_Gn||XrrOiM5>Tkn(*I$LddH)AwWJRoV zoCdUm?XdUR+E;Cx2~p8{#Xv@#$CdYZs_U)S?O%uuZ*OSX?Af`lm-}rpT{?AX)AH>e zC7E=nnR4M5TtD zshB|NQYPdpg9Sy&;1yxGuGbr>m0cI2ucBm{9?iF9bh%U0paCJPJ$$3_pYo0sYY`=5 z#7d_D?;B;2fEUp=x!D9}->AwF)WRI{9l9o*@asOow}gL5gHE&5Td!T#||jEOGKkM<(ZwRbDwBjl>MDQ z`s45wFZ{yr%CGtA@Q3etPk7zW{ompHUir_$zxuXsg~|k`2k#00?zetRBcQAOpIDGX>ULwKj*WdOw ztYzIFo_X7ClJ&QacAIa8*{+jgZDyIB;p?PzACyjqzZ7&}KtaA2xgsD6d8rz$B^*tT z;wR5i$#fEBC#AYaec0sHwY>edL>Hz?dU+qXjNYZ~ZMMs%H6DsdxAAsB5is>bFJuwJ zT+1M9mfM2<)0wGvRBEV6w2fc?>QIhI75T_Xn4?N{j8d!ScSdWuQ{WcW5`TET1ae*! zEE#x2;GCt`@LroFk)1!=MYx zN=$EuADFe<+~6(4t6_O*HB7wX7k_b^Yg60}cY6x~2wS+*K9eUVd3P^FH(_K8!#Evb z@uPt0KTi8`Z3-fCgBODdg3|=fjBQM7=a+c{+bzB4mwrCH@U=e?KK#x<1O-e9RKCT& zY)!7wjEA#yQe9>NqbeqiEH200Gn`s)Q7{3G{|<98i(3qv|qqISm&0O zq(9ntb)VXDN{J>NyQ1F+#R5fG^rDT7gOZ{bDtT6~$Ox$fjdERAGq6pgQIE8!DF#i( ztdD>8Xrr`gjq+`)Ib~eTQFfI-4(brZo%?L)T^=bt$A^xPyL2dB=Ovsv-@LJNk|(9q zDeI=?&nhE0D0+05*^8)H8qVTo@23J-7A%Gql&;ZdX39Xp)n)D*0DLzqA@ zD{?f9Uwu z5yL4#hSd{}mme3iEnmkawJocbn~#ZiBr8)h;ii&db|DkQOJ|@(CCA7udeJ(b*QSK8 zdu^0GKqlrZCgf=jX9U|xHbqr2JUch+$El!pkZMg(^5f}GH+JrWbI{&DQ7!bn zl4E&tLL$`(C5CH%o3B`Hx>N7O6`8s-+UdiG5xKdn*6mv|oy+9446LI*f3|lzzHlBy=t17uv*4XeF(zC&^aHjJ6m9F-+gY ztxi1BQ1_&!%SnuUippX2h?Vpr!HLCU&naoEP>xY@dw>S8(vO{@2`ycQ?c0ZYnt-zm3((vu(*Oj< z7E&g$48;)@0~Uf6rvnkvBxqr11cOYF5R+W!V!pcutH}s1IUKOV0L+<2y2PhEa!Cuf zS>a|a1T<0+dC%avk zNupMwRzI$B9lk4Om?kPj70O7NaJ`bt^U7B9PqCF-#}R79&kCt(K~d?A*)l(J4^?i+ zYYaZt+kj~<%P2Q~SpgSs7P)JV4_GAfQZKyd9oL1wLRrqy|ltL#VDjE*yhUIA@4+g(L{xDfjYn4X}6{szQoX~~WMbEYSYUBCgk%rqg z$zEF~@*Q(=dcWgM~EO;sVhwEW8%XW1ejpKbt*c7_=O0F0{+t#-iyUY zen=h%1UBV{E(9$)j3FI|Sd6CNAYdVd9pgJjQBw7fO<@^_1uJn?N%|W3o@6>k6Swsj zfsv|bK$X{uOs-}s6Y!O`u(%;2k(UTwF_qg8iB~O+tx!d&6Nx>_;Zk!zpO-2{eTc;& zG6n3|Eg4Gz4yE3rcly3Gel`X5Du36Krf>_{^wG|>%Jx~kR5yD4oG^2}M6c_$sYNSP zU?fbxKo!%O)=yi)uu|R@)Z`lD6fdxt<9jgkz|#hn3)Q0PK)S6vAy-uS6e_fCDBh0I z8f6l^0IHb`uF=AdGQ!IRL_@Cepr=bZ-#HaTIKfjgkOj!Zim7?b#$m<{nde)GE6jVq zQ>4NicC(m8km9HYLnMs05Mwa(T3*}2R3K;iFv=pjywA}K#3*r&>4Y4oVYk0%5^GNk zL?VCygb2W`lw?0Z+Q2A`Yg?1R+v0szycw9IEeTv~5Afu$R{I{ZGMzBK?=;f1;TeWj zI$jOO>zSz8L%qfpG02o=P2HVUMBmUhl(S=o+CqxPH^K9~s`=yWYSAmSn30fx>eA^W z-i4`p38%}_<4>>oP;XW8g*u~Tl60+-sOdi`9}%q0^}zig7r z_4{ir%qmQkSOHeK7G_Iw0NwzR=DHH`yXc>^6c1?_bqwDm z^nlM`#ME}3JY-S^4RLIxH{EJ-g*6CgX|&a?JK|aJSg!GFv_ijH9j@oz4@Clj+N9S} z(kP>)D+r!iLohygR#eMPUC1?6k?RUH$uEQJJLjf5jrBov@cOW5m3*^a${L-}C66>a zJkNAIjdEHyZn9|@b}sddeqm?YO~|Pvs72LVO8$CkS6923tDgH(M^%~8eh!tR zl|H+Dyt;=<-Kky&rZqUiT9wkHEfo?`SxyBjx9*v~T=@o=Ln6kP?ht1)RgI__1%Z=r zatKq4B=N}{Oep6dh*zyG#0lQVJA-uf8SYYnwJCZ2A=iyCD4Jr%ApW>6CN~H}XL=61 zq!U+$aR^kiNS2^M-amz?q)++9HW>(mGMy&7Qee)I1}71~G*ggsiwI(zN<FUVn0zvnC|2TmG+sg&R;nQ;n%Qoy z=K>0963JPfG0Fi0cUYrTlwT?skk>9{JkQD|V`rn=xsP76NxiyGTe>c1mWQ89oVF#y zA}5p1DkjD6LhbOv1yZcm^-3&{Q}W8Xm#v^T?50oxwCdfLKNC$@6^l_Q$(UC6xh~tr zuFG}fj^>z+7BU$H(PZnWg>Wh4lwGluiuH(#PzbnRwcQ#4$;uciGg|npD!yOUm!Y zpfqH}ksc|}GLxc{Ta#KN8wE|?y*sMaFbWXT8<33Wsb1UDGlkxYNATqwt=pSkaL4r6 zjy$MX>U!VOmtUS-P{B*mC5{(%JSd2cDLPits1g%KcX(}+rfyD9r4OYk%pxO z(`v}32S)ex6zfU=;s}W;>5MaSPcMQLx9nqrA2tZYU11R+?h zV?$fc9dhw%3OiXa@F2(`!2%Ct1TY1uERMiKK7v>rWkBKxjMINy!ve6(L1Hw;`>#mi zRNy9}DIXo82SXPyh+wT&#zlD*$W|{#=)#^>`8q{klCFzhSKZT5yaUHRz*v3!7##4*QE+veYq-&*I zrzSC)R<~5A`Y$#mc4EJ+10)hFCQI3hNNk{TN_jGqPAox)zg4@BUS?ENnVLOsF|%R9 zz3^?OsdeEder7H6v*fgO+ICAF*6saIKVM3z8jjN1HcQ>E&y&Zravja6GNost&W!Pm zR1qN*QTbX zI7*@dx)0HfYgo+WV|qFPWgQB_+=2;1D8TAk7Be>J2=BL&T`SN!j=pG&2SOlb54lig z7c1zOEfvY0m)H|GT*K#5)sL|thYF8+2k6RBEcDl?!#=>H2-0ujM6GsFPZo`N3trDaf`;ARsXO)+7D zBP0FAjp&CuM^_9?{PZ*S@JYZM>r~=e6^sLj85-JRL_Y+!=~)Ijrdpt(9A08Yjq6yJ zgHNYP9&{9P_Z>SXw#*{WdZdz3c6>JQkpSMgSgyKZM3vE+=^Bs5jMi`1YqTXhFfy`3 zuwuh+3J%(Y94RZBPM4hVGbMaFx{tbs%6IAY>3Bw! ziDK5%N~ynkgt|nIOPQLEm*S77`r)NYi7uT|&gxxQiEfDLlWe;EXVptMNg7Bb8*pN1 ziFEM0*rm9y*Q|MdDyw8;!{!Eu0|2UDxWR78_3I@cSxT}AFPHE#d0FMU_4;rM9^C*? zgT(@9`DY^eT4;~1cBpoc8@$G!hLU`&|0YO?u?bO=bh`>ARBq)riJ&BxcSvvmG>I3^ z89XA4VVGJ8&L}N@lga`Blwi(a3A?`K;*(3v(c$hbiEz?FSU7D3d z$R6XMq97DHHJXW(JYVl}q)tzo%CBD>>$>Jm*EwNRBFD&io?pu8ho{TNaC(m0)@$?Y zKDMcCtQw__Uy~v&w?Ms|QubvVM{U*LOO;OEm~0nHPWSIdevvBWSWi}RZo5U4En6uB zfgq>EGFnTk!J&qiG6dg-2X(_IuLCs!@h{QPZr`r2P@J%RiYlrZ70-F6wfC z%~6zOo=@Vj^_VK$!p*$g-GZ9BtCHRX#XyFnKa8P}1i_EF?3%u@qBxM2w33=!;jk5lKUGEL`Px7v;DM#WW>)39+xA$2RnXh5T=E9`kc)ZDoa3GA zmg?5YIm2q+W?iH1Nw;2IKF2nh`ma;I-`)5*lCKr-5Fud5YW40;&c7`XUAVBR>ad(~nZaCHUSDqSrc4r$~?MtUM@mM01{ z(j_z2NAWw-5vZ7T~!6^nYJJch&%WMr- zRmkbm>bFI17w*mxyD>+5Gh9Oac1^$7{>m>}TNKuxxrK9m7Rl@C*#ai3x&{dyb-7Sw zLYZULaxO*N`fw)dg zVOePkHx%>sDBM`QAoF&7!iYS(is|VXB=PPjrk^v%P;UMOG9O>hC-81SKsqemjf@0% zq#W)-aN={Y_)II_d&QyNI-IaZQN#X}rgf0BLwWKlMlvQ;$cYStDMa$B6EZx5a4gaB z{2T-|Q))4UP(tNW2Aoqbs8&FxP?|~!zy15Y-(S@nB|{g=UKyp6BNvTG4i}|bn{p9v zcPMI(@Hwi*4pV=v2b)jyg*hP&2XeIo9_Jpa+H5z+d(q~OPwB=R=nza2gVNnt(XT3` zX?AJ1={m_3F^iL-738eiM$Fi$K?QlIRqvCP*#?^;Cru6%Bml9(5tQpyZXU6*7MG7O zreT1ZoSh1@NK0q3#Wc=S$kLl%SU}vtvJ~(21>O_}JB&Hg*f((c%!zXV0h5`3n7UiR z1F$v_V776Ve~5exJbXItHZlffq=nv^o1aH2JF_2RfyAc{9>sExoyDwqvBj|W@%uvY-uVYVVvkap%z0rI$1-RGfsQ}o^PJ~yn2 z4_?mLHJb5;oi7|=h@E7GrS4WHIYsT3?6cZ$gPQ)cRoZMJcRDdrvjvsDopn%BcY<0m z)R6jmqsx}}j+a`M(-1^pmNZJFcT?mdp!F}a!FSE?LLdVOruL{eg-rtalzMrHFD`JD z<+Bji);Z9D1fF@t)b?ovEsn%C5PPPV&tP~43$ouI9u*?V5tsyATh|9)O(WV(19%$& z4TC0Gm*V==^66zPj3Mn10Sh6K2_14s5(Y}VCyOp@Zmem>ptAE<-y6p9wDKx#GR?W{ z=Ca-hRtsjzI#q>0ZNZ@PjNI^8V7K$o&X!{K5``($=utqmGEqm%{J|TRsZvQzXX=Th zrDU?D9rZlD^vCluGZ&?j(A93Gh0YG8OaC1EA{Ucy1WvtpVP@=e5>Z;s$?fDmT$trt zyJfg=Xo%$wjOJ}>3c2Z4ty?bdjq1m}{hesxclgeFp1WQ%H4}-HetVxkkN~`)4w_pZ&IS*`jCa z@MdPU4$oRIOn|wXl0G%q$?v&F%sihfv_sAqFMNGiWipgBgILvldpCIr75Y z$ha|BrVe8}nv=FwvG^qwyx3?9IwDhc1XK!=_J9y)* z!>V)tajD6-AuSyuGps$yu6_#bHEDZ^L><30%xAMUOjy= zsw0$JY^wkN^BA+?O+&LcMw{M1k=F?3Z((OAnR3#riDD5+0u$5KnZ$>L2N^kW?^z~L z@IRM}Fw_AZgC?#haXD&bC9L9aZf+sWV;F2B&j0{G07*naRFp;j^x8VMXvZjN3O5Ba z)^KYjrlfOP54vaqw{IsXo;kwwJ_a(JH!+8(PkJOwK-wXOaBIliz;^Ew7^%%n&jW{1 zlZQ1-YxZi*l#M+*gO%x<7SOPsHjT8!2{fF3F@ozZ87xpvhnQrLCmTm%q_`5WJG=y2 z!-75)7;JzeH48lS#}46Zg)(wb&B`KcoQz=-`B@C*q(QZs9-R==^~tn`-7;X_o8K(~ zg>93^rkJI%6(0wMvOjX)O77#}Ku34iEt_!e<@jFJ(TP(-_B49n>!t0IXC5alO0=mZ z&ggo=Xk>HfhCHM&s$D}cYBG-(Zq1gbRqa-ZUMnwCyn1vp%6Gr2E!Sp!m?B~WV+ya! zI8WkQyoEBa|J>q_qbu1r5cF+K8!};!Q-r9=de-zh7PL0D)-YK&2VrDoFtp*~yp9Df z`p7^=0B)@`g&?%PhBYoGw{yx6j~eE+pEn23V2um68v_H`8*{tEEEwxZ%HW7gqM5XV z7gP=bQ=_)IqaiQ$_D7cRD;)tk?ws4c}jJ}NHK}1tZqsrYKbEBOf|xrd}4soDU+mI zr52t^bTUMMTr-zzlvLwhymP;27thX6q_V}V=RW4Oe%unRUs|}eHzTTbv&_yozIk6v zzig|Qsh7vKn9C=-b@YC!YV*6*aa4xtScwx$oec1!1zhI&gpV1!Hj8n*w_LwMeBt$f4cUTxNN>E1ql|cinYu09 zqs4`!>D5(^ewgitbtvwdj!gvlFvV?28DzAZ1{e2PVN0cT>|U`M_XeCspke^yjl?uG zkLO~|BCu^SWMU)+O$i!&VsJC+k)~Y~y~{2?6rTCiTfzrE@~N<~gyay6vGg!>*fg^s zDOEgl9!Hgq6Jsr-u!Op1bOxG(PO4^?I?1%~&5tD9Q;Nc-<6uiA6DjGBcbzWPZIjyL z@Z;^6cmRPwe!r#mOE2pF)*SMZB}z?xG|do+*6yJ?)pSOo50x8*)5~u=-6K9s*jn8J zs;UotAL>)~)<+&iXjNM+k3L6)nwK=qQA*7P5Hq^!XQY~1NvoReLtzwvSGXwi5%s)3 zSGHS6d5a?_4tQ{l=1d(ED`YD_T(>!3!ajh|H=mZUVr1&;n=a`;rQ`~!!G3IpE+|@Mt}MY6xx(& zPmG^5qw&5Y$8b~HdbsYIE5oU~&SfLLLg*546c-6)*Kkb}L zw7O5&iCWk4)FhiD53d;-&k4<_hNE2aOO8qCIY-HP-8Hk@k6qDk%r%9IP$HQfp~OmN zGpi)MrX*&dXmS}~BULGQ1p#q=oy2_rFpb3h$1FK-dfTjW3>Q3{)XmvQ*?dB%@zEYD0%bCU^;85{u78iSWi+d*ei;uFR|8yk#YObvtt0?!7f z%r>!(#r^-bks(1t%!TLkt=5=K!Kpn2rwvT|F(TTe8Pg6ow-F6-k>=VL4Q|O|nqr{Z z92%(5cm^m6T1QAZk{W5pN0I)_&(DS`d$@GssSjy?QH;~?LB z88s3!1~#_I0@gF1a$ESh*Zu48>u>%2@RmP$2S%TB;m5w``@*wszaxC~u1|&6{PY{e zcm7bY$EtkY|MJrC-QWC*@L%5ZE^+Pr(o*=uJ$HpWKlFIAMKjRkE~H5wY*4spj)DjhN94yPTtw=WFFgi14ySABpz z714&2;-p@2+2vsoKdR3!`5)HaVW-v6P9@7#v3Wa8ly^Phs*Kp610lHySe9dO4dp#l zle1VpVjN;b!DFWIkAaKHe%yA6%S{+@AxeRuBP%=xguw{GiuYY%A`inf{BaixD9pg} zBrf7x*b0Mr^9)A12Ow`rMq?1XWT?l8iHNneg@A{Pc+*T2vSbSXg(c7Tjg+majsaX| zmds$2-Sze5aQN2MuylSgJba&Sl*q;|>|F}`E?txWytTF~oOxtl*td7DMDnH=9b~Qe zrXTu&@XXtv98RA-7tY~LeEMy-hA)573&OX(?hWDiBab#J^jQLS6R?y;`pMI0!;y!M zhX)^iSla#6Cp|el_i0ZL|LuK$7k>M{ye;g9Pw)8mzaIYMTmPT%yMO!+QT)m;dWoFB z>;*5BySnF)zR80!Z;3KO=zOt{O#1!~>eo&@zAuXD-pMF!?~hqvoqtxhvx>838cMmi zuijd}oeS~ABdbMkx7H%BAwAGiP>B|~2G*h(x&~3JRq4KFv=J{JrK9OpA1hWV_sc)^v*GOd^Wg{I z_=fP<$;S#Qdt(a3(r&Z-K{?YQ6y9SjG4X=D&7~&hDPRCJ1$o{m%riD*XDEwm$bkTX zyIU}0kb^7+ugSI5B}|bm$%twjcm48ysA&LlT5kq71as|&qla|_Fm6pTjrF1Vh23G- zzI|c;p#$O26_?_CFf8ob6J`*^@a$sA@Suwrzsayq%J#wlWq%E=`~tC|zOg3AGdcp! z?>Vp*p8gdNh8v&tNO;PN9}Q3al83^~97lfee|A0WIk*&dA6N|23riAcW#@QyCWn0^ zjsyGmNuc`hCqEUw;k#cGzWMuqDE#VMen0HlwJW^v+0Sy?Y>QQ6yXdzB;fZkXv18#C zul>RB*YA5DgeJnF0|!O;KO^Yq^SP{zJnP>>k3Je6K!E$IfBvfQm9PGm@FPF}W*K$8 z=sC|bL(Q36=`)bzf9evqDB*nyjeCvO&I`F6^PLvVe_{`}sFGgSFzr0t*S1xUI~->` zNwd*^&iW0X4fsC9l;n`luJGpJNkkG@|?%%oPXJ>^&JEI*y3J*3J>f zT2(ubV`_+OV*~y)Whk;-Kg{u*`xg9oK77Sh;mtq#6XDRoLm5_*q;B^i0}-%wb}M*oELQ4;gM?3k{iv1R@-e z=awKQGV_Dck&ekBK?)_gn3JN7Pt6jk{H0`~PMe3WI~(>M+zfZWZx)%o#rts{eSi4mx~V{{)fA;xQ7fC;Joe6-z}MkoDO{5 zcf2}Wd-YY}yMFZF2=5nuyO(vSXlc;AOV6rOhLlf};e@v^TDU-kuG7+(29uN6EY;)QEk|MP?I z562O}F4?vGA(b|0{#L=;zdp{Df3GvSKmmC^OX!!Eo$Mxg=GAEV!y?8j5N)uT7e_;dvLS zTr*3P&F6nSI|`?-eV(V5)f^bl=0CP{YNvGE2zN{-Y3X}Bsvk!2N0=Rh?JapP(`P)V zc0qfbE*Vev@@gTs^Y%acW4YdZ_bXo&e*XXZsqor2{z!QEgw7y&U4C{|(^E;&I$u39 zF1>QSW~LuEK@Ui8W7fHBWJ_5Hb8iafL~z+@3e$v~&6~io6I0nYA%H73vd}SAc<8Fj zBz=%`h!W|L#=glNa1pe49~C#X24S=vE{Gv*`v`G-DA02d#kN_M`9-9l7K5;AD^m&Wn!~#hwC;SGNF9k++Kz3bh9Q+NmW@0TQykKKKD_`45(IK1R}&%+ep z+rvHg-537hGoKFM`Ay#}>sNpEckdM+I3l|C%B#YQpZk0n$vyQ+w}xvFgnsXxe@ae0|0Utz9hZdP|Fd_7Pk#EI ztX&se@tvn#3&{9BHsB2d9Iwy_bQVlHA(*I9Ov32?Y%-pvAGJECPR+G1u*Pqqxy;X{ zeD;kn96Q&b-+fbl9#>_RV(rb*y!7xgF${0GR+1dr^-fs^`krt7_VBYm`jg=`KmPjg=!p}V z36nO2gcJL)4Gt9sIE=2=v0Q{v(;TJ%Wv^MLvNQV}I=ugN6C;eN2_*1gdTf3h+2;7S zj`b{zx$xs3A#Lvg>~hON7or%)S{ob4=v&iFjerMYVHFEVdfDMF7tDKKUS@_MGdwVp zh(Mqb4ReYdNimHak0IWgfhI>YU`s5<7gdLeY*cI_8&*5I=#)jUn#3K;Cy&jCJOA*i zaMQC+g)47b#Yk%_?w5XeFGfz*OkT6@ zzW3hn{!e@?yyW@M3;+Gj_sMAKGe_>1VD+)P?+Wk!+rJT%%MTrr^XtFkyUI9A{t-+XJ4 z1T0jIWao?GK^GY5{;+y?FMH`!F6GO5l9V<#?4}R}%DU6*DVi3~)`DEzBuGWMt2=Tf zduKpxf3^zIO0_UjR4WRdB=3C^>TYe4DN5Ek4zP4fMVx>@X#G$B^4;M}Uhv{@+by?- zFL?HI!#m#fr_IN=u;jE7hrP&|FCOL!2N3C@zTgQ1!3QI#S?;`!^{Gur~?Ct&7#h*Fy zKzRL|e?c<%ZolQ`@O5AQrQ!3R`Hb-D|NZO3n}6ds!-OxMMT_v?m9B;WxI;Weiry5E-pw*@ytfA;pvByXaI{(sDC32#9I;h1-)x@K^|IK9I;3TXiUfX~8 zyT32oh9AElK=$#U{pEWi11EE%R4VEe%fFk+5#kev+bHq+%v~!s*0F3vBBuQ$cHnv~ zTL2({kiL!vOa4BCDTiIaD?Mq< z;#a_Po_a_4nlJm}@GHOj`{9A($HNCcrqh7${_WogS6zOoc>CTDeK@@EInS1xp?~!) zZ;@d2`tSVCaK)vUhQI&V#}KFyr5htaZ_2*0T9*66N;3SQPmi8@EPU`EJ`rBEtUINZK)|j|vg*iL{ox(!c{4QpbO@F2N5(KsR**#$v!E1hjnQk1(Oov^&=HU!RWr(1sF%r=9cwvhJ zcdU|IMbd9KUw=b*3D&QO{Sl1TuDtXzXokS)!e`ueTlhb}7D*d8y#G>hHe0;p zN~4*P1ko^kZxN{`85N8b4YHcq7BP>J%5~X@d%>r+7Z(iqIR{96HQMwzvZK-bdp`F2 z)VR_Vh8QelE<`s%MF{(d76vXtH6qi_<9_h^kqo7hf2T?(DlK=498taSxu1_Ej`xQ* z{=%E`KvhDaKHld5w?82ma)yo1H{{IG1hU4t)gA{!D{%wME7LNw z$Jx4BObbf9x#sXe$RT_o2yv?szz)=vKh%5qqc7Z`RGJ{|X^t;7tP7 z^3rnHw|{py{@`Lb_K8FAc>@>rfKd*kF%FLG*a>S}5~-KbhHI|6LgqagXyi{N>1OM= z_vi!RCx7`@!uP!Lo5SnA^VK54q3JvS>aW9F-}UEgS@<9l8u(nVBM&}^tUD}10*5#H zKJC_9CDV^G-0YWheU=OT;l7G?;8D+5aD3al{w%!wrC$|(>ib_CzWi0M4Ey%%5rH3i z^>@gbLGa$AN5W73%G<)DCr^Yw{qKJjp8ND?gqMHCSK=+3kRZnd3_hHUBS;<`I{OeK zME{btS^HUkBV>%Ip@CH^={-p$2VAIU)vV%l*g-gY{q^FHQ#p69+PcTd@;I>G%l0qW z9Eq|Qs~tI(p?Ys}+pcE9Lh>49Eiv-a0T#-(a6)`6{u>)dWj z*B`z%{O#YrH~iEu{hS7gF45T4-j0>Mioa^`bI485F^)i>VkRJNZ$h2HNfIk$@WW(v zAYpK^j_WEoQs;F^mY}$2;1B%vo44m?^g&mQbgQ`NtszaF>E?47j&Yre7u!`Vc5#Gp z{`4u?UTJ!AL8b=hk-p9wak-t*64tk-vGygiZQK{@De*4V=Mw^(a z`iks>1)tX?TgG$hWqQbM^SQ4U*UI{jyge#A%DEnX4K6xBR#me~OhAd9X#H&(mzylq zG~3+A%a6kPKr{Vf`DMW@Xq);q%g?&$=4WCMtskr1hY_V;EjQKFx|DKy-DWP+K(YW< z4>uEKrHE9s(vQ>cjm)v{WuOdLTw#qN;>L-(c zH4X1mx6CL_kHRwL2Q;Bn%j;rvT+2Dc;F?`8<1IUFJ@un(lTxFP(tV{w8%Zc8)-nkS#ywXM=COrT!c9a&CQoqwaSHkJ3__DgykPL!g#?XDv7WMs zX+UOsKwXUE7A!&BQ;nM8)8Z z1Qf|SL1d9L0A#U=nlz4}(xmL~1|LzY@v*H~$8|o}1=?+E zLsuw<+W~6qie^r#33gyMiq@+trw9>elxlp>DMpQv;*HJz!Z4gJi_!Of6BmVBTJm*Y zR%2zW+7h`_qxiXWs@c1dDD9HRF8y-SHI{={6ch583B$OFQkEPbSRTc6Nz0{B6G4+G zF}2>$t?P7Cqh|v_y%@{BU8N0cUqf$%JxaqxVHBduigtrVnp*OxiJeNS4J#02&?yf_ z4?f%%ckoJPxn4mKZJ>Y&J-M}rx_nqKA79VW$1GzEg4r~mLXVj`-qVW>)e&?s+F)t| z6}jaFrwBQ3I5~k47Wm=;hiVv2F^`bbgUt40Vg@rjxUnqf7FV#3)A|M<+PK}^EUW8Z zY;L8=y!czNf({*q0Viq~M$&O~1dD`hCF?OetGd0Kl-M$&J14CunG_(ERZuT{bT~~B zDoKmzT1$2sNhy$PQe85tQF4=&9C4i5P)wDpStO@M_g>`uZY=i1fFAbHJ>{}(qy6jw z8_cr)V4K?>427{C%Mp}1n$~Zn&$ApmwZQx#aw*eijj~=>W!sc4%r1KFMJAP1>b~h5 z!vMj$dWG82r`FJD%Bm%R(Q6(Vuhc2)l%swrU&HKv3%xXZN$Z}P*)^llw(v;fdOrfz zG^X?Tz(v9^xq_K++ZZVE+Aog`kz0NcpfLEEMrOJUq9DiR9HeEe$k2;(h8zV=V5kNd z1SC{2$2fuQFPJ4bfd?;cBgtZ8V+{cbnHfl4-~$&K;COQ|A9A>XY`1OB%OQYq?WrzWwAGwgwFup;End$Uo<)>QZ(w$t53;T326HY_U0+cvdMC`gn!t zkm?Ay)YBsbhuDfT3A0DZglrC&=gLv1Rs{17ZazUtpCxT$qD35#ed}BNMl(s7Orj`O zl`g|A4uZIR#0?rS%EA;Mmu;ByhXIs2z|eyr#e_C)g3deyEJooUZ zG#{9p){`|X*>PQ`?l9OwfWl2%fq@I_R#P0-F@Ql2e_I$<@#f!cOcQclOCBo^Os2n2 z#VJK?N_>rhDg`MvIR>dLK!I+p&j47lZnASrAQCzOA_n*s5t8_uzRHZqdh+&BCS0$Y z$=lh3)o6rNPe%I^-ECl+f-{oSwCP5xbVSt5W7lMd z(1Oo6m9nsh*JxZe$VizAGeD!yXecbW=j|w~&tQnt_oQYWNeU zB|C!tL>ds}hyly0Jkw@*7;Z@)uU?`gOIlLCNpTd?IWc9bb{@+Svrtze)E-rQn*`E^;F)ZO6?qbNUa}1FUH#cc_Te`!Z5!)cV}fHCERY?J4Gk9woVbetsFD8 zDVOouxyHq)mF@4w?2}Bsm-=~IN^YtTl}j46QkNf|?#nfd;WR_CGc|kWG9V_Bv8kh4 z>``kz_3`_#yu}=NDSXN!s3RvT+?D^VRJ|jvOuK`w9%DxfD2OAAxXC>HHDT;N0?oBxoEpKT#sgKjHNi{6)}|S@r7$5o*}Z1(CLC_RDm2w z{E~sNgwf;9<3tma$;+3q;X3LPvy2%;8b}n^F8MbQ_P8UWOy|nT8)xGDw z+*l;BakD8j?9qjt=;WxmUpZdR%k_rVE(S(pD}uR8V(lv)#q+k1IK-C>TafBn{)dpa zL}}JdEAc#41I^jKtxlQcO&dA5d zgCIE`c^=rWZw0}Pqbe?%VR*-g$(4%p{jIT z1w%>sCBFqM4tFZI#CJvz564qwmrNzP_)Q+nuCR@t&O1ZpoN{u9y zI3}BTWr-3=zU0bhDiXbvX^qBjBPzvf8d{g^D7yEoN0#4*fuf4S?@`}jVEs~k2%hIr z#zQt~k5(^RPbXW$bo-?GuoAECPmQ`0of?j(m6%O?N(SoiQ`Kh$|BN-V7&Bs zGZ#E!l2V&mM|?qH3In3qDQqBtP;~AzH!@hoy44~^TTEX^yg{tMS`+99RY+%_oz`86 z_@oYQ1<17aX^x7f5vVpukn9UaLjEz&9YZ#ZmY8BV&AW;L#T&S|KD8lP9D1qXcT5s8 zpw9qEPH%!XMhTaoJ7=sl?=fudwRs$>~rpqTt4Utp|Y_1O6c zC9+g>GagpUoISoNGuWbU7E4deci^)Q2dQ3V{xE{;+eK;n=H$-(k zLSe9}=7`-Ixm=^36_W3c>>-DMIMwbV+vvbt(PBf@7q8O|ZV(lTI%*R1jwI^mwqzYX z)EAS#FfaM_AkxL{p@cTHHF+y`+P1b{@`Ua5{8YB@UGBrETGE#ul&Wv7=WGA=A$rX| zInPs_nr4mWHFJOXt@KA;iyRWANxYVlmZVZC%EpsidUKLjD>)J0PVwD}{c7)>y1}c6 zQ544eFo&mg-0_4PIHJMe2h)8V(C~~uYH`;jZns4L7&8#FfCof0jDH+;F+mWsg&1b> zJ}Cq$8bB@vqT8%&06Wjb3EX+i&e&Mn42wulU#2{Q)E0(p1Z0roL$Yl8kT+a$&nIyV zLn=O8OFI+bWuWpc(l+8X|4=n#DfID7Qf10F+_uU|) zyeoOs*xAKDSv71uD`HL?UGskV@@UN=5=Fmg)hQ;z5Zgm!3_O<|-8Z?sq2%W-nHt^S z7Nq>5FC27p9Tu8Hi{0ZWss)1e9M85o!VUBgMewRz>aoPntt8Od#fc0A87gk9EKByE z$YM~#oQ7@07VhE7QIsUHBT6w*ol8rKu4f2g^$KfNRK~m>QVgMt)=XjAZ-%2L7+6`v zF6xLovk;!fX1BXAibAd-d7}8K1{X2hl)z;3Y{9Q5Q){%U-B^=8prv%JMH!lZ%P-UqxXPi&Fqnr zkC=n(X>%WnM`)KbXWHz4QWW!bRBKHxI$u2f)hV(M?xuycuI zbv>6-IoE1O9(X{Ch)?)N!X?;VM{M9dRx$&J zcr!y;x!q}6X6aO&wPFv^!X8vuia)Aqx50;lO zs@h&%#t7;xZvI_H*g?RYT95`XP;pBPbpRtX$TIkCF-s5|+-@<$LR_a->~uKTI;7`Y zR3$+EzGFvorb6Ykq86Zzf2`rSa; zg)V&qyLB6-2BrwhH%ygn3F7q6ZU!3@(?Sfr>U39P5Ic~PV>l1t<@ zkED9WPiJ-3>W1#6>%2BLbufN`XYwK*GH7vh#h`^rHeBP$*M2OzNlbF4Z5?~L^6B%l z+zSxTr{c(r>F6BPOvpa7(@1AWE(BtR>?I2zKEReSNY=M7Fq)p@P7|0jq{S5oFC%B2 z;1rx-rl8#Xi*XU|nc~gBbMt&sFH+ed&nE$IFj697(mr$IWrT$|%Da>~^0JZD1nO)r z_Y=$x(Dd!isG}>Q7sU!lQ>IAzIvAD01C%S8hA`e)y%e`=txPzTE0x zyX%!Q-1{~HEf3W%bJnMJ z?ovyihytKnq4zVS_8gWg5>oh%R{Gb}W1*>=uADuUsHqiND_@g*D&;bXZYBFZs+>|2 zk5sFvglm)%n%7*;$PN)j9YNs?7zQeyIZE1M@PUfH`#j^?%cvI3ts@A{GC2>^f1DZQ z6X>bDjeH5l25#TS**cDGcrO}%Uxq&4Oun!BVt^jSD|ouerZ>P#Chks37Xis!mA0u5g1RGUf~jJs zIv8To?8c9!X*J}L-I4zyRPo{3IlSrRUi+F!0YjzaY2Cjj880h#fn+p0 z6P&-96UUeGGNrl>k5`p30W}7Z*cj;sGHd-2X*E{Wh$lu&=(6oHo5phVgOH2~c1WGq zUPKh`R9NNjjpvA|Ca8!l} z%E!&GAWvSh10lc$(MI#ms+M~tvt%nxg<_AiWRz>K+F40f=%{LZRJ``3(%Ug4o^yJE zYS3O`V7Z2*s=391a63|JW6S7Q$Tk1eh^#{l6jrzW`cPQJajO?jB+OQ2{UUBK+nmcxh+d#A$@Tfv zsng-`;cLRlQ~E^uOYi{SJ$rY{lRY?z2wB8EtW(jQ8B7CmQgMP$_Kh7!Izgu}s+z2H9l!s`kCMNY#ttB`%p=nzWXvt;!tGKE;n0DDm=eSjJ?3|Xef#%fISGk;O!!0o1QIha zyke3$<_7s(s*SBRJQ)P@h1lb73IU6X3_|p60*hb)HwH5fVYUy30m4AHfs8`vaCvGA zNf_IBnBz942q&1Rf#+NCpu=)B1>bbX&$`5v{F!uMoZl8 zQkPz7vm2o;nSWp!O$h3jub~VowDAY1HO*=Y&AX8(qj7d*do-*_D0W9*H5l~PycoxG z0`TXL=@P{(`j24q6REM-Ul`YiI$H9|^Ns3l7|qN1GWlNK^NMmytVIw7vuNkKRDqpU zD;gD&shAzB%Ng=Dy3u&9l?_9$CGj0M+fXo_B!^Nn#DRPvP*hEgO8A33PFhOug6XtA z+0l-T+wVgl4`@I@S32deZo-|IUK$?%V?60zvdC778lRU%p6BB zoT1xh(gg-WM3|oEW2c~v4w%QSQk=cx4Bg4cP9Ruedka1i1hawQbI(8Q?MaBcuszc`-4G6hy9Xfy`Myk;N3@1|lD~&e%fGW8OS0f{(7kbYS6j*>1RKN7g(e zR?gPZ6_zJ;z?Jqo#5~eJfwFpOzI&fL1C(zJ@rD% z9#uW!Yn$3-$4jP{nc_>xMit|54Stvpn&rdy|ti&&R0Th4l2vhIaZ zOB|z*I-A}onj9znzy0aIfmzVp;TlD0&^ zq;MezA=ObzmC|&*E;eES@?}bAK`Ye_NW@w3HX}wNJEkj=Z~8n7%XAT>_@2uu6v`Z| z@L()i#ts%MtB5t{7iCbhchBCih;^!!<<)TD;6cfKc=XXn5WMEX?%lh>Bac1`y$$3@ z>_QF(Gt-e}K85K%8f0qW6t=#=Em-gd({~t}Z9sT~XZ*>B2BR~{M27-X+d1mu;En-{ z$2O)5buT9bH;lAoD2QoB*-@8#k=n^i(OcrN#~Byd%O~tqA~t16u`_A@$fZ5U%4(%8 z*QS_8-`Q&wzt)XaZPbqOab8F5{$oIdi2;KJoP; zX!VP69%Yj@xk9h(t{$T0Hd7 z!kOl z={McwpB=tzG&^glfQj?3=WX0c%Eo;itep6TvZrqkyg+RR?Cn_378c)mnrwEyT#?C5c4(B#q zFNUNWnw3qKbSpckLB+bBS!zLusk%-}b__zNy>U!cWQl9oQjRimuTu1nAAj;n^^zv< z1BjF(Pro;;#~+kJBts9wZ5%+sY-rFb6a>k%4aDm4TLOUQ`x3#LIz`PuDu}bCB|~k_ z)Qdt51Td5YivEX;Qsfm4lzXtEs$KV2k+QyL-(K0lViDPZGn+Hv^2;xm`*)enzJKw9ZEtC>5SZ2j7wTzEpEq*z{o*2K?_o~#3iU7><5sYKiohUe zBZm@-YK0GmREn~0JUg3A_60SfJGadgMjK?O6pN*;mcwn8(Uit~Qy8t&NSKbD$>=IK zO0l4F?KYKiL+a6{fq56aI{1x9myDN}av@k$TjC|b$(wEIqFCX{=n^QX?{xUx@dsr+ zN$U7u>t`DXAQ&F?DBFDQJ;Rth8={QJv@W>9b1&YoXn_!E^0}{+op!sJ)Ei#S#m4_e zDw>VLa*7?rfs7u!`su72>m>7jTW&gW`s7KOsbhTM6d;$FxQsNvYffhK*05PRGXRR_`PmI1U4L9F(GZO!BU(`0H^w!t#+>mvo7fx*;tq|L`&ml7d_gKwhdT^R~ zg}C5hzjZ`HJpT$e4o`~_1~F{Eg#7@S%D%xT1S4~U+c0qmIK$^*VU(r60@;w*quQd% zD`ogs9vo6mhU>369QNUr{yAzPb7O8^fO6 zyXDu-)1Lg4aN84asmP9cAKEJVK+bl%+7x0N)y|4{$-aHznYTX`AI5q8C{Wb?M8qmQ zkAKiw-yab@e~1N>A0k`IP&Yq{_KCpG+M44IukoV1vo;O%)4*|Vim_~7HrF&G^qq?? z>l4j*&RzN;2Wa9G&+(6+KM7PgHQ7ys~q8sx9nOMPpTS#r^V?lU(7ROP%fHETxu>@;ac%arK z)~%2X$o-;76IYv03m}_A8`e}sGS%`Duwds(1Qf2NojG^Tv9~4AoH=(kJa+n&()n#D z;e}H=qQ3xS*h-z=VnX)C{a1LL2HL_@Sg>%T9Ils6VmXK}3Uogrqy-CR39F<{k{k*5# z5gvHxczE#Phms;n@@o=xXF|7DA*z{B|)jY zg`_*OR&$!v@)r?vvKd!=R?E%%V19S$#Lt$nqtm9s#u`0ew*m+8g+Y|N8SUA#N3#Ex zmX^bb6OUqdq=m2>i55$XOJNnaI6Zdc6n3qc47)J0`s}Cg5BDCq7gK`=!u8ibA)I*Z z6t-Z(yT`RArmt@!0&QRz#>dukR5gt$KrVDmpw1@;Gg2}#ZgbZP(Ab4s^CHH~4D$Xk zs$%LPo!iDRj*XaR#FD0HFQm80cVBG1CygvCURx~n

    ak&8&7XIK+=xWamC`3awMu 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

  1. 9**Gc9*DP5zEz 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] +# Defaults to `dev` if no version is given. + +set -euo pipefail + +VERSION="${1:-dev}" +BUNDLE_NAME="CodeBurnMenubar.app" +BUNDLE_ID="org.agentseal.codeburn-menubar" +EXECUTABLE_NAME="CodeBurnMenubar" +MIN_MACOS="14.0" + +repo_root() { + git rev-parse --show-toplevel 2>/dev/null || (cd "$(dirname "$0")/../.." && pwd) +} + +ROOT=$(repo_root) +MAC_DIR="${ROOT}/mac" +DIST_DIR="${MAC_DIR}/.build/dist" + +cd "${MAC_DIR}" + +echo "▸ Cleaning previous dist..." +rm -rf "${DIST_DIR}" +mkdir -p "${DIST_DIR}" + +echo "▸ Building universal binary (arm64 + x86_64)..." +swift build -c release --arch arm64 --arch x86_64 + +BIN_PATH=$(swift build -c release --arch arm64 --arch x86_64 --show-bin-path) +BUILT_BINARY="${BIN_PATH}/${EXECUTABLE_NAME}" +if [[ ! -x "${BUILT_BINARY}" ]]; then + echo "Binary not found at ${BUILT_BINARY}" >&2 + exit 1 +fi + +echo "▸ Assembling ${BUNDLE_NAME}..." +BUNDLE="${DIST_DIR}/${BUNDLE_NAME}" +mkdir -p "${BUNDLE}/Contents/MacOS" +mkdir -p "${BUNDLE}/Contents/Resources" +cp "${BUILT_BINARY}" "${BUNDLE}/Contents/MacOS/${EXECUTABLE_NAME}" + +cat > "${BUNDLE}/Contents/Info.plist" < + + + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + CodeBurn Menubar + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFile + AppIcon + CFBundleIdentifier + ${BUNDLE_ID} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${EXECUTABLE_NAME} + CFBundlePackageType + APPL + CFBundleShortVersionString + ${VERSION} + CFBundleVersion + ${VERSION} + LSMinimumSystemVersion + ${MIN_MACOS} + LSUIElement + + NSHighResolutionCapable + + NSHumanReadableCopyright + © AgentSeal + + +PLIST + +cat > "${BUNDLE}/Contents/PkgInfo" <<'PKG' +APPL???? +PKG + +# Ad-hoc sign so macOS treats the bundle as internally consistent. This does NOT give us a +# recognisable developer name in Finder (that needs the $99 Developer ID cert), but it +# satisfies macOS's minimum bundle-validity checks on 14+ and prevents some Gatekeeper edge +# cases on managed Macs. +echo "▸ Ad-hoc signing..." +codesign --force --sign - --timestamp=none --deep "${BUNDLE}" 2>/dev/null || true +codesign --verify --deep --strict "${BUNDLE}" 2>/dev/null || echo " (signature verify skipped)" + +ZIP_NAME="CodeBurnMenubar-${VERSION}.zip" +ZIP_PATH="${DIST_DIR}/${ZIP_NAME}" +echo "▸ Packaging ${ZIP_NAME}..." +(cd "${DIST_DIR}" && /usr/bin/ditto -c -k --keepParent "${BUNDLE_NAME}" "${ZIP_NAME}") + +echo "" +echo "✓ Built ${ZIP_PATH}" +ls -la "${DIST_DIR}" diff --git a/mac/Sources/CodeBurnMenubar/AppStore.swift b/mac/Sources/CodeBurnMenubar/AppStore.swift new file mode 100644 index 0000000..cd26d76 --- /dev/null +++ b/mac/Sources/CodeBurnMenubar/AppStore.swift @@ -0,0 +1,307 @@ +import Foundation +import Observation + +private let cacheTTLSeconds: TimeInterval = 300 + +struct CachedPayload { + let payload: MenubarPayload + let fetchedAt: Date + var isFresh: Bool { Date().timeIntervalSince(fetchedAt) < cacheTTLSeconds } +} + +struct PayloadCacheKey: Hashable { + let period: Period + let provider: ProviderFilter +} + +@MainActor +@Observable +final class AppStore { + var selectedProvider: ProviderFilter = .all + var selectedPeriod: Period = .today + var selectedInsight: InsightMode = .trend + var currency: String = "USD" + var isLoading: Bool = false + var lastError: String? + var subscription: SubscriptionUsage? + var subscriptionError: String? + var subscriptionLoadState: SubscriptionLoadState = .idle + var capacityEstimates: [String: CapacityEstimate] = [:] + + private var cache: [PayloadCacheKey: CachedPayload] = [:] + + private var currentKey: PayloadCacheKey { + PayloadCacheKey(period: selectedPeriod, provider: selectedProvider) + } + + var payload: MenubarPayload { + cache[currentKey]?.payload ?? .empty + } + + /// Today (across all providers) is pinned for the always-visible menubar icon, independent of + /// the popover's selected period or provider. + var todayPayload: MenubarPayload? { + cache[PayloadCacheKey(period: .today, provider: .all)]?.payload + } + + var hasCachedData: Bool { + cache[currentKey] != nil + } + + var findingsCount: Int { + payload.optimize.findingCount + } + + /// Switch to a period. Uses cached payload if fresh; otherwise fetches. + func switchTo(period: Period) async { + selectedPeriod = period + if let cached = cache[currentKey], cached.isFresh { return } + await refresh(includeOptimize: true) + } + + /// Switch to a provider filter. Uses cached payload if fresh; otherwise fetches. + func switchTo(provider: ProviderFilter) async { + selectedProvider = provider + if let cached = cache[currentKey], cached.isFresh { return } + await refresh(includeOptimize: true) + } + + private var inFlightKeys: Set = [] + + /// Refresh the currently selected (period, provider) combination. Guards against concurrent + /// fetches for the same key so a slow initial request can't overwrite a newer one that + /// finished first (which would show stale numbers the user has already moved past). + func refresh(includeOptimize: Bool) async { + let key = currentKey + guard !inFlightKeys.contains(key) else { return } + inFlightKeys.insert(key) + isLoading = true + defer { + inFlightKeys.remove(key) + isLoading = false + } + do { + let fresh = try await DataClient.fetch(period: key.period, provider: key.provider, includeOptimize: includeOptimize) + cache[key] = CachedPayload(payload: fresh, fetchedAt: Date()) + lastError = nil + } catch { + lastError = String(describing: error) + NSLog("CodeBurn: fetch failed for \(key.period.rawValue)/\(key.provider.rawValue): \(error)") + } + } + + /// Background refresh for a period other than the visible one (e.g. keeping today fresh for the menubar badge). + /// Does not toggle isLoading, so the popover's loading overlay is unaffected. + /// Always uses the .all provider since the menubar badge shows total spend. + func refreshQuietly(period: Period) async { + do { + let fresh = try await DataClient.fetch(period: period, provider: .all, includeOptimize: true) + cache[PayloadCacheKey(period: period, provider: .all)] = CachedPayload(payload: fresh, fetchedAt: Date()) + } catch { + NSLog("CodeBurn: quiet refresh failed for \(period.rawValue): \(error)") + } + } + + /// Fetch Claude subscription usage. Sets subscription = nil on missing creds (API users / unauthenticated). + /// Triggered lazily when the user opens the Plan pill, so the Keychain prompt only fires on intent. + func refreshSubscription() async { + subscriptionLoadState = .loading + do { + let usage = try await SubscriptionClient.fetch() + subscription = usage + subscriptionError = nil + subscriptionLoadState = .loaded + await captureSnapshots(for: usage) + } catch SubscriptionError.noCredentials { + subscription = nil + subscriptionError = nil + subscriptionLoadState = .noCredentials + } catch { + subscription = nil + subscriptionError = String(describing: error) + subscriptionLoadState = .failed + NSLog("CodeBurn: subscription fetch failed: \(error)") + } + } + + /// Persist one snapshot per window so we can answer "what did the prior cycle end at?" + /// when the current window has just reset and projection from current data isn't meaningful. + /// Also computes the effective_tokens consumed inside each 7-day window from local history, + /// which the CapacityEstimator uses to derive the absolute token capacity per tier. + private func captureSnapshots(for usage: SubscriptionUsage) async { + let now = Date() + let history = payload.history.daily + + let captures: [(key: String, percent: Double?, resetsAt: Date?, effective: Double?)] = [ + ("five_hour", usage.fiveHourPercent, usage.fiveHourResetsAt, nil), + ("seven_day", usage.sevenDayPercent, usage.sevenDayResetsAt, + effectiveTokensInLast7Days(history: history, asOf: now)), + ("seven_day_opus", usage.sevenDayOpusPercent, usage.sevenDayOpusResetsAt, nil), + ("seven_day_sonnet", usage.sevenDaySonnetPercent, usage.sevenDaySonnetResetsAt, nil), + ] + for capture in captures { + guard let percent = capture.percent, let resetsAt = capture.resetsAt else { continue } + await SubscriptionSnapshotStore.record(SubscriptionSnapshot( + windowKey: capture.key, + percent: percent, + resetsAt: resetsAt, + capturedAt: now, + effectiveTokens: capture.effective + )) + } + + await refreshCapacityEstimates() + } + + /// Sum effective tokens (input + 5*output + cache_creation + 0.1*cache_read) across the + /// last 7 days of dailyHistory. Used as the "tokens consumed in 7-day window" reading paired + /// with the API-reported percent for capacity estimation. + private func effectiveTokensInLast7Days(history: [DailyHistoryEntry], asOf now: Date) -> Double { + let cutoff = ISO8601DateFormatter().string(from: now.addingTimeInterval(-7 * 86400)).prefix(10) + return history + .filter { $0.date >= cutoff } + .reduce(0.0) { $0 + $1.effectiveTokens } + } + + /// Run CapacityEstimator over each window's accumulated snapshots. Only snapshots with a + /// non-nil effectiveTokens contribute. Result lives in capacityEstimates dict for UI gating. + private func refreshCapacityEstimates() async { + var next: [String: CapacityEstimate] = [:] + for key in ["seven_day", "seven_day_opus", "seven_day_sonnet"] { + let snaps = await SubscriptionSnapshotStore.snapshots(for: key) + let capacitySnaps = snaps.compactMap { s -> CapacitySnapshot? in + guard let effective = s.effectiveTokens, effective > 0 else { return nil } + return CapacitySnapshot(percent: s.percent, effectiveTokens: effective, capturedAt: s.capturedAt) + } + if let estimate = CapacityEstimator.estimate(capacitySnaps) { + next[key] = estimate + } + } + capacityEstimates = next + } +} + +enum SupportedCurrency: String, CaseIterable, Identifiable { + case USD, GBP, EUR, AUD, CAD, NZD, JPY, CHF, INR, BRL, SEK, SGD, HKD, KRW, MXN, ZAR, DKK + var id: String { rawValue } + var displayName: String { + switch self { + case .USD: "US Dollar" + case .GBP: "British Pound" + case .EUR: "Euro" + case .AUD: "Australian Dollar" + case .CAD: "Canadian Dollar" + case .NZD: "New Zealand Dollar" + case .JPY: "Japanese Yen" + case .CHF: "Swiss Franc" + case .INR: "Indian Rupee" + case .BRL: "Brazilian Real" + case .SEK: "Swedish Krona" + case .SGD: "Singapore Dollar" + case .HKD: "Hong Kong Dollar" + case .KRW: "South Korean Won" + case .MXN: "Mexican Peso" + case .ZAR: "South African Rand" + case .DKK: "Danish Krone" + } + } +} + +enum ProviderFilter: String, CaseIterable, Identifiable { + case all = "All" + case claude = "Claude" + case codex = "Codex" + case cursor = "Cursor" + case copilot = "Copilot" + + var id: String { rawValue } + + /// Maps to the CLI's `--provider` argument values. + var cliArg: String { + switch self { + case .all: "all" + case .claude: "claude" + case .codex: "codex" + case .cursor: "cursor" + case .copilot: "copilot" + } + } +} + +enum SubscriptionLoadState: Sendable, Equatable { + case idle // never tried, awaiting user intent + case loading // fetch in progress + case loaded // success; subscription is populated + case noCredentials // tried; user has no Claude OAuth (API user / not logged in) + case failed // tried; error occurred +} + +enum InsightMode: String, CaseIterable, Identifiable { + case plan = "Plan" + case trend = "Trend" + case forecast = "Forecast" + case pulse = "Pulse" + case stats = "Stats" + var id: String { rawValue } +} + +enum Period: String, CaseIterable, Identifiable { + case today = "Today" + case sevenDays = "7 Days" + case thirtyDays = "30 Days" + case month = "Month" + case all = "All" + + var id: String { rawValue } + + /// Maps to the CLI's `--period` argument values. + var cliArg: String { + switch self { + case .today: "today" + case .sevenDays: "week" + case .thirtyDays: "30days" + case .month: "month" + case .all: "all" + } + } +} + +/// NumberFormatter is expensive to instantiate (~microseconds each) and currency/token values +/// are formatted dozens of times per popover refresh. These shared instances avoid thousands of +/// allocations per frame while SwiftUI's Observation framework still triggers redraws when +/// CurrencyState.shared mutates. +private let groupedDecimalFormatter: NumberFormatter = { + let f = NumberFormatter() + f.numberStyle = .decimal + f.groupingSeparator = "," + f.decimalSeparator = "." + f.maximumFractionDigits = 2 + f.minimumFractionDigits = 2 + return f +}() + +private let thousandsFormatter: NumberFormatter = { + let f = NumberFormatter() + f.numberStyle = .decimal + f.groupingSeparator = "," + return f +}() + +extension Double { + func asCurrency() -> String { + let state = CurrencyState.shared + let converted = self * state.rate + return state.symbol + (groupedDecimalFormatter.string(from: NSNumber(value: converted)) ?? "\(converted)") + } + + func asCompactCurrency() -> String { + let state = CurrencyState.shared + return String(format: "\(state.symbol)%.2f", self * state.rate) + } +} + +extension Int { + func asThousandsSeparated() -> String { + thousandsFormatter.string(from: NSNumber(value: self)) ?? "\(self)" + } +} diff --git a/mac/Sources/CodeBurnMenubar/CodeBurnApp.swift b/mac/Sources/CodeBurnMenubar/CodeBurnApp.swift new file mode 100644 index 0000000..9a18364 --- /dev/null +++ b/mac/Sources/CodeBurnMenubar/CodeBurnApp.swift @@ -0,0 +1,182 @@ +import SwiftUI +import AppKit +import Observation + +private let refreshIntervalSeconds: UInt64 = 60 +private let nanosPerSecond: UInt64 = 1_000_000_000 +private let refreshIntervalNanos: UInt64 = refreshIntervalSeconds * nanosPerSecond +/// Fixed so the popover's anchor point doesn't shift each time today's cost changes. +private let statusItemFixedWidth: CGFloat = 130 +private let popoverWidth: CGFloat = 360 +private let popoverHeight: CGFloat = 660 +private let menubarTitleFontSize: CGFloat = 13 + +@main +struct CodeBurnApp: App { + @NSApplicationDelegateAdaptor(AppDelegate.self) var delegate + + var body: some Scene { + // SwiftUI App needs at least one scene. Settings is invisible by default. + Settings { + EmptyView() + } + } +} + +@MainActor +final class AppDelegate: NSObject, NSApplicationDelegate, NSPopoverDelegate { + private var statusItem: NSStatusItem! + private var popover: NSPopover! + private let store = AppStore() + private var refreshTask: Task? + + func applicationDidFinishLaunching(_ notification: Notification) { + // Menubar accessory -- no Dock icon, no app switcher entry. + NSApp.setActivationPolicy(.accessory) + + restorePersistedCurrency() + setupStatusItem() + setupPopover() + observeStore() + startRefreshLoop() + // Subscription is fetched lazily when the user opens the Plan pill, so the macOS + // Keychain prompt never fires until the user explicitly asks for it. + } + + /// Loads the currency code persisted by `codeburn currency` so a relaunch picks up where + /// the user left off. Rate is resolved from the on-disk FX cache if present, otherwise + /// fetched live in the background. + private func restorePersistedCurrency() { + guard let code = CLICurrencyConfig.loadCode(), code != "USD" else { return } + let symbol = CurrencyState.symbolForCode(code) + store.currency = code + + Task { + let cached = await FXRateCache.shared.cachedRate(for: code) + await MainActor.run { + CurrencyState.shared.apply(code: code, rate: cached, symbol: symbol) + } + let fresh = await FXRateCache.shared.rate(for: code) + if let fresh, fresh != cached { + await MainActor.run { + CurrencyState.shared.apply(code: code, rate: fresh, symbol: symbol) + } + } + } + } + + func applicationWillTerminate(_ notification: Notification) { + refreshTask?.cancel() + } + + private func startRefreshLoop() { + refreshTask = Task { [weak self] in + while !Task.isCancelled { + guard let self else { return } + if self.store.selectedPeriod != .today { + await self.store.refreshQuietly(period: .today) + } + // Optimize is fast (~1s warm-cache) so include findings on every refresh. + await self.store.refresh(includeOptimize: true) + try? await Task.sleep(nanoseconds: refreshIntervalNanos) + } + } + } + + private func observeStore() { + withObservationTracking { + _ = store.payload + _ = store.todayPayload + } onChange: { [weak self] in + Task { @MainActor in + self?.refreshStatusButton() + self?.observeStore() + } + } + } + + // MARK: - Status Item + + private func setupStatusItem() { + // Fixed width so the popover anchor (and thus popover position) doesn't shift + // every time today's cost or findings badge changes. + statusItem = NSStatusBar.system.statusItem(withLength: statusItemFixedWidth) + guard let button = statusItem.button else { return } + button.target = self + button.action = #selector(handleButtonClick(_:)) + button.sendAction(on: [.leftMouseUp, .rightMouseUp]) + refreshStatusButton() + } + + /// Composes the menubar title as a single attributed string with the flame as an inline + /// NSTextAttachment. NSStatusItem's separate `image` + `attributedTitle` path leaves a + /// stubborn gap between icon and text on some macOS releases (the icon hugs the left edge + /// of the status item, the title starts at its own baseline), so we inline both so they + /// flow as one typographic unit with a single, controllable gap. + private func refreshStatusButton() { + guard let button = statusItem.button else { return } + + // Clear any previously-set image so the attachment is the only glyph rendered. + button.image = nil + button.imagePosition = .noImage + + let font = NSFont.monospacedDigitSystemFont(ofSize: menubarTitleFontSize, weight: .medium) + let flameConfig = NSImage.SymbolConfiguration(pointSize: menubarTitleFontSize, weight: .medium) + let flame = NSImage(systemSymbolName: "flame.fill", accessibilityDescription: "CodeBurn")? + .withSymbolConfiguration(flameConfig) + flame?.isTemplate = true + + let attachment = NSTextAttachment() + attachment.image = flame + if let size = flame?.size { + // Nudge the image down ~2pt so its visual centre sits on the text baseline mid-line + // rather than riding high. Exact value tuned against SF Pro Display 13pt. + attachment.bounds = CGRect(x: 0, y: -2, width: size.width, height: size.height) + } + + let hasPayload = store.todayPayload != nil + let valueText = " " + (store.todayPayload?.current.cost.asCompactCurrency() ?? "$—") + let color: NSColor = hasPayload ? .labelColor : .secondaryLabelColor + + let composed = NSMutableAttributedString() + composed.append(NSAttributedString(attachment: attachment)) + composed.append(NSAttributedString( + string: valueText, + attributes: [.font: font, .foregroundColor: color] + )) + button.attributedTitle = composed + } + + // MARK: - Popover + + private func setupPopover() { + popover = NSPopover() + popover.contentSize = NSSize(width: popoverWidth, height: popoverHeight) + popover.behavior = .transient // auto-close only on explicit outside click + popover.animates = true + popover.delegate = self + + let content = MenuBarContent() + .environment(store) + .frame(width: popoverWidth) + + popover.contentViewController = NSHostingController(rootView: content) + } + + @objc private func handleButtonClick(_ sender: AnyObject?) { + guard let button = statusItem.button else { return } + if popover.isShown { + popover.performClose(sender) + } else { + NSApp.activate(ignoringOtherApps: true) + popover.show(relativeTo: button.bounds, of: button, preferredEdge: .minY) + popover.contentViewController?.view.window?.makeKey() + } + } + + // MARK: - NSPopoverDelegate + + func popoverShouldDetach(_ popover: NSPopover) -> Bool { + false + } +} diff --git a/mac/Sources/CodeBurnMenubar/CurrencyState.swift b/mac/Sources/CodeBurnMenubar/CurrencyState.swift new file mode 100644 index 0000000..e668139 --- /dev/null +++ b/mac/Sources/CodeBurnMenubar/CurrencyState.swift @@ -0,0 +1,209 @@ +import Foundation +import Observation + +private let fxCacheTTLSeconds: TimeInterval = 24 * 3600 +private let frankfurterBaseURL = "https://api.frankfurter.app/latest?from=USD&to=" +/// Defensive bounds on any fetched FX rate. Real-world USD→X rates sit in [0.0001, 200000] +/// for every ISO 4217 pair; anything outside is either a parser bug or a MITM poisoning +/// attempt. We clamp hard so UI can't render NaN, negative, or astronomical numbers. +private let minValidFXRate: Double = 0.0001 +private let maxValidFXRate: Double = 1_000_000 +private let fxFetchTimeoutSeconds: TimeInterval = 10 + +@Observable +final class CurrencyState: @unchecked Sendable { + static let shared = CurrencyState() + + var code: String = "USD" + var rate: Double = 1.0 + var symbol: String = "$" + + private init() {} + + /// Applies a new currency context. Callers must invoke on the main actor so @Observable + /// view updates run on the UI thread. Rejects non-finite or out-of-band rates so a + /// poisoned Frankfurter response can't corrupt displayed costs. + func apply(code: String, rate: Double?, symbol: String) { + self.code = code + self.symbol = symbol + if let r = rate, r.isFinite, r >= minValidFXRate, r <= maxValidFXRate { + self.rate = r + } + } + + static func symbolForCode(_ code: String) -> String { + // Some locales return "US$" for USD or "CA$" for CAD via NumberFormatter. Prefer the + // plain glyph form everyone recognises. + if let override = symbolOverrides[code] { return override } + let formatter = NumberFormatter() + formatter.numberStyle = .currency + formatter.currencyCode = code + formatter.locale = Locale(identifier: "en_\(code.prefix(2))") + return formatter.currencySymbol ?? code + } + + private static let symbolOverrides: [String: String] = [ + "USD": "$", + "CAD": "$", + "AUD": "$", + "NZD": "$", + "HKD": "$", + "SGD": "$", + "MXN": "$", + "EUR": "\u{20AC}", + "GBP": "\u{00A3}", + "JPY": "\u{00A5}", + "CNY": "\u{00A5}", + "KRW": "\u{20A9}", + "INR": "\u{20B9}", + "BRL": "R$", + "CHF": "CHF", + "SEK": "kr", + "DKK": "kr", + "ZAR": "R" + ] +} + +actor FXRateCache { + static let shared = FXRateCache() + + private struct Entry: Codable { + let rate: Double + let savedAt: TimeInterval + } + + private var entries: [String: Entry] = [:] + private var loaded = false + + private var cacheFilePath: String { + let base = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask)[0] + return base + .appendingPathComponent("codeburn-mac", isDirectory: true) + .appendingPathComponent("fx-rates.json") + .path + } + + private func loadIfNeeded() { + guard !loaded else { return } + loaded = true + do { + let data = try SafeFile.read(from: cacheFilePath) + let decoded = try JSONDecoder().decode([String: Entry].self, from: data) + // Drop any persisted entries whose rate violates the sanity bounds -- covers an + // old cache that was written before the clamp was introduced. + entries = decoded.filter { _, entry in + entry.rate.isFinite && entry.rate >= minValidFXRate && entry.rate <= maxValidFXRate + } + } catch { + entries = [:] + } + } + + private func persist() { + guard let data = try? JSONEncoder().encode(entries) else { return } + try? SafeFile.write(data, to: cacheFilePath) + } + + /// Returns a cached rate regardless of freshness. Nil if never fetched. + func cachedRate(for code: String) -> Double? { + if code == "USD" { return 1.0 } + loadIfNeeded() + return entries[code]?.rate + } + + /// Returns a fresh rate, fetching from Frankfurter when cache is stale or absent. Nil on + /// failure. The returned rate is always finite, positive, and within the sanity bounds. + func rate(for code: String) async -> Double? { + if code == "USD" { return 1.0 } + loadIfNeeded() + + if let entry = entries[code], + Date().timeIntervalSince1970 - entry.savedAt < fxCacheTTLSeconds { + return entry.rate + } + + guard let url = URL(string: "\(frankfurterBaseURL)\(code)") else { return entries[code]?.rate } + + let config = URLSessionConfiguration.ephemeral + config.timeoutIntervalForRequest = fxFetchTimeoutSeconds + config.tlsMinimumSupportedProtocolVersion = .TLSv12 + let session = URLSession(configuration: config) + + do { + let (data, response) = try await session.data(from: url) + guard let http = response as? HTTPURLResponse, http.statusCode == 200 else { + return entries[code]?.rate + } + struct Response: Decodable { let rates: [String: Double] } + let decoded = try JSONDecoder().decode(Response.self, from: data) + guard let fresh = decoded.rates[code], + fresh.isFinite, fresh >= minValidFXRate, fresh <= maxValidFXRate else { + NSLog("CodeBurn: discarding out-of-band FX rate for \(code)") + return entries[code]?.rate + } + entries[code] = Entry(rate: fresh, savedAt: Date().timeIntervalSince1970) + persist() + return fresh + } catch { + return entries[code]?.rate + } + } +} + +/// Reads and writes the CLI's persisted currency config (~/.config/codeburn/config.json). +/// Uses an on-disk flock so a concurrent `codeburn currency ...` invocation from a terminal +/// can't race the menubar and silently drop each other's writes (TOCTOU on config.json). +enum CLICurrencyConfig { + private static var configDir: String { + (NSHomeDirectory() as NSString).appendingPathComponent(".config/codeburn") + } + private static var configPath: String { + (configDir as NSString).appendingPathComponent("config.json") + } + private static var lockPath: String { + (configDir as NSString).appendingPathComponent(".config.lock") + } + + static func loadCode() -> String? { + guard + let data = try? SafeFile.read(from: configPath), + let json = try? JSONSerialization.jsonObject(with: data) as? [String: Any], + let currency = json["currency"] as? [String: Any], + let code = currency["code"] as? String + else { + return nil + } + return code.uppercased() + } + + static func persist(code: String) { + do { + try SafeFile.withExclusiveLock(at: lockPath) { + var existing: [String: Any] = [:] + if let data = try? SafeFile.read(from: configPath), + let parsed = try? JSONSerialization.jsonObject(with: data) as? [String: Any] { + existing = parsed + } + + if code == "USD" { + existing.removeValue(forKey: "currency") + } else { + existing["currency"] = [ + "code": code, + "symbol": CurrencyState.symbolForCode(code) + ] + } + + guard let data = try? JSONSerialization.data( + withJSONObject: existing, + options: [.prettyPrinted, .sortedKeys] + ) else { + return + } + try SafeFile.write(data, to: configPath, mode: 0o600) + } + } catch { + NSLog("CodeBurn: failed to persist currency config: \(error)") + } + } +} diff --git a/mac/Sources/CodeBurnMenubar/Data/CapacityEstimator.swift b/mac/Sources/CodeBurnMenubar/Data/CapacityEstimator.swift new file mode 100644 index 0000000..446d0e7 --- /dev/null +++ b/mac/Sources/CodeBurnMenubar/Data/CapacityEstimator.swift @@ -0,0 +1,127 @@ +import Foundation + +public struct CapacitySnapshot: Sendable, Equatable { + public let percent: Double // 0..100, Anthropic-reported utilization + public let effectiveTokens: Double // weighted sum of input/output/cache tokens consumed at capture + public let capturedAt: Date + + public init(percent: Double, effectiveTokens: Double, capturedAt: Date) { + self.percent = percent + self.effectiveTokens = effectiveTokens + self.capturedAt = capturedAt + } +} + +public enum CapacityConfidence: String, Sendable { + case low, medium, solid +} + +public struct CapacityEstimate: Sendable, Equatable { + public let capacity: Double // tokens equivalent to 100% + public let confidence: CapacityConfidence + public let sampleSize: Int // post-decorrelation count + public let nonLinearityWarning: Bool + + public init(capacity: Double, confidence: CapacityConfidence, sampleSize: Int, nonLinearityWarning: Bool) { + self.capacity = capacity + self.confidence = confidence + self.sampleSize = sampleSize + self.nonLinearityWarning = nonLinearityWarning + } +} + +public enum CapacityEstimator { + private static let minSampleSize = 5 + private static let minPercentRange = 15.0 + private static let recencyHalfLifeSeconds: Double = 30 * 86400 + private static let solidR2 = 0.97 + private static let mediumR2 = 0.85 + private static let solidSampleThreshold = 15 + private static let mediumSampleThreshold = 6 + private static let nonLinearityRunLengthThreshold = 0.7 + + public static func estimate(_ snapshots: [CapacitySnapshot], asOf now: Date = Date()) -> CapacityEstimate? { + guard snapshots.count >= minSampleSize else { return nil } + let percents = snapshots.map(\.percent) + let range = (percents.max() ?? 0) - (percents.min() ?? 0) + guard range >= minPercentRange else { return nil } + + let weighted = snapshots.map { snap -> (p: Double, t: Double, w: Double) in + let ageSeconds = now.timeIntervalSince(snap.capturedAt) + let weight = pow(0.5, max(0, ageSeconds) / recencyHalfLifeSeconds) + return (snap.percent, snap.effectiveTokens, weight) + } + + // Weighted least squares through origin: minimize sum(w * (t - p * cap/100)^2) + // Solution: cap = 100 * sum(w * t * p) / sum(w * p * p) + let numerator = weighted.reduce(0.0) { $0 + $1.w * $1.t * $1.p } + let denominator = weighted.reduce(0.0) { $0 + $1.w * $1.p * $1.p } + guard denominator > 0 else { return nil } + let capacity = 100.0 * numerator / denominator + guard capacity > 0 else { return nil } + + // Weighted R^2 against the through-origin fit. + let weightedTokenSum = weighted.reduce(0.0) { $0 + $1.w * $1.t } + let weightSum = weighted.reduce(0.0) { $0 + $1.w } + let weightedMeanT = weightedTokenSum / max(weightSum, .ulpOfOne) + let ssRes = weighted.reduce(0.0) { acc, s in + let predicted = s.p * capacity / 100 + let diff = s.t - predicted + return acc + s.w * diff * diff + } + let ssTot = weighted.reduce(0.0) { acc, s in + let diff = s.t - weightedMeanT + return acc + s.w * diff * diff + } + let r2 = ssTot > 0 ? max(0.0, 1.0 - ssRes / ssTot) : 0.0 + + let n = snapshots.count + let confidence: CapacityConfidence = { + if n >= solidSampleThreshold && r2 >= solidR2 { return .solid } + if n >= mediumSampleThreshold && r2 >= mediumR2 { return .medium } + return .low + }() + + let nonLinearityWarning = detectNonLinearity(snapshots: weighted, capacity: capacity) + + return CapacityEstimate( + capacity: capacity, + confidence: confidence, + sampleSize: n, + nonLinearityWarning: nonLinearityWarning + ) + } + + /// Sign-test on residuals across the percent range. If residuals form a long monotonic run + /// (e.g. all-negative in low percents then all-positive at high), the relationship isn't linear. + private static func detectNonLinearity( + snapshots: [(p: Double, t: Double, w: Double)], + capacity: Double + ) -> Bool { + let sorted = snapshots.sorted { $0.p < $1.p } + let signs = sorted.map { s -> Int in + let predicted = s.p * capacity / 100 + let diff = s.t - predicted + if abs(diff) < .ulpOfOne { return 0 } + return diff > 0 ? 1 : -1 + }.filter { $0 != 0 } + guard signs.count >= minSampleSize else { return false } + + // Longest single-sign run length / total + var longestRun = 0 + var currentRun = 0 + var currentSign = 0 + for s in signs { + if s == currentSign { + currentRun += 1 + } else { + longestRun = max(longestRun, currentRun) + currentSign = s + currentRun = 1 + } + } + longestRun = max(longestRun, currentRun) + let runFraction = Double(longestRun) / Double(signs.count) + return runFraction >= nonLinearityRunLengthThreshold + } +} diff --git a/mac/Sources/CodeBurnMenubar/Data/DataClient.swift b/mac/Sources/CodeBurnMenubar/Data/DataClient.swift new file mode 100644 index 0000000..6e4dbeb --- /dev/null +++ b/mac/Sources/CodeBurnMenubar/Data/DataClient.swift @@ -0,0 +1,107 @@ +import Foundation + +/// Upper bound on payload + stderr bytes read from the CLI. Real payloads top out near 500 KB +/// (365 days of history with dozens of models); anything larger is pathological and truncating +/// prevents unbounded memory growth. Hard timeout guards against a hung CLI keeping Process and +/// Pipe file descriptors pinned forever. +private let maxPayloadBytes = 20 * 1024 * 1024 +private let maxStderrBytes = 256 * 1024 +private let spawnTimeoutSeconds: UInt64 = 60 + +enum DataClientError: Error { + case spawn(String) + case nonZeroExit(code: Int32, stderr: String) + case decode(Error) + case timeout + case outputTooLarge +} + +/// Runs the CLI via argv (no shell interpretation). See `CodeburnCLI` for why we never route +/// commands through `/bin/zsh -c` anymore. +struct DataClient { + static func fetch(period: Period, provider: ProviderFilter, includeOptimize: Bool) async throws -> MenubarPayload { + var subcommand = [ + "status", + "--format", "menubar-json", + "--period", period.cliArg, + "--provider", provider.cliArg, + ] + if !includeOptimize { + subcommand.append("--no-optimize") + } + + let result = try await runCLI(subcommand: subcommand) + guard result.exitCode == 0 else { + throw DataClientError.nonZeroExit(code: result.exitCode, stderr: result.stderr) + } + do { + return try JSONDecoder().decode(MenubarPayload.self, from: result.stdout) + } catch { + throw DataClientError.decode(error) + } + } + + private struct ProcessResult { + let stdout: Data + let stderr: String + let exitCode: Int32 + } + + private static func runCLI(subcommand: [String]) async throws -> ProcessResult { + let process = CodeburnCLI.makeProcess(subcommand: subcommand) + + let outPipe = Pipe() + let errPipe = Pipe() + process.standardOutput = outPipe + process.standardError = errPipe + + do { + try process.run() + } catch { + throw DataClientError.spawn(error.localizedDescription) + } + + // Drain both pipes concurrently so a large stderr can't deadlock stdout (the child + // blocks on write once the pipe buffer fills). `drain` also enforces a byte cap. + async let stdoutData = drain(outPipe.fileHandleForReading, limit: maxPayloadBytes) + async let stderrData = drain(errPipe.fileHandleForReading, limit: maxStderrBytes) + + // Wall-clock timeout: if the CLI hangs (parser stuck, disk stall), kill it. + let timeoutTask = Task.detached(priority: .utility) { + try? await Task.sleep(nanoseconds: spawnTimeoutSeconds * 1_000_000_000) + if process.isRunning { + process.terminate() + } + } + defer { timeoutTask.cancel() } + + let (out, err) = await (stdoutData, stderrData) + process.waitUntilExit() + + if out.count >= maxPayloadBytes { + throw DataClientError.outputTooLarge + } + + let stderrString = String(data: err, encoding: .utf8) ?? "" + return ProcessResult(stdout: out, stderr: stderrString, exitCode: process.terminationStatus) + } + + /// Pulls bytes off a pipe until EOF or `limit`. Intentionally uses `availableData`, which + /// returns empty on EOF -- no blocking once the child exits. + private static func drain(_ handle: FileHandle, limit: Int) async -> Data { + await Task.detached(priority: .utility) { + var buffer = Data() + while buffer.count < limit { + let chunk = handle.availableData + if chunk.isEmpty { break } + let remaining = limit - buffer.count + if chunk.count > remaining { + buffer.append(chunk.prefix(remaining)) + break + } + buffer.append(chunk) + } + return buffer + }.value + } +} diff --git a/mac/Sources/CodeBurnMenubar/Data/MenubarPayload.swift b/mac/Sources/CodeBurnMenubar/Data/MenubarPayload.swift new file mode 100644 index 0000000..2e44fae --- /dev/null +++ b/mac/Sources/CodeBurnMenubar/Data/MenubarPayload.swift @@ -0,0 +1,123 @@ +import Foundation + +/// Shape of `codeburn status --format menubar-json --period `. +/// `current` is scoped to the requested period; the whole payload reflects that slice. +struct MenubarPayload: Codable, Sendable { + let generated: String + let current: CurrentBlock + let optimize: OptimizeBlock + let history: HistoryBlock +} + +struct HistoryBlock: Codable, Sendable { + let daily: [DailyHistoryEntry] +} + +struct DailyModelBreakdown: Codable, Sendable { + let name: String + let cost: Double + let calls: Int + let inputTokens: Int + let outputTokens: Int + + var totalTokens: Int { inputTokens + outputTokens } +} + +struct DailyHistoryEntry: Codable, Sendable { + let date: String + let cost: Double + let calls: Int + let inputTokens: Int + let outputTokens: Int + let cacheReadTokens: Int + let cacheWriteTokens: Int + let topModels: [DailyModelBreakdown] + + /// Pricing-ratio prior: input + 5x output + cache_creation + 0.1x cache_read. + /// Matches Anthropic's published per-token pricing on Sonnet/Opus closely enough to be a useful proxy. + var effectiveTokens: Double { + Double(inputTokens) + 5.0 * Double(outputTokens) + Double(cacheWriteTokens) + 0.1 * Double(cacheReadTokens) + } +} + +extension DailyHistoryEntry { + /// Required for legacy payloads (no topModels emitted yet). + enum CodingKeys: String, CodingKey { + case date, cost, calls, inputTokens, outputTokens, cacheReadTokens, cacheWriteTokens, topModels + } + init(from decoder: Decoder) throws { + let c = try decoder.container(keyedBy: CodingKeys.self) + date = try c.decode(String.self, forKey: .date) + cost = try c.decode(Double.self, forKey: .cost) + calls = try c.decode(Int.self, forKey: .calls) + inputTokens = try c.decode(Int.self, forKey: .inputTokens) + outputTokens = try c.decode(Int.self, forKey: .outputTokens) + cacheReadTokens = try c.decode(Int.self, forKey: .cacheReadTokens) + cacheWriteTokens = try c.decode(Int.self, forKey: .cacheWriteTokens) + topModels = try c.decodeIfPresent([DailyModelBreakdown].self, forKey: .topModels) ?? [] + } +} + +struct CurrentBlock: Codable, Sendable { + let label: String + let cost: Double + let calls: Int + let sessions: Int + let oneShotRate: Double? + let inputTokens: Int + let outputTokens: Int + let cacheHitPercent: Double + let topActivities: [ActivityEntry] + let topModels: [ModelEntry] + let providers: [String: Double] +} + +struct ActivityEntry: Codable, Sendable { + let name: String + let cost: Double + let turns: Int + let oneShotRate: Double? +} + +struct ModelEntry: Codable, Sendable { + let name: String + let cost: Double + let calls: Int +} + +struct OptimizeBlock: Codable, Sendable { + let findingCount: Int + let savingsUSD: Double + let topFindings: [FindingEntry] +} + +struct FindingEntry: Codable, Sendable { + let title: String + let impact: String + let savingsUSD: Double +} + +// MARK: - Empty fallback + +extension MenubarPayload { + /// Strictly-empty payload. Used as the fallback before real data arrives, so no + /// plausible-looking fake numbers leak into the UI. + static let empty = MenubarPayload( + generated: "", + current: CurrentBlock( + label: "", + cost: 0, + calls: 0, + sessions: 0, + oneShotRate: nil, + inputTokens: 0, + outputTokens: 0, + cacheHitPercent: 0, + topActivities: [], + topModels: [], + providers: [:] + ), + optimize: OptimizeBlock(findingCount: 0, savingsUSD: 0, topFindings: []), + history: HistoryBlock(daily: []) + ) +} diff --git a/mac/Sources/CodeBurnMenubar/Data/SubscriptionClient.swift b/mac/Sources/CodeBurnMenubar/Data/SubscriptionClient.swift new file mode 100644 index 0000000..79c5794 --- /dev/null +++ b/mac/Sources/CodeBurnMenubar/Data/SubscriptionClient.swift @@ -0,0 +1,306 @@ +import Foundation +import Security + +private let credentialsRelativePath = ".claude/.credentials.json" +private let keychainService = "Claude Code-credentials" +private let oauthClientID = "9d1c250a-e61b-44d9-88ed-5944d1962f5e" +private let refreshURL = URL(string: "https://platform.claude.com/v1/oauth/token")! +private let usageURL = URL(string: "https://api.anthropic.com/api/oauth/usage")! +private let betaHeader = "oauth-2025-04-20" +private let userAgent = "claude-code/2.1.0" +private let requestTimeout: TimeInterval = 30 + +/// Claude Code writes Keychain items with `kSecAttrAccount = "default"`. Filtering on this +/// prevents a planted Keychain item from another app (or a stale install with a mangled +/// account) from being accepted as our source of OAuth credentials. +private let expectedKeychainAccounts: Set = ["default"] +private let maxCredentialBytes = 64 * 1024 + +enum SubscriptionError: Error, LocalizedError { + case noCredentials + case credentialsInvalid + case refreshFailed(Int, String?) + case usageFetchFailed(Int, String?) + case decodeFailed(Error) + + var errorDescription: String? { + switch self { + case .noCredentials: "No Claude OAuth credentials found" + case .credentialsInvalid: "Claude OAuth credentials malformed" + case let .refreshFailed(code, body): "Token refresh failed (\(code))\(body.map { ": \($0)" } ?? "")" + case let .usageFetchFailed(code, body): "Usage fetch failed (\(code))\(body.map { ": \($0)" } ?? "")" + case let .decodeFailed(err): "Decode failed: \(err.localizedDescription)" + } + } +} + +struct SubscriptionClient { + static func fetch() async throws -> SubscriptionUsage { + let creds = try loadCredentials() + + // Try the usage call with the existing token first. Only refresh on 401. + do { + let response = try await fetchUsage(token: creds.accessToken) + return mapResponse(response, rawTier: creds.rateLimitTier) + } catch SubscriptionError.usageFetchFailed(401, _) { + guard let refreshToken = creds.refreshToken, !refreshToken.isEmpty else { + throw SubscriptionError.usageFetchFailed(401, "no refresh token available") + } + let newToken = try await refreshAccessToken(refreshToken: refreshToken) + let response = try await fetchUsage(token: newToken) + return mapResponse(response, rawTier: creds.rateLimitTier) + } + } + + // MARK: - Credentials + + private static func loadCredentials() throws -> StoredCredentials { + if let data = try readFileCredentials() { + return try parseCredentials(data: sanitizeKeychainData(data)) + } + if let creds = try readKeychainCredentials() { + return creds + } + throw SubscriptionError.noCredentials + } + + private static func readFileCredentials() throws -> Data? { + let url = FileManager.default.homeDirectoryForCurrentUser.appendingPathComponent(credentialsRelativePath) + guard FileManager.default.fileExists(atPath: url.path) else { return nil } + // SafeFile refuses to follow symlinks and caps the read, so a 6 GB /dev/urandom + // masquerading as the creds file can't blow up the app. + return try SafeFile.read(from: url.path, maxBytes: maxCredentialBytes) + } + + /// Two-phase keychain enumeration: (1) list persistent refs + accounts, (2) fetch each + /// item's data by ref. The combination kSecMatchLimitAll + kSecReturnData errors with -50, + /// so the data fetch has to be per-item. + private static func readKeychainCredentials() throws -> StoredCredentials? { + let listQuery: [String: Any] = [ + kSecClass as String: kSecClassGenericPassword, + kSecAttrService as String: keychainService, + kSecMatchLimit as String: kSecMatchLimitAll, + kSecReturnAttributes as String: true, + kSecReturnPersistentRef as String: true, + ] + var listResult: CFTypeRef? + let listStatus = SecItemCopyMatching(listQuery as CFDictionary, &listResult) + if listStatus == errSecItemNotFound { + NSLog("CodeBurn: keychain query found no items for service \(keychainService)") + return nil + } + guard listStatus == errSecSuccess, let rows = listResult as? [[String: Any]] else { + NSLog("CodeBurn: keychain enumerate failed status=\(listStatus)") + return nil + } + + var best: StoredCredentials? = nil + for row in rows { + guard let ref = row[kSecValuePersistentRef as String] as? Data else { continue } + let account = (row[kSecAttrAccount as String] as? String) ?? "" + // Ignore rows whose account doesn't match Claude Code's known writer. Stops another + // app's item (or a legacy install with an unexpected account) from being accepted. + guard expectedKeychainAccounts.contains(account) else { continue } + let dataQuery: [String: Any] = [ + kSecClass as String: kSecClassGenericPassword, + kSecValuePersistentRef as String: ref, + kSecMatchLimit as String: kSecMatchLimitOne, + kSecReturnData as String: true, + ] + var dataResult: CFTypeRef? + let dataStatus = SecItemCopyMatching(dataQuery as CFDictionary, &dataResult) + guard dataStatus == errSecSuccess, let data = dataResult as? Data else { continue } + let sanitized = sanitizeKeychainData(data) + guard let parsed = try? parseCredentials(data: sanitized) else { continue } + if let current = best { + if (parsed.expiresAt ?? .distantPast) > (current.expiresAt ?? .distantPast) { + best = parsed + } + } else { + best = parsed + } + } + return best + } + + /// Claude Code's keychain writer line-wraps long string values (newline + leading spaces) + /// mid-token, producing JSON with literal control chars and stray spaces inside string + /// values. Replace every newline (CR/LF) plus the run of spaces/tabs that follows it. + /// Drops both the wrapping in tokens AND pretty-print indentation between fields (both + /// produce valid, compact JSON afterward). + private static func sanitizeKeychainData(_ data: Data) -> Data { + guard var s = String(data: data, encoding: .utf8) else { return data } + s = s.replacingOccurrences(of: "\r", with: "") + let regex = try? NSRegularExpression(pattern: "\\n[ \\t]*", options: []) + if let regex { + let range = NSRange(s.startIndex.. StoredCredentials { + do { + let root = try JSONDecoder().decode(CredentialsRoot.self, from: data) + guard let oauth = root.claudeAiOauth else { throw SubscriptionError.credentialsInvalid } + let token = oauth.accessToken?.trimmingCharacters(in: .whitespacesAndNewlines) ?? "" + guard !token.isEmpty else { throw SubscriptionError.credentialsInvalid } + let expiresAt = oauth.expiresAt.map { Date(timeIntervalSince1970: $0 / 1000.0) } + return StoredCredentials( + accessToken: token, + refreshToken: oauth.refreshToken, + expiresAt: expiresAt, + rateLimitTier: oauth.rateLimitTier + ) + } catch let err as SubscriptionError { + throw err + } catch { + throw SubscriptionError.decodeFailed(error) + } + } + + // MARK: - Refresh + + private static func refreshAccessToken(refreshToken: String) async throws -> String { + var request = URLRequest(url: refreshURL) + request.httpMethod = "POST" + request.timeoutInterval = requestTimeout + request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type") + request.setValue("application/json", forHTTPHeaderField: "Accept") + var components = URLComponents() + components.queryItems = [ + URLQueryItem(name: "grant_type", value: "refresh_token"), + URLQueryItem(name: "refresh_token", value: refreshToken), + URLQueryItem(name: "client_id", value: oauthClientID), + ] + request.httpBody = (components.percentEncodedQuery ?? "").data(using: .utf8) + + let (data, response) = try await URLSession.shared.data(for: request) + guard let http = response as? HTTPURLResponse else { + throw SubscriptionError.refreshFailed(-1, nil) + } + guard http.statusCode == 200 else { + let body = String(data: data, encoding: .utf8) + throw SubscriptionError.refreshFailed(http.statusCode, body) + } + do { + let decoded = try JSONDecoder().decode(TokenRefreshResponse.self, from: data) + return decoded.accessToken + } catch { + throw SubscriptionError.decodeFailed(error) + } + } + + // MARK: - Usage fetch + + private static func fetchUsage(token: String) async throws -> UsageResponse { + var request = URLRequest(url: usageURL) + request.httpMethod = "GET" + request.timeoutInterval = requestTimeout + request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization") + request.setValue("application/json", forHTTPHeaderField: "Accept") + request.setValue(betaHeader, forHTTPHeaderField: "anthropic-beta") + request.setValue(userAgent, forHTTPHeaderField: "User-Agent") + + let (data, response) = try await URLSession.shared.data(for: request) + guard let http = response as? HTTPURLResponse else { + throw SubscriptionError.usageFetchFailed(-1, nil) + } + guard http.statusCode == 200 else { + let body = String(data: data, encoding: .utf8) + throw SubscriptionError.usageFetchFailed(http.statusCode, body) + } + do { + return try JSONDecoder().decode(UsageResponse.self, from: data) + } catch { + throw SubscriptionError.decodeFailed(error) + } + } + + // MARK: - Mapping + + private static func mapResponse(_ r: UsageResponse, rawTier: String?) -> SubscriptionUsage { + SubscriptionUsage( + tier: SubscriptionUsage.tier(from: rawTier), + rawTier: rawTier, + fiveHourPercent: r.fiveHour?.utilization, + fiveHourResetsAt: parseDate(r.fiveHour?.resetsAt), + sevenDayPercent: r.sevenDay?.utilization, + sevenDayResetsAt: parseDate(r.sevenDay?.resetsAt), + sevenDayOpusPercent: r.sevenDayOpus?.utilization, + sevenDayOpusResetsAt: parseDate(r.sevenDayOpus?.resetsAt), + sevenDaySonnetPercent: r.sevenDaySonnet?.utilization, + sevenDaySonnetResetsAt: parseDate(r.sevenDaySonnet?.resetsAt), + fetchedAt: Date() + ) + } + + private static func parseDate(_ s: String?) -> Date? { + guard let s, !s.isEmpty else { return nil } + let f = ISO8601DateFormatter() + f.formatOptions = [.withInternetDateTime, .withFractionalSeconds] + if let d = f.date(from: s) { return d } + f.formatOptions = [.withInternetDateTime] + return f.date(from: s) + } +} + +// MARK: - Internal models + +private struct StoredCredentials { + let accessToken: String + let refreshToken: String? + let expiresAt: Date? + let rateLimitTier: String? +} + +private struct CredentialsRoot: Decodable { + let claudeAiOauth: OAuthBlock? +} + +private struct OAuthBlock: Decodable { + let accessToken: String? + let refreshToken: String? + let expiresAt: Double? + let rateLimitTier: String? +} + +private struct TokenRefreshResponse: Decodable { + let accessToken: String + let refreshToken: String? + let expiresIn: Int? + + enum CodingKeys: String, CodingKey { + case accessToken = "access_token" + case refreshToken = "refresh_token" + case expiresIn = "expires_in" + } +} + +private struct UsageResponse: Decodable { + let fiveHour: Window? + let sevenDay: Window? + let sevenDayOpus: Window? + let sevenDaySonnet: Window? + + enum CodingKeys: String, CodingKey { + case fiveHour = "five_hour" + case sevenDay = "seven_day" + case sevenDayOpus = "seven_day_opus" + case sevenDaySonnet = "seven_day_sonnet" + } +} + +private struct Window: Decodable { + let utilization: Double? + let resetsAt: String? + + enum CodingKeys: String, CodingKey { + case utilization + case resetsAt = "resets_at" + } +} diff --git a/mac/Sources/CodeBurnMenubar/Data/SubscriptionSnapshotStore.swift b/mac/Sources/CodeBurnMenubar/Data/SubscriptionSnapshotStore.swift new file mode 100644 index 0000000..931154a --- /dev/null +++ b/mac/Sources/CodeBurnMenubar/Data/SubscriptionSnapshotStore.swift @@ -0,0 +1,102 @@ +import Foundation + +/// Persisted snapshot of a single utilization reading. We capture one per window every time +/// SubscriptionClient.fetch() succeeds so we can answer "what did the prior 7-day cycle finish at?" +/// when the current window has no usable data yet (just reset). +struct SubscriptionSnapshot: Codable, Sendable { + let windowKey: String // "five_hour", "seven_day", "seven_day_opus", "seven_day_sonnet" + let percent: Double // 0..100 + let resetsAt: Date // resets_at active at capture (identifies which window cycle this belongs to) + let capturedAt: Date // when the snapshot was recorded + let effectiveTokens: Double? // tokens consumed in window at capture (nil if not computed) +} + +private let snapshotFilename = "subscription-snapshots.json" +private let pruneOlderThanSeconds: TimeInterval = 30 * 24 * 3600 + +private func snapshotsCacheDir() -> String { + return ProcessInfo.processInfo.environment["CODEBURN_CACHE_DIR"] + ?? (NSHomeDirectory() as NSString).appendingPathComponent(".cache/codeburn") +} + +private func snapshotsPath() -> String { + return (snapshotsCacheDir() as NSString).appendingPathComponent(snapshotFilename) +} + +private actor SnapshotLock { + static let shared = SnapshotLock() + func run(_ fn: () throws -> T) rethrows -> T { try fn() } +} + +enum SubscriptionSnapshotStore { + /// Append a snapshot. Auto-prunes entries older than 30 days. Idempotent: if a snapshot + /// with the same windowKey + resetsAt already exists, only update percent if new is higher + /// (so "final" reading near reset is preserved). + static func record(_ snapshot: SubscriptionSnapshot) async { + await SnapshotLock.shared.run { + do { + var all = loadAll() + let key = "\(snapshot.windowKey)|\(snapshot.resetsAt.timeIntervalSince1970)" + if let idx = all.firstIndex(where: { "\($0.windowKey)|\($0.resetsAt.timeIntervalSince1970)" == key }) { + if snapshot.percent > all[idx].percent { + all[idx] = snapshot + } + } else { + all.append(snapshot) + } + let cutoff = Date().addingTimeInterval(-pruneOlderThanSeconds) + all = all.filter { $0.capturedAt >= cutoff } + try save(all) + } catch { + NSLog("CodeBurn: snapshot record failed: \(error)") + } + } + } + + /// Returns the final percent of the immediately-prior cycle for this window, or nil if no + /// prior data is available. Logic: among snapshots whose resetsAt < currentResetsAt, pick + /// the group with the largest resetsAt (most recent prior cycle), then return the max + /// percent in that group (the closest-to-final reading we have). + static func previousWindowFinal(windowKey: String, currentResetsAt: Date) async -> Double? { + await SnapshotLock.shared.run { + let all = loadAll() + let priors = all.filter { $0.windowKey == windowKey && $0.resetsAt < currentResetsAt } + guard let mostRecentPriorReset = priors.map({ $0.resetsAt }).max() else { return nil } + let priorWindow = priors.filter { $0.resetsAt == mostRecentPriorReset } + return priorWindow.map(\.percent).max() + } + } + + /// Return all snapshots for a given window key, useful for capacity estimation. + static func snapshots(for windowKey: String) async -> [SubscriptionSnapshot] { + await SnapshotLock.shared.run { + loadAll().filter { $0.windowKey == windowKey } + } + } + + /// Test seam: clear all snapshots. + static func resetForTesting() async { + await SnapshotLock.shared.run { + try? FileManager.default.removeItem(atPath: snapshotsPath()) + } + } + + // MARK: - Internals + + private static func loadAll() -> [SubscriptionSnapshot] { + let path = snapshotsPath() + guard FileManager.default.fileExists(atPath: path) else { return [] } + guard let data = try? SafeFile.read(from: path) else { return [] } + let decoder = JSONDecoder() + decoder.dateDecodingStrategy = .iso8601 + return (try? decoder.decode([SubscriptionSnapshot].self, from: data)) ?? [] + } + + private static func save(_ snapshots: [SubscriptionSnapshot]) throws { + let encoder = JSONEncoder() + encoder.dateEncodingStrategy = .iso8601 + let data = try encoder.encode(snapshots) + // SafeFile.write refuses symlinked targets and does the tmp+rename atomic dance. + try SafeFile.write(data, to: snapshotsPath(), mode: 0o600) + } +} diff --git a/mac/Sources/CodeBurnMenubar/Data/SubscriptionUsage.swift b/mac/Sources/CodeBurnMenubar/Data/SubscriptionUsage.swift new file mode 100644 index 0000000..350983f --- /dev/null +++ b/mac/Sources/CodeBurnMenubar/Data/SubscriptionUsage.swift @@ -0,0 +1,46 @@ +import Foundation + +struct SubscriptionUsage: Sendable, Equatable { + enum Tier: String, Sendable, Equatable { + case pro + case max5x + case max20x + case team + case enterprise + case unknown + + var displayName: String { + switch self { + case .pro: "Pro" + case .max5x: "Max 5x" + case .max20x: "Max 20x" + case .team: "Team" + case .enterprise: "Enterprise" + case .unknown: "Subscription" + } + } + } + + let tier: Tier + let rawTier: String? + let fiveHourPercent: Double? + let fiveHourResetsAt: Date? + let sevenDayPercent: Double? + let sevenDayResetsAt: Date? + let sevenDayOpusPercent: Double? + let sevenDayOpusResetsAt: Date? + let sevenDaySonnetPercent: Double? + let sevenDaySonnetResetsAt: Date? + let fetchedAt: Date + + static func tier(from raw: String?) -> Tier { + guard let raw = raw?.lowercased() else { return .unknown } + if raw.contains("max_20x") || raw.contains("max20x") || raw.contains("max-20x") { return .max20x } + if raw.contains("max_5x") || raw.contains("max5x") || raw.contains("max-5x") { return .max5x } + if raw.contains("max") { return .max5x } + if raw.contains("pro") { return .pro } + if raw.contains("team") { return .team } + if raw.contains("enterprise") { return .enterprise } + return .unknown + } +} diff --git a/mac/Sources/CodeBurnMenubar/Security/CodeburnCLI.swift b/mac/Sources/CodeBurnMenubar/Security/CodeburnCLI.swift new file mode 100644 index 0000000..d86987a --- /dev/null +++ b/mac/Sources/CodeBurnMenubar/Security/CodeburnCLI.swift @@ -0,0 +1,59 @@ +import Foundation + +/// Single entry point for spawning the `codeburn` CLI. All callers route through here so the +/// binary argv is validated once and no code path ever passes user-influenced strings through +/// a shell (`/bin/zsh -c`, `open --args`, AppleScript). This closes the shell-injection attack +/// surface end-to-end. +enum CodeburnCLI { + /// Matches a plain file path / program name: alphanumerics, dot, underscore, slash, hyphen, + /// space. Deliberately excludes shell metacharacters (`$`, `;`, `&`, `|`, quotes, backticks, + /// newlines) so a malicious `CODEBURN_BIN="codeburn; rm -rf ~"` can't slip through. + private static let safeArgPattern = try! NSRegularExpression(pattern: "^[A-Za-z0-9 ._/\\-]+$") + + /// PATH additions for GUI-launched apps, which otherwise get a minimal PATH that misses + /// Homebrew and npm global installs. + private static let additionalPathEntries = ["/opt/homebrew/bin", "/usr/local/bin"] + + /// Returns the argv that launches the CLI. Dev override via `CODEBURN_BIN` is honoured only + /// if every whitespace-delimited token passes `safeArgPattern`. Otherwise falls back to the + /// plain `codeburn` name (resolved via PATH). + static func baseArgv() -> [String] { + guard let raw = ProcessInfo.processInfo.environment["CODEBURN_BIN"], !raw.isEmpty else { + return ["codeburn"] + } + let parts = raw.split(separator: " ", omittingEmptySubsequences: true).map(String.init) + guard parts.allSatisfy(isSafe) else { + NSLog("CodeBurn: refusing unsafe CODEBURN_BIN; using default 'codeburn'") + return ["codeburn"] + } + return parts + } + + /// Builds a `Process` that runs the CLI with the given subcommand args. Uses `/usr/bin/env` + /// so PATH lookup happens without involving a shell, and augments PATH with Homebrew + /// defaults. Caller sets stdout/stderr pipes and calls `run()`. + static func makeProcess(subcommand: [String]) -> Process { + let process = Process() + process.executableURL = URL(fileURLWithPath: "/usr/bin/env") + var environment = ProcessInfo.processInfo.environment + environment["PATH"] = augmentedPath(environment["PATH"] ?? "") + process.environment = environment + // `env --` treats everything following as argv, not VAR=val pairs -- guards against an + // argument accidentally resembling an env assignment. + process.arguments = ["--"] + baseArgv() + subcommand + return process + } + + static func isSafe(_ s: String) -> Bool { + let range = NSRange(s.startIndex.. String { + var parts = existing.split(separator: ":", omittingEmptySubsequences: true).map(String.init) + for extra in additionalPathEntries where !parts.contains(extra) { + parts.append(extra) + } + return parts.joined(separator: ":") + } +} diff --git a/mac/Sources/CodeBurnMenubar/Security/SafeFile.swift b/mac/Sources/CodeBurnMenubar/Security/SafeFile.swift new file mode 100644 index 0000000..3d6bda5 --- /dev/null +++ b/mac/Sources/CodeBurnMenubar/Security/SafeFile.swift @@ -0,0 +1,128 @@ +import Foundation + +/// Symlink-safe file I/O with atomic writes and optional cross-process flock. +/// +/// Every cache file we touch (`~/Library/Caches/codeburn-mac/fx-rates.json`, +/// `~/.cache/codeburn/subscription-snapshots.json`, `~/.config/codeburn/config.json`) is a +/// legitimate target for a local-symlink attack: if an attacker plants a symlink from one of +/// those paths to, say, `~/.ssh/config`, a naive `Data.write(to:)` blindly follows the link and +/// clobbers the real file. `O_NOFOLLOW` on the write() refuses the operation instead. +enum SafeFile { + enum Error: Swift.Error { + case symlinkDetected(String) + case openFailed(String, Int32) + case writeFailed(String, Int32) + case renameFailed(String, Int32) + case readFailed(String, Int32) + case sizeLimitExceeded(String, Int) + } + + /// Default max bytes when reading untrusted cache files. Prevents a malicious cache file + /// from exhausting memory in the Swift process. + static let defaultReadLimit = 8 * 1024 * 1024 + + /// Refuses to follow symlinks and writes atomically via a tmp file + rename. `mode` is the + /// final file permission (0o600 by default so cache files stay user-private). + static func write(_ data: Data, to path: String, mode: mode_t = 0o600) throws { + let parent = (path as NSString).deletingLastPathComponent + try FileManager.default.createDirectory( + atPath: parent, + withIntermediateDirectories: true, + attributes: [.posixPermissions: NSNumber(value: 0o700)] + ) + + // Reject if the existing file is a symlink. We use lstat so the link itself is + // inspected, not its target. + var linkInfo = stat() + if lstat(path, &linkInfo) == 0, (linkInfo.st_mode & S_IFMT) == S_IFLNK { + throw Error.symlinkDetected(path) + } + + let tmpPath = parent + "/.codeburn-" + UUID().uuidString + ".tmp" + let flags: Int32 = O_CREAT | O_WRONLY | O_EXCL | O_NOFOLLOW + let fd = Darwin.open(tmpPath, flags, mode) + guard fd >= 0 else { + throw Error.openFailed(tmpPath, errno) + } + + let writeResult: Int = data.withUnsafeBytes { buffer -> Int in + guard let base = buffer.baseAddress else { return 0 } + return Darwin.write(fd, base, buffer.count) + } + let writeErrno = errno + fsync(fd) + Darwin.close(fd) + + guard writeResult == data.count else { + unlink(tmpPath) + throw Error.writeFailed(tmpPath, writeErrno) + } + + if rename(tmpPath, path) != 0 { + let renameErrno = errno + unlink(tmpPath) + throw Error.renameFailed(path, renameErrno) + } + } + + /// Refuses to read through a symlink. `maxBytes` bounds the read so a tampered cache file + /// can't balloon the process. + static func read(from path: String, maxBytes: Int = defaultReadLimit) throws -> Data { + var linkInfo = stat() + guard lstat(path, &linkInfo) == 0 else { + throw Error.readFailed(path, errno) + } + if (linkInfo.st_mode & S_IFMT) == S_IFLNK { + throw Error.symlinkDetected(path) + } + + let fd = Darwin.open(path, O_RDONLY | O_NOFOLLOW) + guard fd >= 0 else { + throw Error.readFailed(path, errno) + } + defer { Darwin.close(fd) } + + let size = Int(linkInfo.st_size) + if size > maxBytes { + throw Error.sizeLimitExceeded(path, size) + } + + var data = Data(count: size) + let readBytes: Int = data.withUnsafeMutableBytes { buffer -> Int in + guard let base = buffer.baseAddress else { return 0 } + return Darwin.read(fd, base, buffer.count) + } + guard readBytes >= 0 else { + throw Error.readFailed(path, errno) + } + if readBytes < size { + data = data.prefix(readBytes) + } + return data + } + + /// Runs `body` while holding an exclusive POSIX advisory lock on `path`. The lock file is + /// created if missing (with 0o600 permissions) and released on scope exit, so other + /// codeburn processes (the CLI running in a terminal, say) block on the same file instead + /// of racing on a shared config. + static func withExclusiveLock(at path: String, body: () throws -> T) throws -> T { + let parent = (path as NSString).deletingLastPathComponent + try FileManager.default.createDirectory( + atPath: parent, + withIntermediateDirectories: true, + attributes: [.posixPermissions: NSNumber(value: 0o700)] + ) + let fd = Darwin.open(path, O_CREAT | O_RDWR | O_NOFOLLOW, 0o600) + guard fd >= 0 else { + throw Error.openFailed(path, errno) + } + defer { Darwin.close(fd) } + + guard flock(fd, LOCK_EX) == 0 else { + throw Error.openFailed(path, errno) + } + defer { _ = flock(fd, LOCK_UN) } + + return try body() + } +} diff --git a/mac/Sources/CodeBurnMenubar/Security/TerminalLauncher.swift b/mac/Sources/CodeBurnMenubar/Security/TerminalLauncher.swift new file mode 100644 index 0000000..09f8dad --- /dev/null +++ b/mac/Sources/CodeBurnMenubar/Security/TerminalLauncher.swift @@ -0,0 +1,40 @@ +import AppKit +import Foundation + +/// Opens a codeburn subcommand in the user's Terminal. The argv is validated through +/// `CodeburnCLI.isSafe` before it's interpolated into AppleScript so there's no path for a +/// rogue environment variable to smuggle shell metacharacters into the `do script` call. +/// Falls back to a detached headless spawn on machines without Terminal.app (iTerm/Ghostty/Warp +/// users) so the subcommand still runs. +enum TerminalLauncher { + private static let terminalPaths = [ + "/System/Applications/Utilities/Terminal.app", + "/Applications/Utilities/Terminal.app", + ] + + static func open(subcommand: [String]) { + let argv = CodeburnCLI.baseArgv() + subcommand + guard argv.allSatisfy(CodeburnCLI.isSafe) else { + NSLog("CodeBurn: refusing to open terminal with unsafe argv") + return + } + let command = argv.joined(separator: " ") + + if terminalPaths.contains(where: FileManager.default.fileExists(atPath:)) { + let script = """ + tell application "Terminal" + activate + do script "\(command)" + end tell + """ + let process = Process() + process.executableURL = URL(fileURLWithPath: "/usr/bin/osascript") + process.arguments = ["-e", script] + try? process.run() + return + } + + let headless = CodeburnCLI.makeProcess(subcommand: subcommand) + try? headless.run() + } +} diff --git a/mac/Sources/CodeBurnMenubar/Theme/Theme.swift b/mac/Sources/CodeBurnMenubar/Theme/Theme.swift new file mode 100644 index 0000000..de79860 --- /dev/null +++ b/mac/Sources/CodeBurnMenubar/Theme/Theme.swift @@ -0,0 +1,32 @@ +import SwiftUI + +/// Design tokens. Warm terracotta-ember palette, not generic orange. +enum Theme { + static let brandAccent = Color(red: 0xC9/255.0, green: 0x52/255.0, blue: 0x1D/255.0) + static let brandAccentDark = Color(red: 0xE8/255.0, green: 0x77/255.0, blue: 0x4A/255.0) + static let brandEmberDeep = Color(red: 0x8B/255.0, green: 0x3E/255.0, blue: 0x13/255.0) + static let brandEmberGlow = Color(red: 0xF0/255.0, green: 0xA0/255.0, blue: 0x70/255.0) + + static let warmSurface = Color(red: 0xFA/255.0, green: 0xF7/255.0, blue: 0xF3/255.0) + static let warmSurfaceDark = Color(red: 0x1C/255.0, green: 0x18/255.0, blue: 0x16/255.0) + + static let categoricalClaude = Color(red: 0xC9/255.0, green: 0x52/255.0, blue: 0x1D/255.0) + static let categoricalCursor = Color(red: 0x3F/255.0, green: 0x6B/255.0, blue: 0x8C/255.0) + static let categoricalCodex = Color(red: 0x4A/255.0, green: 0x7D/255.0, blue: 0x5C/255.0) + + static let oneShotGood = Color(red: 0x30/255.0, green: 0xD1/255.0, blue: 0x58/255.0) + static let oneShotMid = Color(red: 0xFF/255.0, green: 0x9F/255.0, blue: 0x0A/255.0) + static let oneShotLow = Color(red: 0xFF/255.0, green: 0x45/255.0, blue: 0x3A/255.0) + + // Semantic colors -- tuned to sit alongside the terracotta accent without clashing. + static let semanticDanger = Color(red: 0xC8/255.0, green: 0x3F/255.0, blue: 0x2C/255.0) // brick-red, terracotta-leaning + static let semanticWarning = Color(red: 0xD9/255.0, green: 0x8F/255.0, blue: 0x29/255.0) // amber, warmer than vanilla + static let semanticSuccess = Color(red: 0x4E/255.0, green: 0xA8/255.0, blue: 0x65/255.0) // muted green that holds against terracotta +} + +extension Font { + /// SF Mono for currency values -- developer-tool identity. + static func codeMono(size: CGFloat, weight: Font.Weight = .regular) -> Font { + .system(size: size, weight: weight, design: .monospaced) + } +} diff --git a/mac/Sources/CodeBurnMenubar/Views/ActivitySection.swift b/mac/Sources/CodeBurnMenubar/Views/ActivitySection.swift new file mode 100644 index 0000000..9803387 --- /dev/null +++ b/mac/Sources/CodeBurnMenubar/Views/ActivitySection.swift @@ -0,0 +1,87 @@ +import SwiftUI + +struct ActivitySection: View { + @Environment(AppStore.self) private var store + @State private var isExpanded: Bool = true + + var body: some View { + CollapsibleSection( + caption: "Activity", + isExpanded: $isExpanded, + trailing: { + HStack(spacing: 8) { + Text("Cost").frame(minWidth: 54, alignment: .trailing) + Text("Turns").frame(minWidth: 52, alignment: .trailing) + Text("1-shot").frame(minWidth: 44, alignment: .trailing) + } + .font(.system(size: 10, weight: .medium)) + .foregroundStyle(.tertiary) + .tracking(-0.05) + } + ) { + VStack(alignment: .leading, spacing: 7) { + let maxCost = store.payload.current.topActivities.map(\.cost).max() ?? 1 + ForEach(store.payload.current.topActivities, id: \.name) { activity in + ActivityRow(activity: activity, maxCost: maxCost) + } + } + } + } +} + +struct ActivityRow: View { + let activity: ActivityEntry + let maxCost: Double + + var body: some View { + HStack(spacing: 8) { + FixedBar(fraction: activity.cost / maxCost) + .frame(width: 56, height: 6) + + Text(activity.name) + .font(.system(size: 12.5, weight: .medium)) + .frame(maxWidth: .infinity, alignment: .leading) + + Text(activity.cost.asCompactCurrency()) + .font(.codeMono(size: 12, weight: .medium)) + .tracking(-0.2) + .frame(minWidth: 54, alignment: .trailing) + + Text("\(activity.turns)") + .font(.system(size: 11)) + .monospacedDigit() + .foregroundStyle(.secondary) + .frame(minWidth: 52, alignment: .trailing) + + Text(oneShotText) + .font(.system(size: 10.5)) + .monospacedDigit() + .foregroundStyle(.secondary) + .frame(minWidth: 44, alignment: .trailing) + } + .padding(.horizontal, 2) + .padding(.vertical, 1) + } + + private var oneShotText: String { + guard let rate = activity.oneShotRate else { return "—" } + return "\(Int(rate * 100))%" + } +} + +/// Fixed-width horizontal bar that shows a fill fraction. +struct FixedBar: View { + let fraction: Double + + var body: some View { + GeometryReader { geo in + ZStack(alignment: .leading) { + RoundedRectangle(cornerRadius: 2) + .fill(.secondary.opacity(0.15)) + RoundedRectangle(cornerRadius: 2) + .fill(Theme.brandAccent) + .frame(width: max(0, min(geo.size.width, geo.size.width * CGFloat(fraction)))) + } + } + } +} diff --git a/mac/Sources/CodeBurnMenubar/Views/AgentTabStrip.swift b/mac/Sources/CodeBurnMenubar/Views/AgentTabStrip.swift new file mode 100644 index 0000000..4feb180 --- /dev/null +++ b/mac/Sources/CodeBurnMenubar/Views/AgentTabStrip.swift @@ -0,0 +1,92 @@ +import SwiftUI + +struct AgentTabStrip: View { + @Environment(AppStore.self) private var store + + var body: some View { + ScrollView(.horizontal, showsIndicators: false) { + HStack(spacing: 5) { + ForEach(visibleFilters) { filter in + Button { + Task { await store.switchTo(provider: filter) } + } label: { + AgentTab( + filter: filter, + cost: cost(for: filter), + isActive: store.selectedProvider == filter + ) + } + .buttonStyle(.plain) + } + } + .padding(.horizontal, 12) + .padding(.top, 8) + .padding(.bottom, 4) + } + } + + /// Drive tab visibility and per-tab cost labels from the *all-provider* payload (today), + /// not the currently selected provider's payload. Without this, switching to Codex (which + /// has no data) would hide every other tab including Claude. + private var allProvidersToday: MenubarPayload { + store.todayPayload ?? store.payload + } + + private var visibleFilters: [ProviderFilter] { + let activeKeys = Set(allProvidersToday.current.providers.keys.map { $0.lowercased() }) + return ProviderFilter.allCases.filter { filter in + if filter == .all { return true } + return activeKeys.contains(filter.rawValue.lowercased()) + } + } + + private func cost(for filter: ProviderFilter) -> Double? { + switch filter { + case .all: + return allProvidersToday.current.cost + default: + let key = filter.rawValue.lowercased() + return allProvidersToday.current.providers[key] + } + } +} + +private struct AgentTab: View { + let filter: ProviderFilter + let cost: Double? + let isActive: Bool + + var body: some View { + HStack(spacing: 5) { + Text(filter.rawValue) + .font(.system(size: 11.5, weight: .medium)) + .tracking(-0.05) + if let cost, cost > 0 { + Text(cost.asCompactCurrency()) + .font(.codeMono(size: 10.5, weight: .medium)) + .foregroundStyle(isActive ? AnyShapeStyle(.white.opacity(0.8)) : AnyShapeStyle(.secondary)) + .tracking(-0.2) + } + } + .padding(.horizontal, 10) + .padding(.vertical, 4) + .background( + RoundedRectangle(cornerRadius: 6) + .fill(isActive ? AnyShapeStyle(Theme.brandAccent) : AnyShapeStyle(Color.secondary.opacity(0.08))) + ) + .foregroundStyle(isActive ? AnyShapeStyle(.white) : AnyShapeStyle(.secondary)) + .contentShape(Rectangle()) + } +} + +extension ProviderFilter { + var color: Color { + switch self { + case .all: return Theme.brandAccent + case .claude: return Theme.categoricalClaude + case .codex: return Theme.categoricalCodex + case .cursor: return Theme.categoricalCursor + case .copilot: return Color(red: 0x6D/255.0, green: 0x8F/255.0, blue: 0xA6/255.0) + } + } +} diff --git a/mac/Sources/CodeBurnMenubar/Views/FindingsSection.swift b/mac/Sources/CodeBurnMenubar/Views/FindingsSection.swift new file mode 100644 index 0000000..3b31e76 --- /dev/null +++ b/mac/Sources/CodeBurnMenubar/Views/FindingsSection.swift @@ -0,0 +1,290 @@ +import SwiftUI + +private let winColor = Theme.brandAccent +private let riskColor = Theme.brandAccent +private let improveColor = Theme.brandAccent + +/// Three-category insights panel: wins, improvements, risks. +/// Wins/risks are derived from current + history; improvements come from the optimize findings. +struct FindingsSection: View { + @Environment(AppStore.self) private var store + @State private var isExpanded: Bool = true + + var body: some View { + let groups = computeTipGroups(payload: store.payload) + if groups.allSatisfy({ $0.items.isEmpty }) { return AnyView(EmptyView()) } + + return AnyView( + VStack(alignment: .leading, spacing: 8) { + Button { + withAnimation(.easeInOut(duration: 0.18)) { isExpanded.toggle() } + } label: { + HStack(alignment: .firstTextBaseline) { + HStack(spacing: 6) { + Image(systemName: "lightbulb.fill") + .font(.system(size: 11, weight: .semibold)) + .foregroundStyle(Theme.brandAccent) + Text("Tips for you") + .font(.system(size: 12.5, weight: .semibold)) + .foregroundStyle(.primary) + } + Spacer() + Text("\(groups.flatMap { $0.items }.count) signals") + .font(.system(size: 10.5)) + .foregroundStyle(.secondary) + Image(systemName: "chevron.right") + .font(.system(size: 9, weight: .semibold)) + .rotationEffect(.degrees(isExpanded ? 90 : 0)) + .opacity(0.55) + .foregroundStyle(.secondary) + } + .contentShape(Rectangle()) + } + .buttonStyle(.plain) + + if isExpanded { + VStack(alignment: .leading, spacing: 10) { + ForEach(groups) { group in + if !group.items.isEmpty { + TipsGroup(group: group) + } + } + + if store.payload.optimize.findingCount > 0 { + Button { + openOptimize() + } label: { + HStack(spacing: 4) { + Text("Open Full Optimize") + .font(.system(size: 11.5, weight: .semibold)) + Image(systemName: "arrow.forward") + .font(.system(size: 9, weight: .semibold)) + } + .foregroundStyle(Theme.brandAccent) + } + .buttonStyle(.plain) + } + } + .transition(.opacity) + } + } + .padding(12) + .background( + RoundedRectangle(cornerRadius: 8) + .fill(Color.secondary.opacity(0.06)) + ) + .padding(.horizontal, 14) + .padding(.vertical, 8) + ) + } + + private func openOptimize() { + TerminalLauncher.open(subcommand: ["optimize"]) + } +} + +private struct TipsGroup: View { + let group: TipGroup + + var body: some View { + VStack(alignment: .leading, spacing: 5) { + HStack(spacing: 5) { + Image(systemName: group.icon) + .font(.system(size: 10, weight: .bold)) + .foregroundStyle(group.color) + Text(group.label) + .font(.system(size: 10.5, weight: .semibold)) + .foregroundStyle(group.color) + .textCase(.uppercase) + .tracking(0.4) + } + VStack(alignment: .leading, spacing: 4) { + ForEach(group.items) { item in + HStack(alignment: .firstTextBaseline, spacing: 6) { + Circle().fill(group.color).frame(width: 3, height: 3).padding(.top, 4) + Text(item.text) + .font(.system(size: 11.5)) + .foregroundStyle(.primary) + .frame(maxWidth: .infinity, alignment: .leading) + if let trailing = item.trailing { + Text(trailing) + .font(.codeMono(size: 11, weight: .medium)) + .foregroundStyle(.secondary) + .tracking(-0.2) + } + } + } + } + } + } +} + +private struct TipGroup: Identifiable { + let id = UUID() + let label: String + let icon: String + let color: Color + let items: [TipItem] +} + +private struct TipItem: Identifiable { + let id = UUID() + let text: String + let trailing: String? +} + +private func computeTipGroups(payload: MenubarPayload) -> [TipGroup] { + let stats = computeHistoryStats(history: payload.history.daily) + + // What's working + var wins: [TipItem] = [] + let cacheHit = payload.current.cacheHitPercent + if cacheHit >= 80 { + wins.append(TipItem( + text: "Cache hit at \(Int(cacheHit))% — most prompts reuse cache", + trailing: nil + )) + } + if let oneShot = payload.current.oneShotRate, oneShot >= 0.75 { + wins.append(TipItem( + text: "\(Int(oneShot * 100))% one-shot — edits landing first try", + trailing: nil + )) + } + if let delta = stats.weekDeltaPercent, delta < -10 { + wins.append(TipItem( + text: "Spend down \(Int(abs(delta)))% vs last 7 days", + trailing: nil + )) + } + if stats.activeStreakDays >= 5 { + wins.append(TipItem( + text: "\(stats.activeStreakDays)-day usage streak", + trailing: nil + )) + } + + // What to improve (existing optimize findings) + var improvements: [TipItem] = [] + for finding in payload.optimize.topFindings.prefix(3) { + improvements.append(TipItem( + text: finding.title, + trailing: finding.savingsUSD.asCompactCurrency() + )) + } + + // Risks + var risks: [TipItem] = [] + if let delta = stats.weekDeltaPercent, delta > 25 { + risks.append(TipItem( + text: "Spend up \(Int(delta))% vs prior 7 days", + trailing: nil + )) + } + if cacheHit > 0 && cacheHit < 50 { + risks.append(TipItem( + text: "Cache hit only \(Int(cacheHit))% — paying for cold prompts", + trailing: nil + )) + } + if let oneShot = payload.current.oneShotRate, oneShot < 0.5 { + risks.append(TipItem( + text: "\(Int(oneShot * 100))% one-shot — lots of iteration", + trailing: nil + )) + } + if let projected = stats.projectedMonth, let prevMonth = stats.previousMonthTotal, projected > prevMonth * 1.3 { + risks.append(TipItem( + text: "On pace for \(projected.asCompactCurrency()) this month (+\(Int(((projected - prevMonth) / prevMonth) * 100))% vs last)", + trailing: nil + )) + } + + return [ + TipGroup(label: "What's working", icon: "checkmark.circle.fill", color: winColor, items: wins), + TipGroup(label: "What to improve", icon: "arrow.up.right.circle.fill", color: improveColor, items: improvements), + TipGroup(label: "Risks", icon: "exclamationmark.triangle.fill", color: riskColor, items: risks), + ] +} + +private struct HistoryStats { + let weekDeltaPercent: Double? + let activeStreakDays: Int + let projectedMonth: Double? + let previousMonthTotal: Double? +} + +private func computeHistoryStats(history: [DailyHistoryEntry]) -> HistoryStats { + var calendar = Calendar(identifier: .gregorian) + calendar.timeZone = TimeZone(identifier: "UTC")! + let formatter: DateFormatter = { + let f = DateFormatter() + f.dateFormat = "yyyy-MM-dd" + f.timeZone = TimeZone(identifier: "UTC") + return f + }() + let now = Date() + let today = calendar.startOfDay(for: now) + let costByDate = Dictionary(uniqueKeysWithValues: history.map { ($0.date, $0.cost) }) + + let lastWeekStart = calendar.date(byAdding: .day, value: -6, to: today) + let priorWeekStart = calendar.date(byAdding: .day, value: -13, to: today) + let priorWeekEnd = calendar.date(byAdding: .day, value: -7, to: today) + var weekDeltaPercent: Double? = nil + if let lws = lastWeekStart, let pws = priorWeekStart, let pwe = priorWeekEnd { + let lwsStr = formatter.string(from: lws) + let pwsStr = formatter.string(from: pws) + let pweStr = formatter.string(from: pwe) + let thisWeek = history.filter { $0.date >= lwsStr }.reduce(0.0) { $0 + $1.cost } + let prior = history.filter { $0.date >= pwsStr && $0.date <= pweStr }.reduce(0.0) { $0 + $1.cost } + if prior > 0 { + weekDeltaPercent = ((thisWeek - prior) / prior) * 100 + } + } + + var streak = 0 + for offset in 0..<60 { + guard let d = calendar.date(byAdding: .day, value: -offset, to: today) else { break } + let key = formatter.string(from: d) + if (costByDate[key] ?? 0) > 0 { streak += 1 } else { break } + } + + var projectedMonth: Double? = nil + var previousMonthTotal: Double? = nil + let comps = calendar.dateComponents([.year, .month, .day], from: now) + if + let firstOfMonth = calendar.date(from: DateComponents(year: comps.year, month: comps.month, day: 1)), + let rangeOfMonth = calendar.range(of: .day, in: .month, for: firstOfMonth) + { + let firstStr = formatter.string(from: firstOfMonth) + let mtd = history.filter { $0.date >= firstStr }.reduce(0.0) { $0 + $1.cost } + let dayOfMonth = comps.day ?? 1 + if dayOfMonth > 0 { + projectedMonth = (mtd / Double(dayOfMonth)) * Double(rangeOfMonth.count) + } + + if + let prevMonth = calendar.date(byAdding: .month, value: -1, to: firstOfMonth), + let prevRange = calendar.range(of: .day, in: .month, for: prevMonth), + let prevFirst = calendar.date(from: DateComponents( + year: calendar.component(.year, from: prevMonth), + month: calendar.component(.month, from: prevMonth), + day: 1 + )), + let prevLast = calendar.date(byAdding: .day, value: prevRange.count - 1, to: prevFirst) + { + let prevFirstStr = formatter.string(from: prevFirst) + let prevLastStr = formatter.string(from: prevLast) + let prevTotal = history.filter { $0.date >= prevFirstStr && $0.date <= prevLastStr } + .reduce(0.0) { $0 + $1.cost } + if prevTotal > 0 { previousMonthTotal = prevTotal } + } + } + + return HistoryStats( + weekDeltaPercent: weekDeltaPercent, + activeStreakDays: streak, + projectedMonth: projectedMonth, + previousMonthTotal: previousMonthTotal + ) +} diff --git a/mac/Sources/CodeBurnMenubar/Views/HeatmapSection.swift b/mac/Sources/CodeBurnMenubar/Views/HeatmapSection.swift new file mode 100644 index 0000000..6466ad0 --- /dev/null +++ b/mac/Sources/CodeBurnMenubar/Views/HeatmapSection.swift @@ -0,0 +1,1219 @@ +import SwiftUI + +private let trendDays = 19 +private let trendBarWidth: CGFloat = 13 +private let trendBarGap: CGFloat = 4 +private let trendChartHeight: CGFloat = 90 + +/// Three switchable insight visualizations: Calendar (this month), Forecast (burn rate), +/// Pulse (efficiency KPIs). Pills at top toggle between them. +struct HeatmapSection: View { + @Environment(AppStore.self) private var store + + var body: some View { + VStack(alignment: .leading, spacing: 10) { + InsightPillSwitcher(selected: bindingMode, visibleModes: visibleModes) + content + } + .frame(maxWidth: .infinity, alignment: .leading) + .onAppear { ensureValidSelection() } + .onChange(of: store.selectedProvider) { _, _ in ensureValidSelection() } + } + + private var bindingMode: Binding { + Binding(get: { store.selectedInsight }, set: { store.selectedInsight = $0 }) + } + + private var visibleModes: [InsightMode] { + // Plan sources from Claude's OAuth usage endpoint, so it only makes sense when the + // Claude provider tab is selected. Hidden on All/Cursor/Codex/etc. + InsightMode.allCases.filter { mode in + if mode == .plan { return store.selectedProvider == .claude } + return true + } + } + + private func ensureValidSelection() { + if !visibleModes.contains(store.selectedInsight) { + store.selectedInsight = visibleModes.first ?? .trend + } + } + + @ViewBuilder + private var content: some View { + switch store.selectedInsight { + case .plan: PlanInsight(usage: store.subscription) + case .trend: TrendInsight(days: store.payload.history.daily) + case .forecast: ForecastInsight(days: store.payload.history.daily) + case .pulse: PulseInsight(payload: store.payload) + case .stats: StatsInsight(payload: store.payload) + } + } +} + +// MARK: - Pill Switcher + +private struct InsightPillSwitcher: View { + @Binding var selected: InsightMode + let visibleModes: [InsightMode] + + var body: some View { + HStack(spacing: 4) { + ForEach(visibleModes) { mode in + Button { + selected = mode + } label: { + Text(mode.rawValue) + .font(.system(size: 11, weight: .medium)) + .foregroundStyle(selected == mode ? AnyShapeStyle(.white) : AnyShapeStyle(.secondary)) + .padding(.horizontal, 10) + .padding(.vertical, 4) + .background( + RoundedRectangle(cornerRadius: 6) + .fill(selected == mode ? AnyShapeStyle(Theme.brandAccent) : AnyShapeStyle(Color.secondary.opacity(0.10))) + ) + } + .buttonStyle(.plain) + } + } + } +} + +// MARK: - Trend (14-day bar chart with peak + average) + +private struct TrendInsight: View { + let days: [DailyHistoryEntry] + + var body: some View { + let bars = buildTrendBars(from: days) + let stats = computeTrendStats(bars: bars, allDays: days) + // Tokens are real for the .all-providers view; per-provider history doesn't carry + // token breakdown yet, so fall back to $ when no tokens are present. + let totalTokens = bars.reduce(0.0) { $0 + $1.tokens } + let useTokens = totalTokens > 0 + let metric: (TrendBar) -> Double = useTokens ? { $0.tokens } : { $0.cost } + let maxValue = max(bars.map(metric).max() ?? 1, 0.01) + let avgValue = bars.isEmpty ? 0 : bars.map(metric).reduce(0, +) / Double(bars.count) + let peakValue = bars.filter({ metric($0) > 0 }).max(by: { metric($0) < metric($1) }) + let yesterdayValue = stats.yesterdayBar.map(metric) + + VStack(alignment: .leading, spacing: 10) { + HStack(alignment: .firstTextBaseline) { + VStack(alignment: .leading, spacing: 1) { + Text("Last \(trendDays) days") + .font(.system(size: 10, weight: .medium)) + .foregroundStyle(.tertiary) + Text(formatHero(useTokens: useTokens, tokens: totalTokens, dollars: stats.totalThisWindow)) + .font(.system(size: 18, weight: .semibold, design: .rounded)) + .monospacedDigit() + .foregroundStyle(.primary) + } + Spacer() + if let delta = stats.deltaPercent { + HStack(spacing: 3) { + Image(systemName: delta >= 0 ? "arrow.up.right" : "arrow.down.right") + .font(.system(size: 9, weight: .bold)) + Text("\(delta >= 0 ? "+" : "")\(String(format: "%.0f", delta))% vs prior \(trendDays)d") + .font(.system(size: 10.5)) + .monospacedDigit() + } + .foregroundStyle(Theme.brandAccent) + } + } + + TrendChart( + bars: bars, + maxValue: maxValue, + avgValue: avgValue, + metric: metric, + formatValue: { formatValue($0, useTokens: useTokens) } + ) + .zIndex(1) + + HStack(spacing: 14) { + MiniStat(label: "Avg/day", value: formatValue(avgValue, useTokens: useTokens)) + MiniStat(label: "Peak", value: peakLabel(peakValue, metric: metric, useTokens: useTokens)) + MiniStat(label: "Yesterday", value: yesterdayValue.map { formatValue($0, useTokens: useTokens) } ?? "—") + } + } + } + + private func formatHero(useTokens: Bool, tokens: Double, dollars: Double) -> String { + useTokens ? "\(formatTokens(tokens)) tokens" : dollars.asCurrency() + } + + private func formatValue(_ v: Double, useTokens: Bool) -> String { + useTokens ? "\(formatTokens(v)) tok" : v.asCompactCurrency() + } + + private func peakLabel(_ peak: TrendBar?, metric: (TrendBar) -> Double, useTokens: Bool) -> String { + guard let peak, metric(peak) > 0 else { return "—" } + return "\(formatValue(metric(peak), useTokens: useTokens)) on \(shortDate(peak.date))" + } + + private func formatTokens(_ n: Double) -> String { + if n >= 1_000_000 { return String(format: "%.1fM", n / 1_000_000) } + if n >= 1_000 { return String(format: "%.0fK", n / 1_000) } + return String(format: "%.0f", n) + } + + private func shortDate(_ ymd: String) -> String { + let parts = ymd.split(separator: "-") + guard parts.count == 3 else { return ymd } + return "\(parts[1])/\(parts[2])" + } +} + +private struct TrendChart: View { + let bars: [TrendBar] + let maxValue: Double + let avgValue: Double + let metric: (TrendBar) -> Double + let formatValue: (Double) -> String + + @State private var hoveredBarID: TrendBar.ID? + + var body: some View { + let avgFraction = maxValue > 0 ? CGFloat(min(avgValue / maxValue, 1.0)) : 0 + + ZStack(alignment: .bottomLeading) { + HStack(alignment: .bottom, spacing: trendBarGap) { + ForEach(bars) { bar in + BarColumn( + bar: bar, + value: metric(bar), + maxValue: maxValue, + isHovered: hoveredBarID == bar.id + ) + .onHover { hovering in + hoveredBarID = hovering ? bar.id : (hoveredBarID == bar.id ? nil : hoveredBarID) + } + } + } + .frame(maxWidth: .infinity, alignment: .leading) + .frame(height: trendChartHeight, alignment: .bottom) + + GeometryReader { geo in + Path { p in + let y = geo.size.height - (geo.size.height * avgFraction) + p.move(to: CGPoint(x: 0, y: y)) + p.addLine(to: CGPoint(x: geo.size.width, y: y)) + } + .stroke(Color.secondary.opacity(0.5), style: StrokeStyle(lineWidth: 1, dash: [3, 3])) + } + .frame(height: trendChartHeight) + .allowsHitTesting(false) + } + .frame(height: trendChartHeight) + .overlay(alignment: .bottomLeading) { + // Floats below the chart without taking layout space. Opaque dark card hides + // whatever sits beneath it (mini stats, activity rows). + if let hoveredBar { + BarTooltipCard(bar: hoveredBar, formatValue: formatValue) + .padding(.top, 6) + .offset(y: 92) + .transition(.opacity) + .allowsHitTesting(false) + .zIndex(10) + } + } + .animation(.easeInOut(duration: 0.12), value: hoveredBarID) + } + + private var hoveredBar: TrendBar? { + guard let id = hoveredBarID else { return nil } + return bars.first { $0.id == id } + } +} + +private struct BarColumn: View { + let bar: TrendBar + let value: Double + let maxValue: Double + let isHovered: Bool + + var body: some View { + let fraction = maxValue > 0 ? CGFloat(value / maxValue) : 0 + let height = max(2, trendChartHeight * fraction) + + VStack(spacing: 2) { + Spacer(minLength: 0) + RoundedRectangle(cornerRadius: 2) + .fill(barColor) + .frame(width: trendBarWidth, height: height) + .overlay( + RoundedRectangle(cornerRadius: 2) + .stroke(Theme.brandAccent.opacity(isHovered ? 0.9 : 0), lineWidth: 1) + ) + .scaleEffect(x: isHovered ? 1.08 : 1.0, y: 1.0, anchor: .bottom) + .animation(.easeOut(duration: 0.12), value: isHovered) + } + .contentShape(Rectangle()) + } + + private var barColor: Color { + if bar.isToday { return Theme.brandAccent } + if value <= 0 { return Color.secondary.opacity(0.15) } + return isHovered ? Theme.brandAccent.opacity(0.85) : Theme.brandAccent.opacity(0.55) + } +} + +private struct BarTooltipCard: View { + let bar: TrendBar + let formatValue: (Double) -> String + @Environment(\.colorScheme) private var colorScheme + + private var backgroundFill: Color { + colorScheme == .dark ? Color.white : Color.black + } + + private var primaryText: Color { + colorScheme == .dark ? Color.black : Color.white + } + + private var secondaryText: Color { + colorScheme == .dark ? Color.black.opacity(0.7) : Color.white.opacity(0.72) + } + + private var tertiaryText: Color { + colorScheme == .dark ? Color.black.opacity(0.5) : Color.white.opacity(0.52) + } + + private var borderStroke: Color { + colorScheme == .dark ? Color.black.opacity(0.12) : Color.white.opacity(0.12) + } + + var body: some View { + VStack(alignment: .leading, spacing: 5) { + HStack(alignment: .firstTextBaseline) { + Text(prettyDate(bar.date)) + .font(.system(size: 11, weight: .semibold)) + .foregroundStyle(primaryText) + Spacer() + Text("\(formatValue(bar.tokens))") + .font(.codeMono(size: 10.5, weight: .semibold)) + .foregroundStyle(Theme.brandAccent) + } + + if !bar.topModels.isEmpty { + VStack(alignment: .leading, spacing: 3) { + ForEach(bar.topModels.prefix(4), id: \.name) { m in + HStack(spacing: 6) { + Circle().fill(Theme.brandAccent.opacity(0.7)).frame(width: 4, height: 4) + Text(m.name) + .font(.system(size: 10, weight: .medium)) + .foregroundStyle(primaryText) + Spacer() + Text("\(formatTokensCompact(Double(m.totalTokens))) tok") + .font(.codeMono(size: 9.5, weight: .medium)) + .foregroundStyle(secondaryText) + Text("(\(formatTokensCompact(Double(m.inputTokens)))/\(formatTokensCompact(Double(m.outputTokens))))") + .font(.codeMono(size: 9, weight: .regular)) + .foregroundStyle(tertiaryText) + } + } + } + } else { + Text("No model breakdown available") + .font(.system(size: 10)) + .foregroundStyle(tertiaryText) + } + } + .padding(11) + .frame(maxWidth: .infinity, alignment: .leading) + .background( + RoundedRectangle(cornerRadius: 8) + .fill(backgroundFill) + ) + .overlay( + RoundedRectangle(cornerRadius: 8) + .stroke(borderStroke, lineWidth: 0.5) + ) + .shadow(color: Color.black.opacity(0.35), radius: 10, y: 4) + } + + private func formatTokensCompact(_ n: Double) -> String { + if n >= 1_000_000 { return String(format: "%.1fM", n / 1_000_000) } + if n >= 1_000 { return String(format: "%.0fK", n / 1_000) } + return String(format: "%.0f", n) + } +} + +private func prettyDate(_ ymd: String) -> String { + let parser = DateFormatter() + parser.dateFormat = "yyyy-MM-dd" + parser.timeZone = TimeZone(identifier: "UTC") + guard let date = parser.date(from: ymd) else { return ymd } + let display = DateFormatter() + display.dateFormat = "EEE MMM d" + return display.string(from: date) +} + +private struct MiniStat: View { + let label: String + let value: String + + var body: some View { + VStack(alignment: .leading, spacing: 1) { + Text(label) + .font(.system(size: 9.5, weight: .medium)) + .foregroundStyle(.tertiary) + Text(value) + .font(.system(size: 11.5, weight: .semibold)) + .monospacedDigit() + .foregroundStyle(.primary) + } + .frame(maxWidth: .infinity, alignment: .leading) + } +} + +private struct TrendBar: Identifiable { + let id = UUID() + let date: String + let cost: Double + let inputTokens: Double + let outputTokens: Double + let isToday: Bool + let topModels: [DailyModelBreakdown] + + var tokens: Double { inputTokens + outputTokens } +} + +private struct TrendStats { + let totalThisWindow: Double + let avgPerDay: Double + let peak: TrendBar? + let activeDays: Int + let deltaPercent: Double? + let yesterdayBar: TrendBar? +} + +private func buildTrendBars(from days: [DailyHistoryEntry]) -> [TrendBar] { + var calendar = Calendar(identifier: .gregorian) + calendar.timeZone = TimeZone(identifier: "UTC")! + let formatter: DateFormatter = { + let f = DateFormatter() + f.dateFormat = "yyyy-MM-dd" + f.timeZone = TimeZone(identifier: "UTC") + return f + }() + let entryByDate = Dictionary(uniqueKeysWithValues: days.map { ($0.date, $0) }) + let today = calendar.startOfDay(for: Date()) + let todayKey = formatter.string(from: today) + + var bars: [TrendBar] = [] + for offset in (0.. TrendStats { + let total = bars.reduce(0.0) { $0 + $1.cost } + let active = bars.filter { $0.cost > 0 }.count + let avg = bars.isEmpty ? 0 : total / Double(bars.count) + let peak = bars.filter { $0.cost > 0 }.max(by: { $0.cost < $1.cost }) + + var calendar = Calendar(identifier: .gregorian) + calendar.timeZone = TimeZone(identifier: "UTC")! + let formatter: DateFormatter = { + let f = DateFormatter() + f.dateFormat = "yyyy-MM-dd" + f.timeZone = TimeZone(identifier: "UTC") + return f + }() + let today = calendar.startOfDay(for: Date()) + let priorWindowStart = calendar.date(byAdding: .day, value: -(2 * trendDays - 1), to: today) + let thisWindowStart = calendar.date(byAdding: .day, value: -(trendDays - 1), to: today) + var deltaPercent: Double? = nil + if let priorStart = priorWindowStart, let thisStart = thisWindowStart { + let priorStartStr = formatter.string(from: priorStart) + let thisStartStr = formatter.string(from: thisStart) + let priorTotal = allDays + .filter { $0.date >= priorStartStr && $0.date < thisStartStr } + .reduce(0.0) { $0 + $1.cost } + if priorTotal > 0 { + deltaPercent = ((total - priorTotal) / priorTotal) * 100 + } + } + + let yesterdayDate = calendar.date(byAdding: .day, value: -1, to: today) + let yesterdayKey = yesterdayDate.map { formatter.string(from: $0) } + let yesterdayBar = bars.first(where: { $0.date == yesterdayKey }) + + return TrendStats( + totalThisWindow: total, + avgPerDay: avg, + peak: peak, + activeDays: active, + deltaPercent: deltaPercent, + yesterdayBar: yesterdayBar + ) +} + +// MARK: - Forecast + +private struct ForecastInsight: View { + let days: [DailyHistoryEntry] + + var body: some View { + let stats = computeForecast(days: days) + VStack(alignment: .leading, spacing: 10) { + HStack(alignment: .firstTextBaseline) { + VStack(alignment: .leading, spacing: 2) { + Text("Month-to-date") + .font(.system(size: 10, weight: .medium)) + .foregroundStyle(.tertiary) + Text(stats.mtd.asCurrency()) + .font(.system(size: 22, weight: .semibold, design: .rounded)) + .monospacedDigit() + .foregroundStyle(Theme.brandAccent) + } + Spacer() + VStack(alignment: .trailing, spacing: 2) { + Text("On pace for") + .font(.system(size: 10, weight: .medium)) + .foregroundStyle(.tertiary) + Text(stats.projection.asCurrency()) + .font(.system(size: 16, weight: .semibold)) + .monospacedDigit() + } + } + + HStack(spacing: 14) { + ForecastStat(label: "Avg/day (this wk)", value: stats.weekAvg.asCompactCurrency()) + ForecastStat(label: "Yesterday", value: stats.yesterday.asCompactCurrency()) + ForecastStat(label: "Last 7d", value: stats.weekTotal.asCompactCurrency()) + } + + if let prevTotal = stats.previousMonthTotal { + HStack(spacing: 4) { + Image(systemName: stats.projection > prevTotal ? "arrow.up.right" : "arrow.down.right") + .font(.system(size: 9, weight: .bold)) + Text(comparisonText(projection: stats.projection, previous: prevTotal)) + .font(.system(size: 10.5)) + .monospacedDigit() + } + .foregroundStyle(Theme.brandAccent) + } + } + } + + private func comparisonText(projection: Double, previous: Double) -> String { + guard previous > 0 else { return "no prior month" } + let diff = ((projection - previous) / previous) * 100 + let sign = diff >= 0 ? "+" : "" + return "\(sign)\(String(format: "%.0f", diff))% vs last month ($\(String(format: "%.0f", previous)))" + } +} + +private struct ForecastStat: View { + let label: String + let value: String + var body: some View { + VStack(alignment: .leading, spacing: 1) { + Text(label) + .font(.system(size: 9.5, weight: .medium)) + .foregroundStyle(.tertiary) + Text(value) + .font(.system(size: 12, weight: .semibold)) + .monospacedDigit() + .foregroundStyle(.primary) + } + .frame(maxWidth: .infinity, alignment: .leading) + } +} + +private struct ForecastStats { + let mtd: Double + let projection: Double + let weekAvg: Double + let weekTotal: Double + let yesterday: Double + let previousMonthTotal: Double? +} + +private func computeForecast(days: [DailyHistoryEntry]) -> ForecastStats { + var calendar = Calendar(identifier: .gregorian) + calendar.timeZone = TimeZone(identifier: "UTC")! + let formatter: DateFormatter = { + let f = DateFormatter() + f.dateFormat = "yyyy-MM-dd" + f.timeZone = TimeZone(identifier: "UTC") + return f + }() + let now = Date() + let comps = calendar.dateComponents([.year, .month, .day], from: now) + guard + let firstOfMonth = calendar.date(from: DateComponents(year: comps.year, month: comps.month, day: 1)), + let rangeOfMonth = calendar.range(of: .day, in: .month, for: firstOfMonth) + else { + return ForecastStats(mtd: 0, projection: 0, weekAvg: 0, weekTotal: 0, yesterday: 0, previousMonthTotal: nil) + } + + let firstStr = formatter.string(from: firstOfMonth) + let totalDays = rangeOfMonth.count + let dayOfMonth = comps.day ?? 1 + + let mtdEntries = days.filter { $0.date >= firstStr } + let mtd = mtdEntries.reduce(0.0) { $0 + $1.cost } + let avgPerElapsedDay = dayOfMonth > 0 ? mtd / Double(dayOfMonth) : 0 + let projection = avgPerElapsedDay * Double(totalDays) + + let weekStart = calendar.date(byAdding: .day, value: -6, to: calendar.startOfDay(for: now)) + let weekStartStr = weekStart.map { formatter.string(from: $0) } ?? "" + let weekEntries = days.filter { $0.date >= weekStartStr } + let weekTotal = weekEntries.reduce(0.0) { $0 + $1.cost } + let weekAvg = weekTotal / 7.0 + + let yesterdayDate = calendar.date(byAdding: .day, value: -1, to: calendar.startOfDay(for: now)) + let yesterdayStr = yesterdayDate.map { formatter.string(from: $0) } ?? "" + let yesterday = days.first(where: { $0.date == yesterdayStr })?.cost ?? 0 + + var previousMonthTotal: Double? = nil + if + let prevMonthDate = calendar.date(byAdding: .month, value: -1, to: firstOfMonth), + let prevRange = calendar.range(of: .day, in: .month, for: prevMonthDate), + let prevFirst = calendar.date(from: DateComponents(year: calendar.component(.year, from: prevMonthDate), month: calendar.component(.month, from: prevMonthDate), day: 1)), + let prevLast = calendar.date(byAdding: .day, value: prevRange.count - 1, to: prevFirst) + { + let prevFirstStr = formatter.string(from: prevFirst) + let prevLastStr = formatter.string(from: prevLast) + let prevEntries = days.filter { $0.date >= prevFirstStr && $0.date <= prevLastStr } + if !prevEntries.isEmpty { + previousMonthTotal = prevEntries.reduce(0.0) { $0 + $1.cost } + } + } + + return ForecastStats( + mtd: mtd, + projection: projection, + weekAvg: weekAvg, + weekTotal: weekTotal, + yesterday: yesterday, + previousMonthTotal: previousMonthTotal + ) +} + +// MARK: - Pulse + +private struct PulseInsight: View { + let payload: MenubarPayload + + var body: some View { + HStack(spacing: 10) { + PulseTile(label: "Cache hit", value: cacheHitText, color: Theme.brandAccent) + PulseTile(label: "1-shot", value: oneShotText, color: oneShotColor) + PulseTile( + label: "Cost / session", + value: payload.current.sessions > 0 + ? (payload.current.cost / Double(payload.current.sessions)).asCompactCurrency() + : "—", + color: .secondary + ) + } + } + + private var cacheHitText: String { + let v = payload.current.cacheHitPercent + return v <= 0 ? "—" : String(format: "%.0f%%", v) + } + + private var oneShotText: String { + guard let r = payload.current.oneShotRate else { return "—" } + return String(format: "%.0f%%", r * 100) + } + + private var oneShotColor: Color { + payload.current.oneShotRate == nil ? .secondary : Theme.brandAccent + } +} + +private struct PulseTile: View { + let label: String + let value: String + let color: Color + + var body: some View { + VStack(alignment: .leading, spacing: 3) { + Text(label) + .font(.system(size: 10, weight: .medium)) + .foregroundStyle(.tertiary) + Text(value) + .font(.system(size: 18, weight: .semibold, design: .rounded)) + .monospacedDigit() + .foregroundStyle(color) + } + .padding(.horizontal, 10) + .padding(.vertical, 8) + .frame(maxWidth: .infinity, alignment: .leading) + .background( + RoundedRectangle(cornerRadius: 6) + .fill(Color.secondary.opacity(0.06)) + ) + } +} + +/// Connects optimize findings directly to plan utilization: "address N findings to recover X +/// tokens" framed as the same currency the rest of the Plan view uses (effective tokens). +/// Scoped to whatever period the user selected (today / 7d / 30d / month / all). +private struct OptimizeSavingsBadge: View { + let payload: MenubarPayload + + var body: some View { + let findingCount = payload.optimize.findingCount + let savingsUSD = payload.optimize.savingsUSD + if findingCount == 0 || savingsUSD <= 0 { + EmptyView() + } else { + Button { openOptimize() } label: { + HStack(spacing: 6) { + Image(systemName: "lightbulb.fill") + .font(.system(size: 10, weight: .semibold)) + .foregroundStyle(Theme.brandAccent) + Text(captionText(findingCount: findingCount, savingsUSD: savingsUSD)) + .font(.system(size: 11, weight: .medium)) + .foregroundStyle(.primary) + Spacer() + Image(systemName: "chevron.right") + .font(.system(size: 8, weight: .semibold)) + .foregroundStyle(.tertiary) + } + .padding(.horizontal, 10) + .padding(.vertical, 7) + .background( + RoundedRectangle(cornerRadius: 6) + .fill(Theme.brandAccent.opacity(0.10)) + ) + } + .buttonStyle(.plain) + .padding(.top, 2) + } + } + + private func captionText(findingCount: Int, savingsUSD: Double) -> String { + let tokens = savingsUSD / 9.0 * 1_000_000 // ~$9/M effective tokens (Sonnet-weighted approx) + let tokensLabel = formatTokens(tokens) + let plural = findingCount == 1 ? "finding" : "findings" + return "Save ~\(savingsUSD.asCompactCurrency()) / ~\(tokensLabel) tokens · \(findingCount) \(plural)" + } + + private func openOptimize() { + TerminalLauncher.open(subcommand: ["optimize"]) + } + + private func formatTokens(_ n: Double) -> String { + if n >= 1_000_000 { return String(format: "%.1fM", n / 1_000_000) } + if n >= 1_000 { return String(format: "%.0fK", n / 1_000) } + return String(format: "%.0f", n) + } +} + +// MARK: - Stats + +private struct StatsInsight: View { + let payload: MenubarPayload + + var body: some View { + let stats = computeAllStats(payload: payload) + + VStack(alignment: .leading, spacing: 10) { + HStack(alignment: .top, spacing: 14) { + VStack(alignment: .leading, spacing: 8) { + StatRow(label: "Favorite model", value: stats.favoriteModel) + StatRow(label: "Active days (month)", value: stats.activeDaysFraction) + StatRow(label: "Most active day", value: stats.mostActiveDay) + StatRow(label: "Peak day spend", value: stats.peakDaySpend) + } + .frame(maxWidth: .infinity, alignment: .leading) + + VStack(alignment: .leading, spacing: 8) { + StatRow(label: "Sessions today", value: "\(payload.current.sessions)") + StatRow(label: "Calls today", value: payload.current.calls.asThousandsSeparated()) + StatRow(label: "Current streak", value: stats.currentStreak) + StatRow(label: "Longest streak", value: stats.longestStreak) + } + .frame(maxWidth: .infinity, alignment: .leading) + } + + if let lifetime = stats.lifetimeTotal { + Divider().opacity(0.5) + HStack { + Text("Tracked spend (last \(stats.historyDayCount) days)") + .font(.system(size: 10.5, weight: .medium)) + .foregroundStyle(.tertiary) + Spacer() + Text(lifetime.asCurrency()) + .font(.system(size: 13, weight: .semibold, design: .rounded)) + .monospacedDigit() + .foregroundStyle(Theme.brandAccent) + } + } + } + } +} + +private struct StatRow: View { + let label: String + let value: String + + var body: some View { + VStack(alignment: .leading, spacing: 1) { + Text(label) + .font(.system(size: 9.5, weight: .medium)) + .foregroundStyle(.tertiary) + Text(value) + .font(.system(size: 12, weight: .semibold)) + .monospacedDigit() + .foregroundStyle(.primary) + } + } +} + +private struct AllStats { + let favoriteModel: String + let activeDaysFraction: String + let mostActiveDay: String + let peakDaySpend: String + let currentStreak: String + let longestStreak: String + let lifetimeTotal: Double? + let historyDayCount: Int +} + +private func computeAllStats(payload: MenubarPayload) -> AllStats { + let history = payload.history.daily + let favoriteModel = payload.current.topModels.first?.name ?? "—" + + var calendar = Calendar(identifier: .gregorian) + calendar.timeZone = TimeZone(identifier: "UTC")! + let formatter: DateFormatter = { + let f = DateFormatter() + f.dateFormat = "yyyy-MM-dd" + f.timeZone = TimeZone(identifier: "UTC") + return f + }() + let displayFormatter: DateFormatter = { + let f = DateFormatter() + f.dateFormat = "MMM d" + f.timeZone = TimeZone(identifier: "UTC") + return f + }() + + let now = Date() + let today = calendar.startOfDay(for: now) + let comps = calendar.dateComponents([.year, .month, .day], from: now) + + var activeDaysFraction = "—" + if + let firstOfMonth = calendar.date(from: DateComponents(year: comps.year, month: comps.month, day: 1)), + let rangeOfMonth = calendar.range(of: .day, in: .month, for: firstOfMonth) + { + let firstStr = formatter.string(from: firstOfMonth) + let mtdActive = history.filter { $0.date >= firstStr && $0.cost > 0 }.count + activeDaysFraction = "\(mtdActive)/\(rangeOfMonth.count)" + } + + let peak = history.max(by: { $0.cost < $1.cost }) + let mostActiveDay: String + let peakDaySpend: String + if let peak, peak.cost > 0, let date = formatter.date(from: peak.date) { + mostActiveDay = displayFormatter.string(from: date) + peakDaySpend = peak.cost.asCompactCurrency() + } else { + mostActiveDay = "—" + peakDaySpend = "—" + } + + let costByDate = Dictionary(uniqueKeysWithValues: history.map { ($0.date, $0.cost) }) + + var currentStreak = 0 + for offset in 0..<400 { + guard let d = calendar.date(byAdding: .day, value: -offset, to: today) else { break } + let key = formatter.string(from: d) + if (costByDate[key] ?? 0) > 0 { currentStreak += 1 } else { break } + } + + var longestStreak = 0 + var running = 0 + let sortedDates = history.map(\.date).sorted() + for date in sortedDates { + if (costByDate[date] ?? 0) > 0 { + running += 1 + longestStreak = max(longestStreak, running) + } else { + running = 0 + } + } + + let lifetimeTotal: Double? = history.isEmpty ? nil : history.reduce(0.0) { $0 + $1.cost } + + return AllStats( + favoriteModel: favoriteModel, + activeDaysFraction: activeDaysFraction, + mostActiveDay: mostActiveDay, + peakDaySpend: peakDaySpend, + currentStreak: currentStreak == 0 ? "—" : "\(currentStreak) days", + longestStreak: longestStreak == 0 ? "—" : "\(longestStreak) days", + lifetimeTotal: lifetimeTotal, + historyDayCount: history.count + ) +} + +// MARK: - Plan (subscription) + +private struct PlanInsight: View { + @Environment(AppStore.self) private var store + let usage: SubscriptionUsage? + + private static let fiveHourSeconds: TimeInterval = 5 * 3600 + private static let sevenDaySeconds: TimeInterval = 7 * 86400 + private static let freshWindowThreshold: Double = 0.05 + + @State private var projections: [String: WindowProjection] = [:] + + var body: some View { + Group { + switch store.subscriptionLoadState { + case .idle: + PlanIdleView() + case .loading: + PlanLoadingView() + case .noCredentials: + PlanNoCredentialsView() + case .failed: + PlanFailedView(error: store.subscriptionError) + case .loaded: + if let usage { + loadedBody(usage: usage) + } else { + PlanNoCredentialsView() + } + } + } + .task { + // Lazy-trigger fetch the first time Plan is opened. + if store.subscriptionLoadState == .idle { + await store.refreshSubscription() + } + } + } + + @ViewBuilder + private func loadedBody(usage: SubscriptionUsage) -> some View { + VStack(alignment: .leading, spacing: 10) { + HStack(alignment: .firstTextBaseline) { + Text(usage.tier.displayName) + .font(.system(size: 13, weight: .semibold)) + .foregroundStyle(Theme.brandAccent) + Spacer() + if let resets = headlineReset(usage: usage) { + Text("Resets \(resets)") + .font(.system(size: 10.5)) + .foregroundStyle(.secondary) + } + } + + VStack(spacing: 8) { + if let p = usage.fiveHourPercent { + UtilizationRow(label: "5-hour window", percent: p, resetsAt: usage.fiveHourResetsAt, projection: projections["five_hour"]) + } + if let p = usage.sevenDayPercent { + UtilizationRow(label: "7-day total", percent: p, resetsAt: usage.sevenDayResetsAt, projection: projections["seven_day"]) + } + if let p = usage.sevenDayOpusPercent { + UtilizationRow(label: "7-day Opus", percent: p, resetsAt: usage.sevenDayOpusResetsAt, projection: projections["seven_day_opus"]) + } + if let p = usage.sevenDaySonnetPercent { + UtilizationRow(label: "7-day Sonnet", percent: p, resetsAt: usage.sevenDaySonnetResetsAt, projection: projections["seven_day_sonnet"]) + } + } + + OptimizeSavingsBadge(payload: store.payload) + } + .task(id: usage.fetchedAt) { + await recomputeProjections(usage: usage) + } + } + + private func recomputeProjections(usage: SubscriptionUsage) async { + var result: [String: WindowProjection] = [:] + let inputs: [(String, Double?, Date?, TimeInterval)] = [ + ("five_hour", usage.fiveHourPercent, usage.fiveHourResetsAt, Self.fiveHourSeconds), + ("seven_day", usage.sevenDayPercent, usage.sevenDayResetsAt, Self.sevenDaySeconds), + ("seven_day_opus", usage.sevenDayOpusPercent, usage.sevenDayOpusResetsAt, Self.sevenDaySeconds), + ("seven_day_sonnet", usage.sevenDaySonnetPercent, usage.sevenDaySonnetResetsAt, Self.sevenDaySeconds), + ] + for (key, percent, resetsAt, windowSeconds) in inputs { + if let projection = await project(key: key, percent: percent, resetsAt: resetsAt, windowSeconds: windowSeconds) { + result[key] = projection + } + } + projections = result + } + + /// Linear extrapolation when window is past the freshness threshold; otherwise falls back to + /// the prior cycle's final percent from the snapshot store. + private func project(key: String, percent: Double?, resetsAt: Date?, windowSeconds: TimeInterval) async -> WindowProjection? { + guard let percent, let resetsAt else { return nil } + let windowStart = resetsAt.addingTimeInterval(-windowSeconds) + let elapsed = Date().timeIntervalSince(windowStart) + let elapsedFraction = elapsed / windowSeconds + + if elapsedFraction > Self.freshWindowThreshold, percent > 0 { + let projectedPercent = percent / elapsedFraction + var hitDate: Date? = nil + if projectedPercent > 100, percent < 100 { + let remainingPercent = 100 - percent + let percentPerSecond = percent / elapsed + if percentPerSecond > 0 { + hitDate = Date().addingTimeInterval(remainingPercent / percentPerSecond) + } + } + return WindowProjection(percent: projectedPercent, willOverflow: projectedPercent > 100, hitsLimitAt: hitDate, source: .linear) + } + + // Window too fresh OR percent exactly zero -- use the prior cycle's final reading. + if let prior = await SubscriptionSnapshotStore.previousWindowFinal(windowKey: key, currentResetsAt: resetsAt) { + return WindowProjection(percent: prior, willOverflow: prior > 100, hitsLimitAt: nil, source: .historicalBaseline) + } + return nil + } + + private func headlineReset(usage: SubscriptionUsage) -> String? { + let candidates = [ + usage.fiveHourResetsAt, + usage.sevenDayResetsAt, + usage.sevenDayOpusResetsAt, + usage.sevenDaySonnetResetsAt, + ].compactMap { $0 } + guard let earliest = candidates.min() else { return nil } + return relativeReset(earliest) + } +} + +// MARK: - Plan empty/loading/failure states + +private struct PlanIdleView: View { + var body: some View { + VStack(spacing: 8) { + Image(systemName: "person.crop.circle.dashed") + .font(.system(size: 22)) + .foregroundStyle(.tertiary) + Text("Loading your plan...") + .font(.system(size: 11.5, weight: .medium)) + .foregroundStyle(.secondary) + Text("macOS may ask permission to read your Claude Code credentials.") + .font(.system(size: 10)) + .foregroundStyle(.tertiary) + .multilineTextAlignment(.center) + .frame(maxWidth: 260) + } + .frame(maxWidth: .infinity) + .padding(.vertical, 16) + } +} + +private struct PlanLoadingView: View { + var body: some View { + VStack(spacing: 8) { + ProgressView().scaleEffect(0.8) + Text("Reading Claude credentials...") + .font(.system(size: 11, weight: .medium)) + .foregroundStyle(.secondary) + } + .frame(maxWidth: .infinity) + .padding(.vertical, 16) + } +} + +private struct PlanNoCredentialsView: View { + @Environment(AppStore.self) private var store + + var body: some View { + VStack(spacing: 8) { + Image(systemName: "key.slash") + .font(.system(size: 20)) + .foregroundStyle(.tertiary) + Text("No Claude subscription connected") + .font(.system(size: 12, weight: .semibold)) + .foregroundStyle(.primary) + Text("Run `claude login` in your terminal, then retry.") + .font(.system(size: 10.5)) + .foregroundStyle(.secondary) + .multilineTextAlignment(.center) + .frame(maxWidth: 260) + Button("Retry") { + Task { await store.refreshSubscription() } + } + .controlSize(.small) + .buttonStyle(.bordered) + } + .frame(maxWidth: .infinity) + .padding(.vertical, 14) + } +} + +private struct PlanFailedView: View { + @Environment(AppStore.self) private var store + let error: String? + + var body: some View { + VStack(spacing: 8) { + Image(systemName: "exclamationmark.triangle") + .font(.system(size: 18)) + .foregroundStyle(Theme.brandAccent) + Text("Couldn't load plan data") + .font(.system(size: 12, weight: .semibold)) + .foregroundStyle(.primary) + if let error { + Text(error) + .font(.system(size: 10)) + .foregroundStyle(.tertiary) + .multilineTextAlignment(.center) + .frame(maxWidth: 280) + .lineLimit(3) + } + Button("Retry") { + Task { await store.refreshSubscription() } + } + .controlSize(.small) + .buttonStyle(.bordered) + } + .frame(maxWidth: .infinity) + .padding(.vertical, 14) + } +} + +private struct WindowProjection { + enum Source { case linear, historicalBaseline } + let percent: Double + let willOverflow: Bool + let hitsLimitAt: Date? + let source: Source +} + +private struct UtilizationRow: View { + let label: String + /// API returns utilization as 0..100 (a percentage value, not a fraction). + let percent: Double + let resetsAt: Date? + let projection: WindowProjection? + + var body: some View { + VStack(spacing: 3) { + HStack(alignment: .firstTextBaseline) { + Text(label) + .font(.system(size: 11, weight: .medium)) + .foregroundStyle(.secondary) + Spacer() + Text(String(format: "%.0f%%", clampedPercent)) + .font(.codeMono(size: 11, weight: .semibold)) + .foregroundStyle(barColor) + .monospacedDigit() + } + UtilizationBar( + fraction: clampedPercent / 100, + color: barColor, + markerFraction: projection.map { min(max($0.percent, 0), 100) / 100 } + ) + .frame(height: 6) + if let projection { + ProjectionCaption(projection: projection) + } + } + } + + private var clampedPercent: Double { min(max(percent, 0), 100) } + + /// Single-color brand palette decision (see session notes): the number is the signal, not + /// the color. Keeping this as a computed property so a future threshold-based palette + /// reintroduction stays scoped to one place. + private var barColor: Color { Theme.brandAccent } +} + +private struct ProjectionCaption: View { + let projection: WindowProjection + + var body: some View { + HStack(spacing: 3) { + if projection.willOverflow { + Image(systemName: "exclamationmark.triangle.fill") + .font(.system(size: 8, weight: .bold)) + .foregroundStyle(Theme.brandAccent) + } else { + Image(systemName: "arrow.up.right") + .font(.system(size: 8, weight: .bold)) + .foregroundStyle(.tertiary) + } + Text(captionText) + .font(.system(size: 9.5, weight: .medium)) + .foregroundStyle(projection.willOverflow + ? AnyShapeStyle(Theme.brandAccent) + : AnyShapeStyle(.tertiary)) + Spacer() + } + } + + private var captionText: String { + let projected = String(format: "%.0f%%", projection.percent) + switch projection.source { + case .linear: + if projection.willOverflow, let hit = projection.hitsLimitAt { + return "On pace: \(projected) at reset · hits 100% \(relativeReset(hit))" + } + return "On pace: \(projected) at reset" + case .historicalBaseline: + return "Based on last cycle: \(projected)" + } + } +} + +private struct UtilizationBar: View { + /// 0..1 fraction of the bar to fill. + let fraction: Double + let color: Color + /// Optional 0..1 marker position for projected utilization at reset. + let markerFraction: Double? + + var body: some View { + GeometryReader { geo in + ZStack(alignment: .leading) { + RoundedRectangle(cornerRadius: 3).fill(Color.secondary.opacity(0.12)) + RoundedRectangle(cornerRadius: 3) + .fill(color) + .frame(width: max(0, geo.size.width * CGFloat(fraction))) + if let m = markerFraction { + Rectangle() + .fill(Color.primary.opacity(0.55)) + .frame(width: 1.5) + .offset(x: max(0, geo.size.width * CGFloat(m)) - 0.75) + } + } + } + } +} + +private func relativeReset(_ date: Date) -> String { + let interval = date.timeIntervalSinceNow + if interval <= 0 { return "now" } + let hours = interval / 3600 + if hours < 1 { + let minutes = Int(ceil(interval / 60)) + return "in \(minutes)m" + } + if hours < 24 { return "in \(Int(ceil(hours)))h" } + let days = Int(ceil(hours / 24)) + return "in \(days)d" +} + diff --git a/mac/Sources/CodeBurnMenubar/Views/HeroSection.swift b/mac/Sources/CodeBurnMenubar/Views/HeroSection.swift new file mode 100644 index 0000000..ca30cee --- /dev/null +++ b/mac/Sources/CodeBurnMenubar/Views/HeroSection.swift @@ -0,0 +1,55 @@ +import SwiftUI + +struct HeroSection: View { + @Environment(AppStore.self) private var store + + var body: some View { + VStack(alignment: .leading, spacing: 8) { + SectionCaption(text: caption) + + HStack(alignment: .firstTextBaseline) { + Text(store.payload.current.cost.asCurrency()) + .font(.system(size: 32, weight: .semibold, design: .rounded)) + .monospacedDigit() + .tracking(-1) + .foregroundStyle( + LinearGradient( + colors: [Theme.brandAccent, Theme.brandEmberDeep], + startPoint: .top, + endPoint: .bottom + ) + ) + + Spacer() + + VStack(alignment: .trailing, spacing: 2) { + Text("\(store.payload.current.calls.asThousandsSeparated()) calls") + .font(.system(size: 11)) + .monospacedDigit() + .foregroundStyle(.secondary) + Text("\(store.payload.current.sessions) sessions") + .font(.system(size: 10.5)) + .monospacedDigit() + .foregroundStyle(.tertiary) + } + } + } + .padding(.horizontal, 14) + .padding(.top, 10) + .padding(.bottom, 12) + } + + private var caption: String { + let label = store.payload.current.label.isEmpty ? store.selectedPeriod.rawValue : store.payload.current.label + if store.selectedPeriod == .today { + return "\(label) · \(todayDate)" + } + return label + } + + private var todayDate: String { + let formatter = DateFormatter() + formatter.dateFormat = "EEE MMM d" + return formatter.string(from: Date()) + } +} diff --git a/mac/Sources/CodeBurnMenubar/Views/MenuBarContent.swift b/mac/Sources/CodeBurnMenubar/Views/MenuBarContent.swift new file mode 100644 index 0000000..b6c550d --- /dev/null +++ b/mac/Sources/CodeBurnMenubar/Views/MenuBarContent.swift @@ -0,0 +1,401 @@ +import AppKit +import SwiftUI + +/// Popover root. Assembles all sections matching the HTML design spec. +struct MenuBarContent: View { + @Environment(AppStore.self) private var store + + var body: some View { + VStack(spacing: 0) { + Header() + + Divider() + + AgentTabStrip() + + Divider() + + ZStack { + ScrollView(.vertical, showsIndicators: false) { + VStack(spacing: 0) { + HeroSection() + Divider().opacity(0.5) + PeriodSegmentedControl() + Divider().opacity(0.5) + if isFilteredEmpty { + EmptyProviderState(provider: store.selectedProvider, period: store.selectedPeriod) + } else { + HeatmapSection() + .padding(.horizontal, 14) + .padding(.top, 10) + .padding(.bottom, 10) + .zIndex(10) + Divider().opacity(0.5) + ActivitySection() + Divider().opacity(0.5) + ModelsSection() + Divider().opacity(0.5) + FindingsSection() + } + } + } + + if store.isLoading { + BurnLoadingOverlay(periodLabel: store.selectedPeriod.rawValue) + .transition(.opacity) + } + } + .frame(height: 520) + .animation(.easeInOut(duration: 0.2), value: store.isLoading) + + Divider() + + FooterBar() + + StarBanner() + } + } + + /// True when a specific provider tab is selected and that provider has no spend in the + /// currently selected period. The .all tab is exempt -- it always shows aggregated data. + private var isFilteredEmpty: Bool { + guard store.selectedProvider != .all else { return false } + return store.payload.current.cost <= 0 && store.payload.current.calls == 0 + } + +} + +private struct EmptyProviderState: View { + let provider: ProviderFilter + let period: Period + + var body: some View { + VStack(spacing: 10) { + Image(systemName: "tray") + .font(.system(size: 26)) + .foregroundStyle(.tertiary) + Text("No \(provider.rawValue) data for \(periodPhrase)") + .font(.system(size: 12, weight: .medium)) + .foregroundStyle(.secondary) + .multilineTextAlignment(.center) + } + .frame(maxWidth: .infinity) + .padding(.vertical, 60) + } + + private var periodPhrase: String { + switch period { + case .today: "today" + case .sevenDays: "the last 7 days" + case .thirtyDays: "the last 30 days" + case .month: "this month" + case .all: "all time" + } + } +} + +/// Translucent overlay that blurs whatever's behind it (the previous tab/period content) +/// and centers an animated burning flame -- the brand mark filling up bottom-to-top in +/// yellow→orange→red, looping. +private struct BurnLoadingOverlay: View { + let periodLabel: String + @State private var fillProgress: CGFloat = 0 + @State private var glowing: Bool = false + + private let flameSize: CGFloat = 64 + + var body: some View { + ZStack { + // Blur backdrop -- ultraThinMaterial uses live blur of underlying content. + Rectangle() + .fill(.ultraThinMaterial) + + VStack(spacing: 14) { + BurnFlame(size: flameSize, fillProgress: fillProgress, glowing: glowing) + Text("Loading \(periodLabel)…") + .font(.system(size: 11.5, weight: .medium)) + .foregroundStyle(.secondary) + } + } + .onAppear { + withAnimation(.easeInOut(duration: 1.4).repeatForever(autoreverses: true)) { + fillProgress = 1.0 + } + withAnimation(.easeInOut(duration: 0.9).repeatForever(autoreverses: true)) { + glowing = true + } + } + } +} + +private struct BurnFlame: View { + let size: CGFloat + let fillProgress: CGFloat + let glowing: Bool + + var body: some View { + ZStack { + // Soft outer glow that pulses, matching the brand terracotta palette. + Image(systemName: "flame.fill") + .font(.system(size: size, weight: .regular)) + .foregroundStyle(Theme.brandEmberGlow.opacity(glowing ? 0.55 : 0.20)) + .blur(radius: glowing ? 14 : 6) + + // Empty (cool) flame as base + Image(systemName: "flame") + .font(.system(size: size, weight: .regular)) + .foregroundStyle(Theme.brandAccent.opacity(0.25)) + + // Burning gradient (brand orange) masked by an animated bottom-up rectangle + Image(systemName: "flame.fill") + .font(.system(size: size, weight: .regular)) + .foregroundStyle( + LinearGradient( + colors: [ + Theme.brandEmberGlow, + Theme.brandAccentDark, + Theme.brandAccent, + Theme.brandEmberDeep + ], + startPoint: .bottom, + endPoint: .top + ) + ) + .mask( + GeometryReader { geo in + Rectangle() + .frame(height: geo.size.height * fillProgress) + .frame(maxHeight: .infinity, alignment: .bottom) + } + ) + } + .frame(width: size, height: size) + } +} + +private struct Header: View { + var body: some View { + VStack(alignment: .leading, spacing: 1) { + ( + Text("Code").foregroundStyle(.primary) + + Text("Burn").foregroundStyle(Theme.brandAccent) + ) + .font(.system(size: 13, weight: .semibold)) + .tracking(-0.15) + Text("AI Coding Cost Tracker") + .font(.system(size: 10.5)) + .foregroundStyle(.secondary) + } + .frame(maxWidth: .infinity, alignment: .leading) + .padding(.horizontal, 14) + .padding(.top, 10) + .padding(.bottom, 8) + } +} + +struct FlameMark: View { + var body: some View { + ZStack { + RoundedRectangle(cornerRadius: 5) + .fill( + LinearGradient( + colors: [Theme.brandAccentDark, Theme.brandEmberDeep], + startPoint: .topLeading, + endPoint: .bottomTrailing + ) + ) + .shadow(color: .black.opacity(0.2), radius: 1, y: 0.5) + Image(systemName: "flame.fill") + .font(.system(size: 12, weight: .semibold)) + .foregroundStyle(.white) + } + } +} + +private let starBannerGitHubURL = URL(string: "https://github.com/AgentSeal/codeburn")! + +/// Shown at the very bottom on first launch. A small terracotta strip nudges users to star the +/// repo; clicking opens GitHub, clicking the close icon hides it forever (persisted to +/// UserDefaults so it never returns across launches). +struct StarBanner: View { + @AppStorage("codeburn.starBannerDismissed") private var dismissed: Bool = false + + var body: some View { + if !dismissed { + HStack(spacing: 8) { + Image(systemName: "star.fill") + .font(.system(size: 10, weight: .semibold)) + .foregroundStyle(Theme.brandAccent) + + Button { + NSWorkspace.shared.open(starBannerGitHubURL) + } label: { + HStack(spacing: 4) { + Text("Enjoying CodeBurn?") + .foregroundStyle(.primary) + Text("Star us on GitHub") + .foregroundStyle(Theme.brandAccent) + .underline(true, pattern: .solid) + } + .font(.system(size: 10.5, weight: .medium)) + .contentShape(Rectangle()) + } + .buttonStyle(.plain) + + Spacer() + + Button { + dismissed = true + } label: { + Image(systemName: "xmark") + .font(.system(size: 9, weight: .semibold)) + .foregroundStyle(.secondary) + .padding(4) + .contentShape(Rectangle()) + } + .buttonStyle(.plain) + .help("Hide this banner") + } + .padding(.horizontal, 12) + .padding(.vertical, 6) + .background(Theme.brandAccent.opacity(0.08)) + .overlay(alignment: .top) { + Rectangle() + .fill(Color.secondary.opacity(0.18)) + .frame(height: 0.5) + } + } + } +} + +struct FooterBar: View { + @Environment(AppStore.self) private var store + + var body: some View { + HStack(spacing: 6) { + Menu { + ForEach(SupportedCurrency.allCases) { currency in + Button { + applyCurrency(code: currency.rawValue) + } label: { + if currency.rawValue == store.currency { + Label("\(currency.displayName) (\(currency.rawValue))", systemImage: "checkmark") + } else { + Text("\(currency.displayName) (\(currency.rawValue))") + } + } + } + } label: { + Label(store.currency, systemImage: "dollarsign.circle") + .font(.system(size: 11, weight: .medium)) + .labelStyle(.titleAndIcon) + } + .menuStyle(.button) + .menuIndicator(.hidden) + .buttonStyle(.bordered) + .controlSize(.small) + .fixedSize() + + Button { + Task { await store.refresh(includeOptimize: true) } + } label: { + Image(systemName: store.isLoading ? "arrow.triangle.2.circlepath" : "arrow.clockwise") + .font(.system(size: 11, weight: .medium)) + } + .buttonStyle(.bordered) + .controlSize(.small) + .disabled(store.isLoading) + + Menu { + Button("CSV (folder)") { runExport(format: .csv) } + Button("JSON") { runExport(format: .json) } + } label: { + Label("Export", systemImage: "square.and.arrow.down") + .font(.system(size: 11, weight: .medium)) + .labelStyle(.titleAndIcon) + } + .menuStyle(.button) + .menuIndicator(.hidden) + .buttonStyle(.bordered) + .controlSize(.small) + .fixedSize() + + Spacer() + + Button { openReport() } label: { + Label("Open Full Report", systemImage: "terminal") + .font(.system(size: 11, weight: .semibold)) + .labelStyle(.titleAndIcon) + } + .buttonStyle(.borderedProminent) + .controlSize(.small) + .tint(Theme.brandAccent) + } + .padding(.horizontal, 12) + .padding(.vertical, 8) + } + + private func openReport() { + TerminalLauncher.open(subcommand: ["report"]) + } + + private enum ExportFormat { + case csv, json + var cliName: String { self == .csv ? "csv" : "json" } + var suffix: String { self == .csv ? "" : ".json" } + } + + /// Runs `codeburn export` directly into ~/Downloads and reveals the result in Finder. CSV + /// produces a folder of clean one-table-per-file CSVs; JSON produces a single structured + /// file. The CLI is spawned with argv (no shell interpretation), so the output path cannot + /// be abused to inject shell commands even if a pathological value slips through. + private func runExport(format: ExportFormat) { + Task { + let downloads = (NSHomeDirectory() as NSString).appendingPathComponent("Downloads") + let formatter = DateFormatter() + formatter.dateFormat = "yyyy-MM-dd" + let base = "codeburn-\(formatter.string(from: Date()))" + let outputPath = (downloads as NSString).appendingPathComponent(base + format.suffix) + + let process = CodeburnCLI.makeProcess(subcommand: [ + "export", "-f", format.cliName, "-o", outputPath + ]) + + do { + try process.run() + process.waitUntilExit() + if process.terminationStatus == 0 { + NSWorkspace.shared.activateFileViewerSelecting([URL(fileURLWithPath: outputPath)]) + } else { + NSLog("CodeBurn: \(format.cliName.uppercased()) export exited with status \(process.terminationStatus)") + } + } catch { + NSLog("CodeBurn: \(format.cliName.uppercased()) export failed: \(error)") + } + } + } + + /// Instant-feeling currency switch. Updates the symbol and any cached FX rate on the main + /// thread right away so the UI redraws the next frame, then fetches a fresh rate in the + /// background. CLI config is persisted so other codeburn commands stay in sync. + private func applyCurrency(code: String) { + store.currency = code + let symbol = CurrencyState.symbolForCode(code) + + Task { + let cached = await FXRateCache.shared.cachedRate(for: code) + await MainActor.run { + CurrencyState.shared.apply(code: code, rate: cached, symbol: symbol) + } + + let fresh = await FXRateCache.shared.rate(for: code) + if let fresh, fresh != cached { + await MainActor.run { + CurrencyState.shared.apply(code: code, rate: fresh, symbol: symbol) + } + } + } + + CLICurrencyConfig.persist(code: code) + } +} diff --git a/mac/Sources/CodeBurnMenubar/Views/ModelsSection.swift b/mac/Sources/CodeBurnMenubar/Views/ModelsSection.swift new file mode 100644 index 0000000..cac5457 --- /dev/null +++ b/mac/Sources/CodeBurnMenubar/Views/ModelsSection.swift @@ -0,0 +1,97 @@ +import SwiftUI + +struct ModelsSection: View { + @Environment(AppStore.self) private var store + @State private var isExpanded: Bool = true + + var body: some View { + CollapsibleSection( + caption: "Models", + isExpanded: $isExpanded, + trailing: { + HStack(spacing: 8) { + Text("Cost").frame(minWidth: 54, alignment: .trailing) + Text("Calls").frame(minWidth: 52, alignment: .trailing) + } + .font(.system(size: 10, weight: .medium)) + .foregroundStyle(.tertiary) + .tracking(-0.05) + } + ) { + VStack(alignment: .leading, spacing: 7) { + let maxCost = store.payload.current.topModels.map(\.cost).max() ?? 1 + ForEach(store.payload.current.topModels, id: \.name) { model in + ModelRow(model: model, maxCost: maxCost) + } + + TokensLine() + .padding(.top, 5) + } + } + } +} + +private struct ModelRow: View { + let model: ModelEntry + let maxCost: Double + + var body: some View { + HStack(spacing: 8) { + FixedBar(fraction: model.cost / maxCost) + .frame(width: 56, height: 6) + + Text(model.name) + .font(.system(size: 12.5, weight: .medium)) + .frame(maxWidth: .infinity, alignment: .leading) + + Text(model.cost.asCompactCurrency()) + .font(.codeMono(size: 12, weight: .medium)) + .tracking(-0.2) + .frame(minWidth: 54, alignment: .trailing) + + Text("\(model.calls)") + .font(.system(size: 11)) + .monospacedDigit() + .foregroundStyle(.secondary) + .frame(minWidth: 52, alignment: .trailing) + } + .padding(.horizontal, 2) + .padding(.vertical, 1) + } +} + +private struct TokensLine: View { + @Environment(AppStore.self) private var store + + var body: some View { + let t = store.payload.current + let cacheHit = String(format: "%.0f", t.cacheHitPercent) + + HStack(spacing: 4) { + Text("Tokens") + .foregroundStyle(.tertiary) + Text(formatTokens(t.inputTokens) + " in") + .foregroundStyle(.secondary) + Text("·") + .foregroundStyle(.tertiary) + Text(formatTokens(t.outputTokens) + " out") + .foregroundStyle(.secondary) + Text("·") + .foregroundStyle(.tertiary) + Text(cacheHit + "% cache hit") + .foregroundStyle(.secondary) + Spacer() + } + .font(.system(size: 10.5)) + .monospacedDigit() + } + + private func formatTokens(_ n: Int) -> String { + if n >= 1_000_000 { + return String(format: "%.1fM", Double(n) / 1_000_000) + } else if n >= 1_000 { + return String(format: "%.1fK", Double(n) / 1_000) + } + return "\(n)" + } +} diff --git a/mac/Sources/CodeBurnMenubar/Views/PeriodSegmentedControl.swift b/mac/Sources/CodeBurnMenubar/Views/PeriodSegmentedControl.swift new file mode 100644 index 0000000..a636932 --- /dev/null +++ b/mac/Sources/CodeBurnMenubar/Views/PeriodSegmentedControl.swift @@ -0,0 +1,36 @@ +import SwiftUI + +struct PeriodSegmentedControl: View { + @Environment(AppStore.self) private var store + + var body: some View { + HStack(spacing: 1) { + ForEach(Period.allCases) { period in + Button { + Task { await store.switchTo(period: period) } + } label: { + Text(period.rawValue) + .font(.system(size: 11, weight: .medium)) + .foregroundStyle(store.selectedPeriod == period ? AnyShapeStyle(.primary) : AnyShapeStyle(.secondary)) + .frame(maxWidth: .infinity) + .padding(.vertical, 4) + .contentShape(Rectangle()) + } + .buttonStyle(.plain) + .background( + RoundedRectangle(cornerRadius: 5) + .fill(store.selectedPeriod == period ? Color(NSColor.windowBackgroundColor).opacity(0.85) : .clear) + .shadow(color: .black.opacity(store.selectedPeriod == period ? 0.06 : 0), radius: 1, y: 0.5) + ) + } + } + .padding(2) + .background( + RoundedRectangle(cornerRadius: 7) + .fill(Color.secondary.opacity(0.08)) + ) + .padding(.horizontal, 12) + .padding(.top, 6) + .padding(.bottom, 10) + } +} diff --git a/mac/Sources/CodeBurnMenubar/Views/SectionCaption.swift b/mac/Sources/CodeBurnMenubar/Views/SectionCaption.swift new file mode 100644 index 0000000..1c4db4c --- /dev/null +++ b/mac/Sources/CodeBurnMenubar/Views/SectionCaption.swift @@ -0,0 +1,85 @@ +import SwiftUI + +struct SectionCaption: View { + let text: String + + var body: some View { + HStack(spacing: 5) { + Circle() + .fill(Theme.brandAccent.opacity(0.7)) + .frame(width: 3, height: 3) + Text(text) + .font(.system(size: 11.5, weight: .medium)) + .foregroundStyle(.secondary) + .tracking(-0.1) + } + } +} + +/// Collapsible section shell with a clickable caption, optional inline trailing +/// view (e.g. column headers), and a chevron. +struct CollapsibleSection: View { + let caption: String + @Binding var isExpanded: Bool + let trailing: Trailing + let content: Content + + init( + caption: String, + isExpanded: Binding, + @ViewBuilder trailing: () -> Trailing, + @ViewBuilder content: () -> Content + ) { + self.caption = caption + self._isExpanded = isExpanded + self.trailing = trailing() + self.content = content() + } + + var body: some View { + VStack(alignment: .leading, spacing: 7) { + Button { + withAnimation(.easeInOut(duration: 0.18)) { + isExpanded.toggle() + } + } label: { + HStack(spacing: 8) { + HStack(spacing: 5) { + Circle() + .fill(Theme.brandAccent.opacity(0.7)) + .frame(width: 3, height: 3) + Text(caption) + .font(.system(size: 11.5, weight: .medium)) + .tracking(-0.1) + } + Spacer() + trailing + Image(systemName: "chevron.right") + .font(.system(size: 9, weight: .semibold)) + .rotationEffect(.degrees(isExpanded ? 90 : 0)) + .opacity(0.55) + } + .foregroundStyle(.secondary) + .contentShape(Rectangle()) + } + .buttonStyle(.plain) + + if isExpanded { + content + .transition(.opacity) + } + } + .padding(.horizontal, 14) + .padding(.vertical, 11) + } +} + +extension CollapsibleSection where Trailing == EmptyView { + init( + caption: String, + isExpanded: Binding, + @ViewBuilder content: () -> Content + ) { + self.init(caption: caption, isExpanded: isExpanded, trailing: { EmptyView() }, content: content) + } +} diff --git a/mac/Sources/CodeBurnMenubar/Views/SparklineView.swift b/mac/Sources/CodeBurnMenubar/Views/SparklineView.swift new file mode 100644 index 0000000..db7d7cc --- /dev/null +++ b/mac/Sources/CodeBurnMenubar/Views/SparklineView.swift @@ -0,0 +1,99 @@ +import SwiftUI + +struct SparklineView: View { + let points: [Double] + + var body: some View { + GeometryReader { geo in + let cgPoints = makePoints(in: geo.size) + let smooth = smoothPath(cgPoints) + + ZStack { + // Gradient fill under the curve + let fill = closedPath(smooth, width: geo.size.width, height: geo.size.height) + fill.fill( + LinearGradient( + colors: [Theme.brandAccent.opacity(0.25), .clear], + startPoint: .top, + endPoint: .bottom + ) + ) + + // Smooth accent stroke + smooth.stroke( + Theme.brandAccent.opacity(0.85), + style: StrokeStyle(lineWidth: 1.6, lineCap: .round, lineJoin: .round) + ) + + // Highlighted current-day point + if let last = cgPoints.last { + Circle() + .fill(Theme.brandAccent) + .frame(width: 6, height: 6) + .overlay( + Circle() + .stroke(Color(NSColor.windowBackgroundColor).opacity(0.9), lineWidth: 1.3) + ) + .position(last) + } + } + } + } + + // MARK: - Geometry + + private func makePoints(in size: CGSize) -> [CGPoint] { + guard !points.isEmpty else { return [] } + let w = size.width + let h = size.height + let maxV = points.max() ?? 1 + let minV = points.min() ?? 0 + let range = max(maxV - minV, 1) + let count = max(points.count - 1, 1) + let topPad: CGFloat = 5 + let bottomPad: CGFloat = 5 + let usable = max(h - topPad - bottomPad, 1) + + return points.enumerated().map { idx, v in + CGPoint( + x: w * CGFloat(idx) / CGFloat(count), + y: h - bottomPad - usable * CGFloat(v - minV) / CGFloat(range) + ) + } + } + + /// Catmull-Rom → cubic bezier. Standard smooth interpolation, no overshoot. + private func smoothPath(_ pts: [CGPoint]) -> Path { + var path = Path() + guard pts.count >= 2 else { return path } + path.move(to: pts[0]) + + let tension: CGFloat = 0.5 + for i in 0..<(pts.count - 1) { + let p0 = i > 0 ? pts[i - 1] : pts[i] + let p1 = pts[i] + let p2 = pts[i + 1] + let p3 = i + 2 < pts.count ? pts[i + 2] : p2 + + let cp1 = CGPoint( + x: p1.x + (p2.x - p0.x) * tension / 3, + y: p1.y + (p2.y - p0.y) * tension / 3 + ) + let cp2 = CGPoint( + x: p2.x - (p3.x - p1.x) * tension / 3, + y: p2.y - (p3.y - p1.y) * tension / 3 + ) + path.addCurve(to: p2, control1: cp1, control2: cp2) + } + return path + } + + /// Close the path along the bottom to form a fill region. + private func closedPath(_ line: Path, width: CGFloat, height: CGFloat) -> Path { + var p = line + p.addLine(to: CGPoint(x: width, y: height)) + p.addLine(to: CGPoint(x: 0, y: height)) + p.closeSubpath() + return p + } +} diff --git a/mac/Tests/CodeBurnMenubarTests/CapacityEstimatorTests.swift b/mac/Tests/CodeBurnMenubarTests/CapacityEstimatorTests.swift new file mode 100644 index 0000000..b23ba5f --- /dev/null +++ b/mac/Tests/CodeBurnMenubarTests/CapacityEstimatorTests.swift @@ -0,0 +1,158 @@ +import Foundation +import Testing +@testable import CodeBurnMenubar + +private let now = Date(timeIntervalSince1970: 1_734_000_000) + +private func snap(_ percent: Double, _ tokens: Double, ageDays: Double = 0) -> CapacitySnapshot { + CapacitySnapshot( + percent: percent, + effectiveTokens: tokens, + capturedAt: now.addingTimeInterval(-ageDays * 86400) + ) +} + +@Suite("CapacityEstimator -- gating") +struct CapacityEstimatorGatingTests { + @Test("returns nil with no snapshots") + func emptyReturnsNil() { + #expect(CapacityEstimator.estimate([], asOf: now) == nil) + } + + @Test("returns nil with fewer than 5 snapshots") + func tooFewReturnsNil() { + let snaps = (1...4).map { snap(Double($0 * 10), Double($0) * 100_000) } + #expect(CapacityEstimator.estimate(snaps, asOf: now) == nil) + } + + @Test("returns nil when percent range is below 15 points") + func tooNarrowReturnsNil() { + let snaps = [ + snap(40, 4_000_000), + snap(42, 4_200_000), + snap(44, 4_400_000), + snap(46, 4_600_000), + snap(48, 4_800_000), + snap(50, 5_000_000), + ] + #expect(CapacityEstimator.estimate(snaps, asOf: now) == nil) + } +} + +@Suite("CapacityEstimator -- recovery") +struct CapacityEstimatorRecoveryTests { + @Test("recovers capacity from 10 noise-free snapshots within 0.5%") + func recoverFromCleanData() { + let trueCapacity: Double = 10_000_000 + let percents = [5.0, 12, 20, 28, 35, 47, 55, 68, 80, 92] + let snaps = percents.map { p in snap(p, p / 100 * trueCapacity) } + let est = CapacityEstimator.estimate(snaps, asOf: now) + #expect(est != nil) + #expect(est!.capacity > trueCapacity * 0.995) + #expect(est!.capacity < trueCapacity * 1.005) + // 10 perfect samples is below the solid sample threshold (15) but easily medium. + #expect(est!.confidence == .medium || est!.confidence == .solid) + } + + @Test("recovers capacity within 5% from 30 noisy snapshots") + func recoverFromNoisyData() { + let trueCapacity: Double = 8_000_000 + var rng = LinearCongruentialGenerator(seed: 42) + let snaps: [CapacitySnapshot] = (0..<30).map { i in + let p = 5.0 + Double(i) * 3.0 // 5..92, spanning enough + let noise = (rng.nextDouble() - 0.5) * 0.10 // ±5% + let tokens = (p / 100) * trueCapacity * (1 + noise) + return snap(p, tokens) + } + let est = CapacityEstimator.estimate(snaps, asOf: now) + #expect(est != nil) + let ratio = est!.capacity / trueCapacity + #expect(ratio > 0.95 && ratio < 1.05) + #expect(est!.confidence == .solid || est!.confidence == .medium) + } +} + +@Suite("CapacityEstimator -- confidence tiers") +struct CapacityEstimatorConfidenceTests { + @Test("six clean snapshots span sufficient range -> at least medium") + func sixCleanSnapshotsMedium() { + let trueCapacity: Double = 5_000_000 + let percents = [5.0, 18, 32, 51, 70, 88] + let snaps = percents.map { p in snap(p, p / 100 * trueCapacity) } + let est = CapacityEstimator.estimate(snaps, asOf: now) + #expect(est != nil) + #expect(est!.confidence == .medium || est!.confidence == .solid) + } + + @Test("noisy small-sample data falls to low confidence") + func noisySmallSampleLow() { + let trueCapacity: Double = 5_000_000 + var rng = LinearCongruentialGenerator(seed: 7) + let percents = [5.0, 22, 40, 60, 80, 95] + let snaps: [CapacitySnapshot] = percents.map { p in + let noise = (rng.nextDouble() - 0.5) * 1.6 // ±80% noise -> drops R^2 below medium gate + return snap(p, p / 100 * trueCapacity * (1 + noise)) + } + let est = CapacityEstimator.estimate(snaps, asOf: now) + #expect(est != nil) + #expect(est!.confidence == .low) + } +} + +@Suite("CapacityEstimator -- recency weighting") +struct CapacityEstimatorRecencyTests { + @Test("recent snapshots dominate over old ones with different capacity") + func recencyShiftsEstimate() { + // Old data: capacity = 5M (45 days ago) + // New data: capacity = 10M (today) + // With 30-day half-life, recent data should win. + let oldSnaps = (0..<10).map { i -> CapacitySnapshot in + let p = 10.0 + Double(i) * 8 + return snap(p, p / 100 * 5_000_000, ageDays: 45) + } + let newSnaps = (0..<10).map { i -> CapacitySnapshot in + let p = 10.0 + Double(i) * 8 + return snap(p, p / 100 * 10_000_000, ageDays: 1) + } + let est = CapacityEstimator.estimate(oldSnaps + newSnaps, asOf: now) + #expect(est != nil) + // Recent capacity is 10M; estimate should be closer to 10M than 5M. + #expect(est!.capacity > 7_500_000) + } +} + +@Suite("CapacityEstimator -- non-linearity") +struct CapacityEstimatorNonLinearityTests { + @Test("flags non-linearity when residuals show systematic sign pattern") + func detectsKneePattern() { + // Data follows a knee: linear up to 60%, then flatter (Anthropic capping). + let snaps: [CapacitySnapshot] = (0..<20).map { i in + let p = 5.0 + Double(i) * 5 + let tokens: Double = p < 60 ? p / 100 * 8_000_000 : 0.6 * 8_000_000 + (p - 60) / 100 * 4_000_000 + return snap(p, tokens) + } + let est = CapacityEstimator.estimate(snaps, asOf: now) + #expect(est != nil) + #expect(est!.nonLinearityWarning == true) + } + + @Test("does not flag clean linear data") + func cleanLinearNoFlag() { + let trueCapacity: Double = 6_000_000 + let percents = stride(from: 5.0, to: 95.0, by: 5.0).map { $0 } + let snaps = percents.map { p in snap(p, p / 100 * trueCapacity) } + let est = CapacityEstimator.estimate(snaps, asOf: now) + #expect(est != nil) + #expect(est!.nonLinearityWarning == false) + } +} + +// Lightweight deterministic RNG for reproducible noise in tests. +struct LinearCongruentialGenerator { + private var state: UInt64 + init(seed: UInt64) { self.state = seed } + mutating func nextDouble() -> Double { + state = state &* 6364136223846793005 &+ 1442695040888963407 + return Double(state >> 11) / Double(1 << 53) + } +} diff --git a/src/cli.ts b/src/cli.ts index 342a9f2..ac87127 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -1,13 +1,17 @@ import { Command } from 'commander' +import { installMenubarApp } from './menubar-installer.js' import { exportCsv, exportJson, type PeriodExport } from './export.js' import { loadPricing } from './models.js' import { parseAllSessions, filterProjectsByName } from './parser.js' import { convertCost } from './currency.js' import { renderStatusBar } from './format.js' -import { installMenubar, renderMenubarFormat, type PeriodData, type ProviderCost, uninstallMenubar } from './menubar.js' +import { type PeriodData, type ProviderCost } from './menubar-json.js' +import { buildMenubarPayload } from './menubar-json.js' +import { addNewDays, getDaysInRange, loadDailyCache, saveDailyCache, withDailyCacheLock } from './daily-cache.js' +import { aggregateProjectsIntoDays, buildPeriodDataFromDays } from './day-aggregator.js' import { CATEGORY_LABELS, type DateRange, type ProjectSummary, type TaskCategory } from './types.js' import { renderDashboard } from './dashboard.js' -import { runOptimize } from './optimize.js' +import { runOptimize, scanAndDetect } from './optimize.js' import { getAllProviders } from './providers/index.js' import { readConfig, saveConfig, getConfigFilePath } from './config.js' import { createRequire } from 'node:module' @@ -16,6 +20,13 @@ const require = createRequire(import.meta.url) const { version } = require('../package.json') import { loadCurrency, getCurrency, isValidCurrencyCode } from './currency.js' +const MS_PER_DAY = 24 * 60 * 60 * 1000 +const BACKFILL_DAYS = 365 + +function toDateString(date: Date): string { + return date.toISOString().slice(0, 10) +} + function getDateRange(period: string): { range: DateRange; label: string } { const now = new Date() const end = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 23, 59, 59, 999) @@ -43,7 +54,11 @@ function getDateRange(period: string): { range: DateRange; label: string } { return { range: { start, end }, label: 'Last 30 Days' } } case 'all': { - return { range: { start: new Date(0), end }, label: 'All Time' } + // Cap "All Time" to the last 6 months. Older data is rarely actionable for a cost + // tracker and keeps the parse path bounded so providers like Codex/Cursor with sparse + // data still load in seconds. + const start = new Date(now.getFullYear(), now.getMonth() - 6, now.getDate()) + return { range: { start, end }, label: 'Last 6 months' } } default: { const start = new Date(now.getFullYear(), now.getMonth(), now.getDate() - 7) @@ -98,8 +113,10 @@ function buildJsonReport(projects: ProjectSummary[], period: string, periodKey: const totalOutput = sessions.reduce((s, sess) => s + sess.totalOutputTokens, 0) const totalCacheRead = sessions.reduce((s, sess) => s + sess.totalCacheReadTokens, 0) const totalCacheWrite = sessions.reduce((s, sess) => s + sess.totalCacheWriteTokens, 0) - const allInput = totalInput + totalCacheRead + totalCacheWrite - const cacheHitPercent = allInput > 0 ? Math.round((totalCacheRead / allInput) * 1000) / 10 : 0 + // Match src/menubar-json.ts:cacheHitPercent: reads over reads+fresh-input. cache_write + // counts tokens being stored, not served, so it doesn't belong in the denominator. + const cacheHitDenom = totalInput + totalCacheRead + const cacheHitPercent = cacheHitDenom > 0 ? Math.round((totalCacheRead / cacheHitDenom) * 1000) / 10 : 0 const dailyMap: Record = {} for (const sess of sessions) { @@ -262,6 +279,7 @@ function buildPeriodData(label: string, projects: ProjectSummary[]): PeriodData label, cost: projects.reduce((s, p) => s + p.totalCostUSD, 0), calls: projects.reduce((s, p) => s + p.totalApiCalls, 0), + sessions: projects.reduce((s, p) => s + p.sessions.length, 0), inputTokens, outputTokens, cacheReadTokens, cacheWriteTokens, categories: Object.entries(catTotals) .sort(([, a], [, b]) => b.cost - a.cost) @@ -275,27 +293,148 @@ function buildPeriodData(label: string, projects: ProjectSummary[]): PeriodData program .command('status') .description('Compact status output (today + week + month)') - .option('--format ', 'Output format: terminal, menubar, json', 'terminal') + .option('--format ', 'Output format: terminal, menubar-json, json', 'terminal') .option('--provider ', 'Filter by provider: all, claude, codex, cursor', 'all') .option('--project ', 'Show only projects matching name (repeatable)', collect, []) .option('--exclude ', 'Exclude projects matching name (repeatable)', collect, []) + .option('--period ', 'Primary period for menubar-json: today, week, 30days, month, all', 'today') + .option('--no-optimize', 'Skip optimize findings (menubar-json only, faster)') .action(async (opts) => { await loadPricing() const pf = opts.provider const fp = (p: ProjectSummary[]) => filterProjectsByName(p, opts.project, opts.exclude) - if (opts.format === 'menubar') { - const todayRange = getDateRange('today').range - const todayData = buildPeriodData('Today', fp(await parseAllSessions(todayRange, pf))) - const weekData = buildPeriodData('7 Days', fp(await parseAllSessions(getDateRange('week').range, pf))) - const thirtyDayData = buildPeriodData('30 Days', fp(await parseAllSessions(getDateRange('30days').range, pf))) - const monthData = buildPeriodData('Month', fp(await parseAllSessions(getDateRange('month').range, pf))) - const todayProviders: ProviderCost[] = [] - for (const p of await getAllProviders()) { - const data = fp(await parseAllSessions(todayRange, p.name)) - const cost = data.reduce((s, proj) => s + proj.totalCostUSD, 0) - if (cost > 0) todayProviders.push({ name: p.displayName, cost }) + if (opts.format === 'menubar-json') { + const periodInfo = getDateRange(opts.period) + const now = new Date() + const todayStart = new Date(now.getFullYear(), now.getMonth(), now.getDate()) + const yesterdayEnd = new Date(todayStart.getTime() - 1) + const yesterdayStr = toDateString(new Date(todayStart.getTime() - MS_PER_DAY)) + const isAllProviders = pf === 'all' + + // The daily cache is provider-agnostic: always backfill it from .all so subsequent + // provider-filtered reads can derive per-provider cost+calls from DailyEntry.providers. + const cache = await withDailyCacheLock(async () => { + let c = await loadDailyCache() + const gapStart = c.lastComputedDate + ? new Date(new Date(`${c.lastComputedDate}T00:00:00.000Z`).getTime() + MS_PER_DAY) + : new Date(todayStart.getTime() - BACKFILL_DAYS * MS_PER_DAY) + + if (gapStart.getTime() <= yesterdayEnd.getTime()) { + const gapRange: DateRange = { start: gapStart, end: yesterdayEnd } + const gapProjects = filterProjectsByName(await parseAllSessions(gapRange, 'all'), opts.project, opts.exclude) + const gapDays = aggregateProjectsIntoDays(gapProjects) + c = addNewDays(c, gapDays, yesterdayStr) + await saveDailyCache(c) + } + return c + }) + + // CURRENT PERIOD DATA + // - .all provider: assemble from cache + today (fast) + // - specific provider: parse the period range with provider filter (correct, but slower) + let currentData: PeriodData + let scanProjects: ProjectSummary[] + let scanRange: DateRange + + if (isAllProviders) { + const todayRange: DateRange = { start: todayStart, end: now } + const todayProjects = fp(await parseAllSessions(todayRange, 'all')) + const todayDays = aggregateProjectsIntoDays(todayProjects) + const rangeStartStr = toDateString(periodInfo.range.start) + const rangeEndStr = toDateString(periodInfo.range.end) + const historicalDays = getDaysInRange(cache, rangeStartStr, yesterdayStr) + const todayInRange = todayDays.filter(d => d.date >= rangeStartStr && d.date <= rangeEndStr) + const allDays = [...historicalDays, ...todayInRange].sort((a, b) => a.date.localeCompare(b.date)) + currentData = buildPeriodDataFromDays(allDays, periodInfo.label) + scanProjects = todayProjects + scanRange = todayRange + } else { + const projects = fp(await parseAllSessions(periodInfo.range, pf)) + currentData = buildPeriodData(periodInfo.label, projects) + scanProjects = projects + scanRange = periodInfo.range } - console.log(renderMenubarFormat(todayData, weekData, thirtyDayData, monthData, todayProviders)) + + // PROVIDERS + // For .all: enumerate every provider with cost across the period (from cache) + installed-but-zero. + // For specific: just this single provider with its scoped cost. + const allProviders = await getAllProviders() + const displayNameByName = new Map(allProviders.map(p => [p.name, p.displayName])) + const providers: ProviderCost[] = [] + if (isAllProviders) { + const todayRangeForProviders: DateRange = { start: todayStart, end: now } + const todayDaysForProviders = aggregateProjectsIntoDays(fp(await parseAllSessions(todayRangeForProviders, 'all'))) + const rangeStartStr = toDateString(periodInfo.range.start) + const allDaysForProviders = [ + ...getDaysInRange(cache, rangeStartStr, yesterdayStr), + ...todayDaysForProviders.filter(d => d.date >= rangeStartStr), + ] + const providerTotals: Record = {} + for (const d of allDaysForProviders) { + for (const [name, p] of Object.entries(d.providers)) { + providerTotals[name] = (providerTotals[name] ?? 0) + p.cost + } + } + for (const [name, cost] of Object.entries(providerTotals)) { + providers.push({ name: displayNameByName.get(name) ?? name, cost }) + } + for (const p of allProviders) { + if (providers.some(pc => pc.name === p.displayName)) continue + const sources = await p.discoverSessions() + if (sources.length > 0) providers.push({ name: p.displayName, cost: 0 }) + } + } else { + const display = displayNameByName.get(pf) ?? pf + providers.push({ name: display, cost: currentData.cost }) + } + + // DAILY HISTORY (last 365 days) + // Cache stores per-provider cost+calls per day in DailyEntry.providers, so we can derive + // a provider-filtered history without re-parsing. Tokens aren't broken down per provider + // in the cache, so the filtered view shows zero tokens (heatmap/trend still works on cost). + const historyStartStr = toDateString(new Date(todayStart.getTime() - BACKFILL_DAYS * MS_PER_DAY)) + const allCacheDays = getDaysInRange(cache, historyStartStr, yesterdayStr) + const allTodayDaysForHistory = aggregateProjectsIntoDays(fp(await parseAllSessions({ start: todayStart, end: now }, 'all'))) + const fullHistory = [...allCacheDays, ...allTodayDaysForHistory] + const dailyHistory = fullHistory.map(d => { + if (isAllProviders) { + const topModels = Object.entries(d.models) + .filter(([name]) => name !== '') + .sort(([, a], [, b]) => b.cost - a.cost) + .slice(0, 5) + .map(([name, m]) => ({ + name, + cost: m.cost, + calls: m.calls, + inputTokens: m.inputTokens, + outputTokens: m.outputTokens, + })) + return { + date: d.date, + cost: d.cost, + calls: d.calls, + inputTokens: d.inputTokens, + outputTokens: d.outputTokens, + cacheReadTokens: d.cacheReadTokens, + cacheWriteTokens: d.cacheWriteTokens, + topModels, + } + } + const prov = d.providers[pf] ?? { calls: 0, cost: 0 } + return { + date: d.date, + cost: prov.cost, + calls: prov.calls, + inputTokens: 0, + outputTokens: 0, + cacheReadTokens: 0, + cacheWriteTokens: 0, + topModels: [], + } + }) + + const optimize = opts.optimize === false ? null : await scanAndDetect(scanProjects, scanRange) + console.log(JSON.stringify(buildMenubarPayload(currentData, providers, optimize, dailyHistory))) return } @@ -374,29 +513,37 @@ program const outputPath = opts.output ?? `${defaultName}.${opts.format}` let savedPath: string - if (opts.format === 'json') { - savedPath = await exportJson(periods, outputPath) - } else { - savedPath = await exportCsv(periods, outputPath) + try { + if (opts.format === 'json') { + savedPath = await exportJson(periods, outputPath) + } else { + savedPath = await exportCsv(periods, outputPath) + } + } catch (err) { + // Protection guards in export.ts (symlink refusal, non-codeburn folder refusal, etc.) + // throw with a user-readable message. Print just the message, not the stack, so the CLI + // doesn't spray its internals at the user. + const message = err instanceof Error ? err.message : String(err) + console.error(`\n Export failed: ${message}\n`) + process.exit(1) } console.log(`\n Exported (Today + 7 Days + 30 Days) to: ${savedPath}\n`) }) program - .command('install-menubar') - .description('Install macOS menu bar plugin (SwiftBar/xbar)') - .action(async () => { - const result = await installMenubar() - console.log(result) - }) - -program - .command('uninstall-menubar') - .description('Remove macOS menu bar plugin') - .action(async () => { - const result = await uninstallMenubar() - console.log(result) + .command('menubar') + .description('Install and launch the macOS menubar app (one command, no clone)') + .option('--force', 'Reinstall even if an older copy is already in ~/Applications') + .action(async (opts: { force?: boolean }) => { + try { + const result = await installMenubarApp({ force: opts.force }) + console.log(`\n Ready. ${result.installedPath}\n`) + } catch (err) { + const message = err instanceof Error ? err.message : String(err) + console.error(`\n Menubar install failed: ${message}\n`) + process.exit(1) + } }) program diff --git a/src/currency.ts b/src/currency.ts index 53bdb1f..8788e07 100644 --- a/src/currency.ts +++ b/src/currency.ts @@ -12,6 +12,17 @@ type CurrencyState = { const CACHE_TTL_MS = 24 * 60 * 60 * 1000 const FRANKFURTER_URL = 'https://api.frankfurter.app/latest?from=USD&to=' +// Defensive bounds on any fetched FX rate. Outside this band the rate is either a parser bug +// or a tampered Frankfurter response, and we refuse to multiply it into displayed costs. +const MIN_VALID_FX_RATE = 0.0001 +const MAX_VALID_FX_RATE = 1_000_000 + +function isValidRate(value: unknown): value is number { + return typeof value === 'number' + && Number.isFinite(value) + && value >= MIN_VALID_FX_RATE + && value <= MAX_VALID_FX_RATE +} let active: CurrencyState = { code: 'USD', rate: 1, symbol: '$' } @@ -54,18 +65,22 @@ function getRateCachePath(): string { async function fetchRate(code: string): Promise { const response = await fetch(`${FRANKFURTER_URL}${code}`) if (!response.ok) throw new Error(`HTTP ${response.status}`) - const data = await response.json() as { rates: Record } - const rate = data.rates[code] - if (!rate) throw new Error(`No rate returned for ${code}`) + const data = await response.json() as { rates?: Record } + const rate = data.rates?.[code] + if (!isValidRate(rate)) throw new Error(`Invalid rate returned for ${code}`) return rate } async function loadCachedRate(code: string): Promise { try { const raw = await readFile(getRateCachePath(), 'utf-8') - const cached = JSON.parse(raw) as { timestamp: number; code: string; rate: number } - if (cached.code !== code) return null + const cached = JSON.parse(raw) as Partial<{ timestamp: number; code: string; rate: number }> + // Validate every field -- a tampered cache file could set rate to a string, null, or + // Infinity and break downstream math silently. + if (typeof cached.code !== 'string' || cached.code !== code) return null + if (typeof cached.timestamp !== 'number' || !Number.isFinite(cached.timestamp)) return null if (Date.now() - cached.timestamp > CACHE_TTL_MS) return null + if (!isValidRate(cached.rate)) return null return cached.rate } catch { return null diff --git a/src/daily-cache.ts b/src/daily-cache.ts new file mode 100644 index 0000000..1320aa6 --- /dev/null +++ b/src/daily-cache.ts @@ -0,0 +1,118 @@ +import { randomBytes } from 'crypto' +import { existsSync } from 'fs' +import { mkdir, open, readFile, rename, unlink } from 'fs/promises' +import { homedir } from 'os' +import { join } from 'path' + +export const DAILY_CACHE_VERSION = 2 +const DAILY_CACHE_FILENAME = 'daily-cache.json' + +export type DailyEntry = { + date: string + cost: number + calls: number + sessions: number + inputTokens: number + outputTokens: number + cacheReadTokens: number + cacheWriteTokens: number + editTurns: number + oneShotTurns: number + models: Record + categories: Record + providers: Record +} + +export type DailyCache = { + version: number + lastComputedDate: string | null + days: DailyEntry[] +} + +function getCacheDir(): string { + return process.env['CODEBURN_CACHE_DIR'] ?? join(homedir(), '.cache', 'codeburn') +} + +function getCachePath(): string { + return join(getCacheDir(), DAILY_CACHE_FILENAME) +} + +function emptyCache(): DailyCache { + return { version: DAILY_CACHE_VERSION, lastComputedDate: null, days: [] } +} + +function isValidCache(parsed: unknown): parsed is DailyCache { + if (!parsed || typeof parsed !== 'object') return false + const c = parsed as Partial + if (c.version !== DAILY_CACHE_VERSION) return false + if (!Array.isArray(c.days)) return false + return true +} + +export async function loadDailyCache(): Promise { + const path = getCachePath() + if (!existsSync(path)) return emptyCache() + try { + const raw = await readFile(path, 'utf-8') + const parsed: unknown = JSON.parse(raw) + if (!isValidCache(parsed)) return emptyCache() + return parsed + } catch { + return emptyCache() + } +} + +export async function saveDailyCache(cache: DailyCache): Promise { + const dir = getCacheDir() + if (!existsSync(dir)) await mkdir(dir, { recursive: true }) + const finalPath = getCachePath() + const tempPath = `${finalPath}.${randomBytes(8).toString('hex')}.tmp` + const payload = JSON.stringify(cache) + const handle = await open(tempPath, 'w', 0o600) + try { + await handle.writeFile(payload, { encoding: 'utf-8' }) + await handle.sync() + } finally { + await handle.close() + } + try { + await rename(tempPath, finalPath) + } catch (err) { + try { await unlink(tempPath) } catch { /* ignore */ } + throw err + } +} + +export function addNewDays(cache: DailyCache, incoming: DailyEntry[], newestDate: string): DailyCache { + const seen = new Set(cache.days.map(d => d.date)) + const merged = [...cache.days] + for (const day of incoming) { + if (seen.has(day.date)) continue + seen.add(day.date) + merged.push(day) + } + merged.sort((a, b) => a.date.localeCompare(b.date)) + const nextLast = cache.lastComputedDate && cache.lastComputedDate > newestDate + ? cache.lastComputedDate + : newestDate + return { version: DAILY_CACHE_VERSION, lastComputedDate: nextLast, days: merged } +} + +export function getDaysInRange(cache: DailyCache, start: string, end: string): DailyEntry[] { + return cache.days.filter(d => d.date >= start && d.date <= end) +} + +let lockChain: Promise = Promise.resolve() + +export function withDailyCacheLock(fn: () => Promise): Promise { + const next = lockChain.then(() => fn()) + lockChain = next.catch(() => undefined) + return next +} diff --git a/src/day-aggregator.ts b/src/day-aggregator.ts new file mode 100644 index 0000000..5030f8d --- /dev/null +++ b/src/day-aggregator.ts @@ -0,0 +1,142 @@ +import type { DailyEntry } from './daily-cache.js' +import type { PeriodData } from './menubar-json.js' +import { CATEGORY_LABELS, type ProjectSummary, type TaskCategory } from './types.js' + +function emptyEntry(date: string): DailyEntry { + return { + date, + cost: 0, + calls: 0, + sessions: 0, + inputTokens: 0, + outputTokens: 0, + cacheReadTokens: 0, + cacheWriteTokens: 0, + editTurns: 0, + oneShotTurns: 0, + models: {}, + categories: {}, + providers: {}, + } +} + +function dateKey(iso: string): string { + return iso.slice(0, 10) +} + +export function aggregateProjectsIntoDays(projects: ProjectSummary[]): DailyEntry[] { + const byDate = new Map() + const ensure = (date: string): DailyEntry => { + let d = byDate.get(date) + if (!d) { d = emptyEntry(date); byDate.set(date, d) } + return d + } + + for (const project of projects) { + for (const session of project.sessions) { + const sessionDate = dateKey(session.firstTimestamp) + ensure(sessionDate).sessions += 1 + + for (const turn of session.turns) { + if (turn.assistantCalls.length === 0) continue + const turnDate = dateKey(turn.assistantCalls[0]!.timestamp) + const turnDay = ensure(turnDate) + + const editTurns = turn.hasEdits ? 1 : 0 + const oneShotTurns = turn.hasEdits && turn.retries === 0 ? 1 : 0 + const turnCost = turn.assistantCalls.reduce((s, c) => s + c.costUSD, 0) + + turnDay.editTurns += editTurns + turnDay.oneShotTurns += oneShotTurns + + const cat = turnDay.categories[turn.category] ?? { turns: 0, cost: 0, editTurns: 0, oneShotTurns: 0 } + cat.turns += 1 + cat.cost += turnCost + cat.editTurns += editTurns + cat.oneShotTurns += oneShotTurns + turnDay.categories[turn.category] = cat + + for (const call of turn.assistantCalls) { + const callDate = dateKey(call.timestamp) + const callDay = ensure(callDate) + + callDay.cost += call.costUSD + callDay.calls += 1 + callDay.inputTokens += call.usage.inputTokens + callDay.outputTokens += call.usage.outputTokens + callDay.cacheReadTokens += call.usage.cacheReadInputTokens + callDay.cacheWriteTokens += call.usage.cacheCreationInputTokens + + const model = callDay.models[call.model] ?? { + calls: 0, cost: 0, + inputTokens: 0, outputTokens: 0, + cacheReadTokens: 0, cacheWriteTokens: 0, + } + model.calls += 1 + model.cost += call.costUSD + model.inputTokens += call.usage.inputTokens + model.outputTokens += call.usage.outputTokens + model.cacheReadTokens += call.usage.cacheReadInputTokens + model.cacheWriteTokens += call.usage.cacheCreationInputTokens + callDay.models[call.model] = model + + const provider = callDay.providers[call.provider] ?? { calls: 0, cost: 0 } + provider.calls += 1 + provider.cost += call.costUSD + callDay.providers[call.provider] = provider + } + } + } + } + + return [...byDate.values()].sort((a, b) => a.date.localeCompare(b.date)) +} + +export function buildPeriodDataFromDays(days: DailyEntry[], label: string): PeriodData { + let cost = 0, calls = 0, sessions = 0 + let inputTokens = 0, outputTokens = 0, cacheReadTokens = 0, cacheWriteTokens = 0 + const catTotals: Record = {} + const modelTotals: Record = {} + + for (const d of days) { + cost += d.cost + calls += d.calls + sessions += d.sessions + inputTokens += d.inputTokens + outputTokens += d.outputTokens + cacheReadTokens += d.cacheReadTokens + cacheWriteTokens += d.cacheWriteTokens + + for (const [name, m] of Object.entries(d.models)) { + const acc = modelTotals[name] ?? { calls: 0, cost: 0 } + acc.calls += m.calls + acc.cost += m.cost + modelTotals[name] = acc + } + for (const [cat, c] of Object.entries(d.categories)) { + const acc = catTotals[cat] ?? { turns: 0, cost: 0, editTurns: 0, oneShotTurns: 0 } + acc.turns += c.turns + acc.cost += c.cost + acc.editTurns += c.editTurns + acc.oneShotTurns += c.oneShotTurns + catTotals[cat] = acc + } + } + + return { + label, + cost, + calls, + sessions, + inputTokens, + outputTokens, + cacheReadTokens, + cacheWriteTokens, + categories: Object.entries(catTotals) + .sort(([, a], [, b]) => b.cost - a.cost) + .map(([cat, d]) => ({ name: CATEGORY_LABELS[cat as TaskCategory] ?? cat, ...d })), + models: Object.entries(modelTotals) + .sort(([, a], [, b]) => b.cost - a.cost) + .map(([name, d]) => ({ name, ...d })), + } +} diff --git a/src/export.ts b/src/export.ts index c1940aa..d07f08d 100644 --- a/src/export.ts +++ b/src/export.ts @@ -1,8 +1,8 @@ -import { writeFile } from 'fs/promises' -import { resolve } from 'path' +import { writeFile, mkdir, readdir, stat, rm } from 'fs/promises' +import { dirname, join, resolve } from 'path' import { CATEGORY_LABELS, type ProjectSummary, type TaskCategory } from './types.js' -import { getCostColumnHeader, convertCost } from './currency.js' +import { getCurrency, convertCost } from './currency.js' function escCsv(s: string): string { const sanitized = /^[=+\-@]/.test(s) ? `'${s}` : s @@ -12,15 +12,47 @@ function escCsv(s: string): string { return sanitized } -function buildDailyRows(projects: ProjectSummary[]): Array> { - const daily: Record = {} +type Row = Record +function rowsToCsv(rows: Row[]): string { + if (rows.length === 0) return '' + const headers = Object.keys(rows[0]) + const lines = [headers.map(escCsv).join(',')] + for (const row of rows) { + lines.push(headers.map(h => escCsv(String(row[h] ?? ''))).join(',')) + } + return lines.join('\n') + '\n' +} + +function round2(n: number): number { + return Math.round(n * 100) / 100 +} + +function pct(n: number, total: number): number { + return total > 0 ? round2((n / total) * 100) : 0 +} + +type DailyAgg = { + cost: number + calls: number + input: number + output: number + cacheRead: number + cacheWrite: number + sessions: Set +} + +function buildDailyRows(projects: ProjectSummary[], period: string): Row[] { + const daily: Record = {} for (const project of projects) { for (const session of project.sessions) { for (const turn of session.turns) { if (!turn.timestamp) continue const day = turn.timestamp.slice(0, 10) - if (!daily[day]) daily[day] = { cost: 0, calls: 0, input: 0, output: 0, cacheRead: 0, cacheWrite: 0 } + if (!daily[day]) { + daily[day] = { cost: 0, calls: 0, input: 0, output: 0, cacheRead: 0, cacheWrite: 0, sessions: new Set() } + } + daily[day].sessions.add(session.sessionId) for (const call of turn.assistantCalls) { daily[day].cost += call.costUSD daily[day].calls++ @@ -32,11 +64,13 @@ function buildDailyRows(projects: ProjectSummary[]): Array ({ + Period: period, Date: date, - [getCostColumnHeader()]: convertCost(d.cost), + [`Cost (${code})`]: round2(convertCost(d.cost)), 'API Calls': d.calls, + Sessions: d.sessions.size, 'Input Tokens': d.input, 'Output Tokens': d.output, 'Cache Read Tokens': d.cacheRead, @@ -44,7 +78,7 @@ function buildDailyRows(projects: ProjectSummary[]): Array> { +function buildActivityRows(projects: ProjectSummary[], period: string): Row[] { const catTotals: Record = {} for (const project of projects) { for (const session of project.sessions) { @@ -55,40 +89,53 @@ function buildActivityRows(projects: ProjectSummary[]): Array s + d.cost, 0) + const { code } = getCurrency() return Object.entries(catTotals) .sort(([, a], [, b]) => b.cost - a.cost) .map(([cat, d]) => ({ + Period: period, Activity: CATEGORY_LABELS[cat as TaskCategory] ?? cat, - [getCostColumnHeader()]: convertCost(d.cost), + [`Cost (${code})`]: round2(convertCost(d.cost)), + 'Share (%)': pct(d.cost, totalCost), Turns: d.turns, })) } -function buildModelRows(projects: ProjectSummary[]): Array> { - const modelTotals: Record = {} +function buildModelRows(projects: ProjectSummary[], period: string): Row[] { + const modelTotals: Record = {} for (const project of projects) { for (const session of project.sessions) { for (const [model, d] of Object.entries(session.modelBreakdown)) { - if (!modelTotals[model]) modelTotals[model] = { calls: 0, cost: 0, input: 0, output: 0 } + if (!modelTotals[model]) modelTotals[model] = { calls: 0, cost: 0, input: 0, output: 0, cacheRead: 0, cacheWrite: 0 } modelTotals[model].calls += d.calls modelTotals[model].cost += d.costUSD modelTotals[model].input += d.tokens.inputTokens modelTotals[model].output += d.tokens.outputTokens + modelTotals[model].cacheRead += d.tokens.cacheReadInputTokens ?? 0 + modelTotals[model].cacheWrite += d.tokens.cacheCreationInputTokens ?? 0 } } } + const totalCost = Object.values(modelTotals).reduce((s, d) => s + d.cost, 0) + const { code } = getCurrency() return Object.entries(modelTotals) + .filter(([name]) => name !== '') .sort(([, a], [, b]) => b.cost - a.cost) .map(([model, d]) => ({ + Period: period, Model: model, - [getCostColumnHeader()]: convertCost(d.cost), + [`Cost (${code})`]: round2(convertCost(d.cost)), + 'Share (%)': pct(d.cost, totalCost), 'API Calls': d.calls, 'Input Tokens': d.input, 'Output Tokens': d.output, + 'Cache Read Tokens': d.cacheRead, + 'Cache Write Tokens': d.cacheWrite, })) } -function buildToolRows(projects: ProjectSummary[]): Array> { +function buildToolRows(projects: ProjectSummary[]): Row[] { const toolTotals: Record = {} for (const project of projects) { for (const session of project.sessions) { @@ -97,12 +144,17 @@ function buildToolRows(projects: ProjectSummary[]): Array s + n, 0) return Object.entries(toolTotals) .sort(([, a], [, b]) => b - a) - .map(([tool, calls]) => ({ Tool: tool, Calls: calls })) + .map(([tool, calls]) => ({ + Tool: tool, + Calls: calls, + 'Share (%)': pct(calls, total), + })) } -function buildBashRows(projects: ProjectSummary[]): Array> { +function buildBashRows(projects: ProjectSummary[]): Row[] { const bashTotals: Record = {} for (const project of projects) { for (const session of project.sessions) { @@ -111,28 +163,47 @@ function buildBashRows(projects: ProjectSummary[]): Array s + n, 0) return Object.entries(bashTotals) .sort(([, a], [, b]) => b - a) - .map(([cmd, calls]) => ({ Command: cmd, Calls: calls })) + .map(([cmd, calls]) => ({ + Command: cmd, + Calls: calls, + 'Share (%)': pct(calls, total), + })) } -function buildProjectRows(projects: ProjectSummary[]): Array> { - return projects.map(p => ({ - Project: p.projectPath, - [getCostColumnHeader()]: convertCost(p.totalCostUSD), - 'API Calls': p.totalApiCalls, - Sessions: p.sessions.length, - })) +function buildProjectRows(projects: ProjectSummary[]): Row[] { + const { code } = getCurrency() + const total = projects.reduce((s, p) => s + p.totalCostUSD, 0) + return projects + .slice() + .sort((a, b) => b.totalCostUSD - a.totalCostUSD) + .map(p => ({ + Project: p.projectPath, + [`Cost (${code})`]: round2(convertCost(p.totalCostUSD)), + 'Share (%)': pct(p.totalCostUSD, total), + 'API Calls': p.totalApiCalls, + Sessions: p.sessions.length, + })) } -function rowsToCsv(rows: Array>): string { - if (rows.length === 0) return '' - const headers = Object.keys(rows[0]) - const lines = [headers.map(escCsv).join(',')] - for (const row of rows) { - lines.push(headers.map(h => escCsv(String(row[h] ?? ''))).join(',')) +function buildSessionRows(projects: ProjectSummary[]): Row[] { + const { code } = getCurrency() + const rows: Row[] = [] + for (const p of projects) { + for (const s of p.sessions) { + rows.push({ + Project: p.projectPath, + 'Session ID': s.sessionId, + 'Started At': s.firstTimestamp ?? '', + [`Cost (${code})`]: round2(convertCost(s.totalCostUSD)), + 'API Calls': s.apiCalls, + Turns: s.turns.length, + }) + } } - return lines.join('\n') + return rows.sort((a, b) => (b[`Cost (${code})`] as number) - (a[`Cost (${code})`] as number)) } export type PeriodExport = { @@ -140,77 +211,140 @@ export type PeriodExport = { projects: ProjectSummary[] } -function buildSummaryRow(period: PeriodExport): Record { - const cost = period.projects.reduce((s, p) => s + p.totalCostUSD, 0) - const calls = period.projects.reduce((s, p) => s + p.totalApiCalls, 0) - const sessions = period.projects.reduce((s, p) => s + p.sessions.length, 0) - return { Period: period.label, [getCostColumnHeader()]: convertCost(cost), 'API Calls': calls, Sessions: sessions } +function buildSummaryRows(periods: PeriodExport[]): Row[] { + const { code } = getCurrency() + return periods.map(p => { + const cost = p.projects.reduce((s, proj) => s + proj.totalCostUSD, 0) + const calls = p.projects.reduce((s, proj) => s + proj.totalApiCalls, 0) + const sessions = p.projects.reduce((s, proj) => s + proj.sessions.length, 0) + const projectCount = p.projects.filter(proj => proj.totalCostUSD > 0).length + return { + Period: p.label, + [`Cost (${code})`]: round2(convertCost(cost)), + 'API Calls': calls, + Sessions: sessions, + Projects: projectCount, + } + }) } +function buildReadme(periods: PeriodExport[]): string { + const { code } = getCurrency() + const generated = new Date().toISOString() + const lines = [ + 'CodeBurn Usage Export', + '====================', + '', + `Generated: ${generated}`, + `Currency: ${code}`, + `Periods: ${periods.map(p => p.label).join(', ')}`, + '', + 'Files', + '-----', + ' summary.csv One row per period. Headline totals.', + ' daily.csv Day-by-day breakdown, Period column distinguishes the window.', + ' activity.csv Time spent per task category (Coding, Debugging, Exploration, etc.).', + ' models.csv Spend per model with token totals and cache usage.', + ' projects.csv Spend per project folder (30-day window).', + ' sessions.csv One row per session (30-day window) with session IDs and costs.', + ' tools.csv Tool invocations and share (30-day window).', + ' shell-commands.csv Shell commands executed via Bash tool (30-day window).', + '', + 'Notes', + '-----', + ' Every cost column is already converted to the active currency. Tokens are raw integer', + ' counts from provider telemetry. Share (%) is relative to the period/table total.', + '', + ] + return lines.join('\n') +} + +/// Sentinel file dropped into every folder we create so we can safely overwrite an older +/// codeburn export without ever deleting a user's unrelated files by accident. +const EXPORT_MARKER_FILE = '.codeburn-export' + +async function isCodeburnExportFolder(path: string): Promise { + const markerStat = await stat(join(path, EXPORT_MARKER_FILE)).catch(() => null) + return markerStat?.isFile() ?? false +} + +async function clearCodeburnExportFolder(path: string): Promise { + const entries = await readdir(path) + for (const entry of entries) { + await rm(join(path, entry), { recursive: true, force: true }) + } +} + +/// Writes a folder of one-table-per-file CSVs. The outputPath is treated as a directory. If it +/// ends in `.csv` the extension is stripped to form the folder name. Refuses to delete a +/// pre-existing file or a non-codeburn folder, so a typo like `-o ~/.ssh/id_ed25519` can't +/// wipe a sensitive file (prior versions did `rm(path, { force: true })` unconditionally). export async function exportCsv(periods: PeriodExport[], outputPath: string): Promise { - const allProjects = periods.find(p => p.label === '30 Days')?.projects - ?? periods[periods.length - 1].projects + const thirtyDays = periods.find(p => p.label === '30 Days') + const thirtyDayProjects = thirtyDays?.projects ?? periods[periods.length - 1].projects - const parts: string[] = [] - - parts.push('# Summary') - parts.push(rowsToCsv(periods.map(buildSummaryRow))) - parts.push('') - - for (const period of periods) { - parts.push(`# Daily - ${period.label}`) - parts.push(rowsToCsv(buildDailyRows(period.projects))) - parts.push('') - - parts.push(`# Activity - ${period.label}`) - parts.push(rowsToCsv(buildActivityRows(period.projects))) - parts.push('') - - parts.push(`# Models - ${period.label}`) - parts.push(rowsToCsv(buildModelRows(period.projects))) - parts.push('') + let folder = resolve(outputPath) + if (folder.toLowerCase().endsWith('.csv')) { + folder = folder.slice(0, -4) } - parts.push('# Tools - All') - parts.push(rowsToCsv(buildToolRows(allProjects))) - parts.push('') + const existingStat = await stat(folder).catch(() => null) + if (existingStat?.isFile()) { + throw new Error(`Refusing to overwrite existing file at ${folder}. Pass a directory path instead.`) + } + if (existingStat?.isDirectory()) { + if (!(await isCodeburnExportFolder(folder))) { + throw new Error( + `Refusing to reuse non-empty directory ${folder}: no ${EXPORT_MARKER_FILE} marker. ` + + `Delete it manually or pick a different -o path.` + ) + } + await clearCodeburnExportFolder(folder) + } + await mkdir(folder, { recursive: true }) + await writeFile(join(folder, EXPORT_MARKER_FILE), '', 'utf-8') - parts.push('# Shell Commands - All') - parts.push(rowsToCsv(buildBashRows(allProjects))) - parts.push('') + const dailyRows = periods.flatMap(p => buildDailyRows(p.projects, p.label)) + const activityRows = periods.flatMap(p => buildActivityRows(p.projects, p.label)) + const modelRows = periods.flatMap(p => buildModelRows(p.projects, p.label)) - parts.push('# Projects - All') - parts.push(rowsToCsv(buildProjectRows(allProjects))) - parts.push('') + await writeFile(join(folder, 'README.txt'), buildReadme(periods), 'utf-8') + await writeFile(join(folder, 'summary.csv'), rowsToCsv(buildSummaryRows(periods)), 'utf-8') + await writeFile(join(folder, 'daily.csv'), rowsToCsv(dailyRows), 'utf-8') + await writeFile(join(folder, 'activity.csv'), rowsToCsv(activityRows), 'utf-8') + await writeFile(join(folder, 'models.csv'), rowsToCsv(modelRows), 'utf-8') + await writeFile(join(folder, 'projects.csv'), rowsToCsv(buildProjectRows(thirtyDayProjects)), 'utf-8') + await writeFile(join(folder, 'sessions.csv'), rowsToCsv(buildSessionRows(thirtyDayProjects)), 'utf-8') + await writeFile(join(folder, 'tools.csv'), rowsToCsv(buildToolRows(thirtyDayProjects)), 'utf-8') + await writeFile(join(folder, 'shell-commands.csv'), rowsToCsv(buildBashRows(thirtyDayProjects)), 'utf-8') - const fullPath = resolve(outputPath) - await writeFile(fullPath, parts.join('\n'), 'utf-8') - return fullPath + return folder } export async function exportJson(periods: PeriodExport[], outputPath: string): Promise { - const allProjects = periods.find(p => p.label === '30 Days')?.projects - ?? periods[periods.length - 1].projects - - const periodData: Record = {} - for (const period of periods) { - periodData[period.label] = { - summary: buildSummaryRow(period), - daily: buildDailyRows(period.projects), - activity: buildActivityRows(period.projects), - models: buildModelRows(period.projects), - } - } + const thirtyDays = periods.find(p => p.label === '30 Days') + const thirtyDayProjects = thirtyDays?.projects ?? periods[periods.length - 1].projects + const { code, rate, symbol } = getCurrency() const data = { + schema: 'codeburn.export.v2', generated: new Date().toISOString(), - periods: periodData, - tools: buildToolRows(allProjects), - shellCommands: buildBashRows(allProjects), - projects: buildProjectRows(allProjects), + currency: { code, rate, symbol }, + summary: buildSummaryRows(periods), + periods: periods.map(p => ({ + label: p.label, + daily: buildDailyRows(p.projects, p.label), + activity: buildActivityRows(p.projects, p.label), + models: buildModelRows(p.projects, p.label), + })), + projects: buildProjectRows(thirtyDayProjects), + sessions: buildSessionRows(thirtyDayProjects), + tools: buildToolRows(thirtyDayProjects), + shellCommands: buildBashRows(thirtyDayProjects), } - const fullPath = resolve(outputPath) - await writeFile(fullPath, JSON.stringify(data, null, 2), 'utf-8') - return fullPath + const target = resolve(outputPath.toLowerCase().endsWith('.json') ? outputPath : `${outputPath}.json`) + await mkdir(dirname(target), { recursive: true }) + await writeFile(target, JSON.stringify(data, null, 2), 'utf-8') + return target } diff --git a/src/menubar-installer.ts b/src/menubar-installer.ts new file mode 100644 index 0000000..53265c5 --- /dev/null +++ b/src/menubar-installer.ts @@ -0,0 +1,173 @@ +import { spawn } from 'node:child_process' +import { createWriteStream } from 'node:fs' +import { mkdir, mkdtemp, rename, rm, stat } from 'node:fs/promises' +import { homedir, platform, tmpdir } from 'node:os' +import { join } from 'node:path' +import { pipeline } from 'node:stream/promises' +import { Readable } from 'node:stream' + +/// Public GitHub repo that hosts signed macOS release builds. `/releases/latest` returns the +/// newest tagged release; we filter its assets list for our zipped .app bundle. +const RELEASE_API = 'https://api.github.com/repos/AgentSeal/codeburn/releases/latest' +const APP_BUNDLE_NAME = 'CodeBurnMenubar.app' +const ASSET_PATTERN = /^CodeBurnMenubar-.*\.zip$/ +const APP_PROCESS_NAME = 'CodeBurnMenubar' +const SUPPORTED_OS = 'darwin' +const MIN_MACOS_MAJOR = 14 + +export type InstallResult = { installedPath: string; launched: boolean } + +type ReleaseAsset = { name: string; browser_download_url: string } +type ReleaseResponse = { tag_name: string; assets: ReleaseAsset[] } + +function userApplicationsDir(): string { + return join(homedir(), 'Applications') +} + +async function exists(path: string): Promise { + try { + await stat(path) + return true + } catch { + return false + } +} + +async function ensureSupportedPlatform(): Promise { + if (platform() !== SUPPORTED_OS) { + throw new Error(`The menubar app is macOS only (detected: ${platform()}).`) + } + const major = Number((process.env.CODEBURN_FORCE_MACOS_MAJOR ?? '') + || (await sysProductVersion()).split('.')[0]) + if (!Number.isFinite(major) || major < MIN_MACOS_MAJOR) { + throw new Error(`macOS ${MIN_MACOS_MAJOR}+ required (detected ${major}).`) + } +} + +async function sysProductVersion(): Promise { + return new Promise((resolve, reject) => { + const proc = spawn('/usr/bin/sw_vers', ['-productVersion']) + let out = '' + proc.stdout.on('data', (chunk: Buffer) => { out += chunk.toString() }) + proc.on('error', reject) + proc.on('close', (code) => { + if (code !== 0) reject(new Error(`sw_vers exited with ${code}`)) + else resolve(out.trim()) + }) + }) +} + +async function fetchLatestReleaseAsset(): Promise { + const response = await fetch(RELEASE_API, { + headers: { + // Identify the installer so GitHub's abuse heuristics treat us as a known client. + 'User-Agent': 'codeburn-menubar-installer', + Accept: 'application/vnd.github+json', + }, + }) + if (!response.ok) { + throw new Error(`GitHub release lookup failed: HTTP ${response.status}`) + } + const body = await response.json() as ReleaseResponse + const asset = body.assets.find(a => ASSET_PATTERN.test(a.name)) + if (!asset) { + throw new Error( + `No ${APP_BUNDLE_NAME} zip found in release ${body.tag_name}. ` + + `Check https://github.com/AgentSeal/codeburn/releases.` + ) + } + return asset +} + +async function downloadToFile(url: string, destPath: string): Promise { + const response = await fetch(url, { + headers: { 'User-Agent': 'codeburn-menubar-installer' }, + redirect: 'follow', + }) + if (!response.ok || response.body === null) { + throw new Error(`Download failed: HTTP ${response.status}`) + } + // fetch's ReadableStream needs to be wrapped for Node streams. + const nodeStream = Readable.fromWeb(response.body as never) + await pipeline(nodeStream, createWriteStream(destPath)) +} + +async function runCommand(command: string, args: string[]): Promise { + return new Promise((resolve, reject) => { + const proc = spawn(command, args, { stdio: 'inherit' }) + proc.on('error', reject) + proc.on('close', (code) => { + if (code === 0) resolve() + else reject(new Error(`${command} exited with status ${code}`)) + }) + }) +} + +async function isAppRunning(): Promise { + return new Promise((resolve) => { + const proc = spawn('/usr/bin/pgrep', ['-f', APP_PROCESS_NAME]) + proc.on('close', (code) => resolve(code === 0)) + proc.on('error', () => resolve(false)) + }) +} + +async function killRunningApp(): Promise { + await new Promise((resolve) => { + const proc = spawn('/usr/bin/pkill', ['-f', APP_PROCESS_NAME]) + proc.on('close', () => resolve()) + proc.on('error', () => resolve()) + }) +} + +export async function installMenubarApp(options: { force?: boolean } = {}): Promise { + await ensureSupportedPlatform() + + const appsDir = userApplicationsDir() + const targetPath = join(appsDir, APP_BUNDLE_NAME) + const alreadyInstalled = await exists(targetPath) + + if (alreadyInstalled && !options.force) { + if (!(await isAppRunning())) { + await runCommand('/usr/bin/open', [targetPath]) + } + return { installedPath: targetPath, launched: true } + } + + console.log('Looking up the latest CodeBurn Menubar release...') + const asset = await fetchLatestReleaseAsset() + + const stagingDir = await mkdtemp(join(tmpdir(), 'codeburn-menubar-')) + try { + const archivePath = join(stagingDir, asset.name) + console.log(`Downloading ${asset.name}...`) + await downloadToFile(asset.browser_download_url, archivePath) + + console.log('Unpacking...') + await runCommand('/usr/bin/unzip', ['-q', archivePath, '-d', stagingDir]) + + const unpackedApp = join(stagingDir, APP_BUNDLE_NAME) + if (!(await exists(unpackedApp))) { + throw new Error(`Archive did not contain ${APP_BUNDLE_NAME}.`) + } + + // Clear Gatekeeper's quarantine xattr. Without this, the first launch shows the + // "cannot verify developer" prompt even for a signed + notarized app when the bundle + // was delivered via curl/fetch instead of the Mac App Store. + await runCommand('/usr/bin/xattr', ['-dr', 'com.apple.quarantine', unpackedApp]).catch(() => {}) + + await mkdir(appsDir, { recursive: true }) + if (alreadyInstalled) { + // Kill the running copy before replacing its bundle so `mv` can proceed cleanly and the + // user ends up on the new version. + await killRunningApp() + await rm(targetPath, { recursive: true, force: true }) + } + await rename(unpackedApp, targetPath) + + console.log('Launching CodeBurn Menubar...') + await runCommand('/usr/bin/open', [targetPath]) + return { installedPath: targetPath, launched: true } + } finally { + await rm(stagingDir, { recursive: true, force: true }) + } +} diff --git a/src/menubar-json.ts b/src/menubar-json.ts new file mode 100644 index 0000000..bab4e40 --- /dev/null +++ b/src/menubar-json.ts @@ -0,0 +1,182 @@ +/// Rollup of one time window (today / 7 days / 30 days / month / all) used as the canonical +/// input to the menubar payload. Built inside the CLI and also consumed by the day-aggregator +/// when hydrating per-day cache entries. +export type PeriodData = { + label: string + cost: number + calls: number + sessions: number + inputTokens: number + outputTokens: number + cacheReadTokens: number + cacheWriteTokens: number + categories: Array<{ name: string; cost: number; turns: number; editTurns: number; oneShotTurns: number }> + models: Array<{ name: string; cost: number; calls: number }> +} + +export type ProviderCost = { + name: string + cost: number +} +import type { OptimizeResult } from './optimize.js' + +const TOP_ACTIVITIES_LIMIT = 20 +const TOP_MODELS_LIMIT = 20 +const TOP_FINDINGS_LIMIT = 10 +const HISTORY_DAYS_LIMIT = 365 +const SYNTHETIC_MODEL_NAME = '' + +export type DailyModelBreakdown = { + name: string + cost: number + calls: number + inputTokens: number + outputTokens: number +} + +export type DailyHistoryEntry = { + date: string + cost: number + calls: number + inputTokens: number + outputTokens: number + cacheReadTokens: number + cacheWriteTokens: number + topModels: DailyModelBreakdown[] +} + +export type MenubarPayload = { + generated: string + current: { + label: string + cost: number + calls: number + sessions: number + oneShotRate: number | null + inputTokens: number + outputTokens: number + cacheHitPercent: number + topActivities: Array<{ + name: string + cost: number + turns: number + oneShotRate: number | null + }> + topModels: Array<{ + name: string + cost: number + calls: number + }> + providers: Record + } + optimize: { + findingCount: number + savingsUSD: number + topFindings: Array<{ + title: string + impact: 'high' | 'medium' | 'low' + savingsUSD: number + }> + } + history: { + daily: DailyHistoryEntry[] + } +} + +function oneShotRateFor(editTurns: number, oneShotTurns: number): number | null { + if (editTurns === 0) return null + return oneShotTurns / editTurns +} + +function aggregateOneShotRate(categories: PeriodData['categories']): number | null { + let edits = 0 + let oneShots = 0 + for (const cat of categories) { + edits += cat.editTurns + oneShots += cat.oneShotTurns + } + if (edits === 0) return null + return oneShots / edits +} + +function cacheHitPercent(inputTokens: number, cacheReadTokens: number): number { + const denom = inputTokens + cacheReadTokens + if (denom === 0) return 0 + return (cacheReadTokens / denom) * 100 +} + +function buildTopActivities(categories: PeriodData['categories']): MenubarPayload['current']['topActivities'] { + return categories.slice(0, TOP_ACTIVITIES_LIMIT).map(cat => ({ + name: cat.name, + cost: cat.cost, + turns: cat.turns, + oneShotRate: oneShotRateFor(cat.editTurns, cat.oneShotTurns), + })) +} + +function buildTopModels(models: PeriodData['models']): MenubarPayload['current']['topModels'] { + return models + .filter(m => m.name !== SYNTHETIC_MODEL_NAME) + .slice(0, TOP_MODELS_LIMIT) + .map(m => ({ name: m.name, cost: m.cost, calls: m.calls })) +} + +function buildOptimize(optimize: OptimizeResult | null): MenubarPayload['optimize'] { + if (!optimize || optimize.findings.length === 0) { + return { findingCount: 0, savingsUSD: 0, topFindings: [] } + } + const { findings, costRate } = optimize + const totalSavingsUSD = findings.reduce((s, f) => s + f.tokensSaved * costRate, 0) + const topFindings = findings.slice(0, TOP_FINDINGS_LIMIT).map(f => ({ + title: f.title, + impact: f.impact, + savingsUSD: f.tokensSaved * costRate, + })) + return { + findingCount: findings.length, + savingsUSD: totalSavingsUSD, + topFindings, + } +} + +function buildProviders(providers: ProviderCost[]): Record { + const map: Record = {} + for (const p of providers) { + if (p.cost < 0) continue + map[p.name.toLowerCase()] = p.cost + } + return map +} + +function buildHistory(daily: DailyHistoryEntry[] | undefined): MenubarPayload['history'] { + if (!daily || daily.length === 0) return { daily: [] } + const sorted = [...daily].sort((a, b) => a.date.localeCompare(b.date)) + const trimmed = sorted.slice(-HISTORY_DAYS_LIMIT) + return { daily: trimmed } +} + +export function buildMenubarPayload( + current: PeriodData, + providers: ProviderCost[], + optimize: OptimizeResult | null, + dailyHistory?: DailyHistoryEntry[], +): MenubarPayload { + return { + generated: new Date().toISOString(), + current: { + label: current.label, + cost: current.cost, + calls: current.calls, + sessions: current.sessions, + oneShotRate: aggregateOneShotRate(current.categories), + inputTokens: current.inputTokens, + outputTokens: current.outputTokens, + cacheHitPercent: cacheHitPercent(current.inputTokens, current.cacheReadTokens), + topActivities: buildTopActivities(current.categories), + topModels: buildTopModels(current.models), + providers: buildProviders(providers), + }, + optimize: buildOptimize(optimize), + history: buildHistory(dailyHistory), + } +} diff --git a/src/menubar.ts b/src/menubar.ts deleted file mode 100644 index be2bdb8..0000000 --- a/src/menubar.ts +++ /dev/null @@ -1,334 +0,0 @@ -import { execFileSync, execSync } from 'child_process' -import { existsSync } from 'fs' -import { chmod, mkdir, unlink, writeFile } from 'fs/promises' -import { homedir, platform } from 'os' -import { join } from 'path' -import { formatCost, formatTokens } from './format.js' -import { getCurrency } from './currency.js' - -const PLUGIN_REFRESH = '5m' -const SWIFTBAR_PREFERENCES_DOMAIN = 'com.ameba.SwiftBar' -const SWIFTBAR_PLUGIN_DIRECTORY_KEY = 'PluginDirectory' - -const MENUBAR_LABEL_MAX_LENGTH = 14 -const MENUBAR_LABEL_ALLOWLIST = /[^A-Za-z0-9 ._/-]/g - -// SwiftBar/xbar parse `|` as the metadata separator and interpret ANSI escapes -// on some paths. Replace anything outside a conservative allowlist with `?` -// and truncate before padEnd. -function sanitizeMenubarLabel(name: string): string { - return name.replace(MENUBAR_LABEL_ALLOWLIST, '?').slice(0, MENUBAR_LABEL_MAX_LENGTH) -} - -function getSwiftBarPluginDir(): string { - return join(homedir(), 'Library', 'Application Support', 'SwiftBar', 'plugins') -} - -function getXbarPluginDir(): string { - return join(homedir(), 'Library', 'Application Support', 'xbar', 'plugins') -} - -export function parsePluginDirectoryPreference(value: string): string | undefined { - const pluginDir = value.trim() - if (!pluginDir) return undefined - if (pluginDir === '~') return homedir() - if (pluginDir.startsWith('~/')) return join(homedir(), pluginDir.slice(2)) - return pluginDir -} - -function getConfiguredSwiftBarPluginDir(): string | undefined { - if (platform() !== 'darwin') return undefined - - try { - return parsePluginDirectoryPreference(execFileSync('defaults', [ - 'read', - SWIFTBAR_PREFERENCES_DOMAIN, - SWIFTBAR_PLUGIN_DIRECTORY_KEY, - ], { encoding: 'utf-8' })) - } catch { - return undefined - } -} - -function getSwiftBarPluginDirs(): string[] { - const dirs = [getConfiguredSwiftBarPluginDir(), getSwiftBarPluginDir()] - return dirs.filter((dir, index): dir is string => dir !== undefined && dirs.indexOf(dir) === index) -} - -export function chooseMenubarPluginDir( - swiftBarPluginDirs: string[], - xbarPluginDir: string, - pathExists: (path: string) => boolean, -): { pluginDir: string; appName: string } { - const preferredSwiftBarDir = swiftBarPluginDirs[0] ?? getSwiftBarPluginDir() - - for (const pluginDir of swiftBarPluginDirs) { - if (pathExists(pluginDir)) return { pluginDir, appName: 'SwiftBar' } - } - - if (pathExists(xbarPluginDir)) return { pluginDir: xbarPluginDir, appName: 'xbar' } - - return { pluginDir: preferredSwiftBarDir, appName: 'SwiftBar' } -} - -function getCodeburnBin(): string { - try { - return execSync('which codeburn', { encoding: 'utf-8' }).trim() - } catch { - return 'npx --yes codeburn' - } -} - -function generatePlugin(bin: string): string { - const home = homedir() - // Resolve the directory of the node binary used at install time so the - // plugin uses the same Node version codeburn was installed with — even - // when SwiftBar/xbar launch with a minimal PATH that finds an older - // system Node first. Fixes #63. - const nodeBinDir = join(process.execPath, '..') - return `#!/bin/bash -# CodeBurn -# v0.1.0 -# AgentSeal -# agentseal -# See where your AI coding tokens burn. Tracks cost, activity, and model usage across Claude Code, Cursor, and Codex by task type, tool, MCP server, and project. -# file://${home}/codeburn/assets/logo.png -# https://github.com/agentseal/codeburn -# node - -export HOME="${home}" -export PATH="${nodeBinDir}:$HOME/.local/bin:$HOME/.npm-global/bin:/opt/homebrew/bin:/usr/local/bin:$PATH" - -${bin} status --format menubar 2>/dev/null || echo "-- | sfimage=flame.fill" -` -} - -function miniBar(value: number, max: number, width: number = 10): string { - if (max === 0) return '·'.repeat(width) - const filled = Math.round((value / max) * width) - return '█'.repeat(Math.min(filled, width)) + '·'.repeat(Math.max(width - filled, 0)) -} - -export type PeriodData = { - label: string - cost: number - calls: number - inputTokens: number - outputTokens: number - cacheReadTokens: number - cacheWriteTokens: number - categories: Array<{ name: string; cost: number; turns: number; editTurns: number; oneShotTurns: number }> - models: Array<{ name: string; cost: number; calls: number }> -} - -export type ProviderCost = { - name: string - cost: number -} - -export function renderMenubarFormat( - today: PeriodData, - week: PeriodData, - thirtyDays: PeriodData, - month: PeriodData, - todayProviders?: ProviderCost[], -): string { - const lines: string[] = [] - - lines.push(`${formatCost(today.cost)} | sfimage=flame.fill color=#FF8C42`) - lines.push('---') - - lines.push(`CodeBurn | size=15 color=#FF8C42`) - lines.push(`AI Coding Cost Tracker | size=11`) - if (todayProviders && todayProviders.length > 1) { - for (const p of todayProviders) { - lines.push(` ${p.name.padEnd(10)} ${formatCost(p.cost).padStart(10)} | font=Menlo size=11`) - } - } - lines.push('---') - - lines.push(`Today ${formatCost(today.cost)} ${today.calls.toLocaleString()} calls | size=14`) - lines.push('---') - - const maxCat = Math.max(...today.categories.map(c => c.cost), 0.01) - lines.push(`Activity - Today | size=12 color=#FF8C42`) - for (const cat of today.categories.slice(0, 8)) { - const bar = miniBar(cat.cost, maxCat) - const name = sanitizeMenubarLabel(cat.name).padEnd(14) - lines.push(`${bar} ${name} ${formatCost(cat.cost).padStart(8)} ${String(cat.turns).padStart(4)} turns | font=Menlo size=11`) - } - lines.push('---') - - const maxModel = Math.max(...today.models.filter(m => m.name !== '').map(m => m.cost), 0.01) - lines.push(`Models - Today | size=12 color=#FF8C42`) - for (const model of today.models.slice(0, 5)) { - if (model.name === '') continue - const bar = miniBar(model.cost, maxModel) - const name = sanitizeMenubarLabel(model.name).padEnd(14) - lines.push(`${bar} ${name} ${formatCost(model.cost).padStart(8)} ${String(model.calls).padStart(5)} calls | font=Menlo size=11`) - } - - const cacheHit = today.inputTokens + today.cacheReadTokens > 0 - ? ((today.cacheReadTokens / (today.inputTokens + today.cacheReadTokens)) * 100).toFixed(0) - : '0' - lines.push(`Tokens: ${formatTokens(today.inputTokens)} in · ${formatTokens(today.outputTokens)} out · ${cacheHit}% cache hit | font=Menlo size=10`) - lines.push('---') - - lines.push(`7 Days ${formatCost(week.cost)} ${week.calls.toLocaleString()} calls | size=14`) - const weekMaxCat = Math.max(...week.categories.map(c => c.cost), 0.01) - const weekMaxModel = Math.max(...week.models.filter(m => m.name !== '').map(m => m.cost), 0.01) - lines.push(`--Activity | size=12 color=#FF8C42`) - for (const cat of week.categories.slice(0, 8)) { - const bar = miniBar(cat.cost, weekMaxCat) - const name = sanitizeMenubarLabel(cat.name).padEnd(14) - lines.push(`--${bar} ${name} ${formatCost(cat.cost).padStart(8)} ${String(cat.turns).padStart(4)} turns | font=Menlo size=11`) - } - lines.push(`-----`) - lines.push(`--Models | size=12 color=#FF8C42`) - for (const model of week.models.slice(0, 5)) { - if (model.name === '') continue - const bar = miniBar(model.cost, weekMaxModel) - const name = sanitizeMenubarLabel(model.name).padEnd(14) - lines.push(`--${bar} ${name} ${formatCost(model.cost).padStart(8)} ${String(model.calls).padStart(5)} calls | font=Menlo size=11`) - } - - lines.push(`30 Days ${formatCost(thirtyDays.cost)} ${thirtyDays.calls.toLocaleString()} calls | size=14`) - const tdMaxCat = Math.max(...thirtyDays.categories.map(c => c.cost), 0.01) - const tdMaxModel = Math.max(...thirtyDays.models.filter(m => m.name !== '').map(m => m.cost), 0.01) - lines.push(`--Activity | size=12 color=#FF8C42`) - for (const cat of thirtyDays.categories.slice(0, 8)) { - const bar = miniBar(cat.cost, tdMaxCat) - const name = sanitizeMenubarLabel(cat.name).padEnd(14) - lines.push(`--${bar} ${name} ${formatCost(cat.cost).padStart(8)} ${String(cat.turns).padStart(4)} turns | font=Menlo size=11`) - } - lines.push(`-----`) - lines.push(`--Models | size=12 color=#FF8C42`) - for (const model of thirtyDays.models.slice(0, 5)) { - if (model.name === '') continue - const bar = miniBar(model.cost, tdMaxModel) - const name = sanitizeMenubarLabel(model.name).padEnd(14) - lines.push(`--${bar} ${name} ${formatCost(model.cost).padStart(8)} ${String(model.calls).padStart(5)} calls | font=Menlo size=11`) - } - - lines.push(`Month ${formatCost(month.cost)} ${month.calls.toLocaleString()} calls | size=14`) - const monthMaxCat = Math.max(...month.categories.map(c => c.cost), 0.01) - const monthMaxModel = Math.max(...month.models.filter(m => m.name !== '').map(m => m.cost), 0.01) - lines.push(`--Activity | size=12 color=#FF8C42`) - for (const cat of month.categories.slice(0, 8)) { - const bar = miniBar(cat.cost, monthMaxCat) - const name = sanitizeMenubarLabel(cat.name).padEnd(14) - lines.push(`--${bar} ${name} ${formatCost(cat.cost).padStart(8)} ${String(cat.turns).padStart(4)} turns | font=Menlo size=11`) - } - lines.push(`-----`) - lines.push(`--Models | size=12 color=#FF8C42`) - for (const model of month.models.slice(0, 5)) { - if (model.name === '') continue - const bar = miniBar(model.cost, monthMaxModel) - const name = sanitizeMenubarLabel(model.name).padEnd(14) - lines.push(`--${bar} ${name} ${formatCost(model.cost).padStart(8)} ${String(model.calls).padStart(5)} calls | font=Menlo size=11`) - } - - lines.push('---') - const home = process.env.HOME ?? '~' - const bin = getCodeburnBin() - // Invoke the resolved `codeburn` binary directly. SwiftBar/xbar deliver - // each `paramN=` value as its own argv entry, so there's no shell - // quoting involved — and we don't ship the user to a `~/codeburn` - // checkout that only exists when running from a dev clone (#32). - lines.push(`Open Full Report | terminal=true shell=${bin} param1=report`) - lines.push(`Export CSV to Desktop | terminal=false shell=${bin} param1=export param2=-o param3=${home}/Desktop/codeburn-report.csv`) - - // Currency submenu -- common currencies as clickable items. - // Clicking one runs 'codeburn currency XXX' and refreshes the plugin. - const activeCurrency = getCurrency().code - const currencies = [ - { code: 'USD', name: 'US Dollar' }, - { code: 'GBP', name: 'British Pound' }, - { code: 'EUR', name: 'Euro' }, - { code: 'AUD', name: 'Australian Dollar' }, - { code: 'CAD', name: 'Canadian Dollar' }, - { code: 'NZD', name: 'New Zealand Dollar' }, - { code: 'JPY', name: 'Japanese Yen' }, - { code: 'CHF', name: 'Swiss Franc' }, - { code: 'INR', name: 'Indian Rupee' }, - { code: 'BRL', name: 'Brazilian Real' }, - { code: 'SEK', name: 'Swedish Krona' }, - { code: 'SGD', name: 'Singapore Dollar' }, - { code: 'HKD', name: 'Hong Kong Dollar' }, - { code: 'KRW', name: 'South Korean Won' }, - { code: 'MXN', name: 'Mexican Peso' }, - { code: 'ZAR', name: 'South African Rand' }, - { code: 'DKK', name: 'Danish Krone' }, - ] - lines.push(`Currency: ${activeCurrency} | size=14`) - for (const { code, name } of currencies) { - const check = code === activeCurrency ? ' *' : '' - // The real CLI subcommand is `codeburn currency [code]` (with `--reset` - // for USD), not `codeburn config currency` — the latter doesn't exist - // and silently fails when SwiftBar runs it. Fixes #27. - if (code === 'USD') { - lines.push(`--${name} (${code})${check} | terminal=false refresh=true shell=${bin} param1=currency param2=--reset`) - } else { - lines.push(`--${name} (${code})${check} | terminal=false refresh=true shell=${bin} param1=currency param2=${code}`) - } - } - - lines.push(`Refresh | refresh=true`) - - return lines.join('\n') -} - -export async function installMenubar(): Promise { - if (platform() !== 'darwin') { - return 'Menu bar integration is only available on macOS. Use `codeburn watch` or `codeburn status` instead.' - } - - const bin = getCodeburnBin() - const pluginContent = generatePlugin(bin) - - const { pluginDir, appName } = chooseMenubarPluginDir(getSwiftBarPluginDirs(), getXbarPluginDir(), existsSync) - - if (!existsSync(pluginDir)) { - await mkdir(pluginDir, { recursive: true }) - } - - const pluginPath = join(pluginDir, `codeburn.${PLUGIN_REFRESH}.sh`) - await writeFile(pluginPath, pluginContent, 'utf-8') - await chmod(pluginPath, 0o755) - - const swiftbarInstalled = existsSync('/Applications/SwiftBar.app') || existsSync(join(homedir(), 'Applications', 'SwiftBar.app')) - const xbarInstalled = existsSync('/Applications/xbar.app') || existsSync(join(homedir(), 'Applications', 'xbar.app')) - - const lines: string[] = [] - lines.push(`\n Plugin installed to: ${pluginPath}`) - - if (swiftbarInstalled || xbarInstalled) { - lines.push(` ${appName} detected - plugin should appear in your menu bar shortly.`) - lines.push(` If not, open ${appName} and refresh plugins.\n`) - } else { - lines.push(`\n To see CodeBurn in your menu bar, install SwiftBar:`) - lines.push(` brew install --cask swiftbar`) - lines.push(`\n Then launch SwiftBar - the plugin will load automatically.\n`) - } - - return lines.join('\n') -} - -export async function uninstallMenubar(): Promise { - const paths = [ - ...getSwiftBarPluginDirs().map(dir => join(dir, `codeburn.${PLUGIN_REFRESH}.sh`)), - join(getXbarPluginDir(), `codeburn.${PLUGIN_REFRESH}.sh`), - ] - - let removed = false - for (const p of paths) { - if (existsSync(p)) { - await unlink(p) - removed = true - } - } - - return removed - ? '\n Menu bar plugin removed.\n' - : '\n No menu bar plugin found.\n' -} diff --git a/src/parser.ts b/src/parser.ts index 5ba0da9..4adcf3b 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -1,4 +1,4 @@ -import { readdir } from 'fs/promises' +import { readdir, stat } from 'fs/promises' import { basename, join } from 'path' import { readSessionFile } from './fs-utils.js' import { calculateCost, getShortModelName } from './models.js' @@ -266,6 +266,15 @@ async function parseSessionFile( seenMsgIds: Set, dateRange?: DateRange, ): Promise { + // Skip files whose mtime is older than the range start. A session file + // can only contain entries up to its last-modified time; if that predates + // the requested range, nothing in this file can match. + if (dateRange) { + try { + const s = await stat(filePath) + if (s.mtimeMs < dateRange.start.getTime()) return null + } catch { /* fall through to normal read; missing stat shouldn't break parsing */ } + } const content = await readSessionFile(filePath) if (content === null) return null const lines = content.split('\n').filter(l => l.trim()) @@ -388,6 +397,12 @@ async function parseProviderSources( const sessionMap = new Map() for (const source of sources) { + if (dateRange) { + try { + const s = await stat(source.path) + if (s.mtimeMs < dateRange.start.getTime()) continue + } catch { /* fall through; treat unknown stat as "may contain data" */ } + } const parser = provider.createSessionParser( { path: source.path, project: source.project, provider: providerName }, seenKeys, diff --git a/tests/daily-cache.test.ts b/tests/daily-cache.test.ts new file mode 100644 index 0000000..b1741e3 --- /dev/null +++ b/tests/daily-cache.test.ts @@ -0,0 +1,189 @@ +import { afterEach, beforeEach, describe, expect, it } from 'vitest' +import { readFile, rm } from 'fs/promises' +import { existsSync } from 'fs' +import { tmpdir } from 'os' +import { join } from 'path' + +import { + addNewDays, + DAILY_CACHE_VERSION, + type DailyCache, + type DailyEntry, + getDaysInRange, + loadDailyCache, + saveDailyCache, + withDailyCacheLock, +} from '../src/daily-cache.js' + +function emptyDay(date: string, cost = 0, calls = 0): DailyEntry { + return { + date, + cost, + calls, + sessions: 0, + inputTokens: 0, + outputTokens: 0, + cacheReadTokens: 0, + cacheWriteTokens: 0, + editTurns: 0, + oneShotTurns: 0, + models: {}, + categories: {}, + providers: {}, + } +} + +const TMP_CACHE_ROOT = join(tmpdir(), `codeburn-cache-test-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`) + +beforeEach(() => { + process.env['CODEBURN_CACHE_DIR'] = TMP_CACHE_ROOT +}) + +afterEach(async () => { + delete process.env['CODEBURN_CACHE_DIR'] + if (existsSync(TMP_CACHE_ROOT)) { + await rm(TMP_CACHE_ROOT, { recursive: true, force: true }) + } +}) + +describe('loadDailyCache', () => { + it('returns an empty cache when the file does not exist', async () => { + const cache = await loadDailyCache() + expect(cache.version).toBe(DAILY_CACHE_VERSION) + expect(cache.lastComputedDate).toBeNull() + expect(cache.days).toEqual([]) + }) + + it('returns an empty cache when the file contains invalid JSON', async () => { + const { writeFile, mkdir } = await import('fs/promises') + await mkdir(TMP_CACHE_ROOT, { recursive: true }) + await writeFile(join(TMP_CACHE_ROOT, 'daily-cache.json'), 'not valid json{{', 'utf-8') + const cache = await loadDailyCache() + expect(cache.days).toEqual([]) + }) + + it('returns an empty cache when the version does not match', async () => { + const saved: DailyCache = { + version: DAILY_CACHE_VERSION - 999, + lastComputedDate: '2026-04-10', + days: [emptyDay('2026-04-10', 10)], + } + const { writeFile, mkdir } = await import('fs/promises') + await mkdir(TMP_CACHE_ROOT, { recursive: true }) + await writeFile(join(TMP_CACHE_ROOT, 'daily-cache.json'), JSON.stringify(saved), 'utf-8') + const cache = await loadDailyCache() + expect(cache.days).toEqual([]) + expect(cache.lastComputedDate).toBeNull() + }) + + it('round-trips a valid cache through save and load', async () => { + const saved: DailyCache = { + version: DAILY_CACHE_VERSION, + lastComputedDate: '2026-04-10', + days: [emptyDay('2026-04-09', 12.5, 40), emptyDay('2026-04-10', 7.25, 28)], + } + await saveDailyCache(saved) + const loaded = await loadDailyCache() + expect(loaded).toEqual(saved) + }) +}) + +describe('saveDailyCache', () => { + it('writes atomically so no temp file is left after a successful save', async () => { + const saved: DailyCache = { + version: DAILY_CACHE_VERSION, + lastComputedDate: '2026-04-10', + days: [emptyDay('2026-04-10', 5)], + } + await saveDailyCache(saved) + const { readdir } = await import('fs/promises') + const files = await readdir(TMP_CACHE_ROOT) + const tempLeftovers = files.filter(f => f.endsWith('.tmp')) + expect(tempLeftovers).toEqual([]) + const finalFile = await readFile(join(TMP_CACHE_ROOT, 'daily-cache.json'), 'utf-8') + expect(JSON.parse(finalFile)).toEqual(saved) + }) +}) + +describe('addNewDays', () => { + it('returns a new cache with the added days sorted ascending by date', () => { + const base: DailyCache = { + version: DAILY_CACHE_VERSION, + lastComputedDate: '2026-04-08', + days: [emptyDay('2026-04-07', 3), emptyDay('2026-04-08', 5)], + } + const updated = addNewDays(base, [emptyDay('2026-04-10', 9), emptyDay('2026-04-09', 7)], '2026-04-10') + expect(updated.days.map(d => d.date)).toEqual(['2026-04-07', '2026-04-08', '2026-04-09', '2026-04-10']) + expect(updated.lastComputedDate).toBe('2026-04-10') + }) + + it('skips days already present in the cache (first write wins)', () => { + const base: DailyCache = { + version: DAILY_CACHE_VERSION, + lastComputedDate: '2026-04-08', + days: [emptyDay('2026-04-08', 5)], + } + const updated = addNewDays(base, [emptyDay('2026-04-08', 99)], '2026-04-08') + const aprilEight = updated.days.find(d => d.date === '2026-04-08')! + expect(aprilEight.cost).toBe(5) + }) + + it('does not regress lastComputedDate if incoming newestDate is older', () => { + const base: DailyCache = { + version: DAILY_CACHE_VERSION, + lastComputedDate: '2026-04-10', + days: [emptyDay('2026-04-10', 5)], + } + const updated = addNewDays(base, [emptyDay('2026-04-05', 3)], '2026-04-05') + expect(updated.lastComputedDate).toBe('2026-04-10') + }) +}) + +describe('getDaysInRange', () => { + const cache: DailyCache = { + version: DAILY_CACHE_VERSION, + lastComputedDate: '2026-04-10', + days: [ + emptyDay('2026-04-05', 1), + emptyDay('2026-04-06', 2), + emptyDay('2026-04-07', 3), + emptyDay('2026-04-08', 4), + emptyDay('2026-04-09', 5), + emptyDay('2026-04-10', 6), + ], + } + + it('returns inclusive start and end range', () => { + const days = getDaysInRange(cache, '2026-04-07', '2026-04-09') + expect(days.map(d => d.date)).toEqual(['2026-04-07', '2026-04-08', '2026-04-09']) + }) + + it('returns empty when range is entirely outside cache', () => { + expect(getDaysInRange(cache, '2026-03-01', '2026-03-10')).toEqual([]) + expect(getDaysInRange(cache, '2026-05-01', '2026-05-10')).toEqual([]) + }) + + it('clips to available cache days when range extends beyond', () => { + const days = getDaysInRange(cache, '2026-04-09', '2026-04-20') + expect(days.map(d => d.date)).toEqual(['2026-04-09', '2026-04-10']) + }) +}) + +describe('withDailyCacheLock', () => { + it('serializes concurrent operations', async () => { + const sequence: string[] = [] + const op = async (tag: string): Promise => { + await withDailyCacheLock(async () => { + sequence.push(`start-${tag}`) + await new Promise(r => setTimeout(r, 20)) + sequence.push(`end-${tag}`) + }) + } + await Promise.all([op('a'), op('b'), op('c')]) + for (let i = 0; i < sequence.length; i += 2) { + expect(sequence[i]?.startsWith('start-')).toBe(true) + expect(sequence[i + 1]?.startsWith('end-')).toBe(true) + expect(sequence[i]!.slice(6)).toBe(sequence[i + 1]!.slice(4)) + } + }) +}) diff --git a/tests/day-aggregator.test.ts b/tests/day-aggregator.test.ts new file mode 100644 index 0000000..fb90840 --- /dev/null +++ b/tests/day-aggregator.test.ts @@ -0,0 +1,258 @@ +import { describe, expect, it } from 'vitest' + +import { aggregateProjectsIntoDays, buildPeriodDataFromDays } from '../src/day-aggregator.js' +import type { ProjectSummary } from '../src/types.js' + +function makeProject(overrides: Partial & { sessions: ProjectSummary['sessions'] }): ProjectSummary { + return { + project: 'p', + projectPath: '/p', + totalCostUSD: overrides.sessions.reduce((s, sess) => s + sess.totalCostUSD, 0), + totalApiCalls: overrides.sessions.reduce((s, sess) => s + sess.apiCalls, 0), + ...overrides, + } +} + +function makeCall(timestamp: string, costUSD: number, model = 'Opus 4.7', provider = 'claude') { + return { + provider, + model, + usage: { + inputTokens: 100, + outputTokens: 200, + cacheCreationInputTokens: 0, + cacheReadInputTokens: 50, + cachedInputTokens: 0, + reasoningTokens: 0, + webSearchRequests: 0, + }, + costUSD, + tools: [], + mcpTools: [], + hasAgentSpawn: false, + hasPlanMode: false, + speed: 'standard' as const, + timestamp, + bashCommands: [], + deduplicationKey: `dk-${timestamp}-${costUSD}`, + } +} + +describe('aggregateProjectsIntoDays', () => { + it('buckets api calls by calendar date derived from timestamp', () => { + const projects: ProjectSummary[] = [ + makeProject({ + sessions: [{ + sessionId: 's1', + project: 'p', + firstTimestamp: '2026-04-09T10:00:00Z', + lastTimestamp: '2026-04-10T08:00:00Z', + totalCostUSD: 10, + totalInputTokens: 0, + totalOutputTokens: 0, + totalCacheReadTokens: 0, + totalCacheWriteTokens: 0, + apiCalls: 2, + turns: [ + { + userMessage: 'hi', + timestamp: '2026-04-09T10:00:00Z', + sessionId: 's1', + category: 'coding', + retries: 0, + hasEdits: true, + assistantCalls: [ + makeCall('2026-04-09T10:00:00Z', 4), + makeCall('2026-04-10T08:00:00Z', 6), + ], + }, + ], + modelBreakdown: {}, + toolBreakdown: {}, + mcpBreakdown: {}, + bashBreakdown: {}, + categoryBreakdown: {} as never, + }], + }), + ] + + const days = aggregateProjectsIntoDays(projects) + expect(days.map(d => d.date)).toEqual(['2026-04-09', '2026-04-10']) + expect(days[0]!.cost).toBe(4) + expect(days[0]!.calls).toBe(1) + expect(days[1]!.cost).toBe(6) + expect(days[1]!.calls).toBe(1) + }) + + it('attributes category turns + editTurns + oneShotTurns to the first call date of the turn', () => { + const projects: ProjectSummary[] = [ + makeProject({ + sessions: [{ + sessionId: 's1', + project: 'p', + firstTimestamp: '2026-04-09T10:00:00Z', + lastTimestamp: '2026-04-09T10:05:00Z', + totalCostUSD: 3, + totalInputTokens: 0, + totalOutputTokens: 0, + totalCacheReadTokens: 0, + totalCacheWriteTokens: 0, + apiCalls: 1, + turns: [ + { + userMessage: 'hi', + timestamp: '2026-04-09T10:00:00Z', + sessionId: 's1', + category: 'coding', + retries: 0, + hasEdits: true, + assistantCalls: [makeCall('2026-04-09T10:00:00Z', 3)], + }, + ], + modelBreakdown: {}, + toolBreakdown: {}, + mcpBreakdown: {}, + bashBreakdown: {}, + categoryBreakdown: {} as never, + }], + }), + ] + const days = aggregateProjectsIntoDays(projects) + const day = days[0]! + expect(day.editTurns).toBe(1) + expect(day.oneShotTurns).toBe(1) + expect(day.categories['coding']).toEqual({ + turns: 1, + cost: 3, + editTurns: 1, + oneShotTurns: 1, + }) + }) + + it('counts a session under its firstTimestamp date', () => { + const projects: ProjectSummary[] = [ + makeProject({ + sessions: [{ + sessionId: 's1', + project: 'p', + firstTimestamp: '2026-04-09T23:59:00Z', + lastTimestamp: '2026-04-10T00:10:00Z', + totalCostUSD: 1, + totalInputTokens: 0, totalOutputTokens: 0, totalCacheReadTokens: 0, totalCacheWriteTokens: 0, + apiCalls: 0, + turns: [], + modelBreakdown: {}, toolBreakdown: {}, mcpBreakdown: {}, bashBreakdown: {}, + categoryBreakdown: {} as never, + }], + }), + ] + const days = aggregateProjectsIntoDays(projects) + expect(days[0]!.date).toBe('2026-04-09') + expect(days[0]!.sessions).toBe(1) + }) + + it('aggregates per-model and per-provider totals inside each day', () => { + const projects: ProjectSummary[] = [ + makeProject({ + sessions: [{ + sessionId: 's1', + project: 'p', + firstTimestamp: '2026-04-10T10:00:00Z', + lastTimestamp: '2026-04-10T10:00:00Z', + totalCostUSD: 10, + totalInputTokens: 0, totalOutputTokens: 0, totalCacheReadTokens: 0, totalCacheWriteTokens: 0, + apiCalls: 2, + turns: [ + { + userMessage: 'x', timestamp: '2026-04-10T10:00:00Z', sessionId: 's1', + category: 'coding', retries: 0, hasEdits: false, + assistantCalls: [ + makeCall('2026-04-10T10:00:00Z', 7, 'Opus 4.7', 'claude'), + makeCall('2026-04-10T10:00:00Z', 3, 'gpt-5', 'codex'), + ], + }, + ], + modelBreakdown: {}, toolBreakdown: {}, mcpBreakdown: {}, bashBreakdown: {}, + categoryBreakdown: {} as never, + }], + }), + ] + const days = aggregateProjectsIntoDays(projects) + const day = days[0]! + expect(day.models['Opus 4.7']).toEqual({ + calls: 1, cost: 7, + inputTokens: 100, outputTokens: 200, + cacheReadTokens: 50, cacheWriteTokens: 0, + }) + expect(day.models['gpt-5']).toEqual({ + calls: 1, cost: 3, + inputTokens: 100, outputTokens: 200, + cacheReadTokens: 50, cacheWriteTokens: 0, + }) + expect(day.providers['claude']).toEqual({ calls: 1, cost: 7 }) + expect(day.providers['codex']).toEqual({ calls: 1, cost: 3 }) + }) +}) + +describe('buildPeriodDataFromDays', () => { + function makeDay(date: string, cost: number) { + return { + date, + cost, + calls: 10, + sessions: 2, + inputTokens: 100, + outputTokens: 200, + cacheReadTokens: 300, + cacheWriteTokens: 0, + editTurns: 3, + oneShotTurns: 2, + models: { + 'Opus 4.7': { calls: 8, cost: cost * 0.8, inputTokens: 0, outputTokens: 0, cacheReadTokens: 0, cacheWriteTokens: 0 }, + 'Haiku 4.5': { calls: 2, cost: cost * 0.2, inputTokens: 0, outputTokens: 0, cacheReadTokens: 0, cacheWriteTokens: 0 }, + }, + categories: { 'coding': { turns: 2, cost: cost * 0.5, editTurns: 2, oneShotTurns: 1 } }, + providers: { 'claude': { calls: 10, cost } }, + } + } + + it('sums cost, calls, sessions, tokens across days', () => { + const days = [makeDay('2026-04-09', 10), makeDay('2026-04-10', 20)] + const pd = buildPeriodDataFromDays(days, '7 Days') + expect(pd.label).toBe('7 Days') + expect(pd.cost).toBe(30) + expect(pd.calls).toBe(20) + expect(pd.sessions).toBe(4) + expect(pd.inputTokens).toBe(200) + expect(pd.outputTokens).toBe(400) + expect(pd.cacheReadTokens).toBe(600) + }) + + it('merges per-model totals across days and sorts by cost desc', () => { + const days = [makeDay('2026-04-09', 10), makeDay('2026-04-10', 20)] + const pd = buildPeriodDataFromDays(days, 'Today') + expect(pd.models[0]!.name).toBe('Opus 4.7') + expect(pd.models[0]!.cost).toBeCloseTo(24) + expect(pd.models[1]!.name).toBe('Haiku 4.5') + expect(pd.models[1]!.cost).toBeCloseTo(6) + }) + + it('merges per-category totals and keeps editTurns + oneShotTurns per category', () => { + const days = [makeDay('2026-04-09', 10), makeDay('2026-04-10', 20)] + const pd = buildPeriodDataFromDays(days, 'Today') + const coding = pd.categories.find(c => c.name === 'Coding')! + expect(coding.turns).toBe(4) + expect(coding.editTurns).toBe(4) + expect(coding.oneShotTurns).toBe(2) + expect(coding.cost).toBeCloseTo(15) + }) + + it('returns empty period totals when no days supplied', () => { + const pd = buildPeriodDataFromDays([], 'Today') + expect(pd.cost).toBe(0) + expect(pd.calls).toBe(0) + expect(pd.sessions).toBe(0) + expect(pd.categories).toEqual([]) + expect(pd.models).toEqual([]) + }) +}) diff --git a/tests/export.test.ts b/tests/export.test.ts index 1f196bf..b9b6a99 100644 --- a/tests/export.test.ts +++ b/tests/export.test.ts @@ -120,8 +120,15 @@ describe('exportCsv', () => { ] const outputPath = join(tmpDir, 'report.csv') - await exportCsv(periods, outputPath) - const content = await readFile(outputPath, 'utf-8') + const folder = await exportCsv(periods, outputPath) + // exportCsv now writes a folder of clean one-table-per-file CSVs, so the formula-prefix + // guard is scattered across files. Concatenate them for the assertion surface. + const [projects, models, shell] = await Promise.all([ + readFile(join(folder, 'projects.csv'), 'utf-8'), + readFile(join(folder, 'models.csv'), 'utf-8'), + readFile(join(folder, 'shell-commands.csv'), 'utf-8'), + ]) + const content = projects + models + shell expect(content).toContain("\"'=cmd,calc\"") expect(content).toContain("'+danger-model") diff --git a/tests/menubar-json.test.ts b/tests/menubar-json.test.ts new file mode 100644 index 0000000..f7493d0 --- /dev/null +++ b/tests/menubar-json.test.ts @@ -0,0 +1,234 @@ +import { describe, expect, it } from 'vitest' + +import { buildMenubarPayload, type PeriodData, type ProviderCost } from '../src/menubar-json.js' +import type { OptimizeResult } from '../src/optimize.js' + +function emptyPeriod(label: string): PeriodData { + return { + label, + cost: 0, + calls: 0, + sessions: 0, + inputTokens: 0, + outputTokens: 0, + cacheReadTokens: 0, + cacheWriteTokens: 0, + categories: [], + models: [], + } +} + +describe('buildMenubarPayload', () => { + it('emits the full schema with current-period metrics and iso timestamp', () => { + const period: PeriodData = { + label: '7 Days', + cost: 1248.01, + calls: 11231, + sessions: 97, + inputTokens: 19100, + outputTokens: 675600, + cacheReadTokens: 0, + cacheWriteTokens: 0, + categories: [], + models: [], + } + const payload = buildMenubarPayload(period, [], null) + + expect(payload.generated).toMatch(/^\d{4}-\d{2}-\d{2}T/) + expect(payload.current.label).toBe('7 Days') + expect(payload.current.cost).toBe(1248.01) + expect(payload.current.calls).toBe(11231) + expect(payload.current.sessions).toBe(97) + expect(payload.current.inputTokens).toBe(19100) + expect(payload.current.outputTokens).toBe(675600) + }) + + it('computes per-category oneShotRate from editTurns and skips categories without edits', () => { + const period: PeriodData = { + label: 'Today', + cost: 0, calls: 0, sessions: 0, + inputTokens: 0, outputTokens: 0, cacheReadTokens: 0, cacheWriteTokens: 0, + categories: [ + { name: 'Coding', cost: 15.83, turns: 7, editTurns: 7, oneShotTurns: 6 }, + { name: 'Conversation', cost: 16.69, turns: 47, editTurns: 0, oneShotTurns: 0 }, + ], + models: [], + } + const payload = buildMenubarPayload(period, [], null) + + const coding = payload.current.topActivities.find(a => a.name === 'Coding')! + expect(coding.oneShotRate).toBeCloseTo(6 / 7) + + const conv = payload.current.topActivities.find(a => a.name === 'Conversation')! + expect(conv.oneShotRate).toBeNull() + }) + + it('computes aggregate oneShotRate across categories with edits', () => { + const period: PeriodData = { + label: 'Today', + cost: 0, calls: 0, sessions: 0, + inputTokens: 0, outputTokens: 0, cacheReadTokens: 0, cacheWriteTokens: 0, + categories: [ + { name: 'Coding', cost: 1, turns: 7, editTurns: 10, oneShotTurns: 8 }, + { name: 'Debugging', cost: 1, turns: 5, editTurns: 10, oneShotTurns: 6 }, + { name: 'Conversation', cost: 1, turns: 40, editTurns: 0, oneShotTurns: 0 }, + ], + models: [], + } + const payload = buildMenubarPayload(period, [], null) + expect(payload.current.oneShotRate).toBeCloseTo((8 + 6) / (10 + 10)) + }) + + it('returns null aggregate oneShotRate when no categories have editTurns', () => { + const period: PeriodData = { + label: 'Today', + cost: 0, calls: 0, sessions: 0, + inputTokens: 0, outputTokens: 0, cacheReadTokens: 0, cacheWriteTokens: 0, + categories: [{ name: 'Conversation', cost: 1, turns: 5, editTurns: 0, oneShotTurns: 0 }], + models: [], + } + const payload = buildMenubarPayload(period, [], null) + expect(payload.current.oneShotRate).toBeNull() + }) + + it('filters out the synthetic model and caps topModels at 20 so multi-model users see all their models', () => { + const models = Array.from({ length: 30 }, (_, i) => ({ + name: `Model${i}`, cost: 30 - i, calls: 100, + })) + const period: PeriodData = { + label: 'Today', + cost: 0, calls: 0, sessions: 0, + inputTokens: 0, outputTokens: 0, cacheReadTokens: 0, cacheWriteTokens: 0, + categories: [], + models: [{ name: '', cost: 99, calls: 0 }, ...models], + } + const payload = buildMenubarPayload(period, [], null) + expect(payload.current.topModels.find(m => m.name === '')).toBeUndefined() + expect(payload.current.topModels).toHaveLength(20) + expect(payload.current.topModels[0].name).toBe('Model0') + }) + + it('caps topActivities at 20 so all task categories can surface', () => { + const period: PeriodData = { + label: 'Today', + cost: 0, calls: 0, sessions: 0, + inputTokens: 0, outputTokens: 0, cacheReadTokens: 0, cacheWriteTokens: 0, + categories: Array.from({ length: 25 }, (_, i) => ({ + name: `Cat${i}`, cost: 1, turns: 1, editTurns: 1, oneShotTurns: 1, + })), + models: [], + } + const payload = buildMenubarPayload(period, [], null) + expect(payload.current.topActivities).toHaveLength(20) + }) + + it('computes cacheHitPercent from cache reads over input plus cache reads', () => { + const period: PeriodData = { + label: 'Today', + cost: 0, calls: 0, sessions: 0, + inputTokens: 100, + outputTokens: 200, + cacheReadTokens: 900, + cacheWriteTokens: 0, + categories: [], + models: [], + } + const payload = buildMenubarPayload(period, [], null) + expect(payload.current.cacheHitPercent).toBeCloseTo(90) + }) + + it('returns zero cacheHitPercent when there is no input or cache traffic', () => { + const payload = buildMenubarPayload(emptyPeriod('Today'), [], null) + expect(payload.current.cacheHitPercent).toBe(0) + }) + + it('handles null optimize as empty findings block', () => { + const payload = buildMenubarPayload(emptyPeriod('Today'), [], null) + expect(payload.optimize).toEqual({ findingCount: 0, savingsUSD: 0, topFindings: [] }) + }) + + it('converts tokensSaved to savingsUSD via costRate and caps topFindings at 10', () => { + const findings = Array.from({ length: 15 }, (_, i) => ({ + title: `F${i}`, explanation: '', impact: 'low' as const, tokensSaved: 1000, + fix: { type: 'paste' as const, label: '', text: '' }, + })) + const optimize: OptimizeResult = { + findings, + costRate: 0.00002, + healthScore: 60, + healthGrade: 'C', + } + const payload = buildMenubarPayload(emptyPeriod('Today'), [], optimize) + + expect(payload.optimize.findingCount).toBe(15) + expect(payload.optimize.topFindings).toHaveLength(10) + expect(payload.optimize.topFindings[0].title).toBe('F0') + expect(payload.optimize.topFindings[0].savingsUSD).toBeCloseTo(1000 * 0.00002) + expect(payload.optimize.savingsUSD).toBeCloseTo(15 * 1000 * 0.00002) + }) + + it('maps providers into a lowercased dict inside the current-period block', () => { + const providers: ProviderCost[] = [ + { name: 'Claude Code', cost: 76.45 }, + { name: 'Cursor', cost: 2.18 }, + { name: 'Codex', cost: 1.5 }, + ] + const payload = buildMenubarPayload(emptyPeriod('Today'), providers, null) + expect(payload.current.providers).toEqual({ 'claude code': 76.45, cursor: 2.18, codex: 1.5 }) + }) + + it('keeps zero-cost providers in the dict so installed-but-unused providers still render as tabs', () => { + const providers: ProviderCost[] = [ + { name: 'Claude', cost: 76.45 }, + { name: 'Codex', cost: 0 }, + { name: 'Cursor', cost: 2.18 }, + ] + const payload = buildMenubarPayload(emptyPeriod('Today'), providers, null) + expect(payload.current.providers).toEqual({ claude: 76.45, codex: 0, cursor: 2.18 }) + }) + + it('includes up to 365 daily history entries sorted ascending by date', () => { + const history = Array.from({ length: 400 }, (_, i) => { + const d = new Date(2025, 0, 1) + d.setDate(d.getDate() + i) + return { + date: d.toISOString().slice(0, 10), + cost: i, + calls: i * 10, + inputTokens: 0, + outputTokens: 0, + cacheReadTokens: 0, + cacheWriteTokens: 0, + topModels: [], + } + }) + const payload = buildMenubarPayload(emptyPeriod('Today'), [], null, history) + expect(payload.history.daily).toHaveLength(365) + expect(payload.history.daily[0]!.date < payload.history.daily[364]!.date).toBe(true) + expect(payload.history.daily[364]!.date).toBe(history[399]!.date) + }) + + it('preserves token fields in dailyHistory entries', () => { + const history = [ + { date: '2026-04-15', cost: 10, calls: 50, inputTokens: 100, outputTokens: 200, cacheReadTokens: 5000, cacheWriteTokens: 800, topModels: [{ name: 'Opus 4.7', cost: 8, calls: 40, inputTokens: 80, outputTokens: 160 }] }, + { date: '2026-04-16', cost: 20, calls: 75, inputTokens: 150, outputTokens: 350, cacheReadTokens: 8000, cacheWriteTokens: 1200, topModels: [] }, + ] + const payload = buildMenubarPayload(emptyPeriod('Today'), [], null, history) + expect(payload.history.daily[0]).toEqual(history[0]) + expect(payload.history.daily[1]).toEqual(history[1]) + }) + + it('returns empty history when none supplied', () => { + const payload = buildMenubarPayload(emptyPeriod('Today'), [], null) + expect(payload.history.daily).toEqual([]) + }) + + it('drops providers with negative cost defensively', () => { + const providers: ProviderCost[] = [ + { name: 'Claude', cost: 76.45 }, + { name: 'Broken', cost: -1 }, + ] + const payload = buildMenubarPayload(emptyPeriod('Today'), providers, null) + expect(payload.current.providers).toEqual({ claude: 76.45 }) + }) +}) diff --git a/tests/menubar.test.ts b/tests/menubar.test.ts deleted file mode 100644 index 93936b8..0000000 --- a/tests/menubar.test.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { describe, expect, it } from 'vitest' -import { join } from 'path' -import { homedir } from 'os' - -import { chooseMenubarPluginDir, parsePluginDirectoryPreference } from '../src/menubar.js' - -describe('parsePluginDirectoryPreference', () => { - it('trims defaults output and preserves spaces in paths', () => { - expect(parsePluginDirectoryPreference('/Users/test/Documents/Tech stuff/swiftbar_plugins\n')).toBe('/Users/test/Documents/Tech stuff/swiftbar_plugins') - }) - - it('expands tilde paths', () => { - expect(parsePluginDirectoryPreference('~/swiftbar_plugins')).toBe(join(homedir(), 'swiftbar_plugins')) - }) - - it('ignores blank preference values', () => { - expect(parsePluginDirectoryPreference(' \n')).toBeUndefined() - }) -}) - -describe('chooseMenubarPluginDir', () => { - const configuredSwiftBarDir = '/Users/test/Documents/Tech stuff/swiftbar_plugins' - const defaultSwiftBarDir = '/Users/test/Library/Application Support/SwiftBar/plugins' - const xbarDir = '/Users/test/Library/Application Support/xbar/plugins' - - it('uses SwiftBar configured plugin directory before the default directory', () => { - const existing = new Set([configuredSwiftBarDir, defaultSwiftBarDir]) - const result = chooseMenubarPluginDir( - [configuredSwiftBarDir, defaultSwiftBarDir], - xbarDir, - path => existing.has(path), - ) - - expect(result).toEqual({ pluginDir: configuredSwiftBarDir, appName: 'SwiftBar' }) - }) - - it('falls back to xbar when no SwiftBar plugin directory exists', () => { - const existing = new Set([xbarDir]) - const result = chooseMenubarPluginDir( - [defaultSwiftBarDir], - xbarDir, - path => existing.has(path), - ) - - expect(result).toEqual({ pluginDir: xbarDir, appName: 'xbar' }) - }) - - it('creates the preferred SwiftBar directory when no plugin directory exists', () => { - const result = chooseMenubarPluginDir( - [configuredSwiftBarDir, defaultSwiftBarDir], - xbarDir, - () => false, - ) - - expect(result).toEqual({ pluginDir: configuredSwiftBarDir, appName: 'SwiftBar' }) - }) -}) diff --git a/tests/security/menubar-injection.test.ts b/tests/security/menubar-injection.test.ts deleted file mode 100644 index d8de96d..0000000 --- a/tests/security/menubar-injection.test.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { describe, it, expect } from 'vitest' - -import { renderMenubarFormat, type PeriodData } from '../../src/menubar.js' - -const ESC = '\u001b' - -function period(name: string): PeriodData { - return { - label: 'x', - cost: 0.01, - calls: 1, - inputTokens: 1, - outputTokens: 1, - cacheReadTokens: 0, - cacheWriteTokens: 0, - categories: [{ name, cost: 0.01, turns: 1, editTurns: 0, oneShotTurns: 1 }], - models: [{ name, cost: 0.01, calls: 1 }], - } -} - -function linesWithToken(output: string, token: string): string[] { - return output.split('\n').filter(l => l.includes(token)) -} - -describe('MEDIUM-2 menubar directive separator injection', () => { - it('strips pipe separators from model names', () => { - const p = period('foo | href=https://attacker.example/pwn') - const out = renderMenubarFormat(p, p, p, p) - for (const line of linesWithToken(out, 'foo')) { - expect(line.split('|').length).toBeLessThanOrEqual(2) - } - }) - - it('strips ANSI escapes from model names', () => { - const p = period(`foo${ESC}[31mMODEL${ESC}[0m`) - const out = renderMenubarFormat(p, p, p, p) - expect(out).not.toContain(ESC) - }) - - it('strips pipe separators from category names', () => { - const p = period('cat | color=red') - const out = renderMenubarFormat(p, p, p, p) - for (const line of linesWithToken(out, 'cat')) { - expect(line.split('|').length).toBeLessThanOrEqual(2) - } - }) -}) From 3482478a498a2b964d69045956993b4c210e5a49 Mon Sep 17 00:00:00 2001 From: Resham Joshi Date: Fri, 17 Apr 2026 17:01:00 -0700 Subject: [PATCH 43/70] fix(mac): drop empty Resources/ reference from Package.swift Caught in a fresh-clone smoke test: SwiftPM refused to build because .process("../../Resources") pointed at an empty directory that git does not track. The bundle has no assets to ship yet (icon will land with signing work), so the reference is gone. Build passes on a clean checkout and the packaging script produces the universal .app zip as expected. --- mac/Package.swift | 3 --- 1 file changed, 3 deletions(-) diff --git a/mac/Package.swift b/mac/Package.swift index 4d26e3e..67509f2 100644 --- a/mac/Package.swift +++ b/mac/Package.swift @@ -13,9 +13,6 @@ let package = Package( .executableTarget( name: "CodeBurnMenubar", path: "Sources/CodeBurnMenubar", - resources: [ - .process("../../Resources") - ], swiftSettings: [ .enableUpcomingFeature("StrictConcurrency") ] From 03f12ce81f3579142af255465ac7cc1215528a5b Mon Sep 17 00:00:00 2001 From: Resham Joshi Date: Fri, 17 Apr 2026 17:05:08 -0700 Subject: [PATCH 44/70] fix(status): bucket Today/Month by local date, not UTC renderStatusBar computed `today` via `new Date().toISOString().slice(0,10)`, which is the UTC date. Session timestamps are also UTC ISO strings, but the user's expectation of "today" is their wall-clock day. During the window between local midnight and UTC midnight (e.g. 17:00 PDT on 2026-04-17, which is already 00:00 UTC on 2026-04-18), every session bucketed under local April 17 missed the UTC-April-18 filter and the status bar read `Today $0.00 0 calls` even while `--format json` and the menubar app correctly showed the spend. Both sides of the comparison now use the local date of each session timestamp, so the terminal status and the JSON / menubar paths agree. Verified at UTC midnight (the regression moment that surfaced the bug): Before: Today $0.0000 0 calls After: Today $339.87 1839 calls Caught during the fresh-clone review of the menubar PR. --- src/format.ts | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/format.ts b/src/format.ts index 493d4e6..3905048 100644 --- a/src/format.ts +++ b/src/format.ts @@ -13,9 +13,20 @@ export function formatTokens(n: number): string { return n.toString() } +/// Returns YYYY-MM-DD for the given date in the process-local timezone. Cheaper than shelling +/// out to Intl.DateTimeFormat for every turn in a loop and avoids the UTC drift that bites +/// `Date.toISOString().slice(0,10)` whenever the user runs this between local midnight and +/// UTC midnight. +function localDateString(d: Date): string { + const y = d.getFullYear() + const m = String(d.getMonth() + 1).padStart(2, '0') + const day = String(d.getDate()).padStart(2, '0') + return `${y}-${m}-${day}` +} + export function renderStatusBar(projects: ProjectSummary[]): string { const now = new Date() - const today = now.toISOString().slice(0, 10) + const today = localDateString(now) const monthStart = `${today.slice(0, 7)}-01` let todayCost = 0, todayCalls = 0, monthCost = 0, monthCalls = 0 @@ -24,7 +35,11 @@ export function renderStatusBar(projects: ProjectSummary[]): string { for (const session of project.sessions) { for (const turn of session.turns) { if (!turn.timestamp) continue - const day = turn.timestamp.slice(0, 10) + // Bucket by the session timestamp's local date so the user's "today" and "this month" + // match the wall clock on their machine. Session timestamps are stored as UTC ISO + // strings; naively slicing `timestamp.slice(0,10)` bucketed them by UTC date, which + // showed `Today $0` during the UTC-midnight-to-local-midnight window. + const day = localDateString(new Date(turn.timestamp)) const turnCost = turn.assistantCalls.reduce((s, c) => s + c.costUSD, 0) const turnCalls = turn.assistantCalls.length if (day === today) { todayCost += turnCost; todayCalls += turnCalls } From 818a249c87b58697aa443f4b19d18aa8f65f2c5b Mon Sep 17 00:00:00 2001 From: AgentSeal Date: Fri, 17 Apr 2026 17:08:24 -0700 Subject: [PATCH 45/70] chore: release 0.7.2 native macOS menubar app See CHANGELOG.md for the full breakdown. Highlights: - Native Swift + SwiftUI menubar app under mac/ replaces the SwiftBar plugin. Install via `npx codeburn menubar`. - `status --format menubar-json` payload builder. - `export -f csv` now writes a folder of clean per-table CSVs; `-o` path guard prevents arbitrary deletion. - `status` terminal Today/Month bucketed by local date instead of UTC. - FX rate values clamped to sane bounds in both runtimes. - SwiftBar plugin, install-menubar / uninstall-menubar, and `--format menubar` removed. --- CHANGELOG.md | 22 ++++++++++++++++++++++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0e49607..6fc672a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,27 @@ # Changelog +## 0.7.2 - 2026-04-17 + +### Added +- **Native macOS menubar app.** Swift + SwiftUI app under `mac/` replaces the SwiftBar plugin. Agent tabs, Today/7/30/Month/All period switcher, Trend/Forecast/Pulse/Stats/Plan insights, activity and model breakdowns, optimize findings, CSV/JSON export, instant currency switching, live 60s refresh. +- **`codeburn menubar`.** One-command install: downloads the latest `.app` from GitHub Releases, strips Gatekeeper quarantine, drops it into `~/Applications`, and launches it. `--force` reinstalls in place. +- **`status --format menubar-json`.** Structured payload consumed by the native menubar app. Current-period totals, per-activity and per-model breakdowns, provider costs, optimize findings, and 365-day history. +- **Release workflow.** `.github/workflows/release-menubar.yml` builds a universal `.app` bundle and zip on `mac-v*` tag push. Runs on the free macos-latest runner, no Apple Developer Program required. + +### Changed +- **`codeburn export -f csv`** now writes a folder of one-table-per-file CSVs (`summary`, `daily`, `activity`, `models`, `projects`, `sessions`, `tools`, `shell-commands`) plus a `README.txt` index. Each file opens cleanly as a single table in any spreadsheet. +- **`codeburn export -f json`** upgraded to schema `codeburn.export.v2` with currency metadata. + +### Fixed +- **`codeburn status` terminal Today/Month** now buckets by local date instead of UTC, so spend shows correctly during the window between local midnight and UTC midnight. +- **FX rate validation.** Frankfurter responses are checked to be finite and within `[0.0001, 1_000_000]` before they affect displayed costs. + +### Removed +- **SwiftBar plugin.** `src/menubar.ts`, `codeburn install-menubar`, `codeburn uninstall-menubar`, and `status --format menubar` are gone. The native Swift app is the single menubar surface. + +### Security +- **`codeburn export -o` guard.** Writes a `.codeburn-export` marker into every folder it creates and refuses to reuse non-marked directories or overwrite existing files, so a typo like `-o ~/.ssh/id_ed25519` cannot delete a sensitive file. + ## 0.7.1 - 2026-04-17 ### Security diff --git a/package-lock.json b/package-lock.json index c4ffcb6..a406801 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "codeburn", - "version": "0.7.1", + "version": "0.7.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "codeburn", - "version": "0.7.1", + "version": "0.7.2", "license": "MIT", "dependencies": { "chalk": "^5.4.1", diff --git a/package.json b/package.json index 06932e4..d7046b1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "codeburn", - "version": "0.7.1", + "version": "0.7.2", "description": "See where your AI coding tokens go - by task, tool, model, and project", "type": "module", "main": "./dist/cli.js", From 0b96ff182e55fae34f9f763e6d409bd5c3a0650c Mon Sep 17 00:00:00 2001 From: Resham Joshi Date: Fri, 17 Apr 2026 17:12:48 -0700 Subject: [PATCH 46/70] docs: scrub private strategy notes from public text Removes references to future signing decisions, dollar amounts, and star thresholds from the menubar README, the CHANGELOG, the release workflow (its YAML comments and the auto-generated release body), and the packaging script. The technical description stays; the 'we are not paying for X right now' framing is out. --- .github/workflows/release-menubar.yml | 15 +++++++-------- CHANGELOG.md | 2 +- mac/README.md | 2 +- mac/Scripts/package-app.sh | 8 ++++---- 4 files changed, 13 insertions(+), 14 deletions(-) diff --git a/.github/workflows/release-menubar.yml b/.github/workflows/release-menubar.yml index df8fd31..b3902d3 100644 --- a/.github/workflows/release-menubar.yml +++ b/.github/workflows/release-menubar.yml @@ -1,10 +1,9 @@ name: Release macOS Menubar # Triggers on a `mac-v*` tag push (e.g. `git tag mac-v0.8.0 && git push origin mac-v0.8.0`), -# or manually via the Actions tab. Runs entirely on the free macos-latest runner -- no Apple -# Developer Program membership, no signing certificates, no secrets required. The bundle ships -# ad-hoc signed; `npx codeburn menubar` strips the download quarantine flag on install so -# Gatekeeper stays quiet. +# or manually via the Actions tab. Builds a universal arm64+x86_64 bundle, ad-hoc signs it, +# zips via `ditto`, and uploads the zip to the GitHub Release. `npx codeburn menubar` clears +# the download quarantine flag on install so Gatekeeper stays quiet. on: push: tags: @@ -62,9 +61,9 @@ jobs: npx codeburn menubar ``` - Unsigned build. The installer clears Gatekeeper quarantine on download, so the - app launches without warnings. Direct-download users from this page may see - "cannot verify developer" -- right-click → Open once to dismiss it, or use the - npx command above. + That command drops the app into `~/Applications`, clears the download + quarantine, and launches it. If you download the zip from this page directly + and macOS shows "cannot verify developer", right-click the app in Finder and + pick Open to whitelist it once. files: mac/.build/dist/CodeBurnMenubar-*.zip fail_on_unmatched_files: true diff --git a/CHANGELOG.md b/CHANGELOG.md index 6fc672a..831b81d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ - **Native macOS menubar app.** Swift + SwiftUI app under `mac/` replaces the SwiftBar plugin. Agent tabs, Today/7/30/Month/All period switcher, Trend/Forecast/Pulse/Stats/Plan insights, activity and model breakdowns, optimize findings, CSV/JSON export, instant currency switching, live 60s refresh. - **`codeburn menubar`.** One-command install: downloads the latest `.app` from GitHub Releases, strips Gatekeeper quarantine, drops it into `~/Applications`, and launches it. `--force` reinstalls in place. - **`status --format menubar-json`.** Structured payload consumed by the native menubar app. Current-period totals, per-activity and per-model breakdowns, provider costs, optimize findings, and 365-day history. -- **Release workflow.** `.github/workflows/release-menubar.yml` builds a universal `.app` bundle and zip on `mac-v*` tag push. Runs on the free macos-latest runner, no Apple Developer Program required. +- **Release workflow.** `.github/workflows/release-menubar.yml` builds a universal `.app` bundle and zip on `mac-v*` tag push. ### Changed - **`codeburn export -f csv`** now writes a folder of one-table-per-file CSVs (`summary`, `daily`, `activity`, `models`, `projects`, `sessions`, `tools`, `shell-commands`) plus a `README.txt` index. Each file opens cleanly as a single table in any spreadsheet. diff --git a/mac/README.md b/mac/README.md index aab3bc6..4d3e2ae 100644 --- a/mac/README.md +++ b/mac/README.md @@ -16,7 +16,7 @@ One command: npx codeburn menubar ``` -That's it. The command downloads the latest signed `.app` from GitHub Releases, drops it into `~/Applications`, clears Gatekeeper quarantine, and launches it. Re-running it upgrades in place with `--force`, or just launches the existing copy otherwise. +That's it. The command downloads the latest `.app` from GitHub Releases, drops it into `~/Applications`, clears Gatekeeper quarantine, and launches it. Re-running it upgrades in place with `--force`, or just launches the existing copy otherwise. If you already have the CLI installed globally (`npm install -g codeburn`), `codeburn menubar` works the same way. diff --git a/mac/Scripts/package-app.sh b/mac/Scripts/package-app.sh index d8b68c7..5672b5e 100755 --- a/mac/Scripts/package-app.sh +++ b/mac/Scripts/package-app.sh @@ -85,10 +85,10 @@ cat > "${BUNDLE}/Contents/PkgInfo" <<'PKG' APPL???? PKG -# Ad-hoc sign so macOS treats the bundle as internally consistent. This does NOT give us a -# recognisable developer name in Finder (that needs the $99 Developer ID cert), but it -# satisfies macOS's minimum bundle-validity checks on 14+ and prevents some Gatekeeper edge -# cases on managed Macs. +# Ad-hoc sign so macOS treats the bundle as internally consistent. This satisfies the +# minimum bundle-validity checks on macOS 14+ and prevents a class of Gatekeeper edge +# cases on managed Macs. A Developer ID signature (separate setup) would additionally +# surface the publisher name in Finder; not required here. echo "▸ Ad-hoc signing..." codesign --force --sign - --timestamp=none --deep "${BUNDLE}" 2>/dev/null || true codesign --verify --deep --strict "${BUNDLE}" 2>/dev/null || echo " (signature verify skipped)" From feda92124d7aa68680976262c4ad09ffe3ed3357 Mon Sep 17 00:00:00 2001 From: AgentSeal Date: Fri, 17 Apr 2026 17:29:16 -0700 Subject: [PATCH 47/70] docs: bust CDN cache on menubar screenshot Appends ?v=0.7.2 to the image URL so GitHub's Camo proxy re-fetches the new 0.7.2 screenshot instead of serving its stale copy of the SwiftBar-era one. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4b6e167..fb34ffc 100644 --- a/README.md +++ b/README.md @@ -156,7 +156,7 @@ The menu bar widget includes a currency picker with 17 common currencies. For an ## Menu Bar -CodeBurn macOS menubar app +CodeBurn macOS menubar app ```bash npx codeburn menubar From 1037d2c527806b8ec645e189d4e12b29b924f003 Mon Sep 17 00:00:00 2001 From: AgentSeal Date: Fri, 17 Apr 2026 17:41:28 -0700 Subject: [PATCH 48/70] docs: rename README screenshot so CDN+Camo re-fetch The ?v=0.7.2 query bust wasn't enough; GitHub's Camo proxy was still serving the SwiftBar-era image to viewers. Renaming the asset to a new path forces every downstream cache to treat it as a new resource. --- assets/{menubar.png => menubar-0.7.2.png} | Bin 1 file changed, 0 insertions(+), 0 deletions(-) rename assets/{menubar.png => menubar-0.7.2.png} (100%) diff --git a/assets/menubar.png b/assets/menubar-0.7.2.png similarity index 100% rename from assets/menubar.png rename to assets/menubar-0.7.2.png From 2b15256189c55b93c04fe80404ac00cf369abbe9 Mon Sep 17 00:00:00 2001 From: AgentSeal Date: Fri, 17 Apr 2026 17:43:09 -0700 Subject: [PATCH 49/70] docs: actually update README to the renamed screenshot path The prior rename commit moved the PNG but forgot to stage the matching README edit, leaving the live image tag pointing at a path that no longer existed. This fixes it. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fb34ffc..79aa754 100644 --- a/README.md +++ b/README.md @@ -156,7 +156,7 @@ The menu bar widget includes a currency picker with 17 common currencies. For an ## Menu Bar -CodeBurn macOS menubar app +CodeBurn macOS menubar app ```bash npx codeburn menubar From 7aefd674fc4736587144d29d0df609bd8724b5bc Mon Sep 17 00:00:00 2001 From: AgentSeal Date: Sat, 18 Apr 2026 01:26:23 -0700 Subject: [PATCH 50/70] fix: drop better-sqlite3 to remove deprecated prebuild-install (#75) npm was warning on every install that prebuild-install@7.1.3 is no longer maintained. prebuild-install ships as a transitive dependency of better-sqlite3 and upstream PR #1446 to replace it is still open, so we switch to Node's built-in node:sqlite module (stable in Node 24, experimental in Node 22/23) and remove the better-sqlite3 dep entirely. - src/sqlite.ts: uses DatabaseSync from node:sqlite. The one-shot ExperimentalWarning about SQLite on Node 22/23 is silenced for that specific warning; other warnings pass through unchanged. - package.json: engines.node bumped to >=22 (Node 20 EOL 2026-04-30), better-sqlite3 and @types/better-sqlite3 removed, @types/node added (it was coming in transitively via @types/better-sqlite3). - tests/providers/opencode.test.ts: fixture DB creation switched to node:sqlite (API parity for the CREATE TABLE + INSERT + prepare path we use). End-user install footprint shrinks from 167 to 40 packages and prints zero deprecation warnings. Credit: @primeminister for the report. --- CHANGELOG.md | 7 + package-lock.json | 525 +------------------------------ package.json | 9 +- src/sqlite.ts | 76 ++++- tests/providers/opencode.test.ts | 6 +- 5 files changed, 83 insertions(+), 540 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 831b81d..b63721d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## 0.7.3 - 2026-04-18 + +### Changed +- **Dropped `better-sqlite3` in favor of Node's built-in `node:sqlite`.** Removes the deprecated `prebuild-install` transitive dependency that npm warned about on every install (issue #75, credit @primeminister). End-user install is now 40 packages down from 167 and shows zero deprecation notices. The experimental-SQLite warning Node 22/23 normally prints on module load is silenced for this specific warning; other warnings pass through unchanged. +- **Minimum Node version raised to 22.** Node 20 reached EOL on 2026-04-30; `node:sqlite` lives in 22+. Users on older Node get a clear upgrade message when a SQLite-backed provider (Cursor, OpenCode) is loaded. + + ## 0.7.2 - 2026-04-17 ### Added diff --git a/package-lock.json b/package-lock.json index a406801..8911286 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "codeburn", - "version": "0.7.2", + "version": "0.7.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "codeburn", - "version": "0.7.2", + "version": "0.7.3", "license": "MIT", "dependencies": { "chalk": "^5.4.1", @@ -18,7 +18,7 @@ "codeburn": "dist/cli.js" }, "devDependencies": { - "@types/better-sqlite3": "^7.6.0", + "@types/node": "^22.19.17", "@types/react": "^19.2.14", "tsup": "^8.4.0", "tsx": "^4.19.0", @@ -26,10 +26,7 @@ "vitest": "^3.1.0" }, "engines": { - "node": ">=20" - }, - "optionalDependencies": { - "better-sqlite3": "^12.0.0" + "node": ">=22" } }, "node_modules/@alcalzone/ansi-tokenize": { @@ -876,16 +873,6 @@ "win32" ] }, - "node_modules/@types/better-sqlite3": { - "version": "7.6.13", - "resolved": "https://registry.npmjs.org/@types/better-sqlite3/-/better-sqlite3-7.6.13.tgz", - "integrity": "sha512-NMv9ASNARoKksWtsq/SHakpYAYnhBrQgGD8zkLYk/jaK8jUGn08CfEdTRgYhMypUQAfzSP8W6gNLe0q19/t4VA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@types/chai": { "version": "5.2.3", "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", @@ -912,13 +899,13 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "25.6.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-25.6.0.tgz", - "integrity": "sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ==", + "version": "22.19.17", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.17.tgz", + "integrity": "sha512-wGdMcf+vPYM6jikpS/qhg6WiqSV/OhG+jeeHT/KlVqxYfD40iYJf9/AE1uQxVWFvU7MipKRkRv8NSHiCGgPr8Q==", "dev": true, "license": "MIT", "dependencies": { - "undici-types": "~7.19.0" + "undici-types": "~6.21.0" } }, "node_modules/@types/react": { @@ -1127,89 +1114,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "optional": true - }, - "node_modules/better-sqlite3": { - "version": "12.9.0", - "resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-12.9.0.tgz", - "integrity": "sha512-wqUv4Gm3toFpHDQmaKD4QhZm3g1DjUBI0yzS4UBl6lElUmXFYdTQmmEDpAFa5o8FiFiymURypEnfVHzILKaxqQ==", - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "dependencies": { - "bindings": "^1.5.0", - "prebuild-install": "^7.1.1" - }, - "engines": { - "node": "20.x || 22.x || 23.x || 24.x || 25.x" - } - }, - "node_modules/bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "license": "MIT", - "optional": true, - "dependencies": { - "file-uri-to-path": "1.0.0" - } - }, - "node_modules/bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "license": "MIT", - "optional": true, - "dependencies": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "optional": true, - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, "node_modules/bundle-require": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/bundle-require/-/bundle-require-5.1.0.tgz", @@ -1291,13 +1195,6 @@ "url": "https://paulmillr.com/funding/" } }, - "node_modules/chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "license": "ISC", - "optional": true - }, "node_modules/cli-boxes": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-4.0.1.tgz", @@ -1413,22 +1310,6 @@ } } }, - "node_modules/decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "license": "MIT", - "optional": true, - "dependencies": { - "mimic-response": "^3.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/deep-eql": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", @@ -1439,36 +1320,6 @@ "node": ">=6" } }, - "node_modules/deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/detect-libc": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", - "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", - "license": "Apache-2.0", - "optional": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/end-of-stream": { - "version": "1.4.5", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", - "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", - "license": "MIT", - "optional": true, - "dependencies": { - "once": "^1.4.0" - } - }, "node_modules/environment": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", @@ -1559,16 +1410,6 @@ "@types/estree": "^1.0.0" } }, - "node_modules/expand-template": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", - "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", - "license": "(MIT OR WTFPL)", - "optional": true, - "engines": { - "node": ">=6" - } - }, "node_modules/expect-type": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz", @@ -1597,13 +1438,6 @@ } } }, - "node_modules/file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "license": "MIT", - "optional": true - }, "node_modules/fix-dts-default-cjs-exports": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/fix-dts-default-cjs-exports/-/fix-dts-default-cjs-exports-1.0.1.tgz", @@ -1616,13 +1450,6 @@ "rollup": "^4.34.8" } }, - "node_modules/fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "license": "MIT", - "optional": true - }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -1663,34 +1490,6 @@ "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" } }, - "node_modules/github-from-package": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", - "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", - "license": "MIT", - "optional": true - }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "BSD-3-Clause", - "optional": true - }, "node_modules/indent-string": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", @@ -1703,20 +1502,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "license": "ISC", - "optional": true - }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "license": "ISC", - "optional": true - }, "node_modules/ink": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/ink/-/ink-7.0.0.tgz", @@ -1869,36 +1654,6 @@ "node": ">=6" } }, - "node_modules/mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "license": "MIT", - "optional": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/mkdirp-classic": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", - "license": "MIT", - "optional": true - }, "node_modules/mlly": { "version": "1.8.2", "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.8.2.tgz", @@ -1950,26 +1705,6 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, - "node_modules/napi-build-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz", - "integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==", - "license": "MIT", - "optional": true - }, - "node_modules/node-abi": { - "version": "3.89.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.89.0.tgz", - "integrity": "sha512-6u9UwL0HlAl21+agMN3YAMXcKByMqwGx+pq+P76vii5f7hTPtKDp08/H9py6DY+cfDw7kQNTGEj/rly3IgbNQA==", - "license": "MIT", - "optional": true, - "dependencies": { - "semver": "^7.3.5" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -1980,16 +1715,6 @@ "node": ">=0.10.0" } }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "license": "ISC", - "optional": true, - "dependencies": { - "wrappy": "1" - } - }, "node_modules/onetime": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", @@ -2145,61 +1870,6 @@ } } }, - "node_modules/prebuild-install": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz", - "integrity": "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==", - "deprecated": "No longer maintained. Please contact the author of the relevant native addon; alternatives are available.", - "license": "MIT", - "optional": true, - "dependencies": { - "detect-libc": "^2.0.0", - "expand-template": "^2.0.3", - "github-from-package": "0.0.0", - "minimist": "^1.2.3", - "mkdirp-classic": "^0.5.3", - "napi-build-utils": "^2.0.0", - "node-abi": "^3.3.0", - "pump": "^3.0.0", - "rc": "^1.2.7", - "simple-get": "^4.0.0", - "tar-fs": "^2.0.0", - "tunnel-agent": "^0.6.0" - }, - "bin": { - "prebuild-install": "bin.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/pump": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.4.tgz", - "integrity": "sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==", - "license": "MIT", - "optional": true, - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", - "optional": true, - "dependencies": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "bin": { - "rc": "cli.js" - } - }, "node_modules/react": { "version": "19.2.5", "resolved": "https://registry.npmjs.org/react/-/react-19.2.5.tgz", @@ -2224,21 +1894,6 @@ "react": "^19.2.0" } }, - "node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "license": "MIT", - "optional": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/readdirp": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", @@ -2334,46 +1989,12 @@ "fsevents": "~2.3.2" } }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "optional": true - }, "node_modules/scheduler": { "version": "0.27.0", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", "license": "MIT" }, - "node_modules/semver": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", - "license": "ISC", - "optional": true, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/siginfo": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", @@ -2387,53 +2008,6 @@ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "license": "ISC" }, - "node_modules/simple-concat": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", - "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "optional": true - }, - "node_modules/simple-get": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", - "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "optional": true, - "dependencies": { - "decompress-response": "^6.0.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - } - }, "node_modules/slice-ansi": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-9.0.0.tgz", @@ -2496,16 +2070,6 @@ "dev": true, "license": "MIT" }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "license": "MIT", - "optional": true, - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, "node_modules/string-width": { "version": "8.2.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.2.0.tgz", @@ -2537,16 +2101,6 @@ "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/strip-literal": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-3.1.0.tgz", @@ -2605,36 +2159,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/tar-fs": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.4.tgz", - "integrity": "sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==", - "license": "MIT", - "optional": true, - "dependencies": { - "chownr": "^1.1.1", - "mkdirp-classic": "^0.5.2", - "pump": "^3.0.0", - "tar-stream": "^2.1.4" - } - }, - "node_modules/tar-stream": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", - "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", - "license": "MIT", - "optional": true, - "dependencies": { - "bl": "^4.0.3", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/terminal-size": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/terminal-size/-/terminal-size-4.0.1.tgz", @@ -2821,19 +2345,6 @@ "fsevents": "~2.3.3" } }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "license": "Apache-2.0", - "optional": true, - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } - }, "node_modules/type-fest": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-5.5.0.tgz", @@ -2871,19 +2382,12 @@ "license": "MIT" }, "node_modules/undici-types": { - "version": "7.19.2", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.19.2.tgz", - "integrity": "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", "dev": true, "license": "MIT" }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "license": "MIT", - "optional": true - }, "node_modules/vite": { "version": "7.3.2", "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.2.tgz", @@ -3104,13 +2608,6 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "license": "ISC", - "optional": true - }, "node_modules/ws": { "version": "8.20.0", "resolved": "https://registry.npmjs.org/ws/-/ws-8.20.0.tgz", diff --git a/package.json b/package.json index d7046b1..3820034 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "codeburn", - "version": "0.7.2", + "version": "0.7.3", "description": "See where your AI coding tokens go - by task, tool, model, and project", "type": "module", "main": "./dist/cli.js", @@ -29,7 +29,7 @@ "developer-tools" ], "engines": { - "node": ">=20" + "node": ">=22" }, "author": "AgentSeal ", "license": "MIT", @@ -39,11 +39,8 @@ "ink": "^7.0.0", "react": "^19.2.5" }, - "optionalDependencies": { - "better-sqlite3": "^12.0.0" - }, "devDependencies": { - "@types/better-sqlite3": "^7.6.0", + "@types/node": "^22.19.17", "@types/react": "^19.2.14", "tsup": "^8.4.0", "tsx": "^4.19.0", diff --git a/src/sqlite.ts b/src/sqlite.ts index 40981e4..dcc6940 100644 --- a/src/sqlite.ts +++ b/src/sqlite.ts @@ -1,6 +1,7 @@ -import { createRequire } from 'node:module' - -const require = createRequire(import.meta.url) +/// Thin SQLite read-only wrapper over Node's built-in `node:sqlite` module (stable in +/// Node 24, experimental in Node 22 / 23). Replaces the earlier `better-sqlite3` binding +/// so the dependency graph no longer pulls in the deprecated `prebuild-install` package +/// (issue #75). Works across Cursor and OpenCode session DBs, both of which we only read. type Row = Record @@ -9,21 +10,67 @@ export type SqliteDatabase = { close(): void } -let BetterSqlite3: unknown = null +type DatabaseSyncCtor = new (path: string, options?: { readOnly?: boolean }) => { + prepare(sql: string): { all(...params: unknown[]): Row[] } + close(): void +} + +let DatabaseSync: DatabaseSyncCtor | null = null let loadAttempted = false let loadError: string | null = null +/// Lazily imports `node:sqlite`. On Node 22/23 it emits an ExperimentalWarning the first +/// time the module is loaded; we silence that specific warning once so dashboards aren't +/// preceded by a scary stderr line every run. Any other warnings (including future +/// non-SQLite ones) are left untouched. function loadDriver(): boolean { - if (loadAttempted) return BetterSqlite3 !== null + if (loadAttempted) return DatabaseSync !== null loadAttempted = true + + const origEmit = process.emit.bind(process) + let restored = false + const restore = () => { + if (restored) return + restored = true + process.emit = origEmit + } + + // Node's `process.emit` signature is overloaded; we intercept the 'warning' channel + // only and proxy everything else through unchanged. The `any` cast avoids chasing the + // overload union which isn't worth its verbosity for a single-purpose shim. + // eslint-disable-next-line @typescript-eslint/no-explicit-any + process.emit = function patchedEmit(this: NodeJS.Process, event: string, ...args: any[]): boolean { + if (event === 'warning') { + const warning = args[0] as { name?: string; message?: string } | undefined + if ( + warning?.name === 'ExperimentalWarning' && + typeof warning.message === 'string' && + /SQLite/i.test(warning.message) + ) { + return false + } + } + // eslint-disable-next-line @typescript-eslint/no-explicit-any + return (origEmit as any).call(this, event, ...args) + } as typeof process.emit + try { - BetterSqlite3 = require('better-sqlite3') + // Dynamic require via createRequire avoids TypeScript chasing types we don't need at + // build time (node:sqlite landed in @types/node much later than in Node itself). + // eslint-disable-next-line @typescript-eslint/no-require-imports + const mod = eval('require')('node:sqlite') as { DatabaseSync: DatabaseSyncCtor } + DatabaseSync = mod.DatabaseSync return true - } catch { - loadError = 'SQLite-based providers (Cursor, OpenCode) require the better-sqlite3 package.\n' + - 'Install it with: npm install -g better-sqlite3\n' + - 'Then run codeburn again.' + } catch (err) { + const message = err instanceof Error ? err.message : String(err) + loadError = + 'SQLite-based providers (Cursor, OpenCode) need Node 22+ with the node:sqlite module.\n' + + `Current Node: ${process.version}.\n` + + 'Upgrade Node (https://nodejs.org) and run codeburn again.\n' + + `(underlying error: ${message})` return false + } finally { + restore() } } @@ -36,16 +83,11 @@ export function getSqliteLoadError(): string { } export function openDatabase(path: string): SqliteDatabase { - if (!loadDriver()) { + if (!loadDriver() || DatabaseSync === null) { throw new Error(getSqliteLoadError()) } - const Database = BetterSqlite3 as new (path: string, options?: Record) => { - prepare(sql: string): { all(...params: unknown[]): Row[] } - close(): void - } - - const db = new Database(path, { readonly: true, fileMustExist: true }) + const db = new DatabaseSync(path, { readOnly: true }) return { query(sql: string, params: unknown[] = []): T[] { diff --git a/tests/providers/opencode.test.ts b/tests/providers/opencode.test.ts index b1c75b3..bd715be 100644 --- a/tests/providers/opencode.test.ts +++ b/tests/providers/opencode.test.ts @@ -29,7 +29,7 @@ function createTestDb(dir: string): string { mkdirSync(ocDir, { recursive: true }) const dbPath = join(ocDir, 'opencode.db') - const Database = require('better-sqlite3') + const { DatabaseSync: Database } = require('node:sqlite') const db = new Database(dbPath) db.exec(` CREATE TABLE session ( @@ -57,7 +57,7 @@ function createTestDb(dir: string): string { } function withTestDb(dbPath: string, fn: (db: TestDb) => void): void { - const Database = require('better-sqlite3') + const { DatabaseSync: Database } = require('node:sqlite') const db = new Database(dbPath) fn(db) db.close() @@ -221,7 +221,7 @@ skipUnlessSqlite('opencode provider - session discovery', () => { const ocDir = join(tmpDir, 'opencode') await mkdir(ocDir, { recursive: true }) - const Database = require('better-sqlite3') + const { DatabaseSync: Database } = require('node:sqlite') for (const file of ['opencode.db', 'opencode-dev.db']) { const dbPath = join(ocDir, file) const db = new Database(dbPath) From 85d7bea7ea16aa89c119af633ba49910bb3db4b3 Mon Sep 17 00:00:00 2001 From: AgentSeal Date: Sat, 18 Apr 2026 05:07:36 -0700 Subject: [PATCH 51/70] feat(mac): hide agent tabs when fewer than two providers have spend The tab strip was visible for everyone regardless of which tools they actually run, which produced a row of All + one provider for Claude-only users and a row of All + zeros for users on exotic stacks. Hide the whole row until a second provider has real spend, matching the behavior the GNOME extension ships with. Also expand ProviderFilter to include every provider the CLI supports (OpenCode and Pi were missing) so their tabs appear when those tools produce sessions. The CLI already emits pi and opencode in the payload's providers map; the Mac app just wasn't offering a tab for them. visibleFilters now filters on value > 0 instead of key presence, because the CLI includes zero-cost entries for discovered-but-unused providers and we don't want those rendering as blank tabs. --- mac/Sources/CodeBurnMenubar/AppStore.swift | 4 ++++ .../CodeBurnMenubar/Views/AgentTabStrip.swift | 13 ++++++++++++- .../CodeBurnMenubar/Views/MenuBarContent.swift | 16 +++++++++++++--- 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/mac/Sources/CodeBurnMenubar/AppStore.swift b/mac/Sources/CodeBurnMenubar/AppStore.swift index cd26d76..db3e2da 100644 --- a/mac/Sources/CodeBurnMenubar/AppStore.swift +++ b/mac/Sources/CodeBurnMenubar/AppStore.swift @@ -213,6 +213,8 @@ enum ProviderFilter: String, CaseIterable, Identifiable { case codex = "Codex" case cursor = "Cursor" case copilot = "Copilot" + case opencode = "OpenCode" + case pi = "Pi" var id: String { rawValue } @@ -224,6 +226,8 @@ enum ProviderFilter: String, CaseIterable, Identifiable { case .codex: "codex" case .cursor: "cursor" case .copilot: "copilot" + case .opencode: "opencode" + case .pi: "pi" } } } diff --git a/mac/Sources/CodeBurnMenubar/Views/AgentTabStrip.swift b/mac/Sources/CodeBurnMenubar/Views/AgentTabStrip.swift index 4feb180..885bdcc 100644 --- a/mac/Sources/CodeBurnMenubar/Views/AgentTabStrip.swift +++ b/mac/Sources/CodeBurnMenubar/Views/AgentTabStrip.swift @@ -33,7 +33,16 @@ struct AgentTabStrip: View { } private var visibleFilters: [ProviderFilter] { - let activeKeys = Set(allProvidersToday.current.providers.keys.map { $0.lowercased() }) + // Only surface providers that actually spent money in the all-provider view. + // The CLI includes zero-cost providers in the payload for completeness, so + // filtering on value > 0 keeps the tab row honest and avoids showing tabs + // for tools the user hasn't run yet. + let activeKeys = Set( + allProvidersToday.current.providers + .filter { $0.value > 0 } + .keys + .map { $0.lowercased() } + ) return ProviderFilter.allCases.filter { filter in if filter == .all { return true } return activeKeys.contains(filter.rawValue.lowercased()) @@ -87,6 +96,8 @@ extension ProviderFilter { case .codex: return Theme.categoricalCodex case .cursor: return Theme.categoricalCursor case .copilot: return Color(red: 0x6D/255.0, green: 0x8F/255.0, blue: 0xA6/255.0) + case .opencode: return Color(red: 0x5B/255.0, green: 0x83/255.0, blue: 0x5B/255.0) + case .pi: return Color(red: 0xB2/255.0, green: 0x6B/255.0, blue: 0x3D/255.0) } } } diff --git a/mac/Sources/CodeBurnMenubar/Views/MenuBarContent.swift b/mac/Sources/CodeBurnMenubar/Views/MenuBarContent.swift index b6c550d..3c08c27 100644 --- a/mac/Sources/CodeBurnMenubar/Views/MenuBarContent.swift +++ b/mac/Sources/CodeBurnMenubar/Views/MenuBarContent.swift @@ -11,9 +11,10 @@ struct MenuBarContent: View { Divider() - AgentTabStrip() - - Divider() + if showAgentTabs { + AgentTabStrip() + Divider() + } ZStack { ScrollView(.vertical, showsIndicators: false) { @@ -63,6 +64,15 @@ struct MenuBarContent: View { return store.payload.current.cost <= 0 && store.payload.current.calls == 0 } + /// Only show the tab row when two or more providers have non-zero spend. One + /// provider means the tabs are redundant (the All tab already shows it); zero + /// providers means the popover has nothing to filter. + private var showAgentTabs: Bool { + let payload = store.todayPayload ?? store.payload + let active = payload.current.providers.values.filter { $0 > 0 } + return active.count >= 2 + } + } private struct EmptyProviderState: View { From 9483d66e654d42c0f5dce329eb6c5769e9a3b952 Mon Sep 17 00:00:00 2001 From: AgentSeal Date: Sat, 18 Apr 2026 06:54:06 -0700 Subject: [PATCH 52/70] fix(mac): restore agent tab strip to show all detected providers Tabs were filtering on `value > 0` (today's spend), which hid the row whenever only one provider had activity today. The CLI's providers map already contains only providers detected on the system, so showing the map as-is matches user intent: a tab for each installed tool, regardless of today's spend. Tab strip only hides when nothing is detected. This also makes the Plan pill reachable again: it gates on `selectedProvider == .claude`, which required clicking the Claude tab to select. --- .../CodeBurnMenubar/Views/AgentTabStrip.swift | 17 +++++++---------- .../CodeBurnMenubar/Views/MenuBarContent.swift | 9 ++++----- 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/mac/Sources/CodeBurnMenubar/Views/AgentTabStrip.swift b/mac/Sources/CodeBurnMenubar/Views/AgentTabStrip.swift index 885bdcc..e4522dd 100644 --- a/mac/Sources/CodeBurnMenubar/Views/AgentTabStrip.swift +++ b/mac/Sources/CodeBurnMenubar/Views/AgentTabStrip.swift @@ -33,19 +33,16 @@ struct AgentTabStrip: View { } private var visibleFilters: [ProviderFilter] { - // Only surface providers that actually spent money in the all-provider view. - // The CLI includes zero-cost providers in the payload for completeness, so - // filtering on value > 0 keeps the tab row honest and avoids showing tabs - // for tools the user hasn't run yet. - let activeKeys = Set( - allProvidersToday.current.providers - .filter { $0.value > 0 } - .keys - .map { $0.lowercased() } + // Show a tab for every provider detected on this machine. The CLI decides what + // to include in the providers map based on session dirs / credential files it + // finds, so zero-cost-today is still "installed" and the user expects to see + // it. Only providers that aren't installed at all are absent from the map. + let detectedKeys = Set( + allProvidersToday.current.providers.keys.map { $0.lowercased() } ) return ProviderFilter.allCases.filter { filter in if filter == .all { return true } - return activeKeys.contains(filter.rawValue.lowercased()) + return detectedKeys.contains(filter.rawValue.lowercased()) } } diff --git a/mac/Sources/CodeBurnMenubar/Views/MenuBarContent.swift b/mac/Sources/CodeBurnMenubar/Views/MenuBarContent.swift index 3c08c27..a07532d 100644 --- a/mac/Sources/CodeBurnMenubar/Views/MenuBarContent.swift +++ b/mac/Sources/CodeBurnMenubar/Views/MenuBarContent.swift @@ -64,13 +64,12 @@ struct MenuBarContent: View { return store.payload.current.cost <= 0 && store.payload.current.calls == 0 } - /// Only show the tab row when two or more providers have non-zero spend. One - /// provider means the tabs are redundant (the All tab already shows it); zero - /// providers means the popover has nothing to filter. + /// Show the tab row whenever the CLI detected at least one AI coding tool installed + /// on this machine. Hidden only when nothing is detected, which means there's + /// nothing to filter by anyway. private var showAgentTabs: Bool { let payload = store.todayPayload ?? store.payload - let active = payload.current.providers.values.filter { $0 > 0 } - return active.count >= 2 + return !payload.current.providers.isEmpty } } From 43a938ff9eb06c2a990fda7534e60f7a977ff985 Mon Sep 17 00:00:00 2001 From: AgentSeal Date: Sat, 18 Apr 2026 06:54:57 -0700 Subject: [PATCH 53/70] feat(mac): add Connect Claude button to Plan pane The Plan pane previously told users to "run claude login in your terminal, then retry" with no way to start the flow from the app. Added a primary Connect Claude button on both the no-credentials and failed states that launches Terminal.app with `claude login`, so the OAuth flow is one click away. TerminalLauncher.openClaudeLogin() uses a hardcoded literal, so no user input reaches AppleScript. Refactored the common path into runInTerminal(command:preValidated:) which re-validates any non- literal input against CodeburnCLI.isSafe as defense-in-depth. On machines without Terminal.app (iTerm/Ghostty/Warp), the button surfaces an inline instruction to run `claude login` manually instead of failing silently. --- .../Security/TerminalLauncher.swift | 51 ++++++++++++---- .../Views/HeatmapSection.swift | 60 ++++++++++++++----- 2 files changed, 84 insertions(+), 27 deletions(-) diff --git a/mac/Sources/CodeBurnMenubar/Security/TerminalLauncher.swift b/mac/Sources/CodeBurnMenubar/Security/TerminalLauncher.swift index 09f8dad..9d0b3e7 100644 --- a/mac/Sources/CodeBurnMenubar/Security/TerminalLauncher.swift +++ b/mac/Sources/CodeBurnMenubar/Security/TerminalLauncher.swift @@ -1,9 +1,11 @@ import AppKit import Foundation -/// Opens a codeburn subcommand in the user's Terminal. The argv is validated through -/// `CodeburnCLI.isSafe` before it's interpolated into AppleScript so there's no path for a -/// rogue environment variable to smuggle shell metacharacters into the `do script` call. +/// Runs commands in the user's Terminal. Every string that reaches AppleScript `do script` +/// must be whitespace-joined argv where each token passes `CodeburnCLI.isSafe` (regex allowlist +/// that excludes shell metacharacters), OR a hardcoded literal defined here. The private +/// `runInTerminal` re-validates any non-literal input defensively so a future caller can't +/// bypass the invariant. /// Falls back to a detached headless spawn on machines without Terminal.app (iTerm/Ghostty/Warp /// users) so the subcommand still runs. enum TerminalLauncher { @@ -21,20 +23,43 @@ enum TerminalLauncher { let command = argv.joined(separator: " ") if terminalPaths.contains(where: FileManager.default.fileExists(atPath:)) { - let script = """ - tell application "Terminal" - activate - do script "\(command)" - end tell - """ - let process = Process() - process.executableURL = URL(fileURLWithPath: "/usr/bin/osascript") - process.arguments = ["-e", script] - try? process.run() + runInTerminal(command: command, preValidated: true) return } let headless = CodeburnCLI.makeProcess(subcommand: subcommand) try? headless.run() } + + /// Launches `claude login` in Terminal.app so the user can complete the OAuth flow + /// without leaving CodeBurn. The command is a hardcoded literal -- no user input is + /// interpolated, so there's no injection surface. + static func openClaudeLogin() -> Bool { + guard terminalPaths.contains(where: FileManager.default.fileExists(atPath:)) else { + NSLog("CodeBurn: Terminal.app not present; user must run `claude login` manually") + return false + } + runInTerminal(command: "claude login", preValidated: true) + return true + } + + private static func runInTerminal(command: String, preValidated: Bool) { + if !preValidated { + let tokens = command.split(separator: " ", omittingEmptySubsequences: true).map(String.init) + guard tokens.allSatisfy(CodeburnCLI.isSafe) else { + NSLog("CodeBurn: refusing to run unvalidated command in Terminal") + return + } + } + let script = """ + tell application "Terminal" + activate + do script "\(command)" + end tell + """ + let process = Process() + process.executableURL = URL(fileURLWithPath: "/usr/bin/osascript") + process.arguments = ["-e", script] + try? process.run() + } } diff --git a/mac/Sources/CodeBurnMenubar/Views/HeatmapSection.swift b/mac/Sources/CodeBurnMenubar/Views/HeatmapSection.swift index 6466ad0..ed9a03b 100644 --- a/mac/Sources/CodeBurnMenubar/Views/HeatmapSection.swift +++ b/mac/Sources/CodeBurnMenubar/Views/HeatmapSection.swift @@ -1039,6 +1039,7 @@ private struct PlanLoadingView: View { private struct PlanNoCredentialsView: View { @Environment(AppStore.self) private var store + @State private var showManualFallback = false var body: some View { VStack(spacing: 8) { @@ -1048,16 +1049,32 @@ private struct PlanNoCredentialsView: View { Text("No Claude subscription connected") .font(.system(size: 12, weight: .semibold)) .foregroundStyle(.primary) - Text("Run `claude login` in your terminal, then retry.") - .font(.system(size: 10.5)) - .foregroundStyle(.secondary) - .multilineTextAlignment(.center) - .frame(maxWidth: 260) - Button("Retry") { - Task { await store.refreshSubscription() } + if showManualFallback { + Text("Terminal.app isn't available. Open your terminal and run `claude login`, then click Retry.") + .font(.system(size: 10.5)) + .foregroundStyle(.secondary) + .multilineTextAlignment(.center) + .frame(maxWidth: 280) + } else { + Text("Click Connect to sign in with Claude, then return here.") + .font(.system(size: 10.5)) + .foregroundStyle(.secondary) + .multilineTextAlignment(.center) + .frame(maxWidth: 260) + } + HStack(spacing: 8) { + Button("Connect Claude") { + if !TerminalLauncher.openClaudeLogin() { showManualFallback = true } + } + .controlSize(.small) + .buttonStyle(.borderedProminent) + .tint(Theme.brandAccent) + Button("Retry") { + Task { await store.refreshSubscription() } + } + .controlSize(.small) + .buttonStyle(.bordered) } - .controlSize(.small) - .buttonStyle(.bordered) } .frame(maxWidth: .infinity) .padding(.vertical, 14) @@ -1067,6 +1084,7 @@ private struct PlanNoCredentialsView: View { private struct PlanFailedView: View { @Environment(AppStore.self) private var store let error: String? + @State private var showManualFallback = false var body: some View { VStack(spacing: 8) { @@ -1076,7 +1094,13 @@ private struct PlanFailedView: View { Text("Couldn't load plan data") .font(.system(size: 12, weight: .semibold)) .foregroundStyle(.primary) - if let error { + if showManualFallback { + Text("Terminal.app isn't available. Open your terminal and run `claude login`, then click Retry.") + .font(.system(size: 10.5)) + .foregroundStyle(.secondary) + .multilineTextAlignment(.center) + .frame(maxWidth: 280) + } else if let error { Text(error) .font(.system(size: 10)) .foregroundStyle(.tertiary) @@ -1084,11 +1108,19 @@ private struct PlanFailedView: View { .frame(maxWidth: 280) .lineLimit(3) } - Button("Retry") { - Task { await store.refreshSubscription() } + HStack(spacing: 8) { + Button("Reconnect Claude") { + if !TerminalLauncher.openClaudeLogin() { showManualFallback = true } + } + .controlSize(.small) + .buttonStyle(.borderedProminent) + .tint(Theme.brandAccent) + Button("Retry") { + Task { await store.refreshSubscription() } + } + .controlSize(.small) + .buttonStyle(.bordered) } - .controlSize(.small) - .buttonStyle(.bordered) } .frame(maxWidth: .infinity) .padding(.vertical, 14) From d80f68928bd57a17d3adafa0e94142fc68c608bc Mon Sep 17 00:00:00 2001 From: AgentSeal Date: Sat, 18 Apr 2026 07:43:06 -0700 Subject: [PATCH 54/70] ci: add npm OIDC trusted-publish workflow Triggers on v* tag push or manual dispatch. Builds, tests, then publishes codeburn to npm with provenance attestation. Uses OIDC so no NPM_TOKEN is stored in repo secrets. The npm-publish GitHub Environment gates the publish step behind a required reviewer, so every release needs explicit human approval before it reaches the registry. Tag/package version mismatch fails fast before any build work. Tests run before publish to prevent shipping a broken release. --- .github/workflows/publish-npm.yml | 50 +++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 .github/workflows/publish-npm.yml diff --git a/.github/workflows/publish-npm.yml b/.github/workflows/publish-npm.yml new file mode 100644 index 0000000..3f6bcbf --- /dev/null +++ b/.github/workflows/publish-npm.yml @@ -0,0 +1,50 @@ +name: Publish to npm + +# Triggers when a semver tag (v*) is pushed. Publishes `codeburn` to the npm +# registry using npm OIDC trusted publishing, so no NPM_TOKEN lives in +# secrets. The `npm-publish` Environment requires a human approval before +# the publish step runs. +on: + push: + tags: + - 'v*' + workflow_dispatch: + +permissions: + contents: read + id-token: write # Required for npm OIDC provenance + +jobs: + publish: + runs-on: ubuntu-latest + environment: npm-publish + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '22' + registry-url: 'https://registry.npmjs.org' + + - name: Verify tag matches package.json + run: | + TAG_VERSION="${GITHUB_REF#refs/tags/v}" + PKG_VERSION=$(node -p "require('./package.json').version") + if [[ "$TAG_VERSION" != "$PKG_VERSION" ]]; then + echo "Tag version ($TAG_VERSION) does not match package.json version ($PKG_VERSION)" >&2 + exit 1 + fi + + - name: Install dependencies + run: npm ci + + - name: Build + run: npm run build + + - name: Run tests + run: npm test -- --run + + - name: Publish with provenance + run: npm publish --provenance --access public From e834f64c225d84755dae51c66b073e39c5ca8846 Mon Sep 17 00:00:00 2001 From: AgentSeal Date: Sat, 18 Apr 2026 09:02:48 -0700 Subject: [PATCH 55/70] ci: block Co-authored-by Claude/Anthropic trailers on PRs New GitHub Actions check that scans every PR commit for `Co-authored-by: ... claude ...` or `... anthropic ...` trailers and fails the PR with a clear remediation message if found. Contributors can still use AI tools; the trailer attribution must be removed before the PR is eligible to merge, consistent with the project contributor guidelines. The workflow scans only commits introduced by the PR (base.sha..head.sha), so existing history is untouched. --- .github/workflows/block-claude-coauthor.yml | 43 +++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 .github/workflows/block-claude-coauthor.yml diff --git a/.github/workflows/block-claude-coauthor.yml b/.github/workflows/block-claude-coauthor.yml new file mode 100644 index 0000000..c587da2 --- /dev/null +++ b/.github/workflows/block-claude-coauthor.yml @@ -0,0 +1,43 @@ +name: Block Claude / Anthropic co-author trailers + +# Rejects PRs that contain a `Co-authored-by: ... claude ...` or `... anthropic ...` +# trailer in any of their commits. Contributors can still use AI tools to help +# write code, but they must remove the co-author attribution before the PR is +# eligible to merge, per the project's contributor guidelines. + +on: + pull_request: + types: [opened, synchronize, reopened] + +jobs: + check: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Scan PR commits for disallowed co-author trailers + run: | + BASE_SHA="${{ github.event.pull_request.base.sha }}" + HEAD_SHA="${{ github.event.pull_request.head.sha }}" + FOUND=0 + while IFS= read -r c; do + [ -z "$c" ] && continue + SUBJECT=$(git log -1 "$c" --format=%s) + if git log -1 "$c" --format="%B" | grep -qiE 'co-authored-by:.*(claude|anthropic)'; then + echo "::error::Commit $c ($SUBJECT) has a Claude/Anthropic co-author trailer. Please remove it before this PR can merge." + FOUND=1 + fi + done < <(git log --format=%H "$BASE_SHA".."$HEAD_SHA") + if [ "$FOUND" != "0" ]; then + echo "" + echo "How to fix:" + echo " 1. Run: git rebase -i $BASE_SHA" + echo " 2. Mark each flagged commit as 'reword'" + echo " 3. Delete the Co-authored-by line from the commit message" + echo " 4. Save, then: git push --force-with-lease" + exit 1 + fi + echo "No disallowed co-author trailers found." From c90340f205204e581d0d87a506f8e268997dbdb2 Mon Sep 17 00:00:00 2001 From: AgentSeal Date: Sat, 18 Apr 2026 09:08:43 -0700 Subject: [PATCH 56/70] chore: ignore local Discord brand assets Adds `assets/discord-*.png` to .gitignore so local promo/branding assets that aren't ready to publish don't show up as untracked noise in `git status`. Any Discord asset that should be tracked later can be added with `git add -f`. --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 110cddd..23a5028 100644 --- a/.gitignore +++ b/.gitignore @@ -33,3 +33,6 @@ npm-debug.log* # Build artifacts *.tsbuildinfo + +# Local Discord brand / promo assets not yet ready to publish +assets/discord-*.png From 46f72ba348cf986c588fbc7c2af232ba5d67116d Mon Sep 17 00:00:00 2001 From: AgentSeal Date: Sat, 18 Apr 2026 09:25:59 -0700 Subject: [PATCH 57/70] chore: bump to 0.7.4-rc.0 for OIDC test publish Pre-release bump to validate npm OIDC trusted publishing end to end: workflow trigger, Environment approval gate, Trusted Publisher match, provenance attestation. Will not be tagged as `latest` on npm (npm auto-excludes SemVer pre-releases from dist-tags). After this RC succeeds, cut 0.7.4 proper. --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8911286..d5092e1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "codeburn", - "version": "0.7.3", + "version": "0.7.4-rc.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "codeburn", - "version": "0.7.3", + "version": "0.7.4-rc.0", "license": "MIT", "dependencies": { "chalk": "^5.4.1", diff --git a/package.json b/package.json index 3820034..727ddad 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "codeburn", - "version": "0.7.3", + "version": "0.7.4-rc.0", "description": "See where your AI coding tokens go - by task, tool, model, and project", "type": "module", "main": "./dist/cli.js", From 832dd4ada141a131b544be81caa38fec1e5ae9f5 Mon Sep 17 00:00:00 2001 From: AgentSeal Date: Sat, 18 Apr 2026 09:33:52 -0700 Subject: [PATCH 58/70] fix(ci): upgrade npm to 11.5.1+ for OIDC trusted publishing Node 22 ships with npm 10.x, which does not know how to exchange the GitHub OIDC id-token for a short-lived npm token. Without this upgrade, the publish step silently falls back to the empty NODE_AUTH_TOKEN that setup-node writes to .npmrc, and the registry returns 404. First test publish (v0.7.4-rc.0) failed at exactly this point, even though provenance signing via sigstore succeeded, confirming the OIDC handshake with GitHub was fine and only the npm-side auth was broken. Fix: `npm install -g npm@latest` before the publish step. Adds ~5s to runtime. --- .github/workflows/publish-npm.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/workflows/publish-npm.yml b/.github/workflows/publish-npm.yml index 3f6bcbf..30db2dd 100644 --- a/.github/workflows/publish-npm.yml +++ b/.github/workflows/publish-npm.yml @@ -28,6 +28,13 @@ jobs: node-version: '22' registry-url: 'https://registry.npmjs.org' + - name: Upgrade npm for trusted publishing + # Node 22 ships with npm 10.x; npm OIDC trusted publishing requires + # npm 11.5.1+. Without this, the publish step silently falls back + # to the empty NODE_AUTH_TOKEN written by setup-node and the + # registry returns 404. + run: npm install -g npm@latest + - name: Verify tag matches package.json run: | TAG_VERSION="${GITHUB_REF#refs/tags/v}" From e7f1b33196e423460ee5e39bfa1a901f815786e4 Mon Sep 17 00:00:00 2001 From: AgentSeal Date: Sat, 18 Apr 2026 09:36:38 -0700 Subject: [PATCH 59/70] chore: bump to 0.7.4-rc.1 for OIDC retry after npm upgrade fix --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index d5092e1..c589d6c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "codeburn", - "version": "0.7.4-rc.0", + "version": "0.7.4-rc.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "codeburn", - "version": "0.7.4-rc.0", + "version": "0.7.4-rc.1", "license": "MIT", "dependencies": { "chalk": "^5.4.1", diff --git a/package.json b/package.json index 727ddad..4e9ce4a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "codeburn", - "version": "0.7.4-rc.0", + "version": "0.7.4-rc.1", "description": "See where your AI coding tokens go - by task, tool, model, and project", "type": "module", "main": "./dist/cli.js", From 4fccca47d21393013f5d268d0eb7e84145c57d07 Mon Sep 17 00:00:00 2001 From: AgentSeal Date: Sat, 18 Apr 2026 09:46:13 -0700 Subject: [PATCH 60/70] fix(ci): use Node 24 for npm OIDC trusted publishing Node 22 on GitHub's hosted runners currently pins to a broken npm 10.9.7 whose internal `promise-retry` module is missing from the toolcache (runner-images#13883, nodejs/node#62430). Self-upgrading via `npm install -g npm@latest` crashes before the install can run, because `@npmcli/arborist` cannot start without that module. Node 24 LTS bundles npm 11.x natively, which supports OIDC trusted publishing out of the box (minimum is 11.5.1, per npm docs). Bumping the runtime lets us delete the fragile upgrade step entirely. Test: tag `v0.7.4-rc.2` after merge to validate the flow publishes successfully with provenance. --- .github/workflows/publish-npm.yml | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/.github/workflows/publish-npm.yml b/.github/workflows/publish-npm.yml index 30db2dd..acd3208 100644 --- a/.github/workflows/publish-npm.yml +++ b/.github/workflows/publish-npm.yml @@ -25,16 +25,15 @@ jobs: - name: Setup Node.js uses: actions/setup-node@v4 with: - node-version: '22' + # Node 24 (LTS) ships with npm 11.x, which supports OIDC trusted + # publishing natively. Node 22 on GitHub hosted runners currently + # pins to a broken npm 10.9.7 (runner-images#13883) and any + # self-upgrade from within that toolcache crashes on a missing + # promise-retry module, so bumping the runtime is the cleanest + # fix. + node-version: '24' registry-url: 'https://registry.npmjs.org' - - name: Upgrade npm for trusted publishing - # Node 22 ships with npm 10.x; npm OIDC trusted publishing requires - # npm 11.5.1+. Without this, the publish step silently falls back - # to the empty NODE_AUTH_TOKEN written by setup-node and the - # registry returns 404. - run: npm install -g npm@latest - - name: Verify tag matches package.json run: | TAG_VERSION="${GITHUB_REF#refs/tags/v}" From 35d4d32955d516606d1eecf806f7f6e6982d5948 Mon Sep 17 00:00:00 2001 From: AgentSeal Date: Sat, 18 Apr 2026 09:47:21 -0700 Subject: [PATCH 61/70] chore: bump to 0.7.4-rc.2 for Node 24 OIDC retry --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index c589d6c..dc3eb7f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "codeburn", - "version": "0.7.4-rc.1", + "version": "0.7.4-rc.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "codeburn", - "version": "0.7.4-rc.1", + "version": "0.7.4-rc.2", "license": "MIT", "dependencies": { "chalk": "^5.4.1", diff --git a/package.json b/package.json index 4e9ce4a..5ba9b56 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "codeburn", - "version": "0.7.4-rc.1", + "version": "0.7.4-rc.2", "description": "See where your AI coding tokens go - by task, tool, model, and project", "type": "module", "main": "./dist/cli.js", From 9ac2144950791cde33116959f8c3b2642b5ad89d Mon Sep 17 00:00:00 2001 From: AgentSeal Date: Sat, 18 Apr 2026 09:51:58 -0700 Subject: [PATCH 62/70] revert: remove npm OIDC publish workflow Three consecutive failed publish attempts on a live repo are not acceptable. Reverting to manual `npm publish` from the laptop, which has always worked. OIDC can be revisited later in a staging environment, not on the production package. --- .github/workflows/publish-npm.yml | 56 ------------------------------- 1 file changed, 56 deletions(-) delete mode 100644 .github/workflows/publish-npm.yml diff --git a/.github/workflows/publish-npm.yml b/.github/workflows/publish-npm.yml deleted file mode 100644 index acd3208..0000000 --- a/.github/workflows/publish-npm.yml +++ /dev/null @@ -1,56 +0,0 @@ -name: Publish to npm - -# Triggers when a semver tag (v*) is pushed. Publishes `codeburn` to the npm -# registry using npm OIDC trusted publishing, so no NPM_TOKEN lives in -# secrets. The `npm-publish` Environment requires a human approval before -# the publish step runs. -on: - push: - tags: - - 'v*' - workflow_dispatch: - -permissions: - contents: read - id-token: write # Required for npm OIDC provenance - -jobs: - publish: - runs-on: ubuntu-latest - environment: npm-publish - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - # Node 24 (LTS) ships with npm 11.x, which supports OIDC trusted - # publishing natively. Node 22 on GitHub hosted runners currently - # pins to a broken npm 10.9.7 (runner-images#13883) and any - # self-upgrade from within that toolcache crashes on a missing - # promise-retry module, so bumping the runtime is the cleanest - # fix. - node-version: '24' - registry-url: 'https://registry.npmjs.org' - - - name: Verify tag matches package.json - run: | - TAG_VERSION="${GITHUB_REF#refs/tags/v}" - PKG_VERSION=$(node -p "require('./package.json').version") - if [[ "$TAG_VERSION" != "$PKG_VERSION" ]]; then - echo "Tag version ($TAG_VERSION) does not match package.json version ($PKG_VERSION)" >&2 - exit 1 - fi - - - name: Install dependencies - run: npm ci - - - name: Build - run: npm run build - - - name: Run tests - run: npm test -- --run - - - name: Publish with provenance - run: npm publish --provenance --access public From c83a12efed7ecbfdcc11ba49c3763b186f42cdf2 Mon Sep 17 00:00:00 2001 From: AgentSeal Date: Sat, 18 Apr 2026 09:54:03 -0700 Subject: [PATCH 63/70] chore: reset version to 0.7.3 to match published npm --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index dc3eb7f..8911286 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "codeburn", - "version": "0.7.4-rc.2", + "version": "0.7.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "codeburn", - "version": "0.7.4-rc.2", + "version": "0.7.3", "license": "MIT", "dependencies": { "chalk": "^5.4.1", diff --git a/package.json b/package.json index 5ba9b56..3820034 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "codeburn", - "version": "0.7.4-rc.2", + "version": "0.7.3", "description": "See where your AI coding tokens go - by task, tool, model, and project", "type": "module", "main": "./dist/cli.js", From 7ee8b679f9296e3e7f67608256700c9d4fa6a97a Mon Sep 17 00:00:00 2001 From: AgentSeal Date: Sat, 18 Apr 2026 12:58:50 -0700 Subject: [PATCH 64/70] fix(mac): keep (today, all) cache fresh for menubar title and tab labels The refresh loop previously skipped `refreshQuietly(.today)` when the user was already viewing the Today period. That guard meant while the user was on (today, claude) or any other non-.all provider, the (today, all) cache went stale. The menubar title and the agent tab strip both read from that cache, so they displayed stale costs while the hero section (which reads the currently-viewed payload) showed the correct fresh value. Remove the guard so the (today, all) cache refreshes every cycle regardless of the currently selected period/provider. Shipped as mac-v0.7.4. --- mac/Sources/CodeBurnMenubar/CodeBurnApp.swift | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/mac/Sources/CodeBurnMenubar/CodeBurnApp.swift b/mac/Sources/CodeBurnMenubar/CodeBurnApp.swift index 9a18364..87d2341 100644 --- a/mac/Sources/CodeBurnMenubar/CodeBurnApp.swift +++ b/mac/Sources/CodeBurnMenubar/CodeBurnApp.swift @@ -73,10 +73,13 @@ final class AppDelegate: NSObject, NSApplicationDelegate, NSPopoverDelegate { refreshTask = Task { [weak self] in while !Task.isCancelled { guard let self else { return } - if self.store.selectedPeriod != .today { - await self.store.refreshQuietly(period: .today) - } - // Optimize is fast (~1s warm-cache) so include findings on every refresh. + // Always keep the (today, all) payload warm. The menubar title and the + // agent tab strip both read from it, so it has to refresh every cycle + // regardless of whether the user is currently viewing Today or a + // different period / provider. + await self.store.refreshQuietly(period: .today) + // Refresh the currently-viewed payload. Optimize is fast (~1s warm-cache) + // so include findings on every refresh. await self.store.refresh(includeOptimize: true) try? await Task.sleep(nanoseconds: refreshIntervalNanos) } From 94240f53410311b7a3a5d3af24ec5e08d22aa5f4 Mon Sep 17 00:00:00 2001 From: AgentSeal Date: Sat, 18 Apr 2026 13:18:11 -0700 Subject: [PATCH 65/70] fix(mac): show correct cost in trend tooltip for per-provider views The trend chart tooltip always displayed `bar.tokens` in its header, which is zero for provider-filtered history (the CLI only carries per-provider cost+calls in the daily cache, not tokens). Result: when you selected Claude/Codex/Cursor/Pi, hovering a bar showed $0.00 even on days with real spend. The trend chart's main metric already falls back to cost when tokens are zero. Pass that same metric value through to the tooltip so both stay consistent. Also removed the misleading "No model breakdown available" fallback line. For provider-filtered views the per-model breakdown legitimately doesn't exist in the payload, so the tooltip now just shows date + cost without the error-sounding message. --- .../CodeBurnMenubar/Views/HeatmapSection.swift | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/mac/Sources/CodeBurnMenubar/Views/HeatmapSection.swift b/mac/Sources/CodeBurnMenubar/Views/HeatmapSection.swift index ed9a03b..8b64e2b 100644 --- a/mac/Sources/CodeBurnMenubar/Views/HeatmapSection.swift +++ b/mac/Sources/CodeBurnMenubar/Views/HeatmapSection.swift @@ -209,7 +209,7 @@ private struct TrendChart: View { // Floats below the chart without taking layout space. Opaque dark card hides // whatever sits beneath it (mini stats, activity rows). if let hoveredBar { - BarTooltipCard(bar: hoveredBar, formatValue: formatValue) + BarTooltipCard(bar: hoveredBar, value: metric(hoveredBar), formatValue: formatValue) .padding(.top, 6) .offset(y: 92) .transition(.opacity) @@ -260,6 +260,12 @@ private struct BarColumn: View { private struct BarTooltipCard: View { let bar: TrendBar + /// Value to display in the tooltip header. Matches the metric the trend chart + /// is currently using (tokens when the .all-providers view has token data, + /// cost when provider-filtered views force a $ fallback). Passing this in keeps + /// the tooltip in sync with the chart instead of always reading bar.tokens, + /// which is zero for provider-filtered days. + let value: Double let formatValue: (Double) -> String @Environment(\.colorScheme) private var colorScheme @@ -290,7 +296,7 @@ private struct BarTooltipCard: View { .font(.system(size: 11, weight: .semibold)) .foregroundStyle(primaryText) Spacer() - Text("\(formatValue(bar.tokens))") + Text("\(formatValue(value))") .font(.codeMono(size: 10.5, weight: .semibold)) .foregroundStyle(Theme.brandAccent) } @@ -313,10 +319,6 @@ private struct BarTooltipCard: View { } } } - } else { - Text("No model breakdown available") - .font(.system(size: 10)) - .foregroundStyle(tertiaryText) } } .padding(11) From a031c8d32dbc5130a1659d18d81f2843a960d629 Mon Sep 17 00:00:00 2001 From: AgentSeal Date: Sat, 18 Apr 2026 14:55:44 -0700 Subject: [PATCH 66/70] chore: point repo URLs at getagentseal org (#97) Add package.json repository/bugs/homepage fields. Swap hardcoded AgentSeal/codeburn URLs to getagentseal/codeburn across README, mac README, macOS menubar star banner, and the menubar installer's release-API endpoint. 301 redirects keep old URLs working, but canonical links now point at the current org. Co-authored-by: AgentSeal --- README.md | 12 ++++++------ mac/README.md | 2 +- .../CodeBurnMenubar/Views/MenuBarContent.swift | 2 +- package.json | 8 ++++++++ src/menubar-installer.ts | 4 ++-- 5 files changed, 18 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 79aa754..a88949d 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@

    - CodeBurn + CodeBurn

    CodeBurn

    @@ -11,12 +11,12 @@
    total downloads monthly downloads install size - license - node version + license + node version

    - CodeBurn TUI dashboard + CodeBurn TUI dashboard

    By task type, tool, model, MCP server, and project. Supports **Claude Code**, **Codex** (OpenAI), **Cursor**, **OpenCode**, **Pi**, and **GitHub Copilot** with a provider plugin system. Tracks one-shot success rate per activity type so you can see where the AI nails it first try vs. burns tokens on edit/test/fix retries. Interactive TUI dashboard with gradient charts, responsive panels, and keyboard navigation. Native macOS menubar app in `mac/`. CSV/JSON export. @@ -156,7 +156,7 @@ The menu bar widget includes a currency picker with 17 common currencies. For an ## Menu Bar -CodeBurn macOS menubar app +CodeBurn macOS menubar app ```bash npx codeburn menubar @@ -212,7 +212,7 @@ These are starting points, not verdicts. A 60% cache hit on a single experimenta Once you know what to look for, `codeburn optimize` scans your sessions and your `~/.claude/` setup for the most common waste patterns and hands back exact, copy-paste fixes. It never writes to your files.

    - CodeBurn optimize output + CodeBurn optimize output

    ```bash diff --git a/mac/README.md b/mac/README.md index 4d3e2ae..3a7f1d7 100644 --- a/mac/README.md +++ b/mac/README.md @@ -26,7 +26,7 @@ For contributors running a local build instead of the packaged release: ```bash npm install -g codeburn # CLI the app shells out to for data -git clone https://github.com/AgentSeal/codeburn.git +git clone https://github.com/getagentseal/codeburn.git cd codeburn/mac swift build -c release .build/release/CodeBurnMenubar # launch diff --git a/mac/Sources/CodeBurnMenubar/Views/MenuBarContent.swift b/mac/Sources/CodeBurnMenubar/Views/MenuBarContent.swift index a07532d..a295067 100644 --- a/mac/Sources/CodeBurnMenubar/Views/MenuBarContent.swift +++ b/mac/Sources/CodeBurnMenubar/Views/MenuBarContent.swift @@ -221,7 +221,7 @@ struct FlameMark: View { } } -private let starBannerGitHubURL = URL(string: "https://github.com/AgentSeal/codeburn")! +private let starBannerGitHubURL = URL(string: "https://github.com/getagentseal/codeburn")! /// Shown at the very bottom on first launch. A small terracotta strip nudges users to star the /// repo; clicking opens GitHub, clicking the close icon hides it forever (persisted to diff --git a/package.json b/package.json index 3820034..f7aa295 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,14 @@ }, "author": "AgentSeal ", "license": "MIT", + "repository": { + "type": "git", + "url": "git+https://github.com/getagentseal/codeburn.git" + }, + "bugs": { + "url": "https://github.com/getagentseal/codeburn/issues" + }, + "homepage": "https://github.com/getagentseal/codeburn#readme", "dependencies": { "chalk": "^5.4.1", "commander": "^13.1.0", diff --git a/src/menubar-installer.ts b/src/menubar-installer.ts index 53265c5..3557141 100644 --- a/src/menubar-installer.ts +++ b/src/menubar-installer.ts @@ -8,7 +8,7 @@ import { Readable } from 'node:stream' /// Public GitHub repo that hosts signed macOS release builds. `/releases/latest` returns the /// newest tagged release; we filter its assets list for our zipped .app bundle. -const RELEASE_API = 'https://api.github.com/repos/AgentSeal/codeburn/releases/latest' +const RELEASE_API = 'https://api.github.com/repos/getagentseal/codeburn/releases/latest' const APP_BUNDLE_NAME = 'CodeBurnMenubar.app' const ASSET_PATTERN = /^CodeBurnMenubar-.*\.zip$/ const APP_PROCESS_NAME = 'CodeBurnMenubar' @@ -73,7 +73,7 @@ async function fetchLatestReleaseAsset(): Promise { if (!asset) { throw new Error( `No ${APP_BUNDLE_NAME} zip found in release ${body.tag_name}. ` + - `Check https://github.com/AgentSeal/codeburn/releases.` + `Check https://github.com/getagentseal/codeburn/releases.` ) } return asset From 5932a273a18ecf19979e5f0b4542cb537729842d Mon Sep 17 00:00:00 2001 From: Ninym <80782621+lfl1337@users.noreply.github.com> Date: Sun, 19 Apr 2026 00:10:24 +0200 Subject: [PATCH 67/70] chore(ci): add semgrep guard against prototype pollution regressions in provider hot paths (#78) * chore(ci): add semgrep rule no-bracket-assign-on-literal-object-map * chore(ci): add workflow running semgrep bracket-assign guard on push/PR * fix(parser): use Object.create(null) for categoryBreakdown map * chore(ci): expand semgrep rule to cover ||, ??=, and if-guard variants * chore(ci): limit push trigger to main and add semgrep --strict * chore(ci): use jq to enforce finding count (--error unreliable in semgrep 1.x) --- .github/workflows/ci.yml | 27 +++++++++++++++++++ .../rules/no-bracket-assign-hot-paths.yml | 22 +++++++++++++++ src/parser.ts | 2 +- 3 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/ci.yml create mode 100644 .semgrep/rules/no-bracket-assign-hot-paths.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..5233243 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,27 @@ +name: CI + +on: + push: + branches: [main] + pull_request: + +jobs: + semgrep: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Install Semgrep + run: pip install semgrep + + - name: Run Semgrep bracket-assign guard + run: | + set -e + semgrep --config .semgrep/rules/no-bracket-assign-hot-paths.yml \ + --strict --json \ + src/providers/ src/parser.ts > semgrep-out.json + FINDINGS=$(jq '.results | length' semgrep-out.json) + if [ "$FINDINGS" -gt 0 ]; then + jq -r '.results[] | "::error file=\(.path),line=\(.start.line)::\(.extra.message)"' semgrep-out.json + exit 1 + fi diff --git a/.semgrep/rules/no-bracket-assign-hot-paths.yml b/.semgrep/rules/no-bracket-assign-hot-paths.yml new file mode 100644 index 0000000..e2e633d --- /dev/null +++ b/.semgrep/rules/no-bracket-assign-hot-paths.yml @@ -0,0 +1,22 @@ +rules: + - id: no-bracket-assign-on-literal-object-map + languages: [typescript] + severity: ERROR + message: > + Bracket-assign on a map created with `{}` allows prototype pollution when + the key comes from external data. Initialize the map with + `Object.create(null)` instead. + patterns: + - pattern-either: + - pattern: $MAP[$KEY] = $MAP[$KEY] ?? $INIT + - pattern: $MAP[$KEY] = $MAP[$KEY] || $INIT + - pattern: $MAP[$KEY] ??= $INIT + - pattern: | + if (!$MAP[$KEY]) $MAP[$KEY] = $INIT + - pattern-not-inside: | + const $MAP = Object.create(null) + ... + paths: + include: + - '/src/providers/*.ts' + - '/src/parser.ts' diff --git a/src/parser.ts b/src/parser.ts index 4adcf3b..ba0d31c 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -173,7 +173,7 @@ function buildSessionSummary( const toolBreakdown: SessionSummary['toolBreakdown'] = Object.create(null) const mcpBreakdown: SessionSummary['mcpBreakdown'] = Object.create(null) const bashBreakdown: SessionSummary['bashBreakdown'] = Object.create(null) - const categoryBreakdown: SessionSummary['categoryBreakdown'] = {} as SessionSummary['categoryBreakdown'] + const categoryBreakdown: SessionSummary['categoryBreakdown'] = Object.create(null) let totalCost = 0 let totalInput = 0 From c634b10560400c5388869267d99ec61259eab485 Mon Sep 17 00:00:00 2001 From: Ninym <80782621+lfl1337@users.noreply.github.com> Date: Sun, 19 Apr 2026 00:11:33 +0200 Subject: [PATCH 68/70] feat(report): add --from/--to date range filtering and avgCostPerSession (#80) * test(cli): failing tests for parseDateRangeFlags helper * feat(cli): add parseDateRangeFlags helper with local-time dates * feat(report): add --from/--to date range filtering * feat(report): add avgCostPerSession to JSON report and CSV/JSON export --- src/cli-date.ts | 39 ++++++++++++++++++++++ src/cli.ts | 30 +++++++++++++++-- src/dashboard.tsx | 6 ++-- src/export.ts | 1 + tests/date-range-filter.test.ts | 57 +++++++++++++++++++++++++++++++++ 5 files changed, 128 insertions(+), 5 deletions(-) create mode 100644 src/cli-date.ts create mode 100644 tests/date-range-filter.test.ts diff --git a/src/cli-date.ts b/src/cli-date.ts new file mode 100644 index 0000000..66831b9 --- /dev/null +++ b/src/cli-date.ts @@ -0,0 +1,39 @@ +import type { DateRange } from './types.js' + +const ISO_DATE_RE = /^\d{4}-\d{2}-\d{2}$/ + +const END_OF_DAY_HOURS = 23 +const END_OF_DAY_MINUTES = 59 +const END_OF_DAY_SECONDS = 59 +const END_OF_DAY_MS = 999 + +function parseLocalDate(s: string): Date { + if (!ISO_DATE_RE.test(s)) { + throw new Error(`Invalid date format "${s}": expected YYYY-MM-DD`) + } + const [y, m, d] = s.split('-').map(Number) as [number, number, number] + return new Date(y, m - 1, d) +} + +export function parseDateRangeFlags(from: string | undefined, to: string | undefined): DateRange | null { + if (from === undefined && to === undefined) return null + + const now = new Date() + const start = from !== undefined ? parseLocalDate(from) : new Date(0) + + const endDate = to !== undefined ? parseLocalDate(to) : new Date(now.getFullYear(), now.getMonth(), now.getDate()) + const end = new Date( + endDate.getFullYear(), + endDate.getMonth(), + endDate.getDate(), + END_OF_DAY_HOURS, + END_OF_DAY_MINUTES, + END_OF_DAY_SECONDS, + END_OF_DAY_MS, + ) + + if (start > end) { + throw new Error(`--from must not be after --to (got ${from} > ${to})`) + } + return { start, end } +} diff --git a/src/cli.ts b/src/cli.ts index ac87127..059c997 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -11,6 +11,7 @@ import { addNewDays, getDaysInRange, loadDailyCache, saveDailyCache, withDailyCa import { aggregateProjectsIntoDays, buildPeriodDataFromDays } from './day-aggregator.js' import { CATEGORY_LABELS, type DateRange, type ProjectSummary, type TaskCategory } from './types.js' import { renderDashboard } from './dashboard.js' +import { parseDateRangeFlags } from './cli-date.js' import { runOptimize, scanAndDetect } from './optimize.js' import { getAllProviders } from './providers/index.js' import { readConfig, saveConfig, getConfigFilePath } from './config.js' @@ -140,6 +141,9 @@ function buildJsonReport(projects: ProjectSummary[], period: string, periodKey: name: p.project, path: p.projectPath, cost: convertCost(p.totalCostUSD), + avgCostPerSession: p.sessions.length > 0 + ? convertCost(p.totalCostUSD / p.sessions.length) + : null, calls: p.totalApiCalls, sessions: p.sessions.length, })) @@ -236,18 +240,40 @@ program .command('report', { isDefault: true }) .description('Interactive usage dashboard') .option('-p, --period ', 'Starting period: today, week, 30days, month, all', 'week') + .option('--from ', 'Start date (YYYY-MM-DD). Overrides --period when set') + .option('--to ', 'End date (YYYY-MM-DD). Overrides --period when set') .option('--provider ', 'Filter by provider: all, claude, codex, cursor', 'all') .option('--format ', 'Output format: tui, json', 'tui') .option('--project ', 'Show only projects matching name (repeatable)', collect, []) .option('--exclude ', 'Exclude projects matching name (repeatable)', collect, []) .option('--refresh ', 'Auto-refresh interval in seconds', parseInt) .action(async (opts) => { + let customRange: DateRange | null = null + try { + customRange = parseDateRangeFlags(opts.from, opts.to) + } catch (err) { + const message = err instanceof Error ? err.message : String(err) + console.error(`\n Error: ${message}\n`) + process.exit(1) + } + const period = toPeriod(opts.period) if (opts.format === 'json') { - await runJsonReport(period, opts.provider, opts.project, opts.exclude) + await loadPricing() + if (customRange) { + const label = `${opts.from ?? 'all'} to ${opts.to ?? 'today'}` + const projects = filterProjectsByName( + await parseAllSessions(customRange, opts.provider), + opts.project, + opts.exclude, + ) + console.log(JSON.stringify(buildJsonReport(projects, label, 'custom'), null, 2)) + } else { + await runJsonReport(period, opts.provider, opts.project, opts.exclude) + } return } - await renderDashboard(period, opts.provider, opts.refresh, opts.project, opts.exclude) + await renderDashboard(period, opts.provider, opts.refresh, opts.project, opts.exclude, customRange) }) function buildPeriodData(label: string, projects: ProjectSummary[]): PeriodData { diff --git a/src/dashboard.tsx b/src/dashboard.tsx index 21281f8..a4e5cde 100644 --- a/src/dashboard.tsx +++ b/src/dashboard.tsx @@ -2,7 +2,7 @@ import { homedir } from 'os' import React, { useState, useCallback, useEffect, useRef } from 'react' import { render, Box, Text, useInput, useApp, useWindowSize } from 'ink' -import { CATEGORY_LABELS, type ProjectSummary, type TaskCategory } from './types.js' +import { CATEGORY_LABELS, type DateRange, type ProjectSummary, type TaskCategory } from './types.js' import { formatCost, formatTokens } from './format.js' import { parseAllSessions, filterProjectsByName } from './parser.js' import { loadPricing } from './models.js' @@ -719,9 +719,9 @@ function StaticDashboard({ projects, period, activeProvider }: { projects: Proje ) } -export async function renderDashboard(period: Period = 'week', provider: string = 'all', refreshSeconds?: number, projectFilter?: string[], excludeFilter?: string[]): Promise { +export async function renderDashboard(period: Period = 'week', provider: string = 'all', refreshSeconds?: number, projectFilter?: string[], excludeFilter?: string[], customRange?: DateRange | null): Promise { await loadPricing() - const range = getDateRange(period) + const range = customRange ?? getDateRange(period) const projects = filterProjectsByName(await parseAllSessions(range, provider), projectFilter, excludeFilter) const isTTY = process.stdin.isTTY && process.stdout.isTTY if (isTTY) { diff --git a/src/export.ts b/src/export.ts index d07f08d..58f250e 100644 --- a/src/export.ts +++ b/src/export.ts @@ -182,6 +182,7 @@ function buildProjectRows(projects: ProjectSummary[]): Row[] { .map(p => ({ Project: p.projectPath, [`Cost (${code})`]: round2(convertCost(p.totalCostUSD)), + [`Avg/Session (${code})`]: p.sessions.length > 0 ? round2(convertCost(p.totalCostUSD / p.sessions.length)) : '', 'Share (%)': pct(p.totalCostUSD, total), 'API Calls': p.totalApiCalls, Sessions: p.sessions.length, diff --git a/tests/date-range-filter.test.ts b/tests/date-range-filter.test.ts new file mode 100644 index 0000000..c4f9408 --- /dev/null +++ b/tests/date-range-filter.test.ts @@ -0,0 +1,57 @@ +import { describe, it, expect } from 'vitest' +import { parseDateRangeFlags } from '../src/cli-date.js' + +describe('parseDateRangeFlags', () => { + it('returns null when neither flag is provided', () => { + expect(parseDateRangeFlags(undefined, undefined)).toBeNull() + }) + + it('parses a symmetric range in local time', () => { + const range = parseDateRangeFlags('2026-04-07', '2026-04-10') + expect(range).not.toBeNull() + expect(range!.start.getFullYear()).toBe(2026) + expect(range!.start.getMonth()).toBe(3) + expect(range!.start.getDate()).toBe(7) + expect(range!.start.getHours()).toBe(0) + expect(range!.end.getDate()).toBe(10) + expect(range!.end.getHours()).toBe(23) + expect(range!.end.getMinutes()).toBe(59) + expect(range!.end.getSeconds()).toBe(59) + }) + + it('accepts --from alone (open-ended to today 23:59:59)', () => { + const range = parseDateRangeFlags('2026-04-01', undefined) + expect(range).not.toBeNull() + expect(range!.start.getDate()).toBe(1) + expect(range!.end.getHours()).toBe(23) + }) + + it('accepts --to alone (start = epoch)', () => { + const range = parseDateRangeFlags(undefined, '2026-04-10') + expect(range).not.toBeNull() + expect(range!.start.getTime()).toBe(new Date(0).getTime()) + expect(range!.end.getDate()).toBe(10) + }) + + it('throws when --from > --to', () => { + expect(() => parseDateRangeFlags('2026-04-10', '2026-04-07')) + .toThrow('--from must not be after --to') + }) + + it('throws on a non-ISO string', () => { + expect(() => parseDateRangeFlags('April 7', undefined)) + .toThrow('Invalid date format') + }) + + it('throws on wrong digit count', () => { + expect(() => parseDateRangeFlags('26-4-7', undefined)) + .toThrow('Invalid date format') + }) + + it('same day is valid (start midnight, end 23:59:59)', () => { + const range = parseDateRangeFlags('2026-04-10', '2026-04-10') + expect(range).not.toBeNull() + expect(range!.start.getDate()).toBe(10) + expect(range!.end.getDate()).toBe(10) + }) +}) From 82df214958ba1c69d423bc85720561a5763b53ce Mon Sep 17 00:00:00 2001 From: AgentSeal Date: Sat, 18 Apr 2026 15:45:45 -0700 Subject: [PATCH 69/70] docs: cover --from/--to, avgCostPerSession, and semgrep guard (#99) README gains a --from/--to example in the Usage block, a dedicated 'Date range filtering' subsection, and a note that JSON projects[] now includes avgCostPerSession. CHANGELOG opens an Unreleased section crediting @lfl1337 for PRs #78 and #80. Flags the projects.csv column-order shift (Avg/Session now between Cost and Share) so consumers parsing by position read by header instead. Co-authored-by: AgentSeal --- CHANGELOG.md | 9 +++++++++ README.md | 16 +++++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b63721d..d7f2beb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## Unreleased + +### Added +- **`codeburn report --from/--to`.** Filter sessions to an exact `YYYY-MM-DD` date range (local time). Either flag alone is valid: `--from` alone runs from the given date through end-of-today, `--to` alone runs from the earliest data through the given date. Inverted ranges or malformed dates exit with a clear error. In the TUI, pressing `1`-`5` still switches to the predefined periods. Credit: @lfl1337 (PR #80). +- **`avgCostPerSession` in reports.** JSON `projects[]` entries gain an `avgCostPerSession` field and `export -f csv` adds an `Avg/Session (USD)` column to `projects.csv`. Column order in `projects.csv` is now `Project, Cost, Avg/Session, Share, API Calls, Sessions` -- scripts parsing by column position should read by header instead. Credit: @lfl1337 (PR #80). + +### Security +- **Semgrep CI guard against prototype pollution regressions.** New `.github/workflows/ci.yml` runs a bracket-assign guard on `src/providers/` and `src/parser.ts` on every push to main and every PR. Blocks re-introducing `$MAP[$KEY] = $MAP[$KEY] ?? $INIT` patterns on `{}`-initialized maps. `categoryBreakdown` in `parser.ts` switched to `Object.create(null)` for consistency with its sibling breakdown maps. Credit: @lfl1337 (PR #78). + ## 0.7.3 - 2026-04-18 ### Changed diff --git a/README.md b/README.md index a88949d..641670a 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,7 @@ codeburn today # today's usage codeburn month # this month's usage codeburn report -p 30days # rolling 30-day window codeburn report -p all # every recorded session +codeburn report --from 2026-04-01 --to 2026-04-10 # exact date range codeburn report --format json # full dashboard data as JSON codeburn report --refresh 60 # auto-refresh every 60 seconds codeburn status # compact one-liner (today + month) @@ -72,7 +73,7 @@ codeburn month --format json # this month as JSON codeburn report -p 30days --format json # 30-day window ``` -The JSON includes all dashboard panels: overview (cost, calls, sessions, cache hit %), daily breakdown, projects, models with token counts, activities with one-shot rates, core tools, MCP servers, and shell commands. Pipe to `jq` for filtering: +The JSON includes all dashboard panels: overview (cost, calls, sessions, cache hit %), daily breakdown, projects (with `avgCostPerSession`), models with token counts, activities with one-shot rates, core tools, MCP servers, and shell commands. Pipe to `jq` for filtering: ```bash codeburn report --format json | jq '.projects' @@ -113,6 +114,19 @@ codeburn export --project inventory # export only "inventory" proje The `--project` and `--exclude` flags work on all commands and can be combined with `--provider`. +### Date range filtering + +Beyond the preset periods, specify an exact window with `--from` and `--to` (`YYYY-MM-DD`, local time): + +```bash +codeburn report --from 2026-04-01 --to 2026-04-10 # explicit window +codeburn report --from 2026-04-01 # this date through today +codeburn report --to 2026-04-10 # earliest data through this date +codeburn report --from 2026-04-01 --to 2026-04-10 --format json +``` + +Either flag alone is valid. Inverted or malformed dates exit with a clear error. In the TUI, the custom range sets the initial load only -- pressing `1`-`5` switches back to predefined periods. + ### Supported providers | Provider | Data location | Status | From 11b3de89e41123caa100cf0e3c826a24299a4ac1 Mon Sep 17 00:00:00 2001 From: AgentSeal Date: Sun, 19 Apr 2026 05:27:05 +0000 Subject: [PATCH 70/70] fix(sqlite): load node:sqlite in ESM runtime Replace eval-based require with createRequire(import.meta.url) so the SQLite driver loads correctly when the CLI runs as ESM. This restores OpenCode and Cursor session discovery instead of returning empty results when require is unavailable. --- src/sqlite.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/sqlite.ts b/src/sqlite.ts index dcc6940..a1ca812 100644 --- a/src/sqlite.ts +++ b/src/sqlite.ts @@ -1,8 +1,12 @@ +import { createRequire } from 'node:module' + /// Thin SQLite read-only wrapper over Node's built-in `node:sqlite` module (stable in /// Node 24, experimental in Node 22 / 23). Replaces the earlier `better-sqlite3` binding /// so the dependency graph no longer pulls in the deprecated `prebuild-install` package /// (issue #75). Works across Cursor and OpenCode session DBs, both of which we only read. +const requireForSqlite = createRequire(import.meta.url) + type Row = Record export type SqliteDatabase = { @@ -55,10 +59,7 @@ function loadDriver(): boolean { } as typeof process.emit try { - // Dynamic require via createRequire avoids TypeScript chasing types we don't need at - // build time (node:sqlite landed in @types/node much later than in Node itself). - // eslint-disable-next-line @typescript-eslint/no-require-imports - const mod = eval('require')('node:sqlite') as { DatabaseSync: DatabaseSyncCtor } + const mod = requireForSqlite('node:sqlite') as { DatabaseSync: DatabaseSyncCtor } DatabaseSync = mod.DatabaseSync return true } catch (err) {