token-furnace 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +1 -1
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -189,7 +189,7 @@ var SqliteSessionRepository = class {
|
|
|
189
189
|
this.ensureDb();
|
|
190
190
|
if (!this.db || !this.stmtAllFiles || !this.stmtAllTurns) return [];
|
|
191
191
|
const fileRows = this.stmtAllFiles.all();
|
|
192
|
-
const turnRows = this.stmtAllTurns.
|
|
192
|
+
const turnRows = this.stmtAllTurns.iterate();
|
|
193
193
|
const turnsByPath = /* @__PURE__ */ new Map();
|
|
194
194
|
for (const r of turnRows) {
|
|
195
195
|
let list = turnsByPath.get(r.path);
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.ts","../src/compose.ts","../src/repo/memory-repo.ts","../src/repo/sqlite-repo.ts","../src/services/report-service.ts","../src/core/analyze/format.ts","../src/core/analyze/flags.ts","../src/core/analyze/pricing.ts","../src/core/analyze/config-checks.ts","../src/core/analyze/baseline.ts","../src/core/analyze/burn.ts","../src/core/analyze/report.ts","../src/core/analyze/issues.ts","../src/core/analyze/view.ts","../src/services/parse-pool.ts","../src/render/html.ts","../src/render/text.ts","../src/server.ts","../src/render/loading.ts","../src/services/usage-client.ts","../src/setup/churn-hook.ts","../src/setup/agents.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * The CLI: node:util parseArgs, the commands from architecture.md \"Entry points\", and the exit\n * codes of burn.py main(): 1 with no data, 1 with leaks or a failing doctor, 0 otherwise.\n */\n\nimport { mkdirSync, realpathSync, statSync, writeFileSync } from \"node:fs\";\nimport { dirname, resolve } from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport { parseArgs } from \"node:util\";\nimport { compose, type App } from \"./compose\";\nimport { topIssues } from \"./core/analyze/issues\";\nimport { reportView } from \"./core/analyze/view\";\nimport { renderHtml } from \"./render/html\";\nimport { printDoctor, printText } from \"./render/text\";\nimport { serve } from \"./server\";\nimport type { RawReport, ScanProgress, Source } from \"./core/model\";\nimport { planWeek } from \"./services/usage-client\";\nimport { runChurnHook, readStdin } from \"./setup/churn-hook\";\nimport { runSetup } from \"./setup/agents\";\n\nconst USAGE = `Usage: token-furnace [days] [options]\n token-furnace serve [--port 8765]\n token-furnace setup [--apply] [--rollback] [--aggressive] [--verify]\n token-furnace hook churn\n\nWhere the token budget actually went. Reads local Claude Code and Codex transcripts.\n\n days how many days back to look (default 7)\n --source <agent> all (default), claude, or codex\n --json print the Report JSON and nothing else, for agents and scripts\n --full the full text report (the old burn.py output)\n --html <path> also write a self-contained HTML report\n --list-sources each agent, its path and its transcript count\n --weekly-budget <M> weekly budget in millions of weighted tokens\n --no-plan-usage never call api.anthropic.com for the subscription window (a saved reading is still used)\n --no-cache parse every file, write no cache\n serve [--port 8765] live report on http://127.0.0.1:<port>, refreshed in the background\n -h, --help this text\n`;\n\ninterface Options {\n days: number;\n source: Source | \"all\";\n json: boolean;\n full: boolean;\n html: string | null;\n listSources: boolean;\n weeklyBudget: number | null;\n planUsage: boolean;\n port: number;\n}\n\nexport async function main(argv: string[] = process.argv.slice(2), app?: App): Promise<number> {\n if (argv[0] === \"hook\" && argv[1] === \"churn\") {\n return runChurnHook(readStdin(), (app?.env ?? process.env), process.stdout);\n }\n if (argv[0] === \"setup\") {\n const setupArgs = parseArgs({\n args: argv.slice(1),\n allowPositionals: true,\n options: {\n apply: { type: \"boolean\" },\n rollback: { type: \"boolean\" },\n aggressive: { type: \"boolean\" },\n verify: { type: \"boolean\" },\n help: { type: \"boolean\", short: \"h\" },\n },\n });\n if (setupArgs.values.help) {\n process.stdout.write(\n \"Usage: token-furnace setup [--apply] [--aggressive] [--verify] [--rollback]\\n\\n\" +\n \" --apply write changes (default: dry run)\\n\" +\n \" --aggressive also set the flagged-risky subagent spawn depth\\n\" +\n \" --verify check an existing install; exits 1 on any failure\\n\" +\n \" --rollback restore the most recent backup\\n\",\n );\n return 0;\n }\n return runSetup(\n {\n apply: setupArgs.values.apply,\n rollback: setupArgs.values.rollback,\n aggressive: setupArgs.values.aggressive,\n verify: setupArgs.values.verify,\n },\n app?.env ?? process.env,\n process.stdout,\n );\n }\n\n const parsed = parseArgs({\n args: argv,\n allowPositionals: true,\n options: {\n source: { type: \"string\" },\n json: { type: \"boolean\" },\n full: { type: \"boolean\" },\n html: { type: \"string\" },\n \"list-sources\": { type: \"boolean\" },\n \"weekly-budget\": { type: \"string\" },\n \"plan-usage\": { type: \"boolean\" }, // the default now; accepted so old scripts keep working\n \"no-plan-usage\": { type: \"boolean\" },\n \"no-cache\": { type: \"boolean\" },\n port: { type: \"string\" },\n help: { type: \"boolean\", short: \"h\" },\n },\n });\n\n if (parsed.values.help) {\n process.stdout.write(USAGE);\n return 0;\n }\n\n if (!app) {\n app = compose(process.env, { noCache: Boolean(parsed.values[\"no-cache\"]) });\n }\n\n const serveMode = parsed.positionals[0] === \"serve\";\n const positionals = serveMode ? parsed.positionals.slice(1) : parsed.positionals;\n const days = Number(positionals[0] ?? 7);\n if (!Number.isInteger(days) || days < 1) {\n process.stderr.write(`token-furnace: days must be a whole number, got \"${positionals[0] ?? \"\"}\"\\n`);\n return 2;\n }\n const source = (parsed.values.source ?? \"all\") as Source | \"all\";\n if (source !== \"all\" && source !== \"claude\" && source !== \"codex\") {\n process.stderr.write(`token-furnace: --source must be all, claude or codex\\n`);\n return 2;\n }\n const weeklyBudget = weeklyBudgetOf(app.env, parsed.values[\"weekly-budget\"]);\n const port = Number(parsed.values.port ?? 8765);\n if (!Number.isInteger(port) || port < 0 || port > 65_535) {\n process.stderr.write(\"token-furnace: --port must be a port number\\n\");\n return 2;\n }\n const options: Options = {\n days,\n source,\n json: Boolean(parsed.values.json),\n full: Boolean(parsed.values.full),\n html: parsed.values.html ?? null,\n listSources: Boolean(parsed.values[\"list-sources\"]),\n weeklyBudget,\n planUsage: !parsed.values[\"no-plan-usage\"],\n port,\n };\n\n if (options.listSources) {\n listSources(app);\n return 0;\n }\n if (serveMode) {\n await serve(app, options);\n return 0;\n }\n\n const now = app.now();\n await app.reports.refresh(stderrProgress());\n const plan = await planWeek(app.env, now, options.planUsage);\n const report = app.reports.getRaw(options.days, options.source, {\n weeklyBudget: options.weeklyBudget,\n planWeek: plan,\n now,\n });\n if (!report) {\n // --json keeps stdout to the Report alone, so the notice goes to stderr there.\n (options.json ? process.stderr : process.stdout).write(\n \"No transcripts found. Try --list-sources.\\n\",\n );\n return 1;\n }\n\n const htmlPath = writeHtml(report, now, options.html);\n if (options.json) {\n process.stdout.write(`${JSON.stringify(reportView(report, now))}\\n`);\n return 0;\n }\n if (options.full) {\n process.stdout.write(printText(report));\n if (htmlPath) process.stdout.write(`\\nHTML report: ${htmlPath}\\n`);\n return 0;\n }\n process.stdout.write(printDoctor(report, htmlPath));\n return topIssues(report).length ? 1 : 0;\n}\n\n/** A redrawn `Scanning 3,412 / 7,700 files (44%)` line on a terminal's stderr. Nothing otherwise. */\nfunction stderrProgress(): ((progress: ScanProgress) => void) | undefined {\n if (!process.stderr.isTTY) return undefined;\n return (p) => {\n if (!p.filesTotal) return;\n const text = p.phase === \"ready\" ? \"\" : `Scanning ${p.filesDone.toLocaleString()} / ${p.filesTotal.toLocaleString()} files (${Math.round((100 * p.bytesDone) / Math.max(1, p.bytesTotal))}%)`;\n process.stderr.write(`\\r\\x1b[K${text}`);\n };\n}\n\n/** `--weekly-budget M`, or TOKEN_FURNACE_WEEKLY_BUDGET, in millions of weighted tokens. */\nfunction weeklyBudgetOf(env: NodeJS.ProcessEnv, flag: string | undefined): number | null {\n const text = flag || env.TOKEN_FURNACE_WEEKLY_BUDGET || \"\";\n const value = Number.parseFloat(text);\n return text && Number.isFinite(value) ? value : null;\n}\n\n/** Each agent, its path and its transcript count, like burn.py --list-sources. */\nfunction listSources(app: App): void {\n for (const agent of app.sources) {\n const path = agent.root();\n const found = existsDir(path) ? agent.files().length : 0;\n process.stdout.write(\n ` ${agent.name.padEnd(8)} ${path.padEnd(46)} ${found ? `${found} transcripts` : \"not installed\"}\\n`,\n );\n }\n}\n\n/** Writes the static page and returns its absolute path. */\nfunction writeHtml(report: RawReport, now: Date, path: string | null): string | null {\n if (!path) return null;\n const full = resolve(path);\n mkdirSync(dirname(full), { recursive: true });\n writeFileSync(full, renderHtml(report, now));\n return full;\n}\n\nfunction existsDir(path: string): boolean {\n try {\n return statSync(path).isDirectory();\n } catch {\n return false;\n }\n}\n\n/** True when this module is the process entry, even through an npm bin symlink. */\nfunction isEntryPoint(): boolean {\n const entry = process.argv[1];\n if (!entry) return false;\n try {\n return import.meta.url === pathToFileURL(realpathSync(entry)).href;\n } catch {\n return false;\n }\n}\n\n// Only when run as the binary: a test imports main() without starting a command.\nif (isEntryPoint()) {\n process.exitCode = await main();\n}\n","import { existsSync } from \"node:fs\";\nimport { availableParallelism, homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { MemorySessionRepository } from \"./repo/memory-repo\";\nimport { SqliteSessionRepository } from \"./repo/sqlite-repo\";\nimport type { SessionRepository } from \"./repo/session-repo\";\nimport { ReportService } from \"./services/report-service\";\nimport { ClaudeSource } from \"./sources/claude\";\nimport { CodexSource } from \"./sources/codex\";\nimport type { AgentSource, Env } from \"./sources/agent-source\";\n\nexport interface App {\n env: Env;\n sources: AgentSource[];\n repo: SessionRepository;\n reports: ReportService;\n /** The clock. TOKEN_FURNACE_NOW freezes it, so a test can compare two runs byte for byte. */\n now: () => Date;\n}\n\nexport function sqliteCachePath(env: Env): string {\n const base = env.XDG_CACHE_HOME || join(env.HOME || homedir(), \".cache\");\n return join(base, \"token-furnace\", \"cache.sqlite\");\n}\n\n/** The composition root: the only place that calls `new`. architecture.md */\nexport function compose(env: Env = process.env, opts?: { noCache?: boolean }): App {\n const noCache = opts?.noCache ?? Boolean(env.TOKEN_FURNACE_NO_CACHE && env.TOKEN_FURNACE_NO_CACHE !== \"0\");\n const effective: Env = { ...env, TOKEN_FURNACE_NO_CACHE: noCache ? \"1\" : \"0\" };\n const sources: AgentSource[] = [new ClaudeSource(effective), new CodexSource(effective)];\n const repo = noCache ? new MemorySessionRepository() : new SqliteSessionRepository(sqliteCachePath(effective));\n return {\n env: effective,\n sources,\n repo,\n reports: new ReportService(sources, repo, effective, workers(effective)),\n now: () => new Date(effective.TOKEN_FURNACE_NOW || Date.now()),\n };\n}\n\n/**\n * Parse threads, when the built worker script sits next to this bundle. Running from source (a\n * test, `tsx`) has no such file and parses on the main thread. TOKEN_FURNACE_WORKERS=0 turns it off.\n */\nfunction workers(env: Env): { url: URL; size: number } | null {\n const url = new URL(\"./scan-worker.js\", import.meta.url);\n const wanted = env.TOKEN_FURNACE_WORKERS !== undefined\n ? Number(env.TOKEN_FURNACE_WORKERS)\n : Math.max(1, Math.min(availableParallelism(), 12));\n return existsSync(fileURLToPath(url)) && wanted >= 1 ? { url, size: Math.floor(wanted) } : null;\n}\n","import type { SessionInput, SourceFile } from \"../core/model\";\nimport type { SessionRepository } from \"./session-repo\";\n\n/**\n * Turns in a Map, for tests and --no-cache. The file size rides along in the map so a file that\n * was appended to is reparsed even when its mtime is unchanged, like cached() in burn.py:516.\n */\nexport class MemorySessionRepository implements SessionRepository {\n private readonly sessions = new Map<string, { session: SessionInput; size: number }>();\n\n changed(files: SourceFile[]): SourceFile[] {\n const seen = new Set<string>();\n const out: SourceFile[] = [];\n for (const file of files) {\n seen.add(file.path);\n const held = this.sessions.get(file.path);\n if (held && held.session.mtimeMs === file.mtimeMs && held.size === file.size) continue;\n out.push(file);\n }\n for (const path of [...this.sessions.keys()]) if (!seen.has(path)) this.sessions.delete(path);\n return out;\n }\n\n all(): SessionInput[] {\n return [...this.sessions.values()].map((held) => held.session);\n }\n\n save(session: SessionInput, size: number): void {\n this.sessions.set(session.path, { session, size });\n }\n}","import { existsSync, mkdirSync, rmSync } from \"node:fs\";\nimport { dirname } from \"node:path\";\nimport { DatabaseSync, type StatementSync } from \"node:sqlite\";\nimport type { SessionInput, Source, SourceFile, Turn, Wake } from \"../core/model\";\nimport type { SessionRepository } from \"./session-repo\";\n\nconst SCHEMA_VERSION = 1;\n\nconst DDL = `\nPRAGMA foreign_keys = ON;\nPRAGMA user_version = ${SCHEMA_VERSION};\n\nCREATE TABLE files (\n path TEXT PRIMARY KEY,\n source TEXT NOT NULL,\n mtime_ns INTEGER NOT NULL,\n size INTEGER NOT NULL,\n title TEXT,\n bad_lines INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE turns (\n path TEXT NOT NULL REFERENCES files(path) ON DELETE CASCADE,\n seq INTEGER NOT NULL,\n project TEXT NOT NULL,\n session TEXT NOT NULL,\n model TEXT NOT NULL,\n at INTEGER NOT NULL,\n base_in INTEGER NOT NULL,\n cache_read INTEGER NOT NULL,\n cache_write INTEGER NOT NULL,\n output INTEGER NOT NULL,\n tools TEXT NOT NULL,\n reads INTEGER NOT NULL,\n wakes TEXT NOT NULL,\n PRIMARY KEY (path, seq)\n);\nCREATE INDEX turns_at ON turns(at);\n`;\n\ninterface FileRow {\n path: string;\n source: string;\n mtime_ns: number;\n size: number;\n title: string | null;\n bad_lines: number;\n}\n\ninterface TurnRow {\n path: string;\n seq: number;\n project: string;\n session: string;\n model: string;\n at: number;\n base_in: number;\n cache_read: number;\n cache_write: number;\n output: number;\n tools: string;\n reads: number;\n wakes: string;\n}\n\nexport class SqliteSessionRepository implements SessionRepository {\n private db: DatabaseSync | null = null;\n private readonly dbPath: string;\n private stmtDeleteFile: StatementSync | null = null;\n private stmtInsertFile: StatementSync | null = null;\n private stmtInsertTurn: StatementSync | null = null;\n private stmtAllFiles: StatementSync | null = null;\n private stmtAllTurns: StatementSync | null = null;\n\n constructor(dbPath: string) {\n this.dbPath = dbPath;\n this.ensureDb();\n }\n\n private prepareStatements(): void {\n if (!this.db) return;\n this.stmtDeleteFile = this.db.prepare(\"DELETE FROM files WHERE path = ?;\");\n this.stmtInsertFile = this.db.prepare(\n \"INSERT INTO files (path, source, mtime_ns, size, title, bad_lines) VALUES (?, ?, ?, ?, ?, 0);\",\n );\n this.stmtInsertTurn = this.db.prepare(\n \"INSERT INTO turns (path, seq, project, session, model, at, base_in, cache_read, cache_write, output, tools, reads, wakes) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);\",\n );\n this.stmtAllFiles = this.db.prepare(\"SELECT path, source, mtime_ns, size, title, bad_lines FROM files;\");\n this.stmtAllTurns = this.db.prepare(\n \"SELECT path, seq, project, session, model, at, base_in, cache_read, cache_write, output, tools, reads, wakes FROM turns ORDER BY path, seq;\",\n );\n }\n\n private openDb(path: string): DatabaseSync {\n const db = new DatabaseSync(path);\n try {\n db.exec(\"PRAGMA foreign_keys = ON;\");\n db.exec(\"PRAGMA synchronous = NORMAL;\");\n if (path !== \":memory:\") db.exec(\"PRAGMA journal_mode = WAL;\");\n return db;\n } catch (error) {\n db.close();\n throw error;\n }\n }\n\n private ensureDb(): void {\n if (this.db) return;\n try {\n if (this.dbPath !== \":memory:\") {\n mkdirSync(dirname(this.dbPath), { recursive: true });\n }\n const db = this.openDb(this.dbPath);\n const verRow = db.prepare(\"PRAGMA user_version;\").get() as { user_version: number } | undefined;\n const ver = verRow ? verRow.user_version : 0;\n if (ver !== SCHEMA_VERSION) {\n db.close();\n this.recreateDb();\n return;\n }\n this.db = db;\n this.prepareStatements();\n } catch {\n this.recreateDb();\n }\n }\n\n private recreateDb(): void {\n try {\n if (this.dbPath !== \":memory:\" && existsSync(this.dbPath)) {\n rmSync(this.dbPath, { force: true });\n rmSync(`${this.dbPath}-wal`, { force: true });\n rmSync(`${this.dbPath}-shm`, { force: true });\n }\n } catch {\n // ignore deletion errors\n }\n try {\n if (this.dbPath !== \":memory:\") {\n mkdirSync(dirname(this.dbPath), { recursive: true });\n }\n const db = this.openDb(this.dbPath);\n db.exec(DDL);\n this.db = db;\n this.prepareStatements();\n } catch {\n try {\n const memDb = this.openDb(\":memory:\");\n memDb.exec(DDL);\n this.db = memDb;\n this.prepareStatements();\n } catch {\n this.db = null;\n }\n }\n }\n\n changed(files: SourceFile[]): SourceFile[] {\n this.ensureDb();\n if (!this.db || !this.stmtAllFiles || !this.stmtDeleteFile) return files;\n\n const seen = new Set<string>();\n const out: SourceFile[] = [];\n\n const cachedFiles = new Map<string, FileRow>();\n for (const row of this.stmtAllFiles.all() as unknown as FileRow[]) {\n cachedFiles.set(row.path, row);\n }\n\n for (const file of files) {\n seen.add(file.path);\n const held = cachedFiles.get(file.path);\n if (held && held.mtime_ns === file.mtimeMs && held.size === file.size) continue;\n out.push(file);\n }\n\n for (const path of cachedFiles.keys()) {\n if (!seen.has(path)) {\n this.stmtDeleteFile.run(path);\n }\n }\n\n return out;\n }\n\n all(): SessionInput[] {\n this.ensureDb();\n if (!this.db || !this.stmtAllFiles || !this.stmtAllTurns) return [];\n\n const fileRows = this.stmtAllFiles.all() as unknown as FileRow[];\n const turnRows = this.stmtAllTurns.all() as unknown as TurnRow[];\n\n const turnsByPath = new Map<string, Turn[]>();\n for (const r of turnRows) {\n let list = turnsByPath.get(r.path);\n if (!list) {\n list = [];\n turnsByPath.set(r.path, list);\n }\n list.push({\n source: \"claude\",\n project: r.project,\n session: r.session,\n model: r.model,\n when: new Date(r.at),\n baseIn: r.base_in,\n cacheRead: r.cache_read,\n cacheWrite: r.cache_write,\n output: r.output,\n tools: JSON.parse(r.tools) as string[],\n reads: r.reads,\n wakes: JSON.parse(r.wakes) as Wake[],\n });\n }\n\n return fileRows.map((f) => {\n const source = f.source as Source;\n const turns = (turnsByPath.get(f.path) ?? []).map((t) => ({ ...t, source }));\n return {\n source,\n path: f.path,\n mtimeMs: f.mtime_ns,\n title: f.title,\n turns,\n };\n });\n }\n\n save(session: SessionInput, size: number): void {\n this.ensureDb();\n if (!this.db || !this.stmtDeleteFile || !this.stmtInsertFile || !this.stmtInsertTurn) return;\n\n this.db.exec(\"BEGIN IMMEDIATE;\");\n try {\n this.stmtDeleteFile.run(session.path);\n this.stmtInsertFile.run(session.path, session.source, session.mtimeMs, size, session.title ?? null);\n\n for (let seq = 0; seq < session.turns.length; seq++) {\n const t = session.turns[seq];\n this.stmtInsertTurn.run(\n session.path,\n seq,\n t.project,\n t.session,\n t.model,\n t.when.getTime(),\n t.baseIn,\n t.cacheRead,\n t.cacheWrite,\n t.output,\n JSON.stringify(t.tools),\n t.reads,\n JSON.stringify(t.wakes),\n );\n }\n this.db.exec(\"COMMIT;\");\n } catch {\n this.db.exec(\"ROLLBACK;\");\n }\n }\n\n close(): void {\n if (this.db) {\n try {\n this.db.close();\n } catch {\n // ignore\n }\n this.db = null;\n }\n }\n}\n","import { existsSync } from \"node:fs\";\nimport { buildReport } from \"../core/analyze/report\";\nimport { reportView } from \"../core/analyze/view\";\nimport type { ConfigInput, ParsedFile, RawReport, Report, ScanProgress, Source, Week } from \"../core/model\";\nimport type { SessionRepository } from \"../repo/session-repo\";\nimport { ParsePool } from \"./parse-pool\";\nimport type { AgentSource, Env } from \"../sources/agent-source\";\n\nexport interface ReportOptions {\n /** Millions of weighted tokens, or null. */\n weeklyBudget: number | null;\n /** The subscription window, read by the caller: the saved reading, refreshed from the network when a login exists. */\n planWeek?: Week | null;\n /** The clock. Defaults to now, so a test can freeze it. */\n now?: Date;\n}\n\n/**\n * The report over the sources and the repository. Everything the pure buildReport needs arrives\n * in its input, so this class only reads files and hands the contents over. burn.py's build_report\n * and report_view, split at the I/O boundary.\n */\nexport class ReportService {\n constructor(\n private readonly sources: AgentSource[],\n private readonly repo: SessionRepository,\n private readonly env: Env,\n /** The built worker script and how many threads parse. Null parses on the main thread. */\n private readonly workers: { url: URL; size: number } | null = null,\n ) {}\n\n /** Where the scan stands. `/api/status` and the CLI read it. */\n progress: ScanProgress = { phase: \"idle\", filesDone: 0, filesTotal: 0, bytesDone: 0, bytesTotal: 0, startedAt: 0, updatedAt: 0 };\n\n /** True once one full scan has finished: from then on a report is always there to serve. */\n hasScanned = false;\n\n private inflight: Promise<void> | null = null;\n\n /** Each path's place in the sources' own file order, so scanning newest first changes no report. */\n private order = new Map<string, number>();\n\n /**\n * Parse every file whose mtime or size changed since the last scan, newest first. It yields to\n * the event loop between files, so a server keeps answering during a cold scan of gigabytes.\n * Overlapping calls share one scan.\n */\n refresh(onProgress?: (progress: ScanProgress) => void): Promise<void> {\n this.inflight ??= this.scan(onProgress).finally(() => {\n this.inflight = null;\n });\n return this.inflight;\n }\n\n private async scan(onProgress?: (progress: ScanProgress) => void): Promise<void> {\n const live = this.sources.filter((agent) => existsSync(agent.root())); // not installed\n const files = live.flatMap((source) => source.files().map((file) => ({ source, file })));\n this.order = new Map(files.map(({ file }, index) => [file.path, index]));\n const changed = new Set(this.repo.changed(files.map(({ file }) => file)).map((file) => file.path));\n const todo = files.filter(({ file }) => changed.has(file.path)).sort((a, b) => b.file.mtimeMs - a.file.mtimeMs);\n const progress = this.progress;\n Object.assign(progress, {\n phase: \"scanning\",\n filesDone: 0,\n filesTotal: todo.length,\n bytesDone: 0,\n bytesTotal: todo.reduce((sum, { file }) => sum + file.size, 0),\n startedAt: Date.now(),\n updatedAt: Date.now(),\n });\n const save = (item: (typeof todo)[number], parsed: ParsedFile): void => {\n this.repo.save(\n { source: item.source.name, path: item.file.path, mtimeMs: item.file.mtimeMs, title: parsed.title, turns: parsed.turns },\n item.file.size,\n );\n };\n const done = (item: (typeof todo)[number]): void => {\n progress.filesDone += 1;\n progress.bytesDone += item.file.size;\n progress.updatedAt = Date.now();\n onProgress?.(progress);\n };\n\n const poolSize = this.workers && todo.length ? Math.min(this.workers.size, todo.length) : 0;\n const pool = poolSize >= 1 ? new ParsePool(this.workers!.url, this.env, poolSize) : null;\n try {\n if (pool) {\n // One lane per worker: each takes the next file, newest first, as soon as it is free.\n let next = 0;\n const lane = async (index: number): Promise<void> => {\n while (next < todo.length) {\n const item = todo[next++];\n let parsed: ParsedFile;\n try {\n parsed = await pool.parse(index, item.source.name, item.file.path);\n } catch {\n // Fall back to in-process parsing if the worker fails or crashes\n parsed = item.source.parse(item.file.path);\n }\n save(item, parsed);\n done(item);\n }\n };\n await Promise.all(Array.from({ length: poolSize }, (_, index) => lane(index)));\n } else {\n let lastYield = Date.now();\n for (const item of todo) {\n save(item, item.source.parse(item.file.path));\n done(item);\n if (Date.now() - lastYield >= 25) {\n await new Promise<void>((next) => setImmediate(next)); // let requests through\n lastYield = Date.now();\n }\n }\n }\n } finally {\n await pool?.close();\n progress.phase = \"ready\";\n progress.updatedAt = Date.now();\n this.hasScanned = true;\n onProgress?.(progress);\n }\n }\n\n /** The agents to scan: the ones installed, in source order. burn.py:289 */\n live(source: Source | \"all\"): Source[] {\n return this.sources\n .filter((agent) => (source === \"all\" || source === agent.name) && existsSync(agent.root()))\n .map((agent) => agent.name);\n }\n\n /** The raw report, which the text renderers read with burn.py's own key names. */\n getRaw(days: number, source: Source | \"all\", opts: ReportOptions): RawReport | null {\n const now = opts.now ?? new Date();\n const live = this.live(source);\n if (!live.length) return null;\n return buildReport({\n now,\n days,\n weeklyBudget: opts.weeklyBudget,\n live,\n sessions: this.repo\n .all()\n .sort((a, b) => (this.order.get(a.path) ?? Infinity) - (this.order.get(b.path) ?? Infinity)),\n config: this.readConfig(live),\n planWeek: opts.planWeek ?? null,\n codexWeek: live.includes(\"codex\") ? (this.sources.find((s) => s.name === \"codex\")?.week?.(now) ?? null) : null,\n });\n }\n\n /** The Report JSON: /api/report, --json and the inlined --html page all read this. */\n getReport(days: number, source: Source | \"all\", opts: ReportOptions): Report | null {\n const now = opts.now ?? new Date();\n const raw = this.getRaw(days, source, { ...opts, now });\n return raw ? reportView(raw, now) : null;\n }\n\n /** Every config file the checks read, through the agent that owns it. */\n private readConfig(live: Source[]): ConfigInput {\n const claude = this.sources.find((s) => s.name === \"claude\");\n const codex = this.sources.find((s) => s.name === \"codex\");\n return {\n claudeBase: claude?.base() ?? \"\",\n claudeHome: claude?.home() ?? \"\",\n settings: claude?.readFile(\"settings.json\") ?? null,\n codexConfig: codex?.readFile(\"config.toml\") ?? null,\n memoryIndexes: live.includes(\"claude\") ? (claude?.memoryIndexes?.() ?? []) : [],\n env: this.env,\n };\n }\n}\n","/**\n * Python's %-format. burn.py's message strings are the product, so the numbers inside them must\n * round the way Python rounds: the exact value of the double, ties to even.\n */\n\n/**\n * The exact decimal expansion of a finite double, as digits with the decimal point `point`\n * digits from the left. A double is m * 2^e, and for e < 0 that is m * 5^(-e) / 10^(-e), so the\n * expansion terminates and BigInt holds it exactly.\n */\nfunction exact(value: number): { digits: string; point: number } {\n const view = new DataView(new ArrayBuffer(8));\n view.setFloat64(0, value);\n const bits = view.getBigUint64(0);\n const exponentField = Number((bits >> 52n) & 0x7ffn);\n if (exponentField === 0) return { digits: String(bits & ((1n << 52n) - 1n)), point: -1074 }; // subnormal or 0\n const m = (bits & ((1n << 52n) - 1n)) | (1n << 52n); // the implicit leading bit is always set\n const exponent = exponentField - 1023 - 52;\n const n = exponent >= 0 ? m << BigInt(exponent) : m * 5n ** BigInt(-exponent);\n const digits = n.toString();\n return { digits, point: exponent >= 0 ? digits.length : digits.length + exponent };\n}\n\n/** `%.<digits>f` of a finite double, rounded from its exact value with ties to even. */\nexport function fixed(value: number, digits = 0): string {\n if (Number.isNaN(value)) return \"nan\";\n if (!Number.isFinite(value)) return value > 0 ? \"inf\" : \"-inf\";\n const sign = value < 0 ? \"-\" : \"\";\n const { digits: all, point } = exact(value);\n const text = all.padEnd(point + digits + 1, \"0\");\n\n const kept = text.slice(0, point + digits);\n const next = text[point + digits] ?? \"0\";\n const tail = text.slice(point + digits + 1).replace(/0+$/, \"\");\n\n let n = BigInt(kept === \"\" ? \"0\" : kept);\n if (next > \"5\" || (next === \"5\" && (tail !== \"\" || n % 2n !== 0n))) n += 1n;\n\n const body = n.toString().padStart(digits + 1, \"0\");\n return sign + (digits === 0 ? body : `${body.slice(0, -digits)}.${body.slice(-digits)}`);\n}\n\n/** `%d` on a float: Python truncates toward zero. */\nexport function int0(value: number): string {\n return String(Math.trunc(value));\n}","import { fixed } from \"./format\";\nimport type { WakeCounts } from \"../model\";\nimport { int0 } from \"./format\";\n\n// Windows for the weekly-limit gain: percentage points spent in the last N hours.\nexport const GAIN_HOURS = [1, 6, 24];\n// Window for the checks and the leaks: what the user fixed recently must show up.\nexport const CHECK_HOURS = 24;\nexport const LEVELS: Record<number, \"critical\" | \"warn\" | \"info\"> = {\n 1: \"critical\",\n 2: \"warn\",\n 3: \"info\",\n};\n\n/** Thresholds for the per-session leak flags. Each one maps to a measured failure. */\nexport const BENCH_WINDOW = 200_000; // the benchmark: same turns with context capped here\nexport const LATE_COMPACT_PEAK = 300_000; // context above this means auto-compact fires too late\nexport const CALLER_READS = 100; // reads the caller ran itself instead of delegating\nexport const WAKEUPS = 50; // teammate/task/peer messages, each a full-context turn\nexport const TURNS_PER_PROMPT = 200; // an unbounded autonomous loop\nexport const LONG_LIVED_HOURS = 12; // one session carrying many unrelated tasks\nexport const MEMORY_INDEX_LINES = 200; // Claude Code loads only this many lines of MEMORY.md\nexport const COMPACT_WINDOW_MAX = 300_000;\nexport const SUBAGENT_CAP = 3; // most concurrent subagents worth running (each one is a full loop)\nexport const SUBAGENT_DEPTH = 1; // nesting depth: 1 blocks subagents spawning subagents\nexport const TOOL_CONCURRENCY = 4; // parallel tool calls in the main agent\nexport const SUBAGENT_ENV = \"CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS\";\nexport const CODEX_SUBAGENT_KEY = \"max_concurrent_threads_per_session\";\n\n/** A session whose last turn is this recent counts as active right now. */\nexport const ACTIVE_MINUTES = 30;\n\n/** The leak flags for one session, each naming its own fix. burn.py:316 */\nexport function sessionFlags(\n turns: number,\n peak: number,\n hours: number,\n reads: number,\n wakes: WakeCounts,\n): string[] {\n const flags: string[] = [];\n if (peak > LATE_COMPACT_PEAK) {\n flags.push(\n `late compaction: peak ${int0(peak / 1000)}k. Set autoCompactWindow to about 200000.`,\n );\n }\n if (reads >= CALLER_READS) {\n flags.push(\n `caller reads: ${reads} file/log reads. Send them to a cheap read-only agent.`,\n );\n }\n const pings = wakes.teammate + wakes.task + wakes.peer;\n if (pings >= WAKEUPS) {\n flags.push(\n `wakeups: ${pings} (teammate ${wakes.teammate}, task ${wakes.task}, peer ${wakes.peer}). Ask for one report at the end.`,\n );\n }\n if (turns / Math.max(wakes.human, 1) >= TURNS_PER_PROMPT) {\n flags.push(\n `loop: ${turns} turns for ${wakes.human} human prompts. Give the loop a stop condition and a budget.`,\n );\n }\n if (hours >= LONG_LIVED_HOURS) {\n flags.push(`long-lived: ${fixed(hours)}h. Start one fresh session per task.`);\n }\n return flags;\n}","import { int0 } from \"./format\";\n\nexport const CACHE_READ_RATE = 0.1;\nexport const CACHE_WRITE_RATE = 1.25;\nexport const OUTPUT_RATE = 5.0;\n\n/** Rough price ratios against the flagship of each family. burn.py:44 */\nexport const MODEL_RATE: Record<string, number> = {\n haiku: 0.2,\n sonnet: 0.6,\n opus: 1.0,\n \"gpt-5-mini\": 0.2,\n \"gpt-5.5\": 1.0,\n \"gpt-5\": 1.0,\n};\n\n/** Longest key first, so \"gpt-5-mini\" does not match \"gpt-5\". burn.py:61 */\nconst RATES = Object.entries(MODEL_RATE).sort((a, b) => b[0].length - a[0].length);\n\nexport const SIZE_BUCKETS: [number, number | null][] = [\n [0, 100],\n [100, 200],\n [200, 300],\n [300, 500],\n [500, 1000],\n [1000, null],\n];\n\n/** Price ratio for a model id, or null when the model is unknown. burn.py:59 */\nexport function modelRate(model: string | null): number | null {\n const id = model || \"\";\n for (const [name, rate] of RATES) if (id.includes(name)) return rate;\n return null;\n}\n\n/** The context-size bucket a turn of `tokens` falls in. burn.py:67 */\nexport function bucketLabel(tokens: number): string {\n for (const [low, high] of SIZE_BUCKETS) {\n if (high === null || (low <= tokens / 1000 && tokens / 1000 < high)) {\n return high === null ? `${low}k+` : `${low}-${high}k`;\n }\n }\n return \"?\";\n}\n\n/** The bucket label for a bucket row, from its edges. burn.py:751 */\nexport function bucketRowLabel(low: number, high: number | null): string {\n return high === null ? `${low}k+` : `${low}-${high}k`;\n}\n\n/** Shared by flags and reports: \"%dk\" % (tokens / 1000). */\nexport function kilo(tokens: number): string {\n return int0(tokens / 1000);\n}","import { int0 } from \"./format\";\nimport { COMPACT_WINDOW_MAX, MEMORY_INDEX_LINES, SUBAGENT_CAP, SUBAGENT_DEPTH, TOOL_CONCURRENCY, SUBAGENT_ENV, CODEX_SUBAGENT_KEY } from \"./flags\";\nimport type { ConfigInput, ConfigNote, Source } from \"../model\";\n\n/** A numeric note where lower is better: unset or over the limit warns. burn.py:410 */\nfunction atMost(\n agent: Source,\n label: string,\n key: string,\n value: number | null,\n source: string | null,\n limit: number,\n): ConfigNote {\n let shown: string;\n let line: string;\n if (value === null) {\n shown = \"unset\";\n line = `${key} is unset: set it to at most ${limit}.`;\n } else {\n shown = String(value);\n line =\n value > limit\n ? `${key} is ${value} (from ${source}): too high. Use ${limit}.`\n : `${key} is ${value} (from ${source}): ok.`;\n }\n const ok = value !== null && value <= limit;\n return {\n name: label,\n source: agent,\n value: shown,\n target: `at most ${limit}`,\n ok,\n level: ok ? \"ok\" : \"warn\",\n ratio: value ? value / limit : null,\n line,\n };\n}\n\n/** A string note: unset warns, set is ok. `want` is the advice when unset. burn.py:424 */\nfunction isSet(\n agent: Source,\n label: string,\n key: string,\n value: string | null,\n source: string | null,\n want: string,\n): ConfigNote {\n const ok = Boolean(value);\n const line = ok\n ? `${key} is ${value} (from ${source}): ok.`\n : `${key} is unset: ${want}`;\n return {\n name: label,\n source: agent,\n value: value || \"unset\",\n target: \"pinned\",\n ok,\n level: ok ? \"ok\" : \"warn\",\n ratio: null,\n line,\n };\n}\n\n/** The auto-compact window in tokens, and the source that set it. burn.py:335 */\nexport function compactWindow(\n config: ConfigInput,\n): [number | null, string | null] {\n const env = config.env.CLAUDE_CODE_AUTO_COMPACT_WINDOW;\n if (env) {\n const text = env.trim().toLowerCase();\n const scale: Record<string, number> = { k: 1_000, m: 1_000_000 };\n const unit = text.slice(-1);\n const factor = scale[unit] ?? 1;\n const parsed = Number.parseFloat(text.replace(/[km]+$/, \"\"));\n if (!Number.isFinite(parsed)) return [null, `env (unparsed: ${env})`];\n const value = parsed * factor;\n return [Math.trunc(value >= 1000 ? value : value * 1000), \"env\"];\n }\n const value = settings(config)?.autoCompactWindow;\n return typeof value === \"number\" && Number.isFinite(value) ? [Math.trunc(value), \"settings\"] : [null, null];\n}\n\n/** An integer env setting from settings.json .env (which wins) or the process env. burn.py:354 */\nexport function claudeEnvInt(\n config: ConfigInput,\n key: string,\n): [number | null, string | null] {\n const raw = (settings(config)?.env as Record<string, unknown> | undefined)?.[key];\n let value: unknown = raw;\n let source = \"settings\";\n if (value === undefined || value === null) {\n value = config.env[key];\n source = \"env\";\n }\n if (value === undefined || value === null) return [null, null];\n const parsed = typeof value === \"number\" ? value : Number.parseFloat(String(value));\n if (!Number.isFinite(parsed)) return [null, `${source} (unparsed: ${String(value)})`];\n return [Math.trunc(parsed), source];\n}\n\n/** A string env setting from settings.json .env or the process env. burn.py:373 */\nexport function claudeEnvStr(config: ConfigInput, key: string): [string | null, string | null] {\n const raw = (settings(config)?.env as Record<string, unknown> | undefined)?.[key];\n if (raw === undefined || raw === null) return [config.env[key] ?? null, \"env\"];\n return [String(raw), \"settings\"];\n}\n\n/** The concurrent-subagent cap and the source that set it. burn.py:385 */\nexport function claudeSubagentCap(config: ConfigInput): [number | null, string | null] {\n return claudeEnvInt(config, SUBAGENT_ENV);\n}\n\n/** A value (string) from Codex config.toml, under [table] or as a dotted key. burn.py:390 */\nexport function codexValue(config: ConfigInput, key: string): string | null {\n const text = config.codexConfig;\n if (text === null) return null;\n const match = new RegExp(\n `^\\\\s*(?:[a-z_]+\\\\s*\\\\.\\\\s*)?${key.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\")}\\\\s*=\\\\s*(.+)$`,\n \"m\",\n ).exec(text);\n return match ? match[1].trim().replace(/^[\"']|[\"']$/g, \"\") : null;\n}\n\n/** Codex's [agents] max_concurrent_threads_per_session. burn.py:401 */\nexport function codexSubagentCap(config: ConfigInput): [number | null, string | null] {\n const value = codexValue(config, CODEX_SUBAGENT_KEY);\n const parsed = Number.parseInt(value ?? \"\", 10);\n return Number.isFinite(parsed) ? [parsed, \"config.toml\"] : [null, null];\n}\n\n/** Recommended settings, one per agent, judged from actual config. burn.py:434 */\nexport function configNotes(live: Source[], config: ConfigInput): ConfigNote[] {\n const notes: ConfigNote[] = [];\n if (live.includes(\"claude\")) {\n const [window, wsource] = compactWindow(config);\n const within = Boolean(window) && Math.abs((window as number) - 200_000) <= 50_000;\n let line: string;\n if (window === null) {\n line =\n 'autoCompactWindow is unset: compaction waits for the model window (about 1M on 1M models). Set \"autoCompactWindow\": 200000.';\n } else if (window > COMPACT_WINDOW_MAX) {\n line = `autoCompactWindow is ${int0(window / 1000)}k (from ${wsource}): too high. Use about 200k.`;\n } else {\n line = `autoCompactWindow is ${int0(window / 1000)}k (from ${wsource}): ok.`;\n }\n notes.push({\n name: \"autoCompactWindow\",\n source: \"claude\",\n value: window ? `${int0(window / 1000)}k` : \"unset (model max)\",\n target: \"about 200k\",\n ok: within,\n level: within ? \"ok\" : \"warn\",\n ratio: window ? window / 200_000 : null,\n line,\n });\n const [cap, csrc] = claudeSubagentCap(config);\n notes.push(atMost(\"claude\", \"Max concurrent subagents\", SUBAGENT_ENV, cap, csrc, SUBAGENT_CAP));\n const [depth, dsrc] = claudeEnvInt(config, \"CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH\");\n notes.push(\n atMost(\"claude\", \"Subagent spawn depth\", \"CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH\", depth, dsrc, SUBAGENT_DEPTH),\n );\n const [model, msrc] = claudeEnvStr(config, \"CLAUDE_CODE_SUBAGENT_MODEL\");\n notes.push(\n isSet(\n \"claude\",\n \"Subagent model\",\n \"CLAUDE_CODE_SUBAGENT_MODEL\",\n model,\n msrc,\n \"subagents inherit the main model; pin a cheap worker (e.g. CLAUDE_CODE_SUBAGENT_MODEL=sonnet).\",\n ),\n );\n const [tools, tsrc] = claudeEnvInt(config, \"CLAUDE_CODE_MAX_TOOL_USE_CONCURRENCY\");\n notes.push(\n atMost(\"claude\", \"Tool-call concurrency\", \"CLAUDE_CODE_MAX_TOOL_USE_CONCURRENCY\", tools, tsrc, TOOL_CONCURRENCY),\n );\n }\n if (live.includes(\"codex\")) {\n const [cap, csrc] = codexSubagentCap(config);\n notes.push(\n atMost(\"codex\", \"Max concurrent subagents\", `agents.${CODEX_SUBAGENT_KEY}`, cap, csrc, SUBAGENT_CAP),\n );\n const depth = codexValue(config, \"max_depth\");\n notes.push(\n atMost(\n \"codex\",\n \"Agent nesting depth\",\n \"agents.max_depth\",\n depth && /^\\d+$/.test(depth) ? Number.parseInt(depth, 10) : null,\n \"config.toml\",\n SUBAGENT_DEPTH,\n ),\n );\n const effort = codexValue(config, \"default_subagent_reasoning_effort\");\n const effortOk = effort === \"low\" || effort === \"medium\" || effort === \"minimal\" || effort === \"none\";\n notes.push({\n name: \"Subagent reasoning effort\",\n source: \"codex\",\n value: effort || \"unset\",\n target: \"low or medium\",\n ok: effortOk,\n level: effortOk ? \"ok\" : \"warn\",\n ratio: null,\n line: effortOk\n ? `agents.default_subagent_reasoning_effort is ${effort}: ok.`\n : `agents.default_subagent_reasoning_effort is ${effort || \"unset\"}: set it to low or medium so workers don't inherit a costly effort.`,\n });\n const compact = codexValue(config, \"model_auto_compact_token_limit\");\n const compactOk = compact !== null && /^\\d+$/.test(compact) && Number.parseInt(compact, 10) <= COMPACT_WINDOW_MAX;\n notes.push({\n name: \"Auto-compact token limit\",\n source: \"codex\",\n value: compact || \"unset\",\n target: \"about 160k\",\n ok: compactOk,\n level: compactOk ? \"ok\" : \"warn\",\n ratio: null,\n line: compactOk\n ? `model_auto_compact_token_limit is ${compact}: ok.`\n : `model_auto_compact_token_limit is ${compact || \"unset\"}: set about 160000 for a >=200K window.`,\n });\n }\n return notes;\n}\n\n/** The config check sentences. burn.py:498 */\nexport function configChecks(live: Source[], config: ConfigInput): string[] {\n const lines = configNotes(live, config).map((note) => note.line);\n if (live.includes(\"claude\")) {\n for (const index of config.memoryIndexes) {\n const shown =\n config.claudeBase === config.claudeHome\n ? index.path.replace(config.claudeBase, \"~/.claude\")\n : index.path;\n if (index.lines > MEMORY_INDEX_LINES) {\n lines.push(\n `${shown} has ${index.lines} lines: lines after ${MEMORY_INDEX_LINES} are not loaded, so those memories are invisible. Shorten it.`,\n );\n }\n }\n }\n return lines.length ? lines : [\"none\"];\n}\n\n/** The parsed settings.json object, or an empty object for a missing or broken file. */\nfunction settings(config: ConfigInput): Record<string, any> | undefined {\n if (config.settings === null) return undefined;\n try {\n const parsed = JSON.parse(config.settings);\n return typeof parsed === \"object\" && parsed !== null ? parsed : undefined;\n } catch {\n return undefined;\n }\n}","import { fixed, int0 } from \"./format\";\nimport { configNotes } from \"./config-checks\";\nimport { LONG_LIVED_HOURS } from \"./flags\";\nimport type { BaselineRow, ConfigInput, RawPerSource, RawReport, Source } from \"../model\";\n\n/** Level of a value against an \"under\" target: ok up to the target, warn up to twice it. burn.py:1072 */\nexport function severity(ratio: number): \"ok\" | \"warn\" | \"critical\" {\n return ratio <= 1 ? \"ok\" : ratio <= 2 ? \"warn\" : \"critical\";\n}\n\nconst median = (xs: number[]): number | null =>\n xs.length ? [...xs].sort((a, b) => a - b)[xs.length >> 1] : null;\nconst pct = (v: number): string => `${fixed(v)}%`;\nconst count = (v: number): string => fixed(v);\nconst hours = (v: number): string => `${fixed(v)}h`;\nconst kilo = (v: number): string => `${int0(v / 1000)}k`;\nconst share = (a: number, b: number): number | null => (b ? (100 * a) / b : null);\n\n/** The lever rows for one source, from its per-source aggregates. burn.py:1077 */\nfunction providerLevers(src: Source, p: RawPerSource): BaselineRow[] {\n const { recent, stats7: stats, totals: tot } = p;\n const wakes = recent.wakes;\n const ping = (w: typeof wakes) => w.teammate + w.task + w.peer;\n const have = recent.turns > 0;\n\n // (name, format, 24 h value, whole-window value, target text, limit, advisory)\n const levers: [string, (v: number) => string, number | null, number, string, number, boolean][] = [\n [\"Spend on turns over 300k\", pct, share(recent.over, recent.total), p.over_300k, \"under 10%\", 10, false],\n [\"Median context per turn\", kilo, median(recent.contexts), median(p.contexts) ?? 0, \"under 150k\", 150_000, false],\n [\"Turns per human prompt\", count, have ? recent.turns / Math.max(wakes.human, 1) : null, p.turns / Math.max(tot.human, 1), \"under 50\", 50, false],\n [\"Caller reads per tool call\", pct, have ? share(recent.reads, recent.tool_calls) : null, share(tot.reads, tot.tool_calls) ?? 0, \"under 20%\", 20, false],\n [\"Wakeups per session\", count, recent.sessions ? ping(wakes) / recent.sessions : null, ping(tot) / Math.max(p.session_count, 1), \"under 20\", 20, false],\n [\"Longest top session\", hours, p.hours24 || null, p.hours_all, `under ${LONG_LIVED_HOURS}h`, LONG_LIVED_HOURS, false],\n [\"Spend on the top model\", pct, share(recent.top, recent.total), share(stats.top, p.total) ?? 0, \"under 60%\", 60, true],\n ];\n if (stats.cache_input) {\n levers.push([\"Cache rebuilds\", pct, share(recent.cache_write, recent.cache_input), share(stats.cache_write, stats.cache_input) ?? 0, \"under 10%\", 10, false]);\n }\n if (p.preamble) {\n levers.push([\"Preamble per session (p50)\", kilo, median(recent.preambles), p.preamble[0], \"under 40k\", 40_000, false]);\n }\n\n const rows: BaselineRow[] = [];\n for (const [name, fmt, now, week, target, limit, advisory] of levers) {\n const ratio = now === null ? null : now / limit;\n let level: BaselineRow[\"level\"] = ratio === null ? \"ok\" : severity(ratio);\n if (advisory && level !== \"ok\") level = \"info\";\n rows.push({\n name,\n now_24h: now === null ? \"-\" : fmt(now),\n value_7d: fmt(week),\n target,\n ok: level === \"ok\",\n level,\n ratio,\n advisory,\n source: src,\n });\n }\n return rows;\n}\n\n/**\n * Every lever per live provider over the last CHECK_HOURS and the whole window, against a\n * recommended target, plus the per-agent config rows. The level judges the 24 h value; a\n * lever with no 24 h data is ok. burn.py:1125\n */\nexport function baseline(report: RawReport, config: ConfigInput): BaselineRow[] {\n const live = report.sources.map(([name]) => name);\n const rows: BaselineRow[] = [];\n for (const src of live) {\n const p = report.per_source[src];\n if (p) rows.push(...providerLevers(src, p));\n }\n for (const note of configNotes(live, config)) {\n rows.push({\n name: note.name,\n now_24h: note.value,\n value_7d: null,\n target: note.target,\n ok: note.ok,\n level: note.level,\n ratio: note.ratio,\n advisory: false,\n source: note.source,\n });\n }\n return rows;\n}","import { fixed } from \"./format\";\nimport type { RawReport, Source } from \"../model\";\n\n/**\n * Cumulative (time, % of the weekly limit used, % if context were capped) per hour, from the\n * week start to now. The last point is the calibrated total, so it equals the plan's reading.\n * burn.py:843\n */\nexport function weekPoints(\n buckets: Map<number, [number, number]>,\n start: Date,\n now: Date,\n limit: number,\n): [Date, number, number][] {\n const points: [Date, number, number][] = [[start, 0, 0]];\n let used = 0;\n let capped = 0;\n for (const [hour, slot] of [...buckets.entries()].sort((a, b) => a[0] - b[0])) {\n used += slot[0];\n capped += slot[1];\n const end = new Date(hour + 3_600_000);\n points.push([end < now ? end : now, (used * 100) / limit, (capped * 100) / limit]);\n }\n const last = points[points.length - 1];\n if (last[0].getTime() < now.getTime()) points.push([now, last[1], last[2]]);\n return points;\n}\n\n/**\n * The hourly burn goal for one source: the plan's remaining week over the hours to its\n * reset, else (Claude only) a weekly budget over 168 h, else the window's own average.\n * burn.py:912\n */\nexport function burnGoal(report: RawReport, source: Source): [number, string] {\n const burn = report.burns[source];\n if (!burn) return [0, \"no burn for this source\"];\n const week = burn.week;\n if (week) {\n return [\n week.ideal,\n `ideal pace to the weekly reset ${localStamp(week.resets)} (${fixed(week.hours_left)} h left)`,\n ];\n }\n if (report.budget && source === \"claude\") {\n return [report.budget / 168, `weekly budget ${fixed(report.budget / 1e6)}M / 168 h`];\n }\n return [\n burn.total / (report.days * 24),\n `your ${report.days}-day average; the subscription usage was unavailable`,\n ];\n}\n\n/** Python's strftime(\"%a %H:%M\") in the local zone. */\nfunction localStamp(when: Date): string {\n const local = new Date(when.getTime() - when.getTimezoneOffset() * 60_000);\n const day = [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"][local.getUTCDay()];\n const hours = String(local.getUTCHours()).padStart(2, \"0\");\n const minutes = String(local.getUTCMinutes()).padStart(2, \"0\");\n return `${day} ${hours}:${minutes}`;\n}","import {\n ACTIVE_MINUTES,\n BENCH_WINDOW,\n CHECK_HOURS,\n GAIN_HOURS,\n sessionFlags,\n} from \"./flags\";\nimport {\n CACHE_READ_RATE,\n CACHE_WRITE_RATE,\n MODEL_RATE,\n OUTPUT_RATE,\n SIZE_BUCKETS,\n bucketLabel,\n bucketRowLabel,\n modelRate,\n} from \"./pricing\";\nimport { configChecks } from \"./config-checks\";\nimport { baseline } from \"./baseline\";\nimport { weekPoints } from \"./burn\";\nimport type {\n ActiveSession,\n HourSlot,\n RawRecent,\n RawReport,\n RawStats,\n RawWeek,\n ReportInput,\n SessionRow,\n Source,\n Totals,\n WakeCounts,\n Week,\n} from \"../model\";\n\n/** burn.py:527. Pure: every file, clock reading and env value arrives in the input. */\nexport function buildReport(input: ReportInput): RawReport | null {\n const { now, days, config } = input;\n if (!input.live.length) return null;\n const cutoff = new Date(now.getTime() - days * 86_400_000);\n const recentCut = new Date(now.getTime() - CHECK_HOURS * 3_600_000);\n const hour1Cut = new Date(now.getTime() - 3_600_000);\n const gainCuts = GAIN_HOURS.map((h) => [h, new Date(now.getTime() - h * 3_600_000)] as const);\n\n const bySize = new Map<string, number>();\n const turnsBySize = new Map<string, number>();\n const byProject = new Map<string, number>();\n const bySource = new Map<string, number>();\n const tools = new Map<string, number>();\n const unpriced = new Map<string, number>();\n /** key -> cost, turns, peak, hours */\n const sessions = new Map<string, [number, number, number, number]>();\n /** key -> reads, wakes */\n const signals = new Map<string, [number, WakeCounts]>();\n const paths = new Map<string, string>();\n const titles = new Map<string, string | null>();\n const timeline = new Map<number, [number, number]>();\n const hourly = new Map<number, HourSlot>();\n const contexts: number[] = [];\n const preambles: number[] = [];\n const totals = emptyTotals();\n const lastHour = new Map<Source, number>();\n const recent = new Map<Source, Map<number, number>>();\n const weekHourly = new Map<Source, Map<number, [number, number]>>();\n const active: [string, number, number, string | null, number][] = [];\n const sessions24 = new Map<string, [number, number, number, number]>();\n const signals24 = new Map<string, [number, WakeCounts]>();\n const per = new Map<Source, PerSource>();\n const weeks: Record<Source, Week | null> = { claude: input.planWeek, codex: input.codexWeek };\n const weekNow = new Map<Source, number>();\n\n let total = 0;\n let unpricedCost = 0;\n let preambleReread = 0;\n let allContext = 0;\n const stats7 = emptyStats();\n const last24: RawRecent = { ...emptyRecent(), sessions: 0 };\n const topRate = Math.max(...Object.values(MODEL_RATE));\n\n const filesBySource = new Map<Source, typeof input.sessions>();\n for (const session of input.sessions) {\n const list = filesBySource.get(session.source);\n if (list) list.push(session);\n else filesBySource.set(session.source, [session]);\n }\n\n for (const source of input.live) {\n for (const file of filesBySource.get(source) ?? []) {\n if (file.mtimeMs < cutoff.getTime()) continue; // untouched since before the window\n let cost = 0;\n let reads = 0;\n const wakes = emptyWakes();\n let count = 0;\n let peak = 0;\n let hourCost = 0;\n let model: string | null = null;\n let firstContext = 0;\n let firstSeen: Date | null = null;\n let lastSeen: Date | null = null;\n let lastContext = 0;\n let cCost = 0;\n let cCount = 0;\n let cPeak = 0;\n let cReads = 0;\n const cWakes = emptyWakes();\n let project = \"\";\n let session = \"\";\n\n for (const item of file.turns) {\n if (item.when < cutoff) continue;\n const context = item.baseIn + item.cacheRead + item.cacheWrite;\n if (!context) continue;\n\n const rate = modelRate(item.model);\n const raw =\n item.baseIn +\n CACHE_READ_RATE * item.cacheRead +\n CACHE_WRITE_RATE * item.cacheWrite +\n OUTPUT_RATE * item.output;\n const priced = rate ?? 1;\n const weighted = priced * raw;\n if (rate === null) {\n bump(unpriced, item.model || \"unknown\");\n unpricedCost += weighted;\n }\n\n project = item.project;\n session = item.session;\n const key = sessionKey(source, project, session);\n count += 1;\n cost += weighted;\n total += weighted;\n model = item.model || model;\n if (item.when >= hour1Cut) {\n bumpMap(lastHour, source, weighted);\n hourCost += weighted;\n }\n for (const [h, cut] of gainCuts) if (item.when >= cut) bumpGain(recent, source, h, weighted);\n const week = weeks[source];\n if (week && item.when >= week.start) bumpMap(weekNow, source, weighted);\n allContext += context;\n const isTop = rate !== null && rate >= topRate;\n stats7.turns += 1;\n if (isTop) stats7.top += weighted;\n if (source === \"claude\") {\n // Codex logs no cache writes, so it would read as 0%\n stats7.cache_write += item.cacheWrite;\n stats7.cache_input += context;\n }\n if (context > peak) peak = context;\n bump(byProject, project, weighted);\n bump(bySource, source, weighted);\n const label = bucketLabel(context);\n bump(bySize, label, weighted);\n turnsBySize.set(label, (turnsBySize.get(label) ?? 0) + 1);\n for (const name of item.tools) if (name) bump(tools, name);\n const hour = hourStart(item.when);\n const slot = timeline.get(hour) ?? (timeline.set(hour, [0, 0]), timeline.get(hour)!);\n slot[context >= 300_000 ? 1 : 0] += weighted;\n // Benchmark: the same turn if auto-compact had kept context at BENCH_WINDOW.\n const trimmed = Math.max(item.cacheRead - Math.max(context - BENCH_WINDOW, 0), 0);\n const hourSlot = hourly.get(hour) ?? emptySlot();\n const benchTurn = weighted - priced * (CACHE_READ_RATE * (item.cacheRead - trimmed));\n hourSlot.bench += benchTurn;\n if (!hourly.has(hour)) hourly.set(hour, hourSlot);\n if (week && item.when >= week.start) {\n const per2 = weekHourly.get(source) ?? new Map<number, [number, number]>();\n if (!weekHourly.has(source)) weekHourly.set(source, per2);\n const bucket = per2.get(hour) ?? [0, 0];\n bucket[0] += weighted;\n bucket[1] += benchTurn;\n per2.set(hour, bucket);\n }\n hourSlot.ctx.push(context);\n hourSlot.reads += item.reads;\n hourSlot.calls += item.tools.length;\n contexts.push(context);\n totals.tool_calls += item.tools.length;\n totals.reads += item.reads;\n reads += item.reads;\n for (const wake of item.wakes) wakes[wake] += 1;\n for (const wake of item.wakes) totals[wake] += 1;\n\n const p = perSource(per, source);\n p.total += weighted;\n p.turns += 1;\n if (context >= 300_000) p.over += weighted;\n p.sessions.add(key);\n p.contexts.push(context);\n p.stats7.turns += 1;\n if (isTop) p.stats7.top += weighted;\n p.totals.tool_calls += item.tools.length;\n p.totals.reads += item.reads;\n for (const wake of item.wakes) p.totals[wake] += 1;\n if (source === \"claude\") {\n p.stats7.cache_write += item.cacheWrite;\n p.stats7.cache_input += context;\n }\n\n if (item.when >= recentCut) {\n cCost += weighted;\n cCount += 1;\n if (context > cPeak) cPeak = context;\n cReads += item.reads;\n for (const wake of item.wakes) cWakes[wake] += 1;\n last24.total += weighted;\n if (context >= 300_000) last24.over += weighted;\n last24.turns += 1;\n last24.contexts.push(context);\n last24.tool_calls += item.tools.length;\n last24.reads += item.reads;\n for (const wake of item.wakes) last24.wakes[wake] += 1;\n if (isTop) last24.top += weighted;\n if (source === \"claude\") {\n last24.cache_write += item.cacheWrite;\n last24.cache_input += context;\n }\n const p24 = p.recent;\n p24.total += weighted;\n if (context >= 300_000) p24.over += weighted;\n p24.turns += 1;\n p24.contexts.push(context);\n p24.tool_calls += item.tools.length;\n p24.reads += item.reads;\n for (const wake of item.wakes) p24.wakes[wake] += 1;\n if (isTop) p24.top += weighted;\n if (source === \"claude\") {\n p24.cache_write += item.cacheWrite;\n p24.cache_input += context;\n }\n }\n\n if (count === 1) {\n firstContext = context;\n firstSeen = item.when;\n }\n lastSeen = item.when;\n lastContext = context;\n }\n\n if (!count) continue;\n const key = sessionKey(source, project, session);\n // The first turn is the always-resident prefix: instructions, memory, skill\n // catalog, tool schemas. Every later turn re-reads it.\n preambleReread += firstContext * count;\n preambles.push(firstContext);\n const hours = firstSeen && lastSeen ? (lastSeen.getTime() - firstSeen.getTime()) / 3_600_000 : 0;\n sessions.set(key, [cost, count, peak, hours]);\n signals.set(key, [reads, wakes]);\n if (cCount) {\n sessions24.set(key, [cCost, cCount, cPeak, hours]);\n signals24.set(key, [cReads, cWakes]);\n if (firstSeen && firstSeen >= recentCut) last24.preambles.push(firstContext);\n const p = perSource(per, source);\n p.recent.sessions += 1;\n if (firstSeen && firstSeen >= recentCut) p.recent.preambles.push(firstContext);\n }\n const p = perSource(per, source);\n p.preambles.push(firstContext);\n if (hours > p.hours_all) p.hours_all = hours;\n if (hours > p.hours24) p.hours24 = hours;\n paths.set(key, file.path);\n if (source === \"claude\") titles.set(key, file.title);\n const idle = lastSeen ? (now.getTime() - lastSeen.getTime()) / 60_000 : 0;\n if (idle <= ACTIVE_MINUTES) active.push([key, lastContext, idle, model, hourCost]);\n }\n }\n\n if (!total) return null;\n\n const share = (value: number): number => (100 * value) / total;\n const byCost = (a: [string, [number, number, number, number]], b: [string, [number, number, number, number]]) => b[1][0] - a[1][0];\n const top = [...sessions.entries()].sort(byCost).slice(0, 10);\n\n const buckets: RawReport[\"buckets\"] = [];\n for (const [low, high] of SIZE_BUCKETS) {\n const label = bucketRowLabel(low, high);\n if (bySize.get(label)) {\n buckets.push([label, low, share(bySize.get(label)!), turnsBySize.get(label)!]);\n }\n }\n preambles.sort((a, b) => a - b);\n last24.sessions = sessions24.size;\n const share24 = (value: number): number => (last24.total ? (100 * value) / last24.total : 0);\n const flags24 = (key: string): string[] => {\n const row = sessions24.get(key);\n if (!row) return [];\n const [, turns, cPeak, hours] = row;\n const [cReads, cWakes] = signals24.get(key)!;\n return sessionFlags(turns, cPeak, hours, cReads, cWakes);\n };\n const sessionRow = (\n key: string,\n [cost, count, peak, hours]: [number, number, number, number],\n shareOf: (value: number) => number,\n ): SessionRow => {\n const [source, project, session] = splitKey(key);\n return {\n source: source as Source,\n project: project || \"?\",\n id: (session || \"?\").slice(0, 8),\n title: titles.get(key) ?? null,\n path: paths.get(key) ?? null,\n share: shareOf(cost),\n turns: count,\n peak,\n hours,\n flags: flags24(key),\n };\n };\n\n const report: RawReport = {\n days,\n total,\n turns: [...sessions.values()].reduce((sum, row) => sum + row[1], 0),\n session_count: sessions.size,\n sources: [...bySource.entries()].sort((a, b) => (a[0] < b[0] ? -1 : 1)).map(([name, value]) => [name as Source, share(value)]),\n buckets,\n over_300k: buckets.filter((b) => b[1] >= 300).reduce((sum, b) => sum + b[2], 0),\n preamble: preambles.length\n ? [preambles[preambles.length >> 1], preambles[Math.trunc(preambles.length * 0.9)], (100 * preambleReread) / allContext]\n : null,\n projects: [...byProject.entries()]\n .sort((a, b) => b[1] - a[1])\n .slice(0, 8)\n .map(([name, value]) => [name, share(value)]),\n sessions: top.map(([key, row]) => sessionRow(key, row, share)),\n recent_sessions: [...sessions24.entries()]\n .sort(byCost)\n .slice(0, 10)\n .map(([key, row]) => sessionRow(key, row, share24)),\n recent: last24,\n tools: mostCommon(tools, 6),\n config: configChecks(input.live, config),\n unpriced: unpriced.size ? [share(unpricedCost), mostCommon(unpriced, 5)] : null,\n active: active\n .sort((a, b) => b[4] - a[4])\n .map(([key, context, idle, model, rate]): ActiveSession => {\n const [source, project, session] = splitKey(key);\n const src = source as Source;\n const sessionData = sessions.get(key)!;\n const hourSpend = lastHour.get(src) ?? 0;\n return {\n source: src,\n project: project || \"?\",\n id: (session || \"?\").slice(0, 8),\n title: titles.get(key) ?? null,\n share: share(sessionData[0]),\n turns: sessionData[1],\n peak: sessionData[2],\n hours: sessionData[3],\n context,\n idle,\n flags: flags24(key),\n model,\n rate,\n rateShare: hourSpend ? (100 * rate) / hourSpend : 0,\n };\n }),\n timeline: [...timeline.entries()].sort((a, b) => a[0] - b[0]).map(([hour, slot]) => [new Date(hour), slot]),\n hourly: [...hourly.entries()].sort((a, b) => a[0] - b[0]).map(([hour, slot]) => [new Date(hour), slot]),\n bench_total: [...hourly.values()].reduce((sum, slot) => sum + slot.bench, 0),\n budget: input.weeklyBudget ? input.weeklyBudget * 1e6 : null,\n stats7,\n per_source: {},\n baseline: [],\n burns: {},\n };\n\n for (const src of input.live) {\n const p = per.get(src);\n if (!p || !p.total) continue;\n const ctx = [...p.contexts].sort((a, b) => a - b);\n const pre = [...p.preambles].sort((a, b) => a - b);\n report.per_source[src] = {\n recent: p.recent,\n stats7: p.stats7,\n totals: p.totals,\n turns: p.turns,\n total: p.total,\n over_300k: p.over,\n session_count: p.sessions.size,\n hours24: p.hours24,\n hours_all: p.hours_all,\n contexts: ctx,\n preambles: pre,\n preamble: pre.length ? [pre[pre.length >> 1], pre[Math.trunc(pre.length * 0.9)]] : null,\n };\n }\n report.baseline = baseline(report, config);\n\n for (const src of input.live) {\n const spend = bySource.get(src);\n if (!spend) continue;\n const week = weeks[src];\n const spent = weekNow.get(src) ?? 0;\n const burn: RawReport[\"burns\"][Source] = { rate: lastHour.get(src) ?? 0, total: spend, week: null };\n if (week && week.used >= 1 && spent) {\n // Calibrate: this week's local spend is `used` percent of the plan's week.\n const limit = (spent * 100) / week.used;\n const hoursLeft = Math.max((week.resets.getTime() - now.getTime()) / 3_600_000, 1);\n const weekRecent = recent.get(src) ?? new Map<number, number>();\n const gains: Record<string, number> = {};\n for (const h of GAIN_HOURS) gains[h] = ((weekRecent.get(h) ?? 0) * 100) / limit;\n // Quota points per hour over the last 24 h. A week younger than that has spent only its\n // own points, so divide by the time since the week began.\n const age = Math.max((now.getTime() - week.start.getTime()) / 3_600_000, 1);\n const rate24 = age < CHECK_HOURS ? week.used / age : gains[CHECK_HOURS] / CHECK_HOURS;\n const left = 100 - week.used;\n const toEmpty = rate24 > 0 ? left / rate24 : null;\n const dry = toEmpty ? new Date(now.getTime() + toEmpty * 3_600_000) : null;\n const rawWeek: RawWeek = {\n resets: week.resets,\n hours_left: hoursLeft,\n used: week.used,\n ideal: Math.max(limit - spent, 0) / hoursLeft,\n limit,\n start: week.start,\n rate_pct: (burn.rate * 100) / limit,\n ideal_pct: Math.max(left, 0) / hoursLeft,\n burndown: weekPoints(weekHourly.get(src) ?? new Map(), week.start, now, limit),\n projection: {\n rate_pct: rate24,\n hours_to_empty: toEmpty,\n runs_out: dry && dry < week.resets ? dry : null,\n },\n gains,\n };\n burn.week = rawWeek;\n }\n report.burns[src] = burn;\n }\n return report;\n}\n\nfunction emptyWakes(): WakeCounts {\n return { human: 0, teammate: 0, task: 0, peer: 0 };\n}\n\nfunction emptyTotals(): Totals {\n return { tool_calls: 0, reads: 0, human: 0, teammate: 0, task: 0, peer: 0 };\n}\n\nfunction emptyStats(): RawStats {\n return { cache_write: 0, cache_input: 0, turns: 0, top: 0 };\n}\n\nfunction emptyRecent(): RawRecent {\n return {\n total: 0,\n over: 0,\n turns: 0,\n contexts: [],\n tool_calls: 0,\n reads: 0,\n wakes: emptyWakes(),\n preambles: [],\n cache_write: 0,\n cache_input: 0,\n top: 0,\n sessions: 0,\n };\n}\n\nfunction emptySlot(): HourSlot {\n return { bench: 0, ctx: [], reads: 0, calls: 0 };\n}\n\ninterface PerSource {\n recent: RawRecent;\n stats7: RawStats;\n totals: Totals;\n contexts: number[];\n preambles: number[];\n turns: number;\n total: number;\n over: number;\n sessions: Set<string>;\n hours24: number;\n hours_all: number;\n}\n\nfunction perSource(per: Map<Source, PerSource>, src: Source): PerSource {\n let p = per.get(src);\n if (!p) {\n p = {\n recent: emptyRecent(),\n stats7: emptyStats(),\n totals: emptyTotals(),\n contexts: [],\n preambles: [],\n turns: 0,\n total: 0,\n over: 0,\n sessions: new Set(),\n hours24: 0,\n hours_all: 0,\n };\n per.set(src, p);\n }\n return p;\n}\n\n/** The hour a turn falls in, as an epoch. burn.py:644 */\nfunction hourStart(when: Date): number {\n return Math.floor(when.getTime() / 3_600_000) * 3_600_000;\n}\n\n/** Session identity: the source, project and session id Python used as a tuple key. */\nfunction sessionKey(source: Source, project: string, session: string): string {\n return JSON.stringify([source, project, session]);\n}\n\nfunction splitKey(key: string): [Source, string, string] {\n const [source, project, session] = JSON.parse(key) as [Source, string, string];\n return [source, project, session];\n}\n\nfunction bump(map: Map<string, number>, key: string, value = 1): void {\n map.set(key, (map.get(key) ?? 0) + value);\n}\n\nfunction bumpMap(map: Map<Source, number>, key: Source, value: number): void {\n map.set(key, (map.get(key) ?? 0) + value);\n}\n\nfunction bumpGain(map: Map<Source, Map<number, number>>, key: Source, hours: number, value: number): void {\n let inner = map.get(key);\n if (!inner) {\n inner = new Map();\n map.set(key, inner);\n }\n inner.set(hours, (inner.get(hours) ?? 0) + value);\n}\n\n/** Counter.most_common(n): by count down, insertion order for ties. */\nfunction mostCommon(map: Map<string, number>, n: number): [string, number][] {\n return [...map.entries()].sort((a, b) => b[1] - a[1]).slice(0, n);\n}","import { fixed, int0 } from \"./format\";\nimport {\n CHECK_HOURS,\n CODEX_SUBAGENT_KEY,\n LEVELS,\n MEMORY_INDEX_LINES,\n SUBAGENT_CAP,\n SUBAGENT_DEPTH,\n SUBAGENT_ENV,\n TOOL_CONCURRENCY,\n} from \"./flags\";\nimport type { Priority, RawIssue, RawReport, SessionRow, Source } from \"../model\";\n\n/** Per leak flag prefix: short fix, title, why it costs tokens, and the prompt for an agent. burn.py:1201 */\nexport const ISSUES: Record<string, [fix: string, title: string, why: string, action: string]> = {\n \"late compaction\": [\n \"Set autoCompactWindow to about 200000, then /compact or restart old sessions.\",\n \"Sessions compact too late\",\n \"Every tool call re-reads the whole context. A turn at 500k costs about 5 times a turn at 100k, and auto-compact on a 1M model waits until about 1M.\",\n 'Set \"autoCompactWindow\": 200000 in ~/.claude/settings.json and check that CLAUDE_CODE_AUTO_COMPACT_WINDOW is unset or not higher. Then ask me to /compact or restart each listed session that is still open.',\n ],\n \"caller reads\": [\n \"Send multi-range reads, greps and log parsing to a cheap read-only subagent.\",\n \"The caller reads files and logs itself\",\n \"Each read in the main session is paid at its full context size. A cheap read-only subagent pays it at a small context and returns a short answer.\",\n \"Read the listed transcripts (JSONL, tool_use blocks named Bash/Read/Grep) and find the most repeated read commands. Then add a rule to my global agent instructions: after the brief, any read that is more than one bounded range goes to a cheap read-only subagent. Propose a helper script for any read pattern that repeats more than 20 times.\",\n ],\n wakeups: [\n \"Ask subagents and teammates for one report at the end; wait with one blocking command.\",\n \"Too many wakeups\",\n \"Each teammate message, task notification or cross-session message starts a turn that re-reads the full context.\",\n \"Read the listed transcripts and find which subagents, teammates or background jobs sent the messages. Change their briefs so they report once at the end, and replace polling or progress pings with one blocking background command per wait.\",\n ],\n loop: [\n \"Give each /goal or autonomous loop a stop condition and a turn or time budget.\",\n \"Autonomous loops run without a budget\",\n \"Hundreds of turns per human prompt means a /goal or autonomous loop kept going with no stop condition.\",\n \"Read the listed transcripts and name what kept each loop running. Then add a stop condition and a turn or time budget to the loop instructions I use (goal prompts, skills or CLAUDE.md).\",\n ],\n \"long-lived\": [\n \"Commit, end the session, and start one fresh session per task.\",\n \"Sessions stay open too long\",\n \"A session open for many hours carries summaries of many unrelated tasks, so every turn pays for old work.\",\n \"List which of these sessions are still open. For each, commit its work, end it, and write a one-paragraph handoff so a fresh session can continue from the PRD or task.\",\n ],\n};\n\n/** Extra context appended to a fix prompt, drawn from Token Furnace's community research. burn.py:1246 */\nexport const ISSUE_EXTRA: Record<string, string[]> = {\n \"late compaction\": [\n \"Anthropic supports earlier compaction: `CLAUDE_AUTOCOMPACT_PCT_OVERRIDE=80`, or `/autocompact 200k` in a running session.\",\n \"To drop 1M context entirely: `CLAUDE_CODE_DISABLE_1M_CONTEXT=1`.\",\n \"Codex: `model_auto_compact_token_limit = 160000` for a >=200K window.\",\n \"Do not compact blindly: compact or hand off between meaningful phases, not every N tokens.\",\n ],\n \"subagent fan-out cap\": [\n \"Claude Code defaults to 20 concurrent subagents and nesting depth 3, with no total cap.\",\n \"Also set the depth cap: `CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH=1` (Codex: `agents.max_depth`; note Multi-Agent V2 ignores it).\",\n \"Pin the worker model so it is not inherited silently: `CLAUDE_CODE_SUBAGENT_MODEL=sonnet` (add `CLAUDE_CODE_SUBAGENT_MODEL_FORCE=1` to hard-enforce).\",\n 'Codex: prefer `fork_turns=\"none\"` for independent workers so they do not inherit the parent conversation history.',\n ],\n \"subagent nesting depth\": [\n \"Nesting is the worst fan-out: a worker that spawns workers multiplies the whole loop.\",\n \"Claude: `CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH=1`. Codex: `agents.max_depth` (Multi-Agent V2 ignores it, so verify the effective depth from real traces).\",\n ],\n \"subagent model\": [\n \"`CLAUDE_CODE_SUBAGENT_MODEL=sonnet` is a default, not a guarantee; add `CLAUDE_CODE_SUBAGENT_MODEL_FORCE=1` to hard-enforce (it overrides intentional per-agent specialization).\",\n \"Codex: set `agents.default_subagent_model` explicitly; V2 can silently run a costlier worker than requested.\",\n \"Verify the effective model from real usage, not from the instruction.\",\n ],\n \"subagent reasoning effort\": [\n \"Children mostly scan and summarize; keep them at low/medium and let the parent keep its own effort.\",\n ],\n \"auto-compact token limit\": [\n \"Codex: `model_auto_compact_token_limit = 160000` for a >=200K window.\",\n \"Compact or hand off between meaningful phases, not blindly every N tokens.\",\n ],\n \"tool-call concurrency\": [\n \"`CLAUDE_CODE_MAX_TOOL_USE_CONCURRENCY=4` bounds parallel tool calls in the main agent.\",\n \"Limit shell output at the byte level; a line-count cap fails when one line is huge.\",\n ],\n \"caller reads\": [\n \"Give a worker a self-contained brief (exact paths, objective, acceptance) instead of forking the whole parent history.\",\n \"Trim the always-resident preamble once, then leave it stable: reads bill at 0.1x but rewrites at 1.25x.\",\n ],\n wakeups: [\"Ask teammates and background jobs for one report at the end, then wait once.\"],\n loop: [\n \"Give each worker agent a `maxTurns` ceiling (a 15-30 turn start for bounded tasks).\",\n \"On two identical failures, stop and re-plan instead of retrying.\",\n ],\n \"long-lived\": [\n \"Keep a concise task-state handoff (done / pending / current verification) so a fresh session does not repeat completed work after compaction.\",\n ],\n \"memory index too long\": [\n \"Move detail into topic files that load on demand; keep the index under the load limit.\",\n ],\n};\n\n/** Which agent a config-check line belongs to, for the Checks source column. burn.py:1311 */\nexport function configSource(line: string): Source | \"all\" {\n if (\n line.includes(CODEX_SUBAGENT_KEY) ||\n line.includes(\"max_depth\") ||\n line.includes(\"reasoning_effort\") ||\n line.includes(\"auto_compact_token_limit\") ||\n line.startsWith(\"agents.\")\n ) {\n return \"codex\";\n }\n if (line.includes(\"CLAUDE\") || line.includes(\"autoCompactWindow\") || line.includes(\"MEMORY.md\")) return \"claude\";\n return \"all\";\n}\n\n/** Group session flags and failed config checks into issues, largest spend share first. burn.py:1321 */\nexport function topIssues(report: RawReport): RawIssue[] {\n const groups = new Map<string, [SessionRow, string][]>();\n for (const s of report.recent_sessions) {\n for (const flag of s.flags) {\n const kind = flag.split(\":\")[0];\n const hits = groups.get(kind);\n if (hits) hits.push([s, flag]);\n else groups.set(kind, [[s, flag]]);\n }\n }\n const issues: RawIssue[] = [];\n for (const [kind, hits] of groups) {\n const [fix, title, why, action] = ISSUES[kind];\n const spies = new Map<Source, number>();\n for (const [s] of hits) spies.set(s.source, (spies.get(s.source) ?? 0) + 1);\n let source: Source | \"all\" = \"all\";\n if (spies.size === 1) source = [...spies.keys()][0];\n issues.push({\n title,\n why,\n action,\n fix,\n kind,\n source,\n share: hits.reduce((sum, [s]) => sum + s.share, 0),\n hits,\n priority: 3,\n });\n }\n issues.sort((a, b) => -(a.share ?? 0) - -(b.share ?? 0));\n\n const fixedLines = report.config.filter(\n (line) => line.includes(\"autoCompactWindow\") && line.endsWith(\"ok.\"),\n );\n for (const issue of issues) {\n if (issue.title === ISSUES[\"late compaction\"][1] && fixedLines.length) {\n issue.fix = \"Setting already ok. Restart or /compact the old sessions.\";\n issue.action = `The setting is already fixed (${fixedLines[0]}). Restart or /compact the listed sessions that are still open; new sessions are covered.`;\n }\n }\n for (const line of report.config) {\n if (line.endsWith(\"ok.\") || line === \"none\") continue;\n let title: string;\n let fix: string;\n if (line.includes(\"autoCompactWindow\")) {\n title = \"autoCompactWindow\";\n fix = line;\n } else if (line.includes(\"MEMORY.md\")) {\n title = \"memory index too long\";\n fix = `Shorten MEMORY.md under ${MEMORY_INDEX_LINES} lines; move detail into topic files.`;\n } else if (line.includes(\"SUBAGENT_SPAWN_DEPTH\") || line.includes(\"max_depth\")) {\n title = \"subagent nesting depth\";\n fix = `Cap subagent nesting depth at ${SUBAGENT_DEPTH}: recursive delegation multiplies the loop.`;\n } else if (line.includes(\"SUBAGENT_MODEL\")) {\n title = \"subagent model\";\n fix = \"Pin a cheap worker model so subagents do not inherit a premium one.\";\n } else if (line.includes(SUBAGENT_ENV) || line.includes(CODEX_SUBAGENT_KEY)) {\n title = \"subagent fan-out cap\";\n fix = `Cap concurrent subagents at ${SUBAGENT_CAP}: each one runs its own model and tool loop.`;\n } else if (line.includes(\"reasoning_effort\")) {\n title = \"subagent reasoning effort\";\n fix = \"Set the subagent reasoning effort to low or medium.\";\n } else if (line.includes(\"auto_compact_token_limit\")) {\n title = \"auto-compact token limit\";\n fix = \"Set model_auto_compact_token_limit to about 160000.\";\n } else if (line.includes(\"TOOL_USE_CONCURRENCY\")) {\n title = \"tool-call concurrency\";\n fix = `Cap parallel tool calls at ${TOOL_CONCURRENCY}.`;\n } else {\n title = line.slice(0, 40);\n fix = line;\n }\n issues.push({\n title: `Config: ${title}`,\n why: line,\n fix,\n action: `Fix this config problem: ${line}`,\n share: null,\n kind: title,\n source: configSource(line),\n hits: [],\n priority: 3,\n });\n }\n for (const issue of issues) issue.priority = issuePriority(issue);\n issues.sort((a, b) => a.priority - b.priority || -(a.share ?? 0) - -(b.share ?? 0));\n return issues;\n}\n\n/** 1 fix now, 2 fix this week, 3 when convenient. A one-line config fix behind a big leak is 1. */\nexport function issuePriority(issue: RawIssue): Priority {\n if (issue.share === null) return issue.title.includes(\"autoCompactWindow\") ? 1 : 2;\n return issue.share >= 20 ? 1 : issue.share >= 5 ? 2 : 3;\n}\n\n/** The copy-to-Claude prompt for one issue. burn.py:1390 */\nexport function issuePrompt(issue: RawIssue): string {\n const agents: Record<string, string> = {\n claude: \"Claude Code\",\n codex: \"Codex\",\n all: \"Claude Code and Codex\",\n };\n const agent = (issue.source && agents[issue.source]) || \"the agent\";\n const lines = [`Token leak to fix: ${issue.title}.`, `Applies to: ${agent}.`];\n if (issue.share !== null) {\n lines.push(\n `It affects ${issue.hits.length} of my top sessions, ${fixed(issue.share)}% of ${agent} spend in the last ${CHECK_HOURS} h (burn.py, base-input-equivalent tokens).`,\n );\n }\n lines.push(\"\", `Why it costs tokens: ${issue.why}`);\n if (issue.hits.length) {\n lines.push(\"\", \"Evidence:\");\n for (const [s, flag] of issue.hits) {\n lines.push(\n `- ${s.title || \"untitled\"} (session ${s.id}, ${fixed(s.share, 1)}% of spend, ${s.turns} turns, peak ${int0(s.peak / 1000)}k, ${fixed(s.hours)}h): ${flag}`,\n );\n if (s.path) lines.push(` transcript: ${s.path}`);\n }\n }\n const extra = ISSUE_EXTRA[issue.kind];\n if (extra) lines.push(\"\", \"Additional info:\", ...extra.map((e) => `- ${e}`));\n lines.push(\"\", `What to do: ${issue.action}`, \"\", \"Report what you changed and how to check that it worked.\");\n return lines.join(\"\\n\");\n}\n\nexport { LEVELS };","import { burnGoal } from \"./burn\";\nimport { fixed, int0 } from \"./format\";\nimport { BENCH_WINDOW, CHECK_HOURS, LATE_COMPACT_PEAK, LEVELS, LONG_LIVED_HOURS } from \"./flags\";\nimport { issuePrompt, topIssues } from \"./issues\";\nimport type { Burn, RawBurn, RawReport, Report, Source } from \"../model\";\n\n/** Python's datetime.isoformat() for a UTC datetime: seconds, optional microseconds, +00:00. */\nfunction iso(when: Date): string {\n // Python's isoformat() timespec=\"auto\": seconds, and a fraction only when it is nonzero.\n const text = when.toISOString();\n const body = text.endsWith(\".000Z\") ? text.slice(0, -5) : text.slice(0, -1);\n return `${body}+00:00`;\n}\n\nconst median = (xs: number[]): number => (xs.length ? [...xs].sort((a, b) => a - b)[xs.length >> 1] : 0);\n\n/** Everything dashboard.html draws, as JSON-ready data. The page owns all markup. burn.py:1415 */\nexport function reportView(report: RawReport, now: Date): Report {\n const issues = topIssues(report);\n const actual = new Map(report.timeline.map(([hour, slot]) => [hour.getTime(), slot]));\n let runA = 0;\n let runB = 0;\n const burndown: [string, number, number][] = [];\n for (const [when, slot] of report.hourly) {\n const seen = actual.get(when.getTime());\n runA += seen ? seen[0] + seen[1] : 0;\n runB += slot.bench;\n burndown.push([iso(new Date(when.getTime() + 3_600_000)), runA, runB]);\n }\n\n const blocks = new Map<number, { ctx: number[]; reads: number; calls: number }>();\n for (const [when, slot] of report.hourly) {\n const key = when.getTime() - (when.getUTCHours() % 3) * 3_600_000;\n const block = blocks.get(key) ?? { ctx: [], reads: 0, calls: 0 };\n if (!blocks.has(key)) blocks.set(key, block);\n block.ctx.push(...slot.ctx);\n block.reads += slot.reads;\n block.calls += slot.calls;\n }\n const blockList = [...blocks.values()];\n const kpis: Report[\"kpis\"] = [\n { name: \"Median context per turn\", unit: \"k\", target: 150_000, values: blockList.map((b) => median(b.ctx)) },\n {\n name: \"Turns over 300k context\",\n unit: \"%\",\n target: 0.1,\n values: blockList.map((b) => b.ctx.filter((c) => c >= 300_000).length / Math.max(b.ctx.length, 1)),\n },\n {\n name: \"Caller reads per tool call\",\n unit: \"%\",\n target: 0.2,\n values: blockList.map((b) => b.reads / Math.max(b.calls, 1)),\n },\n ];\n\n // Act now: what a live session needs this minute, before any leak report.\n const actions: string[] = [];\n for (const s of report.active) {\n const name = s.title || s.id;\n if (s.context >= LATE_COMPACT_PEAK) {\n actions.push(`Run /compact in “${name}”: its context is ${int0(s.context / 1000)}k.`);\n } else if (s.hours >= LONG_LIVED_HOURS) {\n actions.push(`Finish “${name}” and start a fresh session: it is ${fixed(s.hours)}h old.`);\n }\n }\n\n const burns: Partial<Record<Source, Burn>> = {};\n for (const [source, burn] of Object.entries(report.burns) as [Source, RawBurn][]) {\n const [goal, basis] = burnGoal(report, source);\n const week = burn.week;\n burns[source] = {\n rate: burn.rate,\n goal,\n basis,\n resets: week ? iso(week.resets) : null,\n hoursLeft: week ? week.hours_left : null,\n used: week ? week.used : null,\n gains: week ? week.gains : null,\n limit: week ? week.limit : null,\n ratePct: week ? week.rate_pct : null,\n idealPct: week ? week.ideal_pct : null,\n start: week ? iso(week.start) : null,\n weekBurndown: week ? week.burndown.map(([t, a, b]) => [iso(t), a, b] as [string, number, number]) : null,\n projection: week\n ? {\n ratePct: week.projection.rate_pct,\n hoursToEmpty: week.projection.hours_to_empty,\n runsOut: week.projection.runs_out ? iso(week.projection.runs_out) : null,\n }\n : null,\n };\n }\n\n return {\n generated: iso(now),\n days: report.days,\n total: report.total,\n sessions: report.session_count,\n turns: report.turns,\n over300k: report.over_300k,\n burns,\n burn: burns.claude ?? Object.values(burns)[0] ?? null,\n actions,\n issues: issues.map((i) => ({\n title: i.title,\n fix: i.fix,\n priority: i.priority,\n level: LEVELS[i.priority],\n source: i.source,\n share: i.share,\n sessions: i.hits.length,\n prompt: issuePrompt(i),\n })),\n active: report.active,\n burndown,\n benchWindow: BENCH_WINDOW,\n budget: report.budget,\n kpis,\n timeline: report.timeline.map(([t, [cool, hot]]) => [iso(t), cool, hot]),\n checkHours: CHECK_HOURS,\n baseline: report.baseline,\n topSessions: report.sessions,\n buckets: report.buckets.map(([label, low, share, turns]) => ({\n label,\n hot: low >= 300,\n share,\n turns,\n })),\n projects: report.projects,\n config: report.config,\n tools: report.tools,\n unpriced: report.unpriced,\n };\n}","import { Worker } from \"node:worker_threads\";\nimport type { ParsedFile, Source } from \"../core/model\";\nimport type { Env } from \"../sources/agent-source\";\nimport type { ParseReply } from \"../scan-worker\";\n\n/** Parsing runs in worker threads. Each worker holds its own sources, built from the same env. */\nexport class ParsePool {\n private readonly workers: Worker[];\n private readonly pending = new Map<number, { resolve: (p: ParsedFile) => void; reject: (e: Error) => void }>();\n private nextId = 0;\n private failure: Error | null = null;\n private closing = false;\n\n constructor(url: URL, env: Env, size: number) {\n this.workers = Array.from({ length: size }, () => {\n const worker = new Worker(url, { workerData: { env } });\n worker.on(\"message\", (reply: ParseReply) => {\n const task = this.pending.get(reply.id);\n this.pending.delete(reply.id);\n if (\"error\" in reply) task?.reject(new Error(reply.error));\n else task?.resolve(reply.parsed);\n });\n worker.on(\"error\", (error) => this.failAll(error));\n worker.on(\"exit\", (code) => {\n if (!this.closing) this.failAll(new Error(`Worker exited with code ${code}`));\n });\n return worker;\n });\n }\n\n /** The caller keeps one request in flight per worker, so a big file never queues a small one. */\n parse(worker: number, source: Source, path: string): Promise<ParsedFile> {\n if (this.failure) return Promise.reject(this.failure);\n return new Promise((resolve, reject) => {\n const id = this.nextId++;\n this.pending.set(id, { resolve, reject });\n this.workers[worker].postMessage({ id, source, path });\n });\n }\n\n async close(): Promise<void> {\n this.closing = true;\n await Promise.all(this.workers.map((worker) => worker.terminate()));\n }\n\n private failAll(error: Error): void {\n this.failure = this.failure ?? error;\n for (const task of this.pending.values()) task.reject(error);\n this.pending.clear();\n }\n}\n","import { readFileSync } from \"node:fs\";\nimport { fileURLToPath } from \"node:url\";\nimport { reportView } from \"../core/analyze/view\";\nimport type { RawReport } from \"../core/model\";\n\n/** The built React page: next to the bundle in dist/, or in dist/ when running from src. */\nconst PAGE = [\"./web/index.html\", \"../../dist/web/index.html\"];\n\n/** The raw page, which the server serves for hot reload and the CLI embeds. */\nexport function loadPage(): string {\n for (const path of PAGE) {\n try {\n return readFileSync(fileURLToPath(new URL(path, import.meta.url)), \"utf8\");\n } catch {\n continue;\n }\n }\n throw new Error(\"Built page dist/web/index.html not found. Run `npm run build`.\");\n}\n\n/** The built page with the report embedded, for a static file or the first paint. burn.py:1498 */\nexport function renderHtml(report: RawReport, now: Date, page = loadPage()): string {\n // `</` would end the script tag; Python escapes it the same way.\n const data = JSON.stringify(reportView(report, now)).replace(/<\\//g, \"<\\\\/\");\n return page.replace(\"/*REPORT*/null\", data);\n}","/**\n * The terminal output: burn.py's print_doctor and print_text, same strings. burn.py:1028, 1142\n *\n * Both read the raw report, because they use burn.py's own key names (session_count, bench_total,\n * recent_sessions). `%f` goes through core/analyze/format so the numbers round like Python's.\n */\n\nimport { burnGoal } from \"../core/analyze/burn\";\nimport { fixed, int0 } from \"../core/analyze/format\";\nimport { BENCH_WINDOW, CHECK_HOURS } from \"../core/analyze/flags\";\nimport { topIssues } from \"../core/analyze/issues\";\nimport { CACHE_READ_RATE, CACHE_WRITE_RATE } from \"../core/analyze/pricing\";\nimport type { RawBurn, RawReport, Source } from \"../core/model\";\n\n/** Python's %-8s and friends. */\nconst end = (text: string, width: number): string => text.padEnd(width);\nconst start = (text: string, width: number): string => text.padStart(width);\n\n/** The doctor verdict: each leak with its share and fix, then the baseline gaps. */\nexport function printDoctor(report: RawReport, htmlPath: string | null): string {\n const out: string[] = [];\n const issues = topIssues(report);\n out.push(\n `TOKEN FURNACE: last ${report.days} days, ${fixed(report.total / 1e6)}M weighted tokens, ` +\n `${int0(report.session_count)} sessions`,\n );\n for (const [source, burn] of Object.entries(report.burns) as [Source, RawBurn][]) {\n const [goal, basis] = burnGoal(report, source);\n out.push(\n `Burn (${source}): ${fixed(burn.rate / 1e6, 1)}M in the last hour, ` +\n `goal ${fixed(goal / 1e6, 1)}M/h (${basis})`,\n );\n }\n for (const s of report.active) {\n const flags = s.flags.length ? `; ${s.flags.map((f) => f.split(\":\")[0]).join(\", \")}` : \"\";\n out.push(\n `Active: ${(s.title || \"(untitled)\").slice(0, 40)} (${s.source} ${s.id}, ${s.model || \"?\"}) ` +\n `burning ${fixed(s.rate / 1e6, 1)}M/h (${fixed(s.rateShare)}% of the hour), ` +\n `context ${fixed(s.context / 1000)}k, ${int0(s.turns)} turns, ${fixed(s.hours)}h old, ` +\n `idle ${fixed(s.idle)}m${flags}`,\n );\n }\n out.push(\n issues.length\n ? `Verdict: ${issues.length} leak${issues.length === 1 ? \"\" : \"s\"} found in the last ` +\n `${CHECK_HOURS} h, largest first.\\n`\n : `Verdict: healthy. No common token leaks in the last ${CHECK_HOURS} h.`,\n );\n issues.forEach((issue, i) => {\n const where =\n issue.share === null ? \"config\" : `${fixed(issue.share)}% of spend, ${issue.hits.length} sessions`;\n out.push(`${i + 1}. [P${issue.priority}] ${issue.title} (${where})`);\n out.push(` Fix: ${issue.fix}`);\n for (const [session, flag] of [...issue.hits]\n .sort((a, b) => b[0].share - a[0].share)\n .slice(0, 2)) {\n out.push(` e.g. ${(session.title || session.id).slice(0, 40)}: ${flag.split(\".\")[0]}`);\n }\n });\n out.push(\n `\\nBenchmark: the same turns at a ${fixed(BENCH_WINDOW / 1000)}k compaction window would cost ` +\n `about ${fixed(report.bench_total / 1e6)}M ` +\n `(${fixed(100 * (1 - report.bench_total / report.total))}% less). Estimate: trims cached ` +\n `context only.`,\n );\n const gaps = report.baseline.filter((row) => !row.ok);\n if (gaps.length) {\n out.push(`\\nBaseline gaps (last ${CHECK_HOURS} h -> recommended):`);\n for (const row of gaps) {\n out.push(` ${end(row.level, 8)} ${end(row.name, 28)} ${end(row.now_24h, 18)} ${row.target}`);\n }\n }\n if (htmlPath) {\n out.push(`\\nReport: ${htmlPath}`);\n out.push('Open it and press \"Copy for Claude\" on a leak to hand over the fix with evidence.');\n }\n return `${out.join(\"\\n\")}\\n`;\n}\n\n/** The full text report: the old burn.py default output. */\nexport function printText(report: RawReport): string {\n const out: string[] = [];\n out.push(\n `=== ${report.days}-day burn: ${fixed(report.total / 1e6)}M weighted tokens, ` +\n `${int0(report.session_count)} sessions, ${int0(report.turns)} turns ===`,\n );\n if (report.sources.length > 1) {\n out.push(` ${report.sources.map(([name, pct]) => `${name} ${fixed(pct)}%`).join(\" \")}`);\n }\n\n out.push(\"\\nSPEND BY CONTEXT SIZE OF THE TURN <- the main lever\");\n for (const [label, , pct, turns] of report.buckets) {\n out.push(` ${end(label, 12)} ${start(fixed(pct, 1), 6)}% ${start(int0(turns), 6)} turns`);\n }\n out.push(\n ` --> ${fixed(report.over_300k)}% of spend is on turns carrying more than 300k of context`,\n );\n\n if (report.preamble) {\n out.push(\"\\nALWAYS-RESIDENT PREAMBLE (instructions, memory, skill catalog, tool schemas)\");\n out.push(\n ` p50=${fixed(report.preamble[0] / 1000)}k p90=${fixed(report.preamble[1] / 1000)}k per ` +\n `session -> ${fixed(report.preamble[2])}% of every token read`,\n );\n out.push(\n ` Prune it once, then leave it stable: reads bill at ${fixed(CACHE_READ_RATE, 1)}x but ` +\n `rewrites at ${fixed(CACHE_WRITE_RATE, 2)}x.`,\n );\n }\n\n out.push(\"\\nTOP PROJECTS\");\n for (const [name, pct] of report.projects) {\n out.push(` ${start(fixed(pct, 1), 6)}% ${name.slice(-58)}`);\n }\n\n out.push(\"\\nTOP SESSIONS (the long ones are where the budget goes)\");\n for (const s of report.sessions) {\n out.push(\n ` ${start(fixed(s.share, 1), 5)}% turns=${end(int0(s.turns), 5)} ` +\n `peak=${start(fixed(s.peak / 1000), 4)}k ${start(fixed(s.hours, 1), 4)}h ` +\n `${end(s.source, 6)} ${s.project.slice(-36)} ${s.id} ${(s.title || \"\").slice(0, 50)}`,\n );\n }\n\n out.push(\"\\nTOOL CALLS\");\n for (const [name, value] of report.tools) {\n out.push(` ${end(name, 28)} ${int0(value)}`);\n }\n\n out.push(`\\nLEAK CHECKS (top sessions of the last ${CHECK_HOURS} h; each flag names its fix)`);\n const flagged = report.recent_sessions.filter((s) => s.flags.length);\n for (const s of flagged) {\n out.push(` ${start(fixed(s.share, 1), 5)}% ${s.source} ${s.id} ${s.title || \"\"}`);\n for (const flag of s.flags) out.push(` - ${flag}`);\n }\n if (!flagged.length) out.push(\" none\");\n\n out.push(\"\\nCONFIG CHECKS\");\n for (const line of report.config) out.push(` - ${line}`);\n\n out.push(`\\nBASELINE (last ${CHECK_HOURS} h, ${report.days}-day value, recommended)`);\n for (const row of report.baseline) {\n out.push(\n ` ${end(row.level, 8)} ${end(row.name, 28)} ${end(row.now_24h, 18)} ` +\n `${end(row.value_7d ?? \"\", 8)} ${row.target}`,\n );\n }\n\n if (report.unpriced) {\n out.push(\n `\\nUNPRICED MODELS (counted at 1.0x -- ${fixed(report.unpriced[0])}% of reported spend)`,\n );\n for (const [name, value] of report.unpriced[1]) {\n out.push(` ${end(name, 28)} ${int0(value)} turns`);\n }\n out.push(\" Add a ratio to MODEL_RATE to price these correctly.\");\n }\n return `${out.join(\"\\n\")}\\n`;\n}","/**\n * The live report: Express on 127.0.0.1 with routing-controllers, rebuilding the report on every\n * request. burn.py serve(). Every route is a controller method: no vanilla routers.\n */\n\nimport type { Server } from \"node:http\";\nimport \"reflect-metadata\";\nimport express, { type Request, type Response } from \"express\";\nimport { Controller, Get, Middleware, Req, Res, useExpressServer, type ExpressMiddlewareInterface } from \"routing-controllers\";\nimport { reportView } from \"./core/analyze/view\";\nimport { loadPage, renderHtml } from \"./render/html\";\nimport { loadingPage } from \"./render/loading\";\nimport type { App } from \"./compose\";\nimport type { Source } from \"./core/model\";\nimport { planWeek } from \"./services/usage-client\";\n\nexport interface ServeOptions {\n days: number;\n source: Source | \"all\";\n /** Millions of weighted tokens, or null. */\n weeklyBudget: number | null;\n planUsage: boolean;\n port: number;\n}\n\nexport interface LiveServer {\n url: string;\n port: number;\n close: () => Promise<void>;\n}\n\n/** Serve until the process is stopped. Ctrl-C ends it. */\nexport async function serve(app: App, options: ServeOptions): Promise<void> {\n const live = await startServer(app, options);\n console.log(`Token Furnace live on ${live.url} (Ctrl-C to stop)`);\n console.log(\"The first scan reads every transcript once. The page shows its progress.\");\n await new Promise<void>(() => {}); // the server keeps the loop alive\n}\n\n/** Bind 127.0.0.1 and answer the routes. Port 0 asks the OS for a free port. */\nexport async function startServer(app: App, options: ServeOptions): Promise<LiveServer> {\n const web = express();\n web.disable(\"x-powered-by\");\n useExpressServer(web, {\n controllers: [reportController(app, options, loadPage())],\n middlewares: [LoopbackHostOnly],\n defaultErrorHandler: true,\n classTransformer: false,\n validation: false,\n });\n\n const http = await new Promise<Server>((ready) => {\n const bound = web.listen(options.port, \"127.0.0.1\", () => ready(bound));\n });\n // Scan after the port is bound. The scan yields, so requests are answered while it runs.\n warm(app);\n const port = (http.address() as { port: number }).port;\n return { url: `http://127.0.0.1:${port}`, port, close: () => new Promise((done) => http.close(() => done())) };\n}\n\n/**\n * A Host header other than the loopback name and the port this server listens on gets 403, so a\n * DNS-rebinding page cannot read the report. No CORS headers go out.\n */\n@Middleware({ type: \"before\", priority: 100 })\nclass LoopbackHostOnly implements ExpressMiddlewareInterface {\n use(req: Request, res: Response, next: (error?: unknown) => void): void {\n const port = req.socket.localPort;\n const host = (req.headers.host ?? \"\").toLowerCase();\n if (host !== `127.0.0.1:${port}` && host !== `localhost:${port}`) {\n res.status(403).type(\"text/plain\").send(\"Forbidden\");\n return;\n }\n next();\n }\n}\n\n/** The routes, closed over the app they serve. The catch-all page is declared last. */\nfunction reportController(app: App, options: ServeOptions, page: string) {\n @Controller()\n class ReportController {\n @Get(\"/api/status\")\n status(@Res() res: Response) {\n if (!app.reports.hasScanned) warm(app);\n return res.set(\"Cache-Control\", \"no-store\").json(app.reports.progress);\n }\n\n @Get(\"/api/report\")\n async report(@Req() req: Request, @Res() res: Response) {\n if (!app.reports.hasScanned) {\n warm(app);\n return res.status(202).json({ status: \"scanning\", progress: app.reports.progress });\n }\n const report = await build(app, options, req.query);\n return res.type(\"application/json\").send(JSON.stringify(report ? reportView(report, app.now()) : null));\n }\n\n @Get(\"/dashboard.html\")\n dashboard(@Res() res: Response) {\n return res.type(\"text/html\").send(page); // the raw page, polled for hot reload: no rebuild\n }\n\n @Get(/.*/)\n async index(@Req() req: Request, @Res() res: Response) {\n if (!app.reports.hasScanned) {\n warm(app);\n return res.type(\"text/html\").send(loadingPage()); // the first scan takes minutes: show progress\n }\n const report = await build(app, options, req.query);\n return res.type(\"text/html\").send(report ? renderHtml(report, app.now(), page) : \"No assistant turns.\");\n }\n }\n return ReportController;\n}\n\n/** Start or join the scan without waiting. A failed scan is logged, not an unhandled rejection. */\nfunction warm(app: App): void {\n app.reports.refresh().catch((error) => console.error(\"token-furnace: scan failed:\", error));\n}\n\n/** Rescan in the background when the last scan is over 5 s old. A request never waits for it. */\nfunction rescan(app: App): void {\n if (Date.now() - app.reports.progress.updatedAt > 5_000) warm(app);\n}\n\n/** One report per request, from the transcripts as they are now. */\nasync function build(app: App, options: ServeOptions, query: Record<string, unknown>) {\n const now = app.now();\n const days = positiveInt(query.days, options.days);\n const source = query.source === \"claude\" || query.source === \"codex\" ? query.source : options.source;\n rescan(app); // the answer is the report we have now; the next poll sees the new scan\n return app.reports.getRaw(days, source, {\n weeklyBudget: options.weeklyBudget,\n planWeek: await planWeek(app.env, now, options.planUsage),\n now,\n });\n}\n\nfunction positiveInt(value: unknown, fallback: number): number {\n const parsed = Number.parseInt(String(value ?? \"\"), 10);\n return parsed > 0 ? parsed : fallback;\n}","/**\n * The page `/` serves while the first scan runs: self-contained, so it needs no bundle. It polls\n * /api/status and reloads into the dashboard when the scan is done.\n */\nexport function loadingPage(): string {\n return `<!doctype html>\n<html lang=\"en\"><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n<title>Token Furnace: scanning</title>\n<style>\n :root { color-scheme: light dark; }\n body { font: 16px/1.5 system-ui, sans-serif; display: grid; place-items: center; min-height: 100vh; margin: 0; }\n main { width: min(30rem, 90vw); text-align: center; }\n .spin { width: 3rem; height: 3rem; margin: 0 auto 1.25rem; border: 4px solid #8884; border-top-color: #e8590c;\n border-radius: 50%; animation: turn 0.9s linear infinite; }\n @keyframes turn { to { transform: rotate(360deg); } }\n .bar { height: 0.75rem; background: #8883; border-radius: 0.4rem; overflow: hidden; }\n .bar > div { height: 100%; width: 0; background: #e8590c; transition: width 0.4s; }\n small { opacity: 0.7; }\n</style></head><body><main>\n <div class=\"spin\" role=\"status\" aria-label=\"Scanning\"></div>\n <h1>Scanning your transcripts</h1>\n <p>Please wait. The first scan reads every Claude Code and Codex session once.</p>\n <div class=\"bar\" role=\"progressbar\" aria-valuemin=\"0\" aria-valuemax=\"100\"><div id=\"fill\"></div></div>\n <p id=\"text\">Starting...</p>\n <small id=\"time\"></small>\n</main>\n<script>\n const fill = document.getElementById(\"fill\"), text = document.getElementById(\"text\"), time = document.getElementById(\"time\");\n const fmt = (n) => n.toLocaleString();\n async function tick() {\n try {\n const s = await (await fetch(\"/api/status\", { cache: \"no-store\" })).json();\n if (s.phase === \"ready\") return location.reload();\n const pct = s.bytesTotal ? Math.min(99, Math.round((100 * s.bytesDone) / s.bytesTotal)) : 0;\n fill.style.width = pct + \"%\";\n text.textContent = s.filesTotal ? fmt(s.filesDone) + \" of \" + fmt(s.filesTotal) + \" files (\" + pct + \"%)\" : \"Looking for transcripts...\";\n if (s.startedAt) time.textContent = Math.round((Date.now() - s.startedAt) / 1000) + \" s elapsed\";\n } catch { /* the server is busy or restarting: try again */ }\n setTimeout(tick, 1000);\n }\n tick();\n</script></body></html>`;\n}\n","import { execFileSync } from \"node:child_process\";\nimport { mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport type { Week } from \"../core/model\";\nimport type { Env } from \"../sources/agent-source\";\n\n/** A saved reading is reused for 5 minutes, and one call is tried per minute. burn.py:862 */\nconst REUSE_SECONDS = 300;\nconst RETRY_SECONDS = 60;\n\n/** Last network call in this process: one a minute, so a server does not burn the rate limit. */\nlet lastTry = 0;\n\n/** The saved reading, in the file burn.py writes and a status line can feed. */\nexport function usageCachePath(env: Env): string {\n const base = env.XDG_CACHE_HOME || join(env.HOME || homedir(), \".cache\");\n return join(base, \"token-furnace\", \"usage.json\");\n}\n\n/**\n * The subscription's 7-day window, or null when unavailable. The saved reading is a local file a\n * status line can feed. With `network` true, a login on this machine (the credentials file or the\n * macOS Keychain) triggers one call to api.anthropic.com when the reading is over 5 minutes old,\n * at most once a minute. The token goes there and nowhere else. A failed call keeps the saved\n * reading. No login on the machine means no call.\n */\nexport async function planWeek(env: Env, now: Date, network: boolean): Promise<Week | null> {\n const at = now.getTime() / 1000;\n const path = usageCachePath(env);\n const saved = readJson(path);\n let data = saved?.seven_day ?? null;\n const stale = !data || at - (saved?.fetched ?? 0) >= REUSE_SECONDS;\n if (network && stale && at - lastTry >= RETRY_SECONDS) {\n const token = accessToken(env);\n if (token) {\n lastTry = at;\n const fresh = await fetchWeek(token);\n if (fresh) {\n data = fresh;\n if (!(env.TOKEN_FURNACE_NO_CACHE && env.TOKEN_FURNACE_NO_CACHE !== \"0\")) {\n writeJson(path, { fetched: at, seven_day: data });\n }\n }\n }\n }\n return toWeek(data, now);\n}\n\nasync function fetchWeek(token: string): Promise<Record<string, any> | null> {\n try {\n const response = await fetch(\"https://api.anthropic.com/api/oauth/usage\", {\n headers: { Authorization: `Bearer ${token}`, \"anthropic-beta\": \"oauth-2025-04-20\" },\n signal: AbortSignal.timeout(10_000),\n });\n if (!response.ok) return null;\n const body = (await response.json()) as Record<string, any>;\n return typeof body?.seven_day === \"object\" && body.seven_day !== null ? body.seven_day : null;\n } catch {\n return null; // the endpoint rate-limits; the saved reading stays\n }\n}\n\n/** The Claude Code login token: the credentials file, else the macOS Keychain. burn.py:881 */\nfunction accessToken(env: Env): string | null {\n let creds: string | null = null;\n const home = env.CLAUDE_CONFIG_DIR || join(env.HOME || homedir(), \".claude\");\n try {\n creds = readFileSync(join(home, \".credentials.json\"), \"utf8\");\n } catch {\n try {\n creds = execFileSync(\n \"security\",\n [\"find-generic-password\", \"-s\", \"Claude Code-credentials\", \"-w\"],\n { encoding: \"utf8\", timeout: 5_000 },\n );\n } catch {\n return null;\n }\n }\n try {\n return (JSON.parse(creds).claudeAiOauth.accessToken as string) ?? null;\n } catch {\n return null;\n }\n}\n\n/** The endpoint's reading as a Week: epoch seconds or an ISO string, and only while it runs. */\nfunction toWeek(data: Record<string, any> | null, now: Date): Week | null {\n if (!data) return null;\n const resets =\n typeof data.resets_at === \"number\"\n ? new Date(data.resets_at * 1000)\n : typeof data.resets_at === \"string\"\n ? new Date(data.resets_at)\n : null;\n if (!resets || Number.isNaN(resets.getTime()) || resets <= now) return null;\n const used = Number(data.utilization);\n if (!Number.isFinite(used)) return null;\n return { start: new Date(resets.getTime() - 7 * 86_400_000), resets, used };\n}\n\nfunction readJson(path: string): Record<string, any> | null {\n try {\n const parsed = JSON.parse(readFileSync(path, \"utf8\"));\n return typeof parsed === \"object\" && parsed !== null ? parsed : null;\n } catch {\n return null;\n }\n}\n\nfunction writeJson(path: string, value: unknown): void {\n try {\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, JSON.stringify(value));\n } catch {\n // A cache we cannot write is a slow run, not a wrong one.\n }\n}","/**\n * The retry circuit breaker as a Claude Code PostToolUse hook. Port of scripts/escalate-on-churn.py.\n *\n * Counts edits per file per session. When one file is edited past a threshold, the agent is grinding\n * at a capability level that is not solving the problem. The hook tells it to ESCALATE -- hand the\n * work to a more capable model or a deeper reasoning pass, carrying what has already been tried --\n * rather than attempting another variation at the same level.\n *\n * It never blocks the edit and never tells the agent to abandon the task. A breaker that stops work\n * converts a token problem into an unfinished-work problem. Malformed input is ignored, not raised:\n * a hook that fails the tool call breaks the work it is meant to protect.\n */\n\nimport { readFileSync, writeFileSync } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { basename, join, sep } from \"node:path\";\nimport type { Env } from \"../sources/agent-source\";\n\n/** Edits to one file before the first nudge, then one nudge every EVERY edits after. */\nfunction thresholds(env: Env): { first: number; every: number } {\n const first = Number.parseInt(env.CHURN_FIRST ?? \"4\", 10);\n const every = Number.parseInt(env.CHURN_EVERY ?? \"3\", 10);\n return {\n first: Number.isInteger(first) && first > 0 ? first : 4,\n every: Number.isInteger(every) && every > 0 ? every : 3,\n };\n}\n\nconst MESSAGE = (name: string, n: number): string =>\n `CIRCUIT BREAKER: ${name} has been edited ${n} times this session.\\n` +\n \"If the last two attempts failed for the same underlying reason, stop trying another variation \" +\n \"at this level and ESCALATE:\\n\" +\n \" 1. State the assumption that must be wrong for these attempts to have failed.\\n\" +\n \" 2. Hand the problem to a more capable model or a higher-effort reasoning pass, or to a fresh \" +\n \"deeper investigation pass.\\n\" +\n \" 3. Carry forward what was already tried and why each attempt failed, so the escalated pass \" +\n \"does not repeat them.\\n\" +\n \"Keep working the task -- escalate the capability applied to it, do not abandon it.\";\n\ninterface HookEvent {\n tool_name?: string;\n tool_input?: { file_path?: string };\n session_id?: string;\n}\n\n/** The stdin payload: one JSON object, or several newline-separated for a piped batch. */\nfunction eventsOf(stdin: string): HookEvent[] {\n try {\n const event: unknown = JSON.parse(stdin);\n return event && typeof event === \"object\" && !Array.isArray(event) ? [event as HookEvent] : [];\n } catch {\n // A batch is newline-delimited; one hook payload may itself span several lines.\n }\n const out: HookEvent[] = [];\n for (const line of stdin.split(\"\\n\")) {\n if (!line.trim()) continue;\n try {\n const event = JSON.parse(line) as HookEvent;\n if (event && typeof event === \"object\") out.push(event);\n } catch {\n // never break the tool call on malformed input\n }\n }\n return out;\n}\n\n/** One session, one file, one counter, in the same place the Python version kept it. */\nfunction stateFile(env: Env, session: string): string {\n const key = (session || \"none\").slice(0, 40).replaceAll(sep, \"_\");\n return join(tmpdir(), `agent-churn-${key}.json`);\n}\n\n/** Counts the edit and prints the escalation prompt when the count lands on a threshold. */\nexport function churnOnce(\n event: HookEvent,\n env: Env,\n out: { write(text: string): unknown },\n): void {\n if (event.tool_name !== \"Edit\" && event.tool_name !== \"Write\" && event.tool_name !== \"NotebookEdit\") {\n return;\n }\n const path = event.tool_input?.file_path;\n if (typeof path !== \"string\" || !path) return;\n\n const file = stateFile(env, String(event.session_id ?? \"none\"));\n let state: Record<string, unknown> = {};\n try {\n const parsed: unknown = JSON.parse(readFileSync(file, \"utf8\"));\n if (parsed && typeof parsed === \"object\" && !Array.isArray(parsed)) {\n state = parsed as Record<string, unknown>;\n }\n } catch {\n state = {};\n }\n\n const previous = Number(state[path]);\n const count = (Number.isInteger(previous) ? previous : 0) + 1;\n state[path] = count;\n try {\n writeFileSync(file, JSON.stringify(state)); // a lost counter is cheaper than a failed edit\n } catch {\n /* see above */\n }\n\n const { first, every } = thresholds(env);\n if (count < first || (count - first) % every) return;\n out.write(\n `${JSON.stringify({\n hookSpecificOutput: {\n hookEventName: \"PostToolUse\",\n additionalContext: MESSAGE(basename(path), count),\n },\n })}\\n`,\n );\n}\n\n/** `token-furnace hook churn`. Always 0: a breaker never fails the tool call. */\nexport function runChurnHook(\n stdin: string,\n env: Env = process.env,\n out: { write(text: string): unknown } = process.stdout,\n): number {\n for (const event of eventsOf(stdin)) churnOnce(event, env, out);\n return 0;\n}\n\n/** Reads stdin to the end. Sync on purpose: a hook is a short-lived process, not a server. */\nexport function readStdin(): string {\n try {\n return readFileSync(0, \"utf8\");\n } catch {\n return \"\";\n }\n}\n","import {\n chmodSync,\n copyFileSync,\n existsSync,\n lstatSync,\n mkdirSync,\n readdirSync,\n readFileSync,\n readlinkSync,\n renameSync,\n symlinkSync,\n writeFileSync,\n} from \"node:fs\";\nimport { basename, dirname, join, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { parse as parseToml } from \"smol-toml\";\nimport type { Env } from \"../sources/agent-source\";\n\nexport interface SetupOptions {\n apply?: boolean;\n aggressive?: boolean;\n rollback?: boolean;\n verify?: boolean;\n}\n\nconst SKILLS = [\"token-furnace\", \"prd-creator\", \"prd-manager\"];\n\nconst BEGIN = \"<!-- token-furnace:begin -->\";\nconst END = \"<!-- token-furnace:end -->\";\nconst LINE =\n \"Token discipline, every session: slice uncertain or cross-file work into a compact PRD with the `prd-creator` skill first and execute from that, rather than exploring and implementing in one context (`prd-manager` reports where PRDs stand); retrieve the smallest range that answers the question and **never re-establish a fact you already have** — no confirming grep after a read that answered it; run the smallest test that can falsify the current hypothesis; after two failures with the same cause, stop editing and re-plan. Full policy: `~/.agents/skills/token-furnace/SKILL.md`.\";\n\nfunction createBackupDir(backupRoot: string): string {\n const d = new Date();\n const pad = (n: number) => String(n).padStart(2, \"0\");\n const base = `${d.getFullYear()}${pad(d.getMonth() + 1)}${pad(d.getDate())}-${pad(d.getHours())}${pad(d.getMinutes())}${pad(d.getSeconds())}`;\n let dir = join(backupRoot, base);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n return dir;\n }\n let counter = 1;\n while (existsSync(`${dir}.${counter}`)) {\n counter++;\n }\n dir = `${dir}.${counter}`;\n mkdirSync(dir, { recursive: true });\n return dir;\n}\n\nfunction collapseHome(path: string, home: string): string {\n if (home && path.startsWith(home)) {\n return `~${path.slice(home.length)}`;\n }\n return path;\n}\n\nfunction isPlainObject(v: unknown): v is Record<string, unknown> {\n return Boolean(v) && typeof v === \"object\" && !Array.isArray(v);\n}\n\n/** Resolve TOML keys through the parser so quoted keys and comments cannot hide existing settings. */\nfunction getTomlValue(text: string, table: string, key: string): string | undefined {\n let data: Record<string, unknown>;\n try {\n data = parseToml(text) as Record<string, unknown>;\n } catch {\n return undefined;\n }\n const scope = table ? data[table] : data;\n if (!isPlainObject(scope)) return undefined;\n const v = scope[key];\n if (v === undefined) return undefined;\n return typeof v === \"string\" ? JSON.stringify(v) : String(v);\n}\n\n/** The unquoted name of a `[table]` header line, or null when the line is not one. */\nfunction tableHeaderName(line: string): string | null {\n const t = line.trim();\n if (!t.startsWith(\"[\") || t.startsWith(\"[[\")) return null;\n const close = t.indexOf(\"]\");\n if (close === -1) return null;\n let name = t.slice(1, close).trim();\n if (name.length >= 2 && name.startsWith('\"') && name.endsWith('\"')) {\n name = name.slice(1, -1);\n }\n return name;\n}\n\nfunction setTomlValue(content: string, table: string, key: string, val: string): string {\n const lines = content.length > 0 ? content.split(\"\\n\") : [];\n // Normalize lines to retain original endings if needed or standard \\n\n const linesWithNl = lines.map((l) => `${l}\\n`);\n const assignment = `${key} = ${val}\\n`;\n const hdr = `[${table}]`;\n if (table) {\n const idx = linesWithNl.findIndex((l) => tableHeaderName(l) === table);\n if (idx === -1) {\n if (linesWithNl.length > 0 && !linesWithNl[linesWithNl.length - 1].endsWith(\"\\n\")) {\n linesWithNl.push(\"\\n\");\n }\n linesWithNl.push(\"\\n\", `${hdr}\\n`, assignment);\n } else {\n linesWithNl.splice(idx + 1, 0, assignment);\n }\n } else {\n let i = linesWithNl.findIndex((l) => l.trimStart().startsWith(\"[\"));\n if (i === -1) i = linesWithNl.length;\n const atTable = i < linesWithNl.length;\n while (i > 0 && !linesWithNl[i - 1].trim()) {\n i--;\n }\n linesWithNl.splice(i, 0, assignment, ...(atTable ? [] : [\"\\n\"]));\n }\n return linesWithNl.join(\"\");\n}\n\nexport function runSetup(\n opts: SetupOptions,\n env: Env = process.env,\n out: { write(text: string): unknown } = process.stdout,\n): number {\n const home = env.HOME ?? \"\";\n const apply = Boolean(opts.apply);\n const aggressive = Boolean(opts.aggressive);\n const rollback = Boolean(opts.rollback);\n const verifyOnly = Boolean(opts.verify);\n\n const hub = join(home, \".agents\", \"skills\");\n const claudeDir = join(home, \".claude\");\n const codexDir = join(home, \".codex\");\n const backupRoot = join(home, \".agents\", \"token-furnace-backups\");\n\n const here = dirname(fileURLToPath(import.meta.url));\n const packageRoot = existsSync(join(here, \"SKILL.md\"))\n ? here\n : existsSync(join(here, \"..\", \"SKILL.md\"))\n ? resolve(here, \"..\")\n : resolve(here, \"..\", \"..\");\n const skillsParent = resolve(packageRoot, \"..\");\n\n const tracked: Array<{ label: string; path: string }> = [\n { label: \"claude-settings.json\", path: join(claudeDir, \"settings.json\") },\n { label: \"claude-mcp.json\", path: join(home, \".claude.json\") },\n { label: \"claude-CLAUDE.md\", path: join(claudeDir, \"CLAUDE.md\") },\n { label: \"codex-config.toml\", path: join(codexDir, \"config.toml\") },\n { label: \"codex-AGENTS.md\", path: join(codexDir, \"AGENTS.md\") },\n ];\n\n const say = (s: string) => out.write(` ${s}\\n`);\n const ok = (s: string) => out.write(` \\x1b[32mok\\x1b[0m ${s}\\n`);\n const plan = (s: string) => out.write(` \\x1b[33mwould\\x1b[0m ${s}\\n`);\n const did = (s: string) => out.write(` \\x1b[36mdid\\x1b[0m ${s}\\n`);\n const warn = (s: string) => out.write(` \\x1b[31mskip\\x1b[0m ${s}\\n`);\n const bad = (s: string) => out.write(` \\x1b[31mFAIL\\x1b[0m ${s}\\n`);\n const head = (s: string) => out.write(`\\n\\x1b[1m${s}\\x1b[0m\\n`);\n\n // --- Rollback ---\n if (rollback) {\n let latest = \"\";\n if (existsSync(backupRoot)) {\n const entries = readdirSync(backupRoot).filter((e) => {\n try {\n return lstatSync(join(backupRoot, e)).isDirectory();\n } catch {\n return false;\n }\n }).sort();\n if (entries.length > 0) {\n latest = join(backupRoot, entries[entries.length - 1]);\n }\n }\n if (!latest) {\n out.write(`no backups in ${backupRoot}\\n`);\n return 1;\n }\n out.write(`restoring ${latest}\\n`);\n for (const item of tracked) {\n const backupFile = join(latest, item.label);\n if (existsSync(backupFile)) {\n mkdirSync(dirname(item.path), { recursive: true });\n // Keep the live file before overwriting it, so this rollback is itself reversible.\n if (existsSync(item.path)) {\n copyFileSync(item.path, join(latest, `${item.label}.pre-rollback`));\n }\n copyFileSync(backupFile, item.path);\n } else if (existsSync(item.path)) {\n renameSync(item.path, `${item.path}.token-furnace-removed`);\n }\n }\n out.write(\"restored\\n\");\n return 0;\n }\n\n // --- Verify ---\n const runVerification = (): number => {\n head(\"Verify\");\n let fails = 0;\n\n const claudeSettings = join(claudeDir, \"settings.json\");\n if (existsSync(claudeSettings)) {\n let valid = false;\n let parsed: any = null;\n try {\n parsed = JSON.parse(readFileSync(claudeSettings, \"utf8\"));\n if (parsed && typeof parsed === \"object\") valid = true;\n } catch {}\n if (valid) {\n ok(\"settings.json parses\");\n for (const k of [\"CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS\", \"ENABLE_TOOL_SEARCH\", \"MAX_MCP_OUTPUT_TOKENS\"]) {\n const v = parsed?.env?.[k];\n if (v !== undefined && v !== \"\") {\n ok(`claude ${k}=${v}`);\n } else {\n bad(`claude ${k} missing`);\n fails++;\n }\n }\n } else {\n bad(\"settings.json is not valid JSON\");\n fails++;\n }\n } else {\n bad(`${claudeSettings} missing`);\n fails++;\n }\n\n const codexConfig = join(codexDir, \"config.toml\");\n if (existsSync(codexConfig)) {\n const tomlText = readFileSync(codexConfig, \"utf8\");\n ok(\"config.toml readable\");\n const pairs: Array<{ table: string; key: string }> = [\n { table: \"\", key: \"model_verbosity\" },\n { table: \"\", key: \"tool_output_token_limit\" },\n { table: \"agents\", key: \"max_concurrent_threads_per_session\" },\n { table: \"agents\", key: \"default_subagent_reasoning_effort\" },\n ];\n for (const p of pairs) {\n const v = getTomlValue(tomlText, p.table, p.key);\n const label = p.table ? `${p.table}.${p.key}` : p.key;\n if (v !== undefined) {\n const display = v.startsWith('\"') && v.endsWith('\"') ? v.slice(1, -1) : v;\n ok(`codex ${label}=${display}`);\n } else {\n bad(`codex ${label} missing`);\n fails++;\n }\n }\n } else {\n bad(`${codexConfig} missing`);\n fails++;\n }\n\n for (const s of SKILLS) {\n // token-furnace must always resolve; prd-* are optional, only checked when the\n // installer had them available.\n if (s !== \"token-furnace\" && !existsSync(join(skillsParent, s))) continue;\n for (const d of [join(claudeDir, \"skills\", s), join(codexDir, \"skills\", s)]) {\n const skillFile = join(d, \"SKILL.md\");\n const disp = collapseHome(d, home);\n if (existsSync(skillFile)) {\n ok(`${disp}/SKILL.md readable`);\n } else {\n let isLink = false;\n try {\n isLink = lstatSync(d).isSymbolicLink();\n } catch {}\n if (isLink) bad(`${disp} is a dangling link`);\n else bad(`${disp} missing`);\n fails++;\n }\n }\n }\n\n // Hook check\n let hookWired = false;\n if (existsSync(claudeSettings)) {\n try {\n const cfg = JSON.parse(readFileSync(claudeSettings, \"utf8\"));\n const postToolUse = cfg?.hooks?.PostToolUse;\n if (Array.isArray(postToolUse)) {\n for (const item of postToolUse) {\n if (Array.isArray(item?.hooks)) {\n for (const h of item.hooks) {\n if (\n typeof h?.command === \"string\" &&\n (h.command.includes(\"hook churn\") || h.command.includes(\"escalate-on-churn.py\"))\n ) {\n hookWired = true;\n }\n }\n }\n }\n }\n } catch {}\n }\n if (hookWired) {\n ok(\"PostToolUse escalate-on-churn wired\");\n } else {\n bad(\"PostToolUse escalate-on-churn not wired\");\n fails++;\n }\n\n for (const f of [join(claudeDir, \"CLAUDE.md\"), join(codexDir, \"AGENTS.md\")]) {\n const disp = collapseHome(f, home);\n let carries = false;\n if (existsSync(f)) {\n const content = readFileSync(f, \"utf8\");\n if (content.includes(LINE)) carries = true;\n }\n if (carries) ok(`${disp} carries the line`);\n else {\n bad(`${disp} is missing the token-furnace line`);\n fails++;\n }\n }\n\n let restorable = false;\n let latestDir = \"\";\n if (existsSync(backupRoot)) {\n const list = readdirSync(backupRoot).filter((e) => {\n try {\n return lstatSync(join(backupRoot, e)).isDirectory();\n } catch {\n return false;\n }\n }).sort();\n if (list.length > 0) {\n latestDir = join(backupRoot, list[list.length - 1]);\n if (existsSync(join(latestDir, \"restore.sh\"))) restorable = true;\n }\n }\n if (restorable) {\n ok(`backup restorable: ${collapseHome(latestDir, home)}`);\n } else {\n bad(`no restorable backup in ${collapseHome(backupRoot, home)}`);\n fails++;\n }\n\n if (fails === 0) {\n out.write(\"\\n \\x1b[32mall checks passed\\x1b[0m\\n\");\n return 0;\n }\n out.write(`\\n \\x1b[31m${fails} check(s) failed\\x1b[0m\\n`);\n return 1;\n };\n\n if (verifyOnly) {\n return runVerification();\n }\n\n function shQuote(s: string): string {\n return \"'\" + s.replace(/'/g, \"'\\\\''\") + \"'\";\n }\n\n // Backup is lazy: created once, immediately before the first real mutation. A\n // no-op apply writes nothing, and the snapshot always predates every change.\n let backupDir = \"\";\n function ensureBackup(): void {\n if (backupDir) return;\n backupDir = createBackupDir(backupRoot);\n const restoreScriptLines: string[] = [\n \"#!/usr/bin/env bash\",\n \"set -euo pipefail\",\n 'd=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"',\n ];\n for (const pair of tracked) {\n if (existsSync(pair.path)) {\n copyFileSync(pair.path, join(backupDir, pair.label));\n const qPath = shQuote(pair.path);\n restoreScriptLines.push(\n `if [ -f ${qPath} ]; then cp -p ${qPath} \"$d/${pair.label}.pre-rollback\"; fi`,\n );\n restoreScriptLines.push(`cp -p \"$d/${pair.label}\" ${qPath}`);\n did(`saved ${pair.path}`);\n } else {\n const qPath = shQuote(pair.path);\n const qRem = shQuote(`${pair.path}.token-furnace-removed`);\n restoreScriptLines.push(`if [ -f ${qPath} ]; then mv ${qPath} ${qRem}; fi`);\n say(`absent ${pair.path} (restore will move it aside, not delete)`);\n }\n }\n restoreScriptLines.push('echo \"restored\"');\n const restoreScript = join(backupDir, \"restore.sh\");\n // Raw writeFileSync, not writeConfig: writing the script must not recurse into a backup.\n writeFileSync(restoreScript, restoreScriptLines.join(\"\\n\") + \"\\n\");\n try {\n chmodSync(restoreScript, 0o755);\n } catch {}\n ok(backupDir);\n say(\"undo with: token-furnace setup --rollback\");\n }\n\n // Every config and instruction write snapshots the tracked files first, exactly once.\n function writeConfig(path: string, text: string): void {\n ensureBackup();\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, text);\n }\n\n // --- Backup ---\n head(\"Backup\");\n if (apply) {\n say(\"created before the first change, if a change is needed\");\n } else {\n plan(`back up 5 files to ${backupRoot}/<timestamp>/ with a restore.sh`);\n }\n\n // --- 1. Skills ---\n head(\"1. Skills (both agents)\");\n const linkSkill = (target: string, linkPath: string) => {\n const disp = collapseHome(linkPath, home);\n const dispT = collapseHome(target, home);\n let exists = false;\n let isLink = false;\n try {\n const stat = lstatSync(linkPath);\n exists = true;\n isLink = stat.isSymbolicLink();\n } catch {}\n\n if (exists) {\n let resolved = \"\";\n try {\n resolved = resolve(dirname(linkPath), readlinkSync(linkPath));\n } catch {\n resolved = resolve(linkPath);\n }\n if (resolved === resolve(target)) {\n ok(disp);\n return;\n }\n warn(`${disp} exists and points elsewhere — left alone`);\n return;\n }\n\n if (apply) {\n mkdirSync(dirname(linkPath), { recursive: true });\n ensureBackup();\n symlinkSync(target, linkPath);\n did(disp);\n } else {\n plan(`link ${disp} -> ${dispT}`);\n }\n };\n\n for (const s of SKILLS) {\n const srcPath = s === \"token-furnace\"\n ? (existsSync(join(packageRoot, \"SKILL.md\")) ? packageRoot : join(skillsParent, s))\n : join(skillsParent, s);\n if (!existsSync(srcPath)) {\n warn(`${s} not found`);\n continue;\n }\n const hubPath = join(hub, s);\n linkSkill(srcPath, hubPath);\n linkSkill(hubPath, join(claudeDir, \"skills\", s));\n linkSkill(hubPath, join(codexDir, \"skills\", s));\n }\n\n // --- 2. Always-on instruction ---\n head(\"2. Always-on instruction\");\n const inject = (filePath: string) => {\n const disp = collapseHome(filePath, home);\n let currentContent = \"\";\n if (existsSync(filePath)) {\n currentContent = readFileSync(filePath, \"utf8\");\n if (currentContent.includes(BEGIN)) {\n if (currentContent.includes(LINE)) {\n ok(`${disp} current`);\n return;\n }\n if (apply) {\n const lines = currentContent.split(\"\\n\");\n const outLines: string[] = [];\n let skip = false;\n for (const l of lines) {\n if (l === BEGIN) {\n outLines.push(BEGIN, LINE, END);\n skip = true;\n continue;\n }\n if (l === END) {\n skip = false;\n continue;\n }\n if (!skip) outLines.push(l);\n }\n writeConfig(filePath, outLines.join(\"\\n\"));\n did(`${disp} line replaced`);\n } else {\n plan(`replace the line between markers in ${disp}`);\n }\n return;\n }\n }\n if (apply) {\n const prefix = currentContent.length > 0 ? \"\\n\" : \"\";\n const addition = `${prefix}${BEGIN}\\n${LINE}\\n${END}\\n`;\n writeConfig(filePath, currentContent + addition);\n did(`${disp} line added`);\n } else {\n plan(`append the marked line to ${disp}`);\n }\n };\n inject(join(claudeDir, \"CLAUDE.md\"));\n inject(join(codexDir, \"AGENTS.md\"));\n\n // --- 3. Token-efficient defaults ---\n head(\"3. Token-efficient defaults\");\n\n const claudeSettingsPath = join(claudeDir, \"settings.json\");\n let claudeCfg: any = {};\n let claudeJsonMalformed = false;\n if (existsSync(claudeSettingsPath)) {\n try {\n const parsed = JSON.parse(readFileSync(claudeSettingsPath, \"utf8\"));\n // A non-object top level, or a non-object env/hooks, would throw or silently\n // clobber bytes on write. Treat all of them as malformed and leave the file alone.\n const envOk = parsed?.env === undefined || isPlainObject(parsed?.env);\n const hooksOk = parsed?.hooks === undefined || isPlainObject(parsed?.hooks);\n if (isPlainObject(parsed) && envOk && hooksOk) {\n claudeCfg = parsed;\n } else {\n claudeJsonMalformed = true;\n }\n } catch {\n claudeJsonMalformed = true;\n }\n }\n\n const setClaudeEnv = (k: string, v: string | boolean | number) => {\n if (claudeJsonMalformed) {\n warn(`claude settings.json is malformed JSON — left alone (wanted ${k}=${v})`);\n return;\n }\n const strVal = String(v);\n const cur = claudeCfg?.env?.[k];\n if (cur !== undefined && String(cur) === strVal) {\n ok(`claude ${k}=${strVal}`);\n return;\n }\n if (cur !== undefined && String(cur) !== \"\") {\n warn(`claude ${k} already set to \"${cur}\" — left alone (wanted ${strVal})`);\n return;\n }\n if (apply) {\n if (!claudeCfg.env) claudeCfg.env = {};\n claudeCfg.env[k] = v;\n writeConfig(claudeSettingsPath, JSON.stringify(claudeCfg, null, 2) + \"\\n\");\n did(`claude ${k}=${strVal}`);\n } else {\n plan(`set claude ${k}=${strVal}`);\n }\n };\n\n const setClaudeHook = () => {\n if (claudeJsonMalformed) {\n warn(\"claude settings.json is malformed JSON — left alone (wanted PostToolUse hook)\");\n return;\n }\n const targetCmd = \"npx -y token-furnace hook churn\";\n let replacedLegacy = false;\n let alreadyConfigured = false;\n const postToolUse = claudeCfg?.hooks?.PostToolUse;\n if (Array.isArray(postToolUse)) {\n for (const item of postToolUse) {\n if (Array.isArray(item?.hooks)) {\n for (const h of item.hooks) {\n if (h?.command === targetCmd) {\n alreadyConfigured = true;\n } else if (typeof h?.command === \"string\" && h.command.includes(\"escalate-on-churn.py\")) {\n if (apply) {\n h.command = targetCmd;\n }\n replacedLegacy = true;\n }\n }\n }\n }\n }\n if (replacedLegacy && apply) {\n writeConfig(claudeSettingsPath, JSON.stringify(claudeCfg, null, 2) + \"\\n\");\n did(\"claude PostToolUse replaced legacy escalate-on-churn.py hook\");\n return;\n }\n if (alreadyConfigured) {\n ok(\"claude PostToolUse escalate-on-churn\");\n return;\n }\n if (apply) {\n if (!claudeCfg.hooks) claudeCfg.hooks = {};\n if (!Array.isArray(claudeCfg.hooks.PostToolUse)) claudeCfg.hooks.PostToolUse = [];\n claudeCfg.hooks.PostToolUse.push({\n matcher: \"Edit|Write|NotebookEdit\",\n hooks: [{ type: \"command\", command: targetCmd }],\n });\n writeConfig(claudeSettingsPath, JSON.stringify(claudeCfg, null, 2) + \"\\n\");\n did(\"claude PostToolUse escalate-on-churn\");\n } else {\n plan(\"wire claude PostToolUse escalate-on-churn\");\n }\n };\n\n const codexConfigPath = join(codexDir, \"config.toml\");\n let codexToml = \"\";\n let codexTomlInvalid = false;\n if (existsSync(codexConfigPath)) {\n codexToml = readFileSync(codexConfigPath, \"utf8\");\n try {\n parseToml(codexToml);\n } catch {\n codexTomlInvalid = true;\n warn(\"codex config.toml is not valid TOML — left unchanged\");\n }\n }\n\n const setCodexIfUnset = (table: string, key: string, tomlVal: string, humanVal: string) => {\n if (codexTomlInvalid) return;\n const cur = getTomlValue(codexToml, table, key);\n const label = table ? `${table}.${key}` : key;\n if (cur !== undefined) {\n const display = cur.startsWith('\"') && cur.endsWith('\"') ? cur.slice(1, -1) : cur;\n if (display === humanVal) {\n ok(`codex ${label} = ${humanVal}`);\n return;\n }\n warn(`codex ${label} already \"${display}\" — left alone (wanted ${humanVal})`);\n return;\n }\n if (apply) {\n const candidate = setTomlValue(codexToml, table, key, tomlVal);\n // shortcut: unsupported table layouts are skipped; use a preserving editor if they need support.\n try {\n parseToml(candidate);\n // An apparent table header can be inside a multiline string.\n if (getTomlValue(candidate, table, key) !== tomlVal) throw new Error(\"Setting was not inserted\");\n } catch {\n warn(`codex ${label}: cannot set without risking config — left alone`);\n return;\n }\n codexToml = candidate;\n writeConfig(codexConfigPath, codexToml);\n did(`codex ${label} = ${tomlVal}`);\n } else {\n plan(`set codex ${label} = ${tomlVal}`);\n }\n };\n\n setClaudeEnv(\"CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS\", \"3\");\n setClaudeEnv(\"ENABLE_TOOL_SEARCH\", \"true\");\n setClaudeEnv(\"MAX_MCP_OUTPUT_TOKENS\", \"12000\");\n setClaudeHook();\n\n setCodexIfUnset(\"\", \"model_verbosity\", '\"low\"', \"low\");\n setCodexIfUnset(\"\", \"tool_output_token_limit\", \"10000\", \"10000\");\n setCodexIfUnset(\"agents\", \"max_concurrent_threads_per_session\", \"3\", \"3\");\n setCodexIfUnset(\"agents\", \"default_subagent_reasoning_effort\", '\"medium\"', \"medium\");\n\n head(\" Flagged as risky\");\n if (aggressive) {\n say(\"--aggressive: spawn depth has version-specific reports of behaving one level off.\");\n say(\"Verify after any Claude Code upgrade that subagents still spawn.\");\n setClaudeEnv(\"CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH\", \"1\");\n } else {\n say(\"not set (pass --aggressive to include, after reading SKILL.md):\");\n say(\" CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH=1 may block all spawning on some versions\");\n }\n\n head(\"Never set by this script\");\n say(\"CLAUDE_CODE_EFFORT_LEVEL your reasoning baseline is yours, not a script's\");\n say(\"codex model_reasoning_effort same — not read, not written, not suggested\");\n say(\"codex skills.max_context_tokens truncates the skill catalog; prune skills instead\");\n say(\"codex agents.max_depth not in the current official config reference\");\n\n // Like the original `verify || true`: report failures, never fail or falsely pass the apply.\n if (apply) {\n runVerification();\n if (!backupDir) ok(\"configuration already current (no-op apply; no backup created)\");\n }\n\n head(\"Next\");\n if (apply) {\n say(\"1. Start a fresh session in either agent.\");\n say(\"2. Confirm the token-furnace line is in context.\");\n say(\"3. Re-check any time: token-furnace setup --verify\");\n say(\"4. Unhappy with anything: token-furnace setup --rollback\");\n } else {\n say(\"Dry run. Nothing was written.\");\n say(\"Apply with: token-furnace setup --apply\");\n }\n\n return 0;\n}\n"],"mappings":"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","names":["mkdirSync","writeFileSync","dirname","resolve","existsSync","existsSync","hours","value","start","end","hours","count","key","p","hours","share","median","share","resolve","workers","existsSync","existsSync","fileURLToPath","fileURLToPath","pct","mkdirSync","readFileSync","homedir","dirname","join","readFileSync","writeFileSync","join","count","existsSync","mkdirSync","readFileSync","writeFileSync","dirname","join","fileURLToPath","resolve","mkdirSync","dirname","writeFileSync"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts","../src/compose.ts","../src/repo/memory-repo.ts","../src/repo/sqlite-repo.ts","../src/services/report-service.ts","../src/core/analyze/format.ts","../src/core/analyze/flags.ts","../src/core/analyze/pricing.ts","../src/core/analyze/config-checks.ts","../src/core/analyze/baseline.ts","../src/core/analyze/burn.ts","../src/core/analyze/report.ts","../src/core/analyze/issues.ts","../src/core/analyze/view.ts","../src/services/parse-pool.ts","../src/render/html.ts","../src/render/text.ts","../src/server.ts","../src/render/loading.ts","../src/services/usage-client.ts","../src/setup/churn-hook.ts","../src/setup/agents.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * The CLI: node:util parseArgs, the commands from architecture.md \"Entry points\", and the exit\n * codes of burn.py main(): 1 with no data, 1 with leaks or a failing doctor, 0 otherwise.\n */\n\nimport { mkdirSync, realpathSync, statSync, writeFileSync } from \"node:fs\";\nimport { dirname, resolve } from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport { parseArgs } from \"node:util\";\nimport { compose, type App } from \"./compose\";\nimport { topIssues } from \"./core/analyze/issues\";\nimport { reportView } from \"./core/analyze/view\";\nimport { renderHtml } from \"./render/html\";\nimport { printDoctor, printText } from \"./render/text\";\nimport { serve } from \"./server\";\nimport type { RawReport, ScanProgress, Source } from \"./core/model\";\nimport { planWeek } from \"./services/usage-client\";\nimport { runChurnHook, readStdin } from \"./setup/churn-hook\";\nimport { runSetup } from \"./setup/agents\";\n\nconst USAGE = `Usage: token-furnace [days] [options]\n token-furnace serve [--port 8765]\n token-furnace setup [--apply] [--rollback] [--aggressive] [--verify]\n token-furnace hook churn\n\nWhere the token budget actually went. Reads local Claude Code and Codex transcripts.\n\n days how many days back to look (default 7)\n --source <agent> all (default), claude, or codex\n --json print the Report JSON and nothing else, for agents and scripts\n --full the full text report (the old burn.py output)\n --html <path> also write a self-contained HTML report\n --list-sources each agent, its path and its transcript count\n --weekly-budget <M> weekly budget in millions of weighted tokens\n --no-plan-usage never call api.anthropic.com for the subscription window (a saved reading is still used)\n --no-cache parse every file, write no cache\n serve [--port 8765] live report on http://127.0.0.1:<port>, refreshed in the background\n -h, --help this text\n`;\n\ninterface Options {\n days: number;\n source: Source | \"all\";\n json: boolean;\n full: boolean;\n html: string | null;\n listSources: boolean;\n weeklyBudget: number | null;\n planUsage: boolean;\n port: number;\n}\n\nexport async function main(argv: string[] = process.argv.slice(2), app?: App): Promise<number> {\n if (argv[0] === \"hook\" && argv[1] === \"churn\") {\n return runChurnHook(readStdin(), (app?.env ?? process.env), process.stdout);\n }\n if (argv[0] === \"setup\") {\n const setupArgs = parseArgs({\n args: argv.slice(1),\n allowPositionals: true,\n options: {\n apply: { type: \"boolean\" },\n rollback: { type: \"boolean\" },\n aggressive: { type: \"boolean\" },\n verify: { type: \"boolean\" },\n help: { type: \"boolean\", short: \"h\" },\n },\n });\n if (setupArgs.values.help) {\n process.stdout.write(\n \"Usage: token-furnace setup [--apply] [--aggressive] [--verify] [--rollback]\\n\\n\" +\n \" --apply write changes (default: dry run)\\n\" +\n \" --aggressive also set the flagged-risky subagent spawn depth\\n\" +\n \" --verify check an existing install; exits 1 on any failure\\n\" +\n \" --rollback restore the most recent backup\\n\",\n );\n return 0;\n }\n return runSetup(\n {\n apply: setupArgs.values.apply,\n rollback: setupArgs.values.rollback,\n aggressive: setupArgs.values.aggressive,\n verify: setupArgs.values.verify,\n },\n app?.env ?? process.env,\n process.stdout,\n );\n }\n\n const parsed = parseArgs({\n args: argv,\n allowPositionals: true,\n options: {\n source: { type: \"string\" },\n json: { type: \"boolean\" },\n full: { type: \"boolean\" },\n html: { type: \"string\" },\n \"list-sources\": { type: \"boolean\" },\n \"weekly-budget\": { type: \"string\" },\n \"plan-usage\": { type: \"boolean\" }, // the default now; accepted so old scripts keep working\n \"no-plan-usage\": { type: \"boolean\" },\n \"no-cache\": { type: \"boolean\" },\n port: { type: \"string\" },\n help: { type: \"boolean\", short: \"h\" },\n },\n });\n\n if (parsed.values.help) {\n process.stdout.write(USAGE);\n return 0;\n }\n\n if (!app) {\n app = compose(process.env, { noCache: Boolean(parsed.values[\"no-cache\"]) });\n }\n\n const serveMode = parsed.positionals[0] === \"serve\";\n const positionals = serveMode ? parsed.positionals.slice(1) : parsed.positionals;\n const days = Number(positionals[0] ?? 7);\n if (!Number.isInteger(days) || days < 1) {\n process.stderr.write(`token-furnace: days must be a whole number, got \"${positionals[0] ?? \"\"}\"\\n`);\n return 2;\n }\n const source = (parsed.values.source ?? \"all\") as Source | \"all\";\n if (source !== \"all\" && source !== \"claude\" && source !== \"codex\") {\n process.stderr.write(`token-furnace: --source must be all, claude or codex\\n`);\n return 2;\n }\n const weeklyBudget = weeklyBudgetOf(app.env, parsed.values[\"weekly-budget\"]);\n const port = Number(parsed.values.port ?? 8765);\n if (!Number.isInteger(port) || port < 0 || port > 65_535) {\n process.stderr.write(\"token-furnace: --port must be a port number\\n\");\n return 2;\n }\n const options: Options = {\n days,\n source,\n json: Boolean(parsed.values.json),\n full: Boolean(parsed.values.full),\n html: parsed.values.html ?? null,\n listSources: Boolean(parsed.values[\"list-sources\"]),\n weeklyBudget,\n planUsage: !parsed.values[\"no-plan-usage\"],\n port,\n };\n\n if (options.listSources) {\n listSources(app);\n return 0;\n }\n if (serveMode) {\n await serve(app, options);\n return 0;\n }\n\n const now = app.now();\n await app.reports.refresh(stderrProgress());\n const plan = await planWeek(app.env, now, options.planUsage);\n const report = app.reports.getRaw(options.days, options.source, {\n weeklyBudget: options.weeklyBudget,\n planWeek: plan,\n now,\n });\n if (!report) {\n // --json keeps stdout to the Report alone, so the notice goes to stderr there.\n (options.json ? process.stderr : process.stdout).write(\n \"No transcripts found. Try --list-sources.\\n\",\n );\n return 1;\n }\n\n const htmlPath = writeHtml(report, now, options.html);\n if (options.json) {\n process.stdout.write(`${JSON.stringify(reportView(report, now))}\\n`);\n return 0;\n }\n if (options.full) {\n process.stdout.write(printText(report));\n if (htmlPath) process.stdout.write(`\\nHTML report: ${htmlPath}\\n`);\n return 0;\n }\n process.stdout.write(printDoctor(report, htmlPath));\n return topIssues(report).length ? 1 : 0;\n}\n\n/** A redrawn `Scanning 3,412 / 7,700 files (44%)` line on a terminal's stderr. Nothing otherwise. */\nfunction stderrProgress(): ((progress: ScanProgress) => void) | undefined {\n if (!process.stderr.isTTY) return undefined;\n return (p) => {\n if (!p.filesTotal) return;\n const text = p.phase === \"ready\" ? \"\" : `Scanning ${p.filesDone.toLocaleString()} / ${p.filesTotal.toLocaleString()} files (${Math.round((100 * p.bytesDone) / Math.max(1, p.bytesTotal))}%)`;\n process.stderr.write(`\\r\\x1b[K${text}`);\n };\n}\n\n/** `--weekly-budget M`, or TOKEN_FURNACE_WEEKLY_BUDGET, in millions of weighted tokens. */\nfunction weeklyBudgetOf(env: NodeJS.ProcessEnv, flag: string | undefined): number | null {\n const text = flag || env.TOKEN_FURNACE_WEEKLY_BUDGET || \"\";\n const value = Number.parseFloat(text);\n return text && Number.isFinite(value) ? value : null;\n}\n\n/** Each agent, its path and its transcript count, like burn.py --list-sources. */\nfunction listSources(app: App): void {\n for (const agent of app.sources) {\n const path = agent.root();\n const found = existsDir(path) ? agent.files().length : 0;\n process.stdout.write(\n ` ${agent.name.padEnd(8)} ${path.padEnd(46)} ${found ? `${found} transcripts` : \"not installed\"}\\n`,\n );\n }\n}\n\n/** Writes the static page and returns its absolute path. */\nfunction writeHtml(report: RawReport, now: Date, path: string | null): string | null {\n if (!path) return null;\n const full = resolve(path);\n mkdirSync(dirname(full), { recursive: true });\n writeFileSync(full, renderHtml(report, now));\n return full;\n}\n\nfunction existsDir(path: string): boolean {\n try {\n return statSync(path).isDirectory();\n } catch {\n return false;\n }\n}\n\n/** True when this module is the process entry, even through an npm bin symlink. */\nfunction isEntryPoint(): boolean {\n const entry = process.argv[1];\n if (!entry) return false;\n try {\n return import.meta.url === pathToFileURL(realpathSync(entry)).href;\n } catch {\n return false;\n }\n}\n\n// Only when run as the binary: a test imports main() without starting a command.\nif (isEntryPoint()) {\n process.exitCode = await main();\n}\n","import { existsSync } from \"node:fs\";\nimport { availableParallelism, homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { MemorySessionRepository } from \"./repo/memory-repo\";\nimport { SqliteSessionRepository } from \"./repo/sqlite-repo\";\nimport type { SessionRepository } from \"./repo/session-repo\";\nimport { ReportService } from \"./services/report-service\";\nimport { ClaudeSource } from \"./sources/claude\";\nimport { CodexSource } from \"./sources/codex\";\nimport type { AgentSource, Env } from \"./sources/agent-source\";\n\nexport interface App {\n env: Env;\n sources: AgentSource[];\n repo: SessionRepository;\n reports: ReportService;\n /** The clock. TOKEN_FURNACE_NOW freezes it, so a test can compare two runs byte for byte. */\n now: () => Date;\n}\n\nexport function sqliteCachePath(env: Env): string {\n const base = env.XDG_CACHE_HOME || join(env.HOME || homedir(), \".cache\");\n return join(base, \"token-furnace\", \"cache.sqlite\");\n}\n\n/** The composition root: the only place that calls `new`. architecture.md */\nexport function compose(env: Env = process.env, opts?: { noCache?: boolean }): App {\n const noCache = opts?.noCache ?? Boolean(env.TOKEN_FURNACE_NO_CACHE && env.TOKEN_FURNACE_NO_CACHE !== \"0\");\n const effective: Env = { ...env, TOKEN_FURNACE_NO_CACHE: noCache ? \"1\" : \"0\" };\n const sources: AgentSource[] = [new ClaudeSource(effective), new CodexSource(effective)];\n const repo = noCache ? new MemorySessionRepository() : new SqliteSessionRepository(sqliteCachePath(effective));\n return {\n env: effective,\n sources,\n repo,\n reports: new ReportService(sources, repo, effective, workers(effective)),\n now: () => new Date(effective.TOKEN_FURNACE_NOW || Date.now()),\n };\n}\n\n/**\n * Parse threads, when the built worker script sits next to this bundle. Running from source (a\n * test, `tsx`) has no such file and parses on the main thread. TOKEN_FURNACE_WORKERS=0 turns it off.\n */\nfunction workers(env: Env): { url: URL; size: number } | null {\n const url = new URL(\"./scan-worker.js\", import.meta.url);\n const wanted = env.TOKEN_FURNACE_WORKERS !== undefined\n ? Number(env.TOKEN_FURNACE_WORKERS)\n : Math.max(1, Math.min(availableParallelism(), 12));\n return existsSync(fileURLToPath(url)) && wanted >= 1 ? { url, size: Math.floor(wanted) } : null;\n}\n","import type { SessionInput, SourceFile } from \"../core/model\";\nimport type { SessionRepository } from \"./session-repo\";\n\n/**\n * Turns in a Map, for tests and --no-cache. The file size rides along in the map so a file that\n * was appended to is reparsed even when its mtime is unchanged, like cached() in burn.py:516.\n */\nexport class MemorySessionRepository implements SessionRepository {\n private readonly sessions = new Map<string, { session: SessionInput; size: number }>();\n\n changed(files: SourceFile[]): SourceFile[] {\n const seen = new Set<string>();\n const out: SourceFile[] = [];\n for (const file of files) {\n seen.add(file.path);\n const held = this.sessions.get(file.path);\n if (held && held.session.mtimeMs === file.mtimeMs && held.size === file.size) continue;\n out.push(file);\n }\n for (const path of [...this.sessions.keys()]) if (!seen.has(path)) this.sessions.delete(path);\n return out;\n }\n\n all(): SessionInput[] {\n return [...this.sessions.values()].map((held) => held.session);\n }\n\n save(session: SessionInput, size: number): void {\n this.sessions.set(session.path, { session, size });\n }\n}","import { existsSync, mkdirSync, rmSync } from \"node:fs\";\nimport { dirname } from \"node:path\";\nimport { DatabaseSync, type StatementSync } from \"node:sqlite\";\nimport type { SessionInput, Source, SourceFile, Turn, Wake } from \"../core/model\";\nimport type { SessionRepository } from \"./session-repo\";\n\nconst SCHEMA_VERSION = 1;\n\nconst DDL = `\nPRAGMA foreign_keys = ON;\nPRAGMA user_version = ${SCHEMA_VERSION};\n\nCREATE TABLE files (\n path TEXT PRIMARY KEY,\n source TEXT NOT NULL,\n mtime_ns INTEGER NOT NULL,\n size INTEGER NOT NULL,\n title TEXT,\n bad_lines INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE turns (\n path TEXT NOT NULL REFERENCES files(path) ON DELETE CASCADE,\n seq INTEGER NOT NULL,\n project TEXT NOT NULL,\n session TEXT NOT NULL,\n model TEXT NOT NULL,\n at INTEGER NOT NULL,\n base_in INTEGER NOT NULL,\n cache_read INTEGER NOT NULL,\n cache_write INTEGER NOT NULL,\n output INTEGER NOT NULL,\n tools TEXT NOT NULL,\n reads INTEGER NOT NULL,\n wakes TEXT NOT NULL,\n PRIMARY KEY (path, seq)\n);\nCREATE INDEX turns_at ON turns(at);\n`;\n\ninterface FileRow {\n path: string;\n source: string;\n mtime_ns: number;\n size: number;\n title: string | null;\n bad_lines: number;\n}\n\ninterface TurnRow {\n path: string;\n seq: number;\n project: string;\n session: string;\n model: string;\n at: number;\n base_in: number;\n cache_read: number;\n cache_write: number;\n output: number;\n tools: string;\n reads: number;\n wakes: string;\n}\n\nexport class SqliteSessionRepository implements SessionRepository {\n private db: DatabaseSync | null = null;\n private readonly dbPath: string;\n private stmtDeleteFile: StatementSync | null = null;\n private stmtInsertFile: StatementSync | null = null;\n private stmtInsertTurn: StatementSync | null = null;\n private stmtAllFiles: StatementSync | null = null;\n private stmtAllTurns: StatementSync | null = null;\n\n constructor(dbPath: string) {\n this.dbPath = dbPath;\n this.ensureDb();\n }\n\n private prepareStatements(): void {\n if (!this.db) return;\n this.stmtDeleteFile = this.db.prepare(\"DELETE FROM files WHERE path = ?;\");\n this.stmtInsertFile = this.db.prepare(\n \"INSERT INTO files (path, source, mtime_ns, size, title, bad_lines) VALUES (?, ?, ?, ?, ?, 0);\",\n );\n this.stmtInsertTurn = this.db.prepare(\n \"INSERT INTO turns (path, seq, project, session, model, at, base_in, cache_read, cache_write, output, tools, reads, wakes) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);\",\n );\n this.stmtAllFiles = this.db.prepare(\"SELECT path, source, mtime_ns, size, title, bad_lines FROM files;\");\n this.stmtAllTurns = this.db.prepare(\n \"SELECT path, seq, project, session, model, at, base_in, cache_read, cache_write, output, tools, reads, wakes FROM turns ORDER BY path, seq;\",\n );\n }\n\n private openDb(path: string): DatabaseSync {\n const db = new DatabaseSync(path);\n try {\n db.exec(\"PRAGMA foreign_keys = ON;\");\n db.exec(\"PRAGMA synchronous = NORMAL;\");\n if (path !== \":memory:\") db.exec(\"PRAGMA journal_mode = WAL;\");\n return db;\n } catch (error) {\n db.close();\n throw error;\n }\n }\n\n private ensureDb(): void {\n if (this.db) return;\n try {\n if (this.dbPath !== \":memory:\") {\n mkdirSync(dirname(this.dbPath), { recursive: true });\n }\n const db = this.openDb(this.dbPath);\n const verRow = db.prepare(\"PRAGMA user_version;\").get() as { user_version: number } | undefined;\n const ver = verRow ? verRow.user_version : 0;\n if (ver !== SCHEMA_VERSION) {\n db.close();\n this.recreateDb();\n return;\n }\n this.db = db;\n this.prepareStatements();\n } catch {\n this.recreateDb();\n }\n }\n\n private recreateDb(): void {\n try {\n if (this.dbPath !== \":memory:\" && existsSync(this.dbPath)) {\n rmSync(this.dbPath, { force: true });\n rmSync(`${this.dbPath}-wal`, { force: true });\n rmSync(`${this.dbPath}-shm`, { force: true });\n }\n } catch {\n // ignore deletion errors\n }\n try {\n if (this.dbPath !== \":memory:\") {\n mkdirSync(dirname(this.dbPath), { recursive: true });\n }\n const db = this.openDb(this.dbPath);\n db.exec(DDL);\n this.db = db;\n this.prepareStatements();\n } catch {\n try {\n const memDb = this.openDb(\":memory:\");\n memDb.exec(DDL);\n this.db = memDb;\n this.prepareStatements();\n } catch {\n this.db = null;\n }\n }\n }\n\n changed(files: SourceFile[]): SourceFile[] {\n this.ensureDb();\n if (!this.db || !this.stmtAllFiles || !this.stmtDeleteFile) return files;\n\n const seen = new Set<string>();\n const out: SourceFile[] = [];\n\n const cachedFiles = new Map<string, FileRow>();\n for (const row of this.stmtAllFiles.all() as unknown as FileRow[]) {\n cachedFiles.set(row.path, row);\n }\n\n for (const file of files) {\n seen.add(file.path);\n const held = cachedFiles.get(file.path);\n if (held && held.mtime_ns === file.mtimeMs && held.size === file.size) continue;\n out.push(file);\n }\n\n for (const path of cachedFiles.keys()) {\n if (!seen.has(path)) {\n this.stmtDeleteFile.run(path);\n }\n }\n\n return out;\n }\n\n all(): SessionInput[] {\n this.ensureDb();\n if (!this.db || !this.stmtAllFiles || !this.stmtAllTurns) return [];\n\n const fileRows = this.stmtAllFiles.all() as unknown as FileRow[];\n const turnRows = this.stmtAllTurns.iterate() as unknown as Iterable<TurnRow>;\n\n const turnsByPath = new Map<string, Turn[]>();\n for (const r of turnRows) {\n let list = turnsByPath.get(r.path);\n if (!list) {\n list = [];\n turnsByPath.set(r.path, list);\n }\n list.push({\n source: \"claude\",\n project: r.project,\n session: r.session,\n model: r.model,\n when: new Date(r.at),\n baseIn: r.base_in,\n cacheRead: r.cache_read,\n cacheWrite: r.cache_write,\n output: r.output,\n tools: JSON.parse(r.tools) as string[],\n reads: r.reads,\n wakes: JSON.parse(r.wakes) as Wake[],\n });\n }\n\n return fileRows.map((f) => {\n const source = f.source as Source;\n const turns = (turnsByPath.get(f.path) ?? []).map((t) => ({ ...t, source }));\n return {\n source,\n path: f.path,\n mtimeMs: f.mtime_ns,\n title: f.title,\n turns,\n };\n });\n }\n\n save(session: SessionInput, size: number): void {\n this.ensureDb();\n if (!this.db || !this.stmtDeleteFile || !this.stmtInsertFile || !this.stmtInsertTurn) return;\n\n this.db.exec(\"BEGIN IMMEDIATE;\");\n try {\n this.stmtDeleteFile.run(session.path);\n this.stmtInsertFile.run(session.path, session.source, session.mtimeMs, size, session.title ?? null);\n\n for (let seq = 0; seq < session.turns.length; seq++) {\n const t = session.turns[seq];\n this.stmtInsertTurn.run(\n session.path,\n seq,\n t.project,\n t.session,\n t.model,\n t.when.getTime(),\n t.baseIn,\n t.cacheRead,\n t.cacheWrite,\n t.output,\n JSON.stringify(t.tools),\n t.reads,\n JSON.stringify(t.wakes),\n );\n }\n this.db.exec(\"COMMIT;\");\n } catch {\n this.db.exec(\"ROLLBACK;\");\n }\n }\n\n close(): void {\n if (this.db) {\n try {\n this.db.close();\n } catch {\n // ignore\n }\n this.db = null;\n }\n }\n}\n","import { existsSync } from \"node:fs\";\nimport { buildReport } from \"../core/analyze/report\";\nimport { reportView } from \"../core/analyze/view\";\nimport type { ConfigInput, ParsedFile, RawReport, Report, ScanProgress, Source, Week } from \"../core/model\";\nimport type { SessionRepository } from \"../repo/session-repo\";\nimport { ParsePool } from \"./parse-pool\";\nimport type { AgentSource, Env } from \"../sources/agent-source\";\n\nexport interface ReportOptions {\n /** Millions of weighted tokens, or null. */\n weeklyBudget: number | null;\n /** The subscription window, read by the caller: the saved reading, refreshed from the network when a login exists. */\n planWeek?: Week | null;\n /** The clock. Defaults to now, so a test can freeze it. */\n now?: Date;\n}\n\n/**\n * The report over the sources and the repository. Everything the pure buildReport needs arrives\n * in its input, so this class only reads files and hands the contents over. burn.py's build_report\n * and report_view, split at the I/O boundary.\n */\nexport class ReportService {\n constructor(\n private readonly sources: AgentSource[],\n private readonly repo: SessionRepository,\n private readonly env: Env,\n /** The built worker script and how many threads parse. Null parses on the main thread. */\n private readonly workers: { url: URL; size: number } | null = null,\n ) {}\n\n /** Where the scan stands. `/api/status` and the CLI read it. */\n progress: ScanProgress = { phase: \"idle\", filesDone: 0, filesTotal: 0, bytesDone: 0, bytesTotal: 0, startedAt: 0, updatedAt: 0 };\n\n /** True once one full scan has finished: from then on a report is always there to serve. */\n hasScanned = false;\n\n private inflight: Promise<void> | null = null;\n\n /** Each path's place in the sources' own file order, so scanning newest first changes no report. */\n private order = new Map<string, number>();\n\n /**\n * Parse every file whose mtime or size changed since the last scan, newest first. It yields to\n * the event loop between files, so a server keeps answering during a cold scan of gigabytes.\n * Overlapping calls share one scan.\n */\n refresh(onProgress?: (progress: ScanProgress) => void): Promise<void> {\n this.inflight ??= this.scan(onProgress).finally(() => {\n this.inflight = null;\n });\n return this.inflight;\n }\n\n private async scan(onProgress?: (progress: ScanProgress) => void): Promise<void> {\n const live = this.sources.filter((agent) => existsSync(agent.root())); // not installed\n const files = live.flatMap((source) => source.files().map((file) => ({ source, file })));\n this.order = new Map(files.map(({ file }, index) => [file.path, index]));\n const changed = new Set(this.repo.changed(files.map(({ file }) => file)).map((file) => file.path));\n const todo = files.filter(({ file }) => changed.has(file.path)).sort((a, b) => b.file.mtimeMs - a.file.mtimeMs);\n const progress = this.progress;\n Object.assign(progress, {\n phase: \"scanning\",\n filesDone: 0,\n filesTotal: todo.length,\n bytesDone: 0,\n bytesTotal: todo.reduce((sum, { file }) => sum + file.size, 0),\n startedAt: Date.now(),\n updatedAt: Date.now(),\n });\n const save = (item: (typeof todo)[number], parsed: ParsedFile): void => {\n this.repo.save(\n { source: item.source.name, path: item.file.path, mtimeMs: item.file.mtimeMs, title: parsed.title, turns: parsed.turns },\n item.file.size,\n );\n };\n const done = (item: (typeof todo)[number]): void => {\n progress.filesDone += 1;\n progress.bytesDone += item.file.size;\n progress.updatedAt = Date.now();\n onProgress?.(progress);\n };\n\n const poolSize = this.workers && todo.length ? Math.min(this.workers.size, todo.length) : 0;\n const pool = poolSize >= 1 ? new ParsePool(this.workers!.url, this.env, poolSize) : null;\n try {\n if (pool) {\n // One lane per worker: each takes the next file, newest first, as soon as it is free.\n let next = 0;\n const lane = async (index: number): Promise<void> => {\n while (next < todo.length) {\n const item = todo[next++];\n let parsed: ParsedFile;\n try {\n parsed = await pool.parse(index, item.source.name, item.file.path);\n } catch {\n // Fall back to in-process parsing if the worker fails or crashes\n parsed = item.source.parse(item.file.path);\n }\n save(item, parsed);\n done(item);\n }\n };\n await Promise.all(Array.from({ length: poolSize }, (_, index) => lane(index)));\n } else {\n let lastYield = Date.now();\n for (const item of todo) {\n save(item, item.source.parse(item.file.path));\n done(item);\n if (Date.now() - lastYield >= 25) {\n await new Promise<void>((next) => setImmediate(next)); // let requests through\n lastYield = Date.now();\n }\n }\n }\n } finally {\n await pool?.close();\n progress.phase = \"ready\";\n progress.updatedAt = Date.now();\n this.hasScanned = true;\n onProgress?.(progress);\n }\n }\n\n /** The agents to scan: the ones installed, in source order. burn.py:289 */\n live(source: Source | \"all\"): Source[] {\n return this.sources\n .filter((agent) => (source === \"all\" || source === agent.name) && existsSync(agent.root()))\n .map((agent) => agent.name);\n }\n\n /** The raw report, which the text renderers read with burn.py's own key names. */\n getRaw(days: number, source: Source | \"all\", opts: ReportOptions): RawReport | null {\n const now = opts.now ?? new Date();\n const live = this.live(source);\n if (!live.length) return null;\n return buildReport({\n now,\n days,\n weeklyBudget: opts.weeklyBudget,\n live,\n sessions: this.repo\n .all()\n .sort((a, b) => (this.order.get(a.path) ?? Infinity) - (this.order.get(b.path) ?? Infinity)),\n config: this.readConfig(live),\n planWeek: opts.planWeek ?? null,\n codexWeek: live.includes(\"codex\") ? (this.sources.find((s) => s.name === \"codex\")?.week?.(now) ?? null) : null,\n });\n }\n\n /** The Report JSON: /api/report, --json and the inlined --html page all read this. */\n getReport(days: number, source: Source | \"all\", opts: ReportOptions): Report | null {\n const now = opts.now ?? new Date();\n const raw = this.getRaw(days, source, { ...opts, now });\n return raw ? reportView(raw, now) : null;\n }\n\n /** Every config file the checks read, through the agent that owns it. */\n private readConfig(live: Source[]): ConfigInput {\n const claude = this.sources.find((s) => s.name === \"claude\");\n const codex = this.sources.find((s) => s.name === \"codex\");\n return {\n claudeBase: claude?.base() ?? \"\",\n claudeHome: claude?.home() ?? \"\",\n settings: claude?.readFile(\"settings.json\") ?? null,\n codexConfig: codex?.readFile(\"config.toml\") ?? null,\n memoryIndexes: live.includes(\"claude\") ? (claude?.memoryIndexes?.() ?? []) : [],\n env: this.env,\n };\n }\n}\n","/**\n * Python's %-format. burn.py's message strings are the product, so the numbers inside them must\n * round the way Python rounds: the exact value of the double, ties to even.\n */\n\n/**\n * The exact decimal expansion of a finite double, as digits with the decimal point `point`\n * digits from the left. A double is m * 2^e, and for e < 0 that is m * 5^(-e) / 10^(-e), so the\n * expansion terminates and BigInt holds it exactly.\n */\nfunction exact(value: number): { digits: string; point: number } {\n const view = new DataView(new ArrayBuffer(8));\n view.setFloat64(0, value);\n const bits = view.getBigUint64(0);\n const exponentField = Number((bits >> 52n) & 0x7ffn);\n if (exponentField === 0) return { digits: String(bits & ((1n << 52n) - 1n)), point: -1074 }; // subnormal or 0\n const m = (bits & ((1n << 52n) - 1n)) | (1n << 52n); // the implicit leading bit is always set\n const exponent = exponentField - 1023 - 52;\n const n = exponent >= 0 ? m << BigInt(exponent) : m * 5n ** BigInt(-exponent);\n const digits = n.toString();\n return { digits, point: exponent >= 0 ? digits.length : digits.length + exponent };\n}\n\n/** `%.<digits>f` of a finite double, rounded from its exact value with ties to even. */\nexport function fixed(value: number, digits = 0): string {\n if (Number.isNaN(value)) return \"nan\";\n if (!Number.isFinite(value)) return value > 0 ? \"inf\" : \"-inf\";\n const sign = value < 0 ? \"-\" : \"\";\n const { digits: all, point } = exact(value);\n const text = all.padEnd(point + digits + 1, \"0\");\n\n const kept = text.slice(0, point + digits);\n const next = text[point + digits] ?? \"0\";\n const tail = text.slice(point + digits + 1).replace(/0+$/, \"\");\n\n let n = BigInt(kept === \"\" ? \"0\" : kept);\n if (next > \"5\" || (next === \"5\" && (tail !== \"\" || n % 2n !== 0n))) n += 1n;\n\n const body = n.toString().padStart(digits + 1, \"0\");\n return sign + (digits === 0 ? body : `${body.slice(0, -digits)}.${body.slice(-digits)}`);\n}\n\n/** `%d` on a float: Python truncates toward zero. */\nexport function int0(value: number): string {\n return String(Math.trunc(value));\n}","import { fixed } from \"./format\";\nimport type { WakeCounts } from \"../model\";\nimport { int0 } from \"./format\";\n\n// Windows for the weekly-limit gain: percentage points spent in the last N hours.\nexport const GAIN_HOURS = [1, 6, 24];\n// Window for the checks and the leaks: what the user fixed recently must show up.\nexport const CHECK_HOURS = 24;\nexport const LEVELS: Record<number, \"critical\" | \"warn\" | \"info\"> = {\n 1: \"critical\",\n 2: \"warn\",\n 3: \"info\",\n};\n\n/** Thresholds for the per-session leak flags. Each one maps to a measured failure. */\nexport const BENCH_WINDOW = 200_000; // the benchmark: same turns with context capped here\nexport const LATE_COMPACT_PEAK = 300_000; // context above this means auto-compact fires too late\nexport const CALLER_READS = 100; // reads the caller ran itself instead of delegating\nexport const WAKEUPS = 50; // teammate/task/peer messages, each a full-context turn\nexport const TURNS_PER_PROMPT = 200; // an unbounded autonomous loop\nexport const LONG_LIVED_HOURS = 12; // one session carrying many unrelated tasks\nexport const MEMORY_INDEX_LINES = 200; // Claude Code loads only this many lines of MEMORY.md\nexport const COMPACT_WINDOW_MAX = 300_000;\nexport const SUBAGENT_CAP = 3; // most concurrent subagents worth running (each one is a full loop)\nexport const SUBAGENT_DEPTH = 1; // nesting depth: 1 blocks subagents spawning subagents\nexport const TOOL_CONCURRENCY = 4; // parallel tool calls in the main agent\nexport const SUBAGENT_ENV = \"CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS\";\nexport const CODEX_SUBAGENT_KEY = \"max_concurrent_threads_per_session\";\n\n/** A session whose last turn is this recent counts as active right now. */\nexport const ACTIVE_MINUTES = 30;\n\n/** The leak flags for one session, each naming its own fix. burn.py:316 */\nexport function sessionFlags(\n turns: number,\n peak: number,\n hours: number,\n reads: number,\n wakes: WakeCounts,\n): string[] {\n const flags: string[] = [];\n if (peak > LATE_COMPACT_PEAK) {\n flags.push(\n `late compaction: peak ${int0(peak / 1000)}k. Set autoCompactWindow to about 200000.`,\n );\n }\n if (reads >= CALLER_READS) {\n flags.push(\n `caller reads: ${reads} file/log reads. Send them to a cheap read-only agent.`,\n );\n }\n const pings = wakes.teammate + wakes.task + wakes.peer;\n if (pings >= WAKEUPS) {\n flags.push(\n `wakeups: ${pings} (teammate ${wakes.teammate}, task ${wakes.task}, peer ${wakes.peer}). Ask for one report at the end.`,\n );\n }\n if (turns / Math.max(wakes.human, 1) >= TURNS_PER_PROMPT) {\n flags.push(\n `loop: ${turns} turns for ${wakes.human} human prompts. Give the loop a stop condition and a budget.`,\n );\n }\n if (hours >= LONG_LIVED_HOURS) {\n flags.push(`long-lived: ${fixed(hours)}h. Start one fresh session per task.`);\n }\n return flags;\n}","import { int0 } from \"./format\";\n\nexport const CACHE_READ_RATE = 0.1;\nexport const CACHE_WRITE_RATE = 1.25;\nexport const OUTPUT_RATE = 5.0;\n\n/** Rough price ratios against the flagship of each family. burn.py:44 */\nexport const MODEL_RATE: Record<string, number> = {\n haiku: 0.2,\n sonnet: 0.6,\n opus: 1.0,\n \"gpt-5-mini\": 0.2,\n \"gpt-5.5\": 1.0,\n \"gpt-5\": 1.0,\n};\n\n/** Longest key first, so \"gpt-5-mini\" does not match \"gpt-5\". burn.py:61 */\nconst RATES = Object.entries(MODEL_RATE).sort((a, b) => b[0].length - a[0].length);\n\nexport const SIZE_BUCKETS: [number, number | null][] = [\n [0, 100],\n [100, 200],\n [200, 300],\n [300, 500],\n [500, 1000],\n [1000, null],\n];\n\n/** Price ratio for a model id, or null when the model is unknown. burn.py:59 */\nexport function modelRate(model: string | null): number | null {\n const id = model || \"\";\n for (const [name, rate] of RATES) if (id.includes(name)) return rate;\n return null;\n}\n\n/** The context-size bucket a turn of `tokens` falls in. burn.py:67 */\nexport function bucketLabel(tokens: number): string {\n for (const [low, high] of SIZE_BUCKETS) {\n if (high === null || (low <= tokens / 1000 && tokens / 1000 < high)) {\n return high === null ? `${low}k+` : `${low}-${high}k`;\n }\n }\n return \"?\";\n}\n\n/** The bucket label for a bucket row, from its edges. burn.py:751 */\nexport function bucketRowLabel(low: number, high: number | null): string {\n return high === null ? `${low}k+` : `${low}-${high}k`;\n}\n\n/** Shared by flags and reports: \"%dk\" % (tokens / 1000). */\nexport function kilo(tokens: number): string {\n return int0(tokens / 1000);\n}","import { int0 } from \"./format\";\nimport { COMPACT_WINDOW_MAX, MEMORY_INDEX_LINES, SUBAGENT_CAP, SUBAGENT_DEPTH, TOOL_CONCURRENCY, SUBAGENT_ENV, CODEX_SUBAGENT_KEY } from \"./flags\";\nimport type { ConfigInput, ConfigNote, Source } from \"../model\";\n\n/** A numeric note where lower is better: unset or over the limit warns. burn.py:410 */\nfunction atMost(\n agent: Source,\n label: string,\n key: string,\n value: number | null,\n source: string | null,\n limit: number,\n): ConfigNote {\n let shown: string;\n let line: string;\n if (value === null) {\n shown = \"unset\";\n line = `${key} is unset: set it to at most ${limit}.`;\n } else {\n shown = String(value);\n line =\n value > limit\n ? `${key} is ${value} (from ${source}): too high. Use ${limit}.`\n : `${key} is ${value} (from ${source}): ok.`;\n }\n const ok = value !== null && value <= limit;\n return {\n name: label,\n source: agent,\n value: shown,\n target: `at most ${limit}`,\n ok,\n level: ok ? \"ok\" : \"warn\",\n ratio: value ? value / limit : null,\n line,\n };\n}\n\n/** A string note: unset warns, set is ok. `want` is the advice when unset. burn.py:424 */\nfunction isSet(\n agent: Source,\n label: string,\n key: string,\n value: string | null,\n source: string | null,\n want: string,\n): ConfigNote {\n const ok = Boolean(value);\n const line = ok\n ? `${key} is ${value} (from ${source}): ok.`\n : `${key} is unset: ${want}`;\n return {\n name: label,\n source: agent,\n value: value || \"unset\",\n target: \"pinned\",\n ok,\n level: ok ? \"ok\" : \"warn\",\n ratio: null,\n line,\n };\n}\n\n/** The auto-compact window in tokens, and the source that set it. burn.py:335 */\nexport function compactWindow(\n config: ConfigInput,\n): [number | null, string | null] {\n const env = config.env.CLAUDE_CODE_AUTO_COMPACT_WINDOW;\n if (env) {\n const text = env.trim().toLowerCase();\n const scale: Record<string, number> = { k: 1_000, m: 1_000_000 };\n const unit = text.slice(-1);\n const factor = scale[unit] ?? 1;\n const parsed = Number.parseFloat(text.replace(/[km]+$/, \"\"));\n if (!Number.isFinite(parsed)) return [null, `env (unparsed: ${env})`];\n const value = parsed * factor;\n return [Math.trunc(value >= 1000 ? value : value * 1000), \"env\"];\n }\n const value = settings(config)?.autoCompactWindow;\n return typeof value === \"number\" && Number.isFinite(value) ? [Math.trunc(value), \"settings\"] : [null, null];\n}\n\n/** An integer env setting from settings.json .env (which wins) or the process env. burn.py:354 */\nexport function claudeEnvInt(\n config: ConfigInput,\n key: string,\n): [number | null, string | null] {\n const raw = (settings(config)?.env as Record<string, unknown> | undefined)?.[key];\n let value: unknown = raw;\n let source = \"settings\";\n if (value === undefined || value === null) {\n value = config.env[key];\n source = \"env\";\n }\n if (value === undefined || value === null) return [null, null];\n const parsed = typeof value === \"number\" ? value : Number.parseFloat(String(value));\n if (!Number.isFinite(parsed)) return [null, `${source} (unparsed: ${String(value)})`];\n return [Math.trunc(parsed), source];\n}\n\n/** A string env setting from settings.json .env or the process env. burn.py:373 */\nexport function claudeEnvStr(config: ConfigInput, key: string): [string | null, string | null] {\n const raw = (settings(config)?.env as Record<string, unknown> | undefined)?.[key];\n if (raw === undefined || raw === null) return [config.env[key] ?? null, \"env\"];\n return [String(raw), \"settings\"];\n}\n\n/** The concurrent-subagent cap and the source that set it. burn.py:385 */\nexport function claudeSubagentCap(config: ConfigInput): [number | null, string | null] {\n return claudeEnvInt(config, SUBAGENT_ENV);\n}\n\n/** A value (string) from Codex config.toml, under [table] or as a dotted key. burn.py:390 */\nexport function codexValue(config: ConfigInput, key: string): string | null {\n const text = config.codexConfig;\n if (text === null) return null;\n const match = new RegExp(\n `^\\\\s*(?:[a-z_]+\\\\s*\\\\.\\\\s*)?${key.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\")}\\\\s*=\\\\s*(.+)$`,\n \"m\",\n ).exec(text);\n return match ? match[1].trim().replace(/^[\"']|[\"']$/g, \"\") : null;\n}\n\n/** Codex's [agents] max_concurrent_threads_per_session. burn.py:401 */\nexport function codexSubagentCap(config: ConfigInput): [number | null, string | null] {\n const value = codexValue(config, CODEX_SUBAGENT_KEY);\n const parsed = Number.parseInt(value ?? \"\", 10);\n return Number.isFinite(parsed) ? [parsed, \"config.toml\"] : [null, null];\n}\n\n/** Recommended settings, one per agent, judged from actual config. burn.py:434 */\nexport function configNotes(live: Source[], config: ConfigInput): ConfigNote[] {\n const notes: ConfigNote[] = [];\n if (live.includes(\"claude\")) {\n const [window, wsource] = compactWindow(config);\n const within = Boolean(window) && Math.abs((window as number) - 200_000) <= 50_000;\n let line: string;\n if (window === null) {\n line =\n 'autoCompactWindow is unset: compaction waits for the model window (about 1M on 1M models). Set \"autoCompactWindow\": 200000.';\n } else if (window > COMPACT_WINDOW_MAX) {\n line = `autoCompactWindow is ${int0(window / 1000)}k (from ${wsource}): too high. Use about 200k.`;\n } else {\n line = `autoCompactWindow is ${int0(window / 1000)}k (from ${wsource}): ok.`;\n }\n notes.push({\n name: \"autoCompactWindow\",\n source: \"claude\",\n value: window ? `${int0(window / 1000)}k` : \"unset (model max)\",\n target: \"about 200k\",\n ok: within,\n level: within ? \"ok\" : \"warn\",\n ratio: window ? window / 200_000 : null,\n line,\n });\n const [cap, csrc] = claudeSubagentCap(config);\n notes.push(atMost(\"claude\", \"Max concurrent subagents\", SUBAGENT_ENV, cap, csrc, SUBAGENT_CAP));\n const [depth, dsrc] = claudeEnvInt(config, \"CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH\");\n notes.push(\n atMost(\"claude\", \"Subagent spawn depth\", \"CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH\", depth, dsrc, SUBAGENT_DEPTH),\n );\n const [model, msrc] = claudeEnvStr(config, \"CLAUDE_CODE_SUBAGENT_MODEL\");\n notes.push(\n isSet(\n \"claude\",\n \"Subagent model\",\n \"CLAUDE_CODE_SUBAGENT_MODEL\",\n model,\n msrc,\n \"subagents inherit the main model; pin a cheap worker (e.g. CLAUDE_CODE_SUBAGENT_MODEL=sonnet).\",\n ),\n );\n const [tools, tsrc] = claudeEnvInt(config, \"CLAUDE_CODE_MAX_TOOL_USE_CONCURRENCY\");\n notes.push(\n atMost(\"claude\", \"Tool-call concurrency\", \"CLAUDE_CODE_MAX_TOOL_USE_CONCURRENCY\", tools, tsrc, TOOL_CONCURRENCY),\n );\n }\n if (live.includes(\"codex\")) {\n const [cap, csrc] = codexSubagentCap(config);\n notes.push(\n atMost(\"codex\", \"Max concurrent subagents\", `agents.${CODEX_SUBAGENT_KEY}`, cap, csrc, SUBAGENT_CAP),\n );\n const depth = codexValue(config, \"max_depth\");\n notes.push(\n atMost(\n \"codex\",\n \"Agent nesting depth\",\n \"agents.max_depth\",\n depth && /^\\d+$/.test(depth) ? Number.parseInt(depth, 10) : null,\n \"config.toml\",\n SUBAGENT_DEPTH,\n ),\n );\n const effort = codexValue(config, \"default_subagent_reasoning_effort\");\n const effortOk = effort === \"low\" || effort === \"medium\" || effort === \"minimal\" || effort === \"none\";\n notes.push({\n name: \"Subagent reasoning effort\",\n source: \"codex\",\n value: effort || \"unset\",\n target: \"low or medium\",\n ok: effortOk,\n level: effortOk ? \"ok\" : \"warn\",\n ratio: null,\n line: effortOk\n ? `agents.default_subagent_reasoning_effort is ${effort}: ok.`\n : `agents.default_subagent_reasoning_effort is ${effort || \"unset\"}: set it to low or medium so workers don't inherit a costly effort.`,\n });\n const compact = codexValue(config, \"model_auto_compact_token_limit\");\n const compactOk = compact !== null && /^\\d+$/.test(compact) && Number.parseInt(compact, 10) <= COMPACT_WINDOW_MAX;\n notes.push({\n name: \"Auto-compact token limit\",\n source: \"codex\",\n value: compact || \"unset\",\n target: \"about 160k\",\n ok: compactOk,\n level: compactOk ? \"ok\" : \"warn\",\n ratio: null,\n line: compactOk\n ? `model_auto_compact_token_limit is ${compact}: ok.`\n : `model_auto_compact_token_limit is ${compact || \"unset\"}: set about 160000 for a >=200K window.`,\n });\n }\n return notes;\n}\n\n/** The config check sentences. burn.py:498 */\nexport function configChecks(live: Source[], config: ConfigInput): string[] {\n const lines = configNotes(live, config).map((note) => note.line);\n if (live.includes(\"claude\")) {\n for (const index of config.memoryIndexes) {\n const shown =\n config.claudeBase === config.claudeHome\n ? index.path.replace(config.claudeBase, \"~/.claude\")\n : index.path;\n if (index.lines > MEMORY_INDEX_LINES) {\n lines.push(\n `${shown} has ${index.lines} lines: lines after ${MEMORY_INDEX_LINES} are not loaded, so those memories are invisible. Shorten it.`,\n );\n }\n }\n }\n return lines.length ? lines : [\"none\"];\n}\n\n/** The parsed settings.json object, or an empty object for a missing or broken file. */\nfunction settings(config: ConfigInput): Record<string, any> | undefined {\n if (config.settings === null) return undefined;\n try {\n const parsed = JSON.parse(config.settings);\n return typeof parsed === \"object\" && parsed !== null ? parsed : undefined;\n } catch {\n return undefined;\n }\n}","import { fixed, int0 } from \"./format\";\nimport { configNotes } from \"./config-checks\";\nimport { LONG_LIVED_HOURS } from \"./flags\";\nimport type { BaselineRow, ConfigInput, RawPerSource, RawReport, Source } from \"../model\";\n\n/** Level of a value against an \"under\" target: ok up to the target, warn up to twice it. burn.py:1072 */\nexport function severity(ratio: number): \"ok\" | \"warn\" | \"critical\" {\n return ratio <= 1 ? \"ok\" : ratio <= 2 ? \"warn\" : \"critical\";\n}\n\nconst median = (xs: number[]): number | null =>\n xs.length ? [...xs].sort((a, b) => a - b)[xs.length >> 1] : null;\nconst pct = (v: number): string => `${fixed(v)}%`;\nconst count = (v: number): string => fixed(v);\nconst hours = (v: number): string => `${fixed(v)}h`;\nconst kilo = (v: number): string => `${int0(v / 1000)}k`;\nconst share = (a: number, b: number): number | null => (b ? (100 * a) / b : null);\n\n/** The lever rows for one source, from its per-source aggregates. burn.py:1077 */\nfunction providerLevers(src: Source, p: RawPerSource): BaselineRow[] {\n const { recent, stats7: stats, totals: tot } = p;\n const wakes = recent.wakes;\n const ping = (w: typeof wakes) => w.teammate + w.task + w.peer;\n const have = recent.turns > 0;\n\n // (name, format, 24 h value, whole-window value, target text, limit, advisory)\n const levers: [string, (v: number) => string, number | null, number, string, number, boolean][] = [\n [\"Spend on turns over 300k\", pct, share(recent.over, recent.total), p.over_300k, \"under 10%\", 10, false],\n [\"Median context per turn\", kilo, median(recent.contexts), median(p.contexts) ?? 0, \"under 150k\", 150_000, false],\n [\"Turns per human prompt\", count, have ? recent.turns / Math.max(wakes.human, 1) : null, p.turns / Math.max(tot.human, 1), \"under 50\", 50, false],\n [\"Caller reads per tool call\", pct, have ? share(recent.reads, recent.tool_calls) : null, share(tot.reads, tot.tool_calls) ?? 0, \"under 20%\", 20, false],\n [\"Wakeups per session\", count, recent.sessions ? ping(wakes) / recent.sessions : null, ping(tot) / Math.max(p.session_count, 1), \"under 20\", 20, false],\n [\"Longest top session\", hours, p.hours24 || null, p.hours_all, `under ${LONG_LIVED_HOURS}h`, LONG_LIVED_HOURS, false],\n [\"Spend on the top model\", pct, share(recent.top, recent.total), share(stats.top, p.total) ?? 0, \"under 60%\", 60, true],\n ];\n if (stats.cache_input) {\n levers.push([\"Cache rebuilds\", pct, share(recent.cache_write, recent.cache_input), share(stats.cache_write, stats.cache_input) ?? 0, \"under 10%\", 10, false]);\n }\n if (p.preamble) {\n levers.push([\"Preamble per session (p50)\", kilo, median(recent.preambles), p.preamble[0], \"under 40k\", 40_000, false]);\n }\n\n const rows: BaselineRow[] = [];\n for (const [name, fmt, now, week, target, limit, advisory] of levers) {\n const ratio = now === null ? null : now / limit;\n let level: BaselineRow[\"level\"] = ratio === null ? \"ok\" : severity(ratio);\n if (advisory && level !== \"ok\") level = \"info\";\n rows.push({\n name,\n now_24h: now === null ? \"-\" : fmt(now),\n value_7d: fmt(week),\n target,\n ok: level === \"ok\",\n level,\n ratio,\n advisory,\n source: src,\n });\n }\n return rows;\n}\n\n/**\n * Every lever per live provider over the last CHECK_HOURS and the whole window, against a\n * recommended target, plus the per-agent config rows. The level judges the 24 h value; a\n * lever with no 24 h data is ok. burn.py:1125\n */\nexport function baseline(report: RawReport, config: ConfigInput): BaselineRow[] {\n const live = report.sources.map(([name]) => name);\n const rows: BaselineRow[] = [];\n for (const src of live) {\n const p = report.per_source[src];\n if (p) rows.push(...providerLevers(src, p));\n }\n for (const note of configNotes(live, config)) {\n rows.push({\n name: note.name,\n now_24h: note.value,\n value_7d: null,\n target: note.target,\n ok: note.ok,\n level: note.level,\n ratio: note.ratio,\n advisory: false,\n source: note.source,\n });\n }\n return rows;\n}","import { fixed } from \"./format\";\nimport type { RawReport, Source } from \"../model\";\n\n/**\n * Cumulative (time, % of the weekly limit used, % if context were capped) per hour, from the\n * week start to now. The last point is the calibrated total, so it equals the plan's reading.\n * burn.py:843\n */\nexport function weekPoints(\n buckets: Map<number, [number, number]>,\n start: Date,\n now: Date,\n limit: number,\n): [Date, number, number][] {\n const points: [Date, number, number][] = [[start, 0, 0]];\n let used = 0;\n let capped = 0;\n for (const [hour, slot] of [...buckets.entries()].sort((a, b) => a[0] - b[0])) {\n used += slot[0];\n capped += slot[1];\n const end = new Date(hour + 3_600_000);\n points.push([end < now ? end : now, (used * 100) / limit, (capped * 100) / limit]);\n }\n const last = points[points.length - 1];\n if (last[0].getTime() < now.getTime()) points.push([now, last[1], last[2]]);\n return points;\n}\n\n/**\n * The hourly burn goal for one source: the plan's remaining week over the hours to its\n * reset, else (Claude only) a weekly budget over 168 h, else the window's own average.\n * burn.py:912\n */\nexport function burnGoal(report: RawReport, source: Source): [number, string] {\n const burn = report.burns[source];\n if (!burn) return [0, \"no burn for this source\"];\n const week = burn.week;\n if (week) {\n return [\n week.ideal,\n `ideal pace to the weekly reset ${localStamp(week.resets)} (${fixed(week.hours_left)} h left)`,\n ];\n }\n if (report.budget && source === \"claude\") {\n return [report.budget / 168, `weekly budget ${fixed(report.budget / 1e6)}M / 168 h`];\n }\n return [\n burn.total / (report.days * 24),\n `your ${report.days}-day average; the subscription usage was unavailable`,\n ];\n}\n\n/** Python's strftime(\"%a %H:%M\") in the local zone. */\nfunction localStamp(when: Date): string {\n const local = new Date(when.getTime() - when.getTimezoneOffset() * 60_000);\n const day = [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"][local.getUTCDay()];\n const hours = String(local.getUTCHours()).padStart(2, \"0\");\n const minutes = String(local.getUTCMinutes()).padStart(2, \"0\");\n return `${day} ${hours}:${minutes}`;\n}","import {\n ACTIVE_MINUTES,\n BENCH_WINDOW,\n CHECK_HOURS,\n GAIN_HOURS,\n sessionFlags,\n} from \"./flags\";\nimport {\n CACHE_READ_RATE,\n CACHE_WRITE_RATE,\n MODEL_RATE,\n OUTPUT_RATE,\n SIZE_BUCKETS,\n bucketLabel,\n bucketRowLabel,\n modelRate,\n} from \"./pricing\";\nimport { configChecks } from \"./config-checks\";\nimport { baseline } from \"./baseline\";\nimport { weekPoints } from \"./burn\";\nimport type {\n ActiveSession,\n HourSlot,\n RawRecent,\n RawReport,\n RawStats,\n RawWeek,\n ReportInput,\n SessionRow,\n Source,\n Totals,\n WakeCounts,\n Week,\n} from \"../model\";\n\n/** burn.py:527. Pure: every file, clock reading and env value arrives in the input. */\nexport function buildReport(input: ReportInput): RawReport | null {\n const { now, days, config } = input;\n if (!input.live.length) return null;\n const cutoff = new Date(now.getTime() - days * 86_400_000);\n const recentCut = new Date(now.getTime() - CHECK_HOURS * 3_600_000);\n const hour1Cut = new Date(now.getTime() - 3_600_000);\n const gainCuts = GAIN_HOURS.map((h) => [h, new Date(now.getTime() - h * 3_600_000)] as const);\n\n const bySize = new Map<string, number>();\n const turnsBySize = new Map<string, number>();\n const byProject = new Map<string, number>();\n const bySource = new Map<string, number>();\n const tools = new Map<string, number>();\n const unpriced = new Map<string, number>();\n /** key -> cost, turns, peak, hours */\n const sessions = new Map<string, [number, number, number, number]>();\n /** key -> reads, wakes */\n const signals = new Map<string, [number, WakeCounts]>();\n const paths = new Map<string, string>();\n const titles = new Map<string, string | null>();\n const timeline = new Map<number, [number, number]>();\n const hourly = new Map<number, HourSlot>();\n const contexts: number[] = [];\n const preambles: number[] = [];\n const totals = emptyTotals();\n const lastHour = new Map<Source, number>();\n const recent = new Map<Source, Map<number, number>>();\n const weekHourly = new Map<Source, Map<number, [number, number]>>();\n const active: [string, number, number, string | null, number][] = [];\n const sessions24 = new Map<string, [number, number, number, number]>();\n const signals24 = new Map<string, [number, WakeCounts]>();\n const per = new Map<Source, PerSource>();\n const weeks: Record<Source, Week | null> = { claude: input.planWeek, codex: input.codexWeek };\n const weekNow = new Map<Source, number>();\n\n let total = 0;\n let unpricedCost = 0;\n let preambleReread = 0;\n let allContext = 0;\n const stats7 = emptyStats();\n const last24: RawRecent = { ...emptyRecent(), sessions: 0 };\n const topRate = Math.max(...Object.values(MODEL_RATE));\n\n const filesBySource = new Map<Source, typeof input.sessions>();\n for (const session of input.sessions) {\n const list = filesBySource.get(session.source);\n if (list) list.push(session);\n else filesBySource.set(session.source, [session]);\n }\n\n for (const source of input.live) {\n for (const file of filesBySource.get(source) ?? []) {\n if (file.mtimeMs < cutoff.getTime()) continue; // untouched since before the window\n let cost = 0;\n let reads = 0;\n const wakes = emptyWakes();\n let count = 0;\n let peak = 0;\n let hourCost = 0;\n let model: string | null = null;\n let firstContext = 0;\n let firstSeen: Date | null = null;\n let lastSeen: Date | null = null;\n let lastContext = 0;\n let cCost = 0;\n let cCount = 0;\n let cPeak = 0;\n let cReads = 0;\n const cWakes = emptyWakes();\n let project = \"\";\n let session = \"\";\n\n for (const item of file.turns) {\n if (item.when < cutoff) continue;\n const context = item.baseIn + item.cacheRead + item.cacheWrite;\n if (!context) continue;\n\n const rate = modelRate(item.model);\n const raw =\n item.baseIn +\n CACHE_READ_RATE * item.cacheRead +\n CACHE_WRITE_RATE * item.cacheWrite +\n OUTPUT_RATE * item.output;\n const priced = rate ?? 1;\n const weighted = priced * raw;\n if (rate === null) {\n bump(unpriced, item.model || \"unknown\");\n unpricedCost += weighted;\n }\n\n project = item.project;\n session = item.session;\n const key = sessionKey(source, project, session);\n count += 1;\n cost += weighted;\n total += weighted;\n model = item.model || model;\n if (item.when >= hour1Cut) {\n bumpMap(lastHour, source, weighted);\n hourCost += weighted;\n }\n for (const [h, cut] of gainCuts) if (item.when >= cut) bumpGain(recent, source, h, weighted);\n const week = weeks[source];\n if (week && item.when >= week.start) bumpMap(weekNow, source, weighted);\n allContext += context;\n const isTop = rate !== null && rate >= topRate;\n stats7.turns += 1;\n if (isTop) stats7.top += weighted;\n if (source === \"claude\") {\n // Codex logs no cache writes, so it would read as 0%\n stats7.cache_write += item.cacheWrite;\n stats7.cache_input += context;\n }\n if (context > peak) peak = context;\n bump(byProject, project, weighted);\n bump(bySource, source, weighted);\n const label = bucketLabel(context);\n bump(bySize, label, weighted);\n turnsBySize.set(label, (turnsBySize.get(label) ?? 0) + 1);\n for (const name of item.tools) if (name) bump(tools, name);\n const hour = hourStart(item.when);\n const slot = timeline.get(hour) ?? (timeline.set(hour, [0, 0]), timeline.get(hour)!);\n slot[context >= 300_000 ? 1 : 0] += weighted;\n // Benchmark: the same turn if auto-compact had kept context at BENCH_WINDOW.\n const trimmed = Math.max(item.cacheRead - Math.max(context - BENCH_WINDOW, 0), 0);\n const hourSlot = hourly.get(hour) ?? emptySlot();\n const benchTurn = weighted - priced * (CACHE_READ_RATE * (item.cacheRead - trimmed));\n hourSlot.bench += benchTurn;\n if (!hourly.has(hour)) hourly.set(hour, hourSlot);\n if (week && item.when >= week.start) {\n const per2 = weekHourly.get(source) ?? new Map<number, [number, number]>();\n if (!weekHourly.has(source)) weekHourly.set(source, per2);\n const bucket = per2.get(hour) ?? [0, 0];\n bucket[0] += weighted;\n bucket[1] += benchTurn;\n per2.set(hour, bucket);\n }\n hourSlot.ctx.push(context);\n hourSlot.reads += item.reads;\n hourSlot.calls += item.tools.length;\n contexts.push(context);\n totals.tool_calls += item.tools.length;\n totals.reads += item.reads;\n reads += item.reads;\n for (const wake of item.wakes) wakes[wake] += 1;\n for (const wake of item.wakes) totals[wake] += 1;\n\n const p = perSource(per, source);\n p.total += weighted;\n p.turns += 1;\n if (context >= 300_000) p.over += weighted;\n p.sessions.add(key);\n p.contexts.push(context);\n p.stats7.turns += 1;\n if (isTop) p.stats7.top += weighted;\n p.totals.tool_calls += item.tools.length;\n p.totals.reads += item.reads;\n for (const wake of item.wakes) p.totals[wake] += 1;\n if (source === \"claude\") {\n p.stats7.cache_write += item.cacheWrite;\n p.stats7.cache_input += context;\n }\n\n if (item.when >= recentCut) {\n cCost += weighted;\n cCount += 1;\n if (context > cPeak) cPeak = context;\n cReads += item.reads;\n for (const wake of item.wakes) cWakes[wake] += 1;\n last24.total += weighted;\n if (context >= 300_000) last24.over += weighted;\n last24.turns += 1;\n last24.contexts.push(context);\n last24.tool_calls += item.tools.length;\n last24.reads += item.reads;\n for (const wake of item.wakes) last24.wakes[wake] += 1;\n if (isTop) last24.top += weighted;\n if (source === \"claude\") {\n last24.cache_write += item.cacheWrite;\n last24.cache_input += context;\n }\n const p24 = p.recent;\n p24.total += weighted;\n if (context >= 300_000) p24.over += weighted;\n p24.turns += 1;\n p24.contexts.push(context);\n p24.tool_calls += item.tools.length;\n p24.reads += item.reads;\n for (const wake of item.wakes) p24.wakes[wake] += 1;\n if (isTop) p24.top += weighted;\n if (source === \"claude\") {\n p24.cache_write += item.cacheWrite;\n p24.cache_input += context;\n }\n }\n\n if (count === 1) {\n firstContext = context;\n firstSeen = item.when;\n }\n lastSeen = item.when;\n lastContext = context;\n }\n\n if (!count) continue;\n const key = sessionKey(source, project, session);\n // The first turn is the always-resident prefix: instructions, memory, skill\n // catalog, tool schemas. Every later turn re-reads it.\n preambleReread += firstContext * count;\n preambles.push(firstContext);\n const hours = firstSeen && lastSeen ? (lastSeen.getTime() - firstSeen.getTime()) / 3_600_000 : 0;\n sessions.set(key, [cost, count, peak, hours]);\n signals.set(key, [reads, wakes]);\n if (cCount) {\n sessions24.set(key, [cCost, cCount, cPeak, hours]);\n signals24.set(key, [cReads, cWakes]);\n if (firstSeen && firstSeen >= recentCut) last24.preambles.push(firstContext);\n const p = perSource(per, source);\n p.recent.sessions += 1;\n if (firstSeen && firstSeen >= recentCut) p.recent.preambles.push(firstContext);\n }\n const p = perSource(per, source);\n p.preambles.push(firstContext);\n if (hours > p.hours_all) p.hours_all = hours;\n if (hours > p.hours24) p.hours24 = hours;\n paths.set(key, file.path);\n if (source === \"claude\") titles.set(key, file.title);\n const idle = lastSeen ? (now.getTime() - lastSeen.getTime()) / 60_000 : 0;\n if (idle <= ACTIVE_MINUTES) active.push([key, lastContext, idle, model, hourCost]);\n }\n }\n\n if (!total) return null;\n\n const share = (value: number): number => (100 * value) / total;\n const byCost = (a: [string, [number, number, number, number]], b: [string, [number, number, number, number]]) => b[1][0] - a[1][0];\n const top = [...sessions.entries()].sort(byCost).slice(0, 10);\n\n const buckets: RawReport[\"buckets\"] = [];\n for (const [low, high] of SIZE_BUCKETS) {\n const label = bucketRowLabel(low, high);\n if (bySize.get(label)) {\n buckets.push([label, low, share(bySize.get(label)!), turnsBySize.get(label)!]);\n }\n }\n preambles.sort((a, b) => a - b);\n last24.sessions = sessions24.size;\n const share24 = (value: number): number => (last24.total ? (100 * value) / last24.total : 0);\n const flags24 = (key: string): string[] => {\n const row = sessions24.get(key);\n if (!row) return [];\n const [, turns, cPeak, hours] = row;\n const [cReads, cWakes] = signals24.get(key)!;\n return sessionFlags(turns, cPeak, hours, cReads, cWakes);\n };\n const sessionRow = (\n key: string,\n [cost, count, peak, hours]: [number, number, number, number],\n shareOf: (value: number) => number,\n ): SessionRow => {\n const [source, project, session] = splitKey(key);\n return {\n source: source as Source,\n project: project || \"?\",\n id: (session || \"?\").slice(0, 8),\n title: titles.get(key) ?? null,\n path: paths.get(key) ?? null,\n share: shareOf(cost),\n turns: count,\n peak,\n hours,\n flags: flags24(key),\n };\n };\n\n const report: RawReport = {\n days,\n total,\n turns: [...sessions.values()].reduce((sum, row) => sum + row[1], 0),\n session_count: sessions.size,\n sources: [...bySource.entries()].sort((a, b) => (a[0] < b[0] ? -1 : 1)).map(([name, value]) => [name as Source, share(value)]),\n buckets,\n over_300k: buckets.filter((b) => b[1] >= 300).reduce((sum, b) => sum + b[2], 0),\n preamble: preambles.length\n ? [preambles[preambles.length >> 1], preambles[Math.trunc(preambles.length * 0.9)], (100 * preambleReread) / allContext]\n : null,\n projects: [...byProject.entries()]\n .sort((a, b) => b[1] - a[1])\n .slice(0, 8)\n .map(([name, value]) => [name, share(value)]),\n sessions: top.map(([key, row]) => sessionRow(key, row, share)),\n recent_sessions: [...sessions24.entries()]\n .sort(byCost)\n .slice(0, 10)\n .map(([key, row]) => sessionRow(key, row, share24)),\n recent: last24,\n tools: mostCommon(tools, 6),\n config: configChecks(input.live, config),\n unpriced: unpriced.size ? [share(unpricedCost), mostCommon(unpriced, 5)] : null,\n active: active\n .sort((a, b) => b[4] - a[4])\n .map(([key, context, idle, model, rate]): ActiveSession => {\n const [source, project, session] = splitKey(key);\n const src = source as Source;\n const sessionData = sessions.get(key)!;\n const hourSpend = lastHour.get(src) ?? 0;\n return {\n source: src,\n project: project || \"?\",\n id: (session || \"?\").slice(0, 8),\n title: titles.get(key) ?? null,\n share: share(sessionData[0]),\n turns: sessionData[1],\n peak: sessionData[2],\n hours: sessionData[3],\n context,\n idle,\n flags: flags24(key),\n model,\n rate,\n rateShare: hourSpend ? (100 * rate) / hourSpend : 0,\n };\n }),\n timeline: [...timeline.entries()].sort((a, b) => a[0] - b[0]).map(([hour, slot]) => [new Date(hour), slot]),\n hourly: [...hourly.entries()].sort((a, b) => a[0] - b[0]).map(([hour, slot]) => [new Date(hour), slot]),\n bench_total: [...hourly.values()].reduce((sum, slot) => sum + slot.bench, 0),\n budget: input.weeklyBudget ? input.weeklyBudget * 1e6 : null,\n stats7,\n per_source: {},\n baseline: [],\n burns: {},\n };\n\n for (const src of input.live) {\n const p = per.get(src);\n if (!p || !p.total) continue;\n const ctx = [...p.contexts].sort((a, b) => a - b);\n const pre = [...p.preambles].sort((a, b) => a - b);\n report.per_source[src] = {\n recent: p.recent,\n stats7: p.stats7,\n totals: p.totals,\n turns: p.turns,\n total: p.total,\n over_300k: p.over,\n session_count: p.sessions.size,\n hours24: p.hours24,\n hours_all: p.hours_all,\n contexts: ctx,\n preambles: pre,\n preamble: pre.length ? [pre[pre.length >> 1], pre[Math.trunc(pre.length * 0.9)]] : null,\n };\n }\n report.baseline = baseline(report, config);\n\n for (const src of input.live) {\n const spend = bySource.get(src);\n if (!spend) continue;\n const week = weeks[src];\n const spent = weekNow.get(src) ?? 0;\n const burn: RawReport[\"burns\"][Source] = { rate: lastHour.get(src) ?? 0, total: spend, week: null };\n if (week && week.used >= 1 && spent) {\n // Calibrate: this week's local spend is `used` percent of the plan's week.\n const limit = (spent * 100) / week.used;\n const hoursLeft = Math.max((week.resets.getTime() - now.getTime()) / 3_600_000, 1);\n const weekRecent = recent.get(src) ?? new Map<number, number>();\n const gains: Record<string, number> = {};\n for (const h of GAIN_HOURS) gains[h] = ((weekRecent.get(h) ?? 0) * 100) / limit;\n // Quota points per hour over the last 24 h. A week younger than that has spent only its\n // own points, so divide by the time since the week began.\n const age = Math.max((now.getTime() - week.start.getTime()) / 3_600_000, 1);\n const rate24 = age < CHECK_HOURS ? week.used / age : gains[CHECK_HOURS] / CHECK_HOURS;\n const left = 100 - week.used;\n const toEmpty = rate24 > 0 ? left / rate24 : null;\n const dry = toEmpty ? new Date(now.getTime() + toEmpty * 3_600_000) : null;\n const rawWeek: RawWeek = {\n resets: week.resets,\n hours_left: hoursLeft,\n used: week.used,\n ideal: Math.max(limit - spent, 0) / hoursLeft,\n limit,\n start: week.start,\n rate_pct: (burn.rate * 100) / limit,\n ideal_pct: Math.max(left, 0) / hoursLeft,\n burndown: weekPoints(weekHourly.get(src) ?? new Map(), week.start, now, limit),\n projection: {\n rate_pct: rate24,\n hours_to_empty: toEmpty,\n runs_out: dry && dry < week.resets ? dry : null,\n },\n gains,\n };\n burn.week = rawWeek;\n }\n report.burns[src] = burn;\n }\n return report;\n}\n\nfunction emptyWakes(): WakeCounts {\n return { human: 0, teammate: 0, task: 0, peer: 0 };\n}\n\nfunction emptyTotals(): Totals {\n return { tool_calls: 0, reads: 0, human: 0, teammate: 0, task: 0, peer: 0 };\n}\n\nfunction emptyStats(): RawStats {\n return { cache_write: 0, cache_input: 0, turns: 0, top: 0 };\n}\n\nfunction emptyRecent(): RawRecent {\n return {\n total: 0,\n over: 0,\n turns: 0,\n contexts: [],\n tool_calls: 0,\n reads: 0,\n wakes: emptyWakes(),\n preambles: [],\n cache_write: 0,\n cache_input: 0,\n top: 0,\n sessions: 0,\n };\n}\n\nfunction emptySlot(): HourSlot {\n return { bench: 0, ctx: [], reads: 0, calls: 0 };\n}\n\ninterface PerSource {\n recent: RawRecent;\n stats7: RawStats;\n totals: Totals;\n contexts: number[];\n preambles: number[];\n turns: number;\n total: number;\n over: number;\n sessions: Set<string>;\n hours24: number;\n hours_all: number;\n}\n\nfunction perSource(per: Map<Source, PerSource>, src: Source): PerSource {\n let p = per.get(src);\n if (!p) {\n p = {\n recent: emptyRecent(),\n stats7: emptyStats(),\n totals: emptyTotals(),\n contexts: [],\n preambles: [],\n turns: 0,\n total: 0,\n over: 0,\n sessions: new Set(),\n hours24: 0,\n hours_all: 0,\n };\n per.set(src, p);\n }\n return p;\n}\n\n/** The hour a turn falls in, as an epoch. burn.py:644 */\nfunction hourStart(when: Date): number {\n return Math.floor(when.getTime() / 3_600_000) * 3_600_000;\n}\n\n/** Session identity: the source, project and session id Python used as a tuple key. */\nfunction sessionKey(source: Source, project: string, session: string): string {\n return JSON.stringify([source, project, session]);\n}\n\nfunction splitKey(key: string): [Source, string, string] {\n const [source, project, session] = JSON.parse(key) as [Source, string, string];\n return [source, project, session];\n}\n\nfunction bump(map: Map<string, number>, key: string, value = 1): void {\n map.set(key, (map.get(key) ?? 0) + value);\n}\n\nfunction bumpMap(map: Map<Source, number>, key: Source, value: number): void {\n map.set(key, (map.get(key) ?? 0) + value);\n}\n\nfunction bumpGain(map: Map<Source, Map<number, number>>, key: Source, hours: number, value: number): void {\n let inner = map.get(key);\n if (!inner) {\n inner = new Map();\n map.set(key, inner);\n }\n inner.set(hours, (inner.get(hours) ?? 0) + value);\n}\n\n/** Counter.most_common(n): by count down, insertion order for ties. */\nfunction mostCommon(map: Map<string, number>, n: number): [string, number][] {\n return [...map.entries()].sort((a, b) => b[1] - a[1]).slice(0, n);\n}","import { fixed, int0 } from \"./format\";\nimport {\n CHECK_HOURS,\n CODEX_SUBAGENT_KEY,\n LEVELS,\n MEMORY_INDEX_LINES,\n SUBAGENT_CAP,\n SUBAGENT_DEPTH,\n SUBAGENT_ENV,\n TOOL_CONCURRENCY,\n} from \"./flags\";\nimport type { Priority, RawIssue, RawReport, SessionRow, Source } from \"../model\";\n\n/** Per leak flag prefix: short fix, title, why it costs tokens, and the prompt for an agent. burn.py:1201 */\nexport const ISSUES: Record<string, [fix: string, title: string, why: string, action: string]> = {\n \"late compaction\": [\n \"Set autoCompactWindow to about 200000, then /compact or restart old sessions.\",\n \"Sessions compact too late\",\n \"Every tool call re-reads the whole context. A turn at 500k costs about 5 times a turn at 100k, and auto-compact on a 1M model waits until about 1M.\",\n 'Set \"autoCompactWindow\": 200000 in ~/.claude/settings.json and check that CLAUDE_CODE_AUTO_COMPACT_WINDOW is unset or not higher. Then ask me to /compact or restart each listed session that is still open.',\n ],\n \"caller reads\": [\n \"Send multi-range reads, greps and log parsing to a cheap read-only subagent.\",\n \"The caller reads files and logs itself\",\n \"Each read in the main session is paid at its full context size. A cheap read-only subagent pays it at a small context and returns a short answer.\",\n \"Read the listed transcripts (JSONL, tool_use blocks named Bash/Read/Grep) and find the most repeated read commands. Then add a rule to my global agent instructions: after the brief, any read that is more than one bounded range goes to a cheap read-only subagent. Propose a helper script for any read pattern that repeats more than 20 times.\",\n ],\n wakeups: [\n \"Ask subagents and teammates for one report at the end; wait with one blocking command.\",\n \"Too many wakeups\",\n \"Each teammate message, task notification or cross-session message starts a turn that re-reads the full context.\",\n \"Read the listed transcripts and find which subagents, teammates or background jobs sent the messages. Change their briefs so they report once at the end, and replace polling or progress pings with one blocking background command per wait.\",\n ],\n loop: [\n \"Give each /goal or autonomous loop a stop condition and a turn or time budget.\",\n \"Autonomous loops run without a budget\",\n \"Hundreds of turns per human prompt means a /goal or autonomous loop kept going with no stop condition.\",\n \"Read the listed transcripts and name what kept each loop running. Then add a stop condition and a turn or time budget to the loop instructions I use (goal prompts, skills or CLAUDE.md).\",\n ],\n \"long-lived\": [\n \"Commit, end the session, and start one fresh session per task.\",\n \"Sessions stay open too long\",\n \"A session open for many hours carries summaries of many unrelated tasks, so every turn pays for old work.\",\n \"List which of these sessions are still open. For each, commit its work, end it, and write a one-paragraph handoff so a fresh session can continue from the PRD or task.\",\n ],\n};\n\n/** Extra context appended to a fix prompt, drawn from Token Furnace's community research. burn.py:1246 */\nexport const ISSUE_EXTRA: Record<string, string[]> = {\n \"late compaction\": [\n \"Anthropic supports earlier compaction: `CLAUDE_AUTOCOMPACT_PCT_OVERRIDE=80`, or `/autocompact 200k` in a running session.\",\n \"To drop 1M context entirely: `CLAUDE_CODE_DISABLE_1M_CONTEXT=1`.\",\n \"Codex: `model_auto_compact_token_limit = 160000` for a >=200K window.\",\n \"Do not compact blindly: compact or hand off between meaningful phases, not every N tokens.\",\n ],\n \"subagent fan-out cap\": [\n \"Claude Code defaults to 20 concurrent subagents and nesting depth 3, with no total cap.\",\n \"Also set the depth cap: `CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH=1` (Codex: `agents.max_depth`; note Multi-Agent V2 ignores it).\",\n \"Pin the worker model so it is not inherited silently: `CLAUDE_CODE_SUBAGENT_MODEL=sonnet` (add `CLAUDE_CODE_SUBAGENT_MODEL_FORCE=1` to hard-enforce).\",\n 'Codex: prefer `fork_turns=\"none\"` for independent workers so they do not inherit the parent conversation history.',\n ],\n \"subagent nesting depth\": [\n \"Nesting is the worst fan-out: a worker that spawns workers multiplies the whole loop.\",\n \"Claude: `CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH=1`. Codex: `agents.max_depth` (Multi-Agent V2 ignores it, so verify the effective depth from real traces).\",\n ],\n \"subagent model\": [\n \"`CLAUDE_CODE_SUBAGENT_MODEL=sonnet` is a default, not a guarantee; add `CLAUDE_CODE_SUBAGENT_MODEL_FORCE=1` to hard-enforce (it overrides intentional per-agent specialization).\",\n \"Codex: set `agents.default_subagent_model` explicitly; V2 can silently run a costlier worker than requested.\",\n \"Verify the effective model from real usage, not from the instruction.\",\n ],\n \"subagent reasoning effort\": [\n \"Children mostly scan and summarize; keep them at low/medium and let the parent keep its own effort.\",\n ],\n \"auto-compact token limit\": [\n \"Codex: `model_auto_compact_token_limit = 160000` for a >=200K window.\",\n \"Compact or hand off between meaningful phases, not blindly every N tokens.\",\n ],\n \"tool-call concurrency\": [\n \"`CLAUDE_CODE_MAX_TOOL_USE_CONCURRENCY=4` bounds parallel tool calls in the main agent.\",\n \"Limit shell output at the byte level; a line-count cap fails when one line is huge.\",\n ],\n \"caller reads\": [\n \"Give a worker a self-contained brief (exact paths, objective, acceptance) instead of forking the whole parent history.\",\n \"Trim the always-resident preamble once, then leave it stable: reads bill at 0.1x but rewrites at 1.25x.\",\n ],\n wakeups: [\"Ask teammates and background jobs for one report at the end, then wait once.\"],\n loop: [\n \"Give each worker agent a `maxTurns` ceiling (a 15-30 turn start for bounded tasks).\",\n \"On two identical failures, stop and re-plan instead of retrying.\",\n ],\n \"long-lived\": [\n \"Keep a concise task-state handoff (done / pending / current verification) so a fresh session does not repeat completed work after compaction.\",\n ],\n \"memory index too long\": [\n \"Move detail into topic files that load on demand; keep the index under the load limit.\",\n ],\n};\n\n/** Which agent a config-check line belongs to, for the Checks source column. burn.py:1311 */\nexport function configSource(line: string): Source | \"all\" {\n if (\n line.includes(CODEX_SUBAGENT_KEY) ||\n line.includes(\"max_depth\") ||\n line.includes(\"reasoning_effort\") ||\n line.includes(\"auto_compact_token_limit\") ||\n line.startsWith(\"agents.\")\n ) {\n return \"codex\";\n }\n if (line.includes(\"CLAUDE\") || line.includes(\"autoCompactWindow\") || line.includes(\"MEMORY.md\")) return \"claude\";\n return \"all\";\n}\n\n/** Group session flags and failed config checks into issues, largest spend share first. burn.py:1321 */\nexport function topIssues(report: RawReport): RawIssue[] {\n const groups = new Map<string, [SessionRow, string][]>();\n for (const s of report.recent_sessions) {\n for (const flag of s.flags) {\n const kind = flag.split(\":\")[0];\n const hits = groups.get(kind);\n if (hits) hits.push([s, flag]);\n else groups.set(kind, [[s, flag]]);\n }\n }\n const issues: RawIssue[] = [];\n for (const [kind, hits] of groups) {\n const [fix, title, why, action] = ISSUES[kind];\n const spies = new Map<Source, number>();\n for (const [s] of hits) spies.set(s.source, (spies.get(s.source) ?? 0) + 1);\n let source: Source | \"all\" = \"all\";\n if (spies.size === 1) source = [...spies.keys()][0];\n issues.push({\n title,\n why,\n action,\n fix,\n kind,\n source,\n share: hits.reduce((sum, [s]) => sum + s.share, 0),\n hits,\n priority: 3,\n });\n }\n issues.sort((a, b) => -(a.share ?? 0) - -(b.share ?? 0));\n\n const fixedLines = report.config.filter(\n (line) => line.includes(\"autoCompactWindow\") && line.endsWith(\"ok.\"),\n );\n for (const issue of issues) {\n if (issue.title === ISSUES[\"late compaction\"][1] && fixedLines.length) {\n issue.fix = \"Setting already ok. Restart or /compact the old sessions.\";\n issue.action = `The setting is already fixed (${fixedLines[0]}). Restart or /compact the listed sessions that are still open; new sessions are covered.`;\n }\n }\n for (const line of report.config) {\n if (line.endsWith(\"ok.\") || line === \"none\") continue;\n let title: string;\n let fix: string;\n if (line.includes(\"autoCompactWindow\")) {\n title = \"autoCompactWindow\";\n fix = line;\n } else if (line.includes(\"MEMORY.md\")) {\n title = \"memory index too long\";\n fix = `Shorten MEMORY.md under ${MEMORY_INDEX_LINES} lines; move detail into topic files.`;\n } else if (line.includes(\"SUBAGENT_SPAWN_DEPTH\") || line.includes(\"max_depth\")) {\n title = \"subagent nesting depth\";\n fix = `Cap subagent nesting depth at ${SUBAGENT_DEPTH}: recursive delegation multiplies the loop.`;\n } else if (line.includes(\"SUBAGENT_MODEL\")) {\n title = \"subagent model\";\n fix = \"Pin a cheap worker model so subagents do not inherit a premium one.\";\n } else if (line.includes(SUBAGENT_ENV) || line.includes(CODEX_SUBAGENT_KEY)) {\n title = \"subagent fan-out cap\";\n fix = `Cap concurrent subagents at ${SUBAGENT_CAP}: each one runs its own model and tool loop.`;\n } else if (line.includes(\"reasoning_effort\")) {\n title = \"subagent reasoning effort\";\n fix = \"Set the subagent reasoning effort to low or medium.\";\n } else if (line.includes(\"auto_compact_token_limit\")) {\n title = \"auto-compact token limit\";\n fix = \"Set model_auto_compact_token_limit to about 160000.\";\n } else if (line.includes(\"TOOL_USE_CONCURRENCY\")) {\n title = \"tool-call concurrency\";\n fix = `Cap parallel tool calls at ${TOOL_CONCURRENCY}.`;\n } else {\n title = line.slice(0, 40);\n fix = line;\n }\n issues.push({\n title: `Config: ${title}`,\n why: line,\n fix,\n action: `Fix this config problem: ${line}`,\n share: null,\n kind: title,\n source: configSource(line),\n hits: [],\n priority: 3,\n });\n }\n for (const issue of issues) issue.priority = issuePriority(issue);\n issues.sort((a, b) => a.priority - b.priority || -(a.share ?? 0) - -(b.share ?? 0));\n return issues;\n}\n\n/** 1 fix now, 2 fix this week, 3 when convenient. A one-line config fix behind a big leak is 1. */\nexport function issuePriority(issue: RawIssue): Priority {\n if (issue.share === null) return issue.title.includes(\"autoCompactWindow\") ? 1 : 2;\n return issue.share >= 20 ? 1 : issue.share >= 5 ? 2 : 3;\n}\n\n/** The copy-to-Claude prompt for one issue. burn.py:1390 */\nexport function issuePrompt(issue: RawIssue): string {\n const agents: Record<string, string> = {\n claude: \"Claude Code\",\n codex: \"Codex\",\n all: \"Claude Code and Codex\",\n };\n const agent = (issue.source && agents[issue.source]) || \"the agent\";\n const lines = [`Token leak to fix: ${issue.title}.`, `Applies to: ${agent}.`];\n if (issue.share !== null) {\n lines.push(\n `It affects ${issue.hits.length} of my top sessions, ${fixed(issue.share)}% of ${agent} spend in the last ${CHECK_HOURS} h (burn.py, base-input-equivalent tokens).`,\n );\n }\n lines.push(\"\", `Why it costs tokens: ${issue.why}`);\n if (issue.hits.length) {\n lines.push(\"\", \"Evidence:\");\n for (const [s, flag] of issue.hits) {\n lines.push(\n `- ${s.title || \"untitled\"} (session ${s.id}, ${fixed(s.share, 1)}% of spend, ${s.turns} turns, peak ${int0(s.peak / 1000)}k, ${fixed(s.hours)}h): ${flag}`,\n );\n if (s.path) lines.push(` transcript: ${s.path}`);\n }\n }\n const extra = ISSUE_EXTRA[issue.kind];\n if (extra) lines.push(\"\", \"Additional info:\", ...extra.map((e) => `- ${e}`));\n lines.push(\"\", `What to do: ${issue.action}`, \"\", \"Report what you changed and how to check that it worked.\");\n return lines.join(\"\\n\");\n}\n\nexport { LEVELS };","import { burnGoal } from \"./burn\";\nimport { fixed, int0 } from \"./format\";\nimport { BENCH_WINDOW, CHECK_HOURS, LATE_COMPACT_PEAK, LEVELS, LONG_LIVED_HOURS } from \"./flags\";\nimport { issuePrompt, topIssues } from \"./issues\";\nimport type { Burn, RawBurn, RawReport, Report, Source } from \"../model\";\n\n/** Python's datetime.isoformat() for a UTC datetime: seconds, optional microseconds, +00:00. */\nfunction iso(when: Date): string {\n // Python's isoformat() timespec=\"auto\": seconds, and a fraction only when it is nonzero.\n const text = when.toISOString();\n const body = text.endsWith(\".000Z\") ? text.slice(0, -5) : text.slice(0, -1);\n return `${body}+00:00`;\n}\n\nconst median = (xs: number[]): number => (xs.length ? [...xs].sort((a, b) => a - b)[xs.length >> 1] : 0);\n\n/** Everything dashboard.html draws, as JSON-ready data. The page owns all markup. burn.py:1415 */\nexport function reportView(report: RawReport, now: Date): Report {\n const issues = topIssues(report);\n const actual = new Map(report.timeline.map(([hour, slot]) => [hour.getTime(), slot]));\n let runA = 0;\n let runB = 0;\n const burndown: [string, number, number][] = [];\n for (const [when, slot] of report.hourly) {\n const seen = actual.get(when.getTime());\n runA += seen ? seen[0] + seen[1] : 0;\n runB += slot.bench;\n burndown.push([iso(new Date(when.getTime() + 3_600_000)), runA, runB]);\n }\n\n const blocks = new Map<number, { ctx: number[]; reads: number; calls: number }>();\n for (const [when, slot] of report.hourly) {\n const key = when.getTime() - (when.getUTCHours() % 3) * 3_600_000;\n const block = blocks.get(key) ?? { ctx: [], reads: 0, calls: 0 };\n if (!blocks.has(key)) blocks.set(key, block);\n block.ctx.push(...slot.ctx);\n block.reads += slot.reads;\n block.calls += slot.calls;\n }\n const blockList = [...blocks.values()];\n const kpis: Report[\"kpis\"] = [\n { name: \"Median context per turn\", unit: \"k\", target: 150_000, values: blockList.map((b) => median(b.ctx)) },\n {\n name: \"Turns over 300k context\",\n unit: \"%\",\n target: 0.1,\n values: blockList.map((b) => b.ctx.filter((c) => c >= 300_000).length / Math.max(b.ctx.length, 1)),\n },\n {\n name: \"Caller reads per tool call\",\n unit: \"%\",\n target: 0.2,\n values: blockList.map((b) => b.reads / Math.max(b.calls, 1)),\n },\n ];\n\n // Act now: what a live session needs this minute, before any leak report.\n const actions: string[] = [];\n for (const s of report.active) {\n const name = s.title || s.id;\n if (s.context >= LATE_COMPACT_PEAK) {\n actions.push(`Run /compact in “${name}”: its context is ${int0(s.context / 1000)}k.`);\n } else if (s.hours >= LONG_LIVED_HOURS) {\n actions.push(`Finish “${name}” and start a fresh session: it is ${fixed(s.hours)}h old.`);\n }\n }\n\n const burns: Partial<Record<Source, Burn>> = {};\n for (const [source, burn] of Object.entries(report.burns) as [Source, RawBurn][]) {\n const [goal, basis] = burnGoal(report, source);\n const week = burn.week;\n burns[source] = {\n rate: burn.rate,\n goal,\n basis,\n resets: week ? iso(week.resets) : null,\n hoursLeft: week ? week.hours_left : null,\n used: week ? week.used : null,\n gains: week ? week.gains : null,\n limit: week ? week.limit : null,\n ratePct: week ? week.rate_pct : null,\n idealPct: week ? week.ideal_pct : null,\n start: week ? iso(week.start) : null,\n weekBurndown: week ? week.burndown.map(([t, a, b]) => [iso(t), a, b] as [string, number, number]) : null,\n projection: week\n ? {\n ratePct: week.projection.rate_pct,\n hoursToEmpty: week.projection.hours_to_empty,\n runsOut: week.projection.runs_out ? iso(week.projection.runs_out) : null,\n }\n : null,\n };\n }\n\n return {\n generated: iso(now),\n days: report.days,\n total: report.total,\n sessions: report.session_count,\n turns: report.turns,\n over300k: report.over_300k,\n burns,\n burn: burns.claude ?? Object.values(burns)[0] ?? null,\n actions,\n issues: issues.map((i) => ({\n title: i.title,\n fix: i.fix,\n priority: i.priority,\n level: LEVELS[i.priority],\n source: i.source,\n share: i.share,\n sessions: i.hits.length,\n prompt: issuePrompt(i),\n })),\n active: report.active,\n burndown,\n benchWindow: BENCH_WINDOW,\n budget: report.budget,\n kpis,\n timeline: report.timeline.map(([t, [cool, hot]]) => [iso(t), cool, hot]),\n checkHours: CHECK_HOURS,\n baseline: report.baseline,\n topSessions: report.sessions,\n buckets: report.buckets.map(([label, low, share, turns]) => ({\n label,\n hot: low >= 300,\n share,\n turns,\n })),\n projects: report.projects,\n config: report.config,\n tools: report.tools,\n unpriced: report.unpriced,\n };\n}","import { Worker } from \"node:worker_threads\";\nimport type { ParsedFile, Source } from \"../core/model\";\nimport type { Env } from \"../sources/agent-source\";\nimport type { ParseReply } from \"../scan-worker\";\n\n/** Parsing runs in worker threads. Each worker holds its own sources, built from the same env. */\nexport class ParsePool {\n private readonly workers: Worker[];\n private readonly pending = new Map<number, { resolve: (p: ParsedFile) => void; reject: (e: Error) => void }>();\n private nextId = 0;\n private failure: Error | null = null;\n private closing = false;\n\n constructor(url: URL, env: Env, size: number) {\n this.workers = Array.from({ length: size }, () => {\n const worker = new Worker(url, { workerData: { env } });\n worker.on(\"message\", (reply: ParseReply) => {\n const task = this.pending.get(reply.id);\n this.pending.delete(reply.id);\n if (\"error\" in reply) task?.reject(new Error(reply.error));\n else task?.resolve(reply.parsed);\n });\n worker.on(\"error\", (error) => this.failAll(error));\n worker.on(\"exit\", (code) => {\n if (!this.closing) this.failAll(new Error(`Worker exited with code ${code}`));\n });\n return worker;\n });\n }\n\n /** The caller keeps one request in flight per worker, so a big file never queues a small one. */\n parse(worker: number, source: Source, path: string): Promise<ParsedFile> {\n if (this.failure) return Promise.reject(this.failure);\n return new Promise((resolve, reject) => {\n const id = this.nextId++;\n this.pending.set(id, { resolve, reject });\n this.workers[worker].postMessage({ id, source, path });\n });\n }\n\n async close(): Promise<void> {\n this.closing = true;\n await Promise.all(this.workers.map((worker) => worker.terminate()));\n }\n\n private failAll(error: Error): void {\n this.failure = this.failure ?? error;\n for (const task of this.pending.values()) task.reject(error);\n this.pending.clear();\n }\n}\n","import { readFileSync } from \"node:fs\";\nimport { fileURLToPath } from \"node:url\";\nimport { reportView } from \"../core/analyze/view\";\nimport type { RawReport } from \"../core/model\";\n\n/** The built React page: next to the bundle in dist/, or in dist/ when running from src. */\nconst PAGE = [\"./web/index.html\", \"../../dist/web/index.html\"];\n\n/** The raw page, which the server serves for hot reload and the CLI embeds. */\nexport function loadPage(): string {\n for (const path of PAGE) {\n try {\n return readFileSync(fileURLToPath(new URL(path, import.meta.url)), \"utf8\");\n } catch {\n continue;\n }\n }\n throw new Error(\"Built page dist/web/index.html not found. Run `npm run build`.\");\n}\n\n/** The built page with the report embedded, for a static file or the first paint. burn.py:1498 */\nexport function renderHtml(report: RawReport, now: Date, page = loadPage()): string {\n // `</` would end the script tag; Python escapes it the same way.\n const data = JSON.stringify(reportView(report, now)).replace(/<\\//g, \"<\\\\/\");\n return page.replace(\"/*REPORT*/null\", data);\n}","/**\n * The terminal output: burn.py's print_doctor and print_text, same strings. burn.py:1028, 1142\n *\n * Both read the raw report, because they use burn.py's own key names (session_count, bench_total,\n * recent_sessions). `%f` goes through core/analyze/format so the numbers round like Python's.\n */\n\nimport { burnGoal } from \"../core/analyze/burn\";\nimport { fixed, int0 } from \"../core/analyze/format\";\nimport { BENCH_WINDOW, CHECK_HOURS } from \"../core/analyze/flags\";\nimport { topIssues } from \"../core/analyze/issues\";\nimport { CACHE_READ_RATE, CACHE_WRITE_RATE } from \"../core/analyze/pricing\";\nimport type { RawBurn, RawReport, Source } from \"../core/model\";\n\n/** Python's %-8s and friends. */\nconst end = (text: string, width: number): string => text.padEnd(width);\nconst start = (text: string, width: number): string => text.padStart(width);\n\n/** The doctor verdict: each leak with its share and fix, then the baseline gaps. */\nexport function printDoctor(report: RawReport, htmlPath: string | null): string {\n const out: string[] = [];\n const issues = topIssues(report);\n out.push(\n `TOKEN FURNACE: last ${report.days} days, ${fixed(report.total / 1e6)}M weighted tokens, ` +\n `${int0(report.session_count)} sessions`,\n );\n for (const [source, burn] of Object.entries(report.burns) as [Source, RawBurn][]) {\n const [goal, basis] = burnGoal(report, source);\n out.push(\n `Burn (${source}): ${fixed(burn.rate / 1e6, 1)}M in the last hour, ` +\n `goal ${fixed(goal / 1e6, 1)}M/h (${basis})`,\n );\n }\n for (const s of report.active) {\n const flags = s.flags.length ? `; ${s.flags.map((f) => f.split(\":\")[0]).join(\", \")}` : \"\";\n out.push(\n `Active: ${(s.title || \"(untitled)\").slice(0, 40)} (${s.source} ${s.id}, ${s.model || \"?\"}) ` +\n `burning ${fixed(s.rate / 1e6, 1)}M/h (${fixed(s.rateShare)}% of the hour), ` +\n `context ${fixed(s.context / 1000)}k, ${int0(s.turns)} turns, ${fixed(s.hours)}h old, ` +\n `idle ${fixed(s.idle)}m${flags}`,\n );\n }\n out.push(\n issues.length\n ? `Verdict: ${issues.length} leak${issues.length === 1 ? \"\" : \"s\"} found in the last ` +\n `${CHECK_HOURS} h, largest first.\\n`\n : `Verdict: healthy. No common token leaks in the last ${CHECK_HOURS} h.`,\n );\n issues.forEach((issue, i) => {\n const where =\n issue.share === null ? \"config\" : `${fixed(issue.share)}% of spend, ${issue.hits.length} sessions`;\n out.push(`${i + 1}. [P${issue.priority}] ${issue.title} (${where})`);\n out.push(` Fix: ${issue.fix}`);\n for (const [session, flag] of [...issue.hits]\n .sort((a, b) => b[0].share - a[0].share)\n .slice(0, 2)) {\n out.push(` e.g. ${(session.title || session.id).slice(0, 40)}: ${flag.split(\".\")[0]}`);\n }\n });\n out.push(\n `\\nBenchmark: the same turns at a ${fixed(BENCH_WINDOW / 1000)}k compaction window would cost ` +\n `about ${fixed(report.bench_total / 1e6)}M ` +\n `(${fixed(100 * (1 - report.bench_total / report.total))}% less). Estimate: trims cached ` +\n `context only.`,\n );\n const gaps = report.baseline.filter((row) => !row.ok);\n if (gaps.length) {\n out.push(`\\nBaseline gaps (last ${CHECK_HOURS} h -> recommended):`);\n for (const row of gaps) {\n out.push(` ${end(row.level, 8)} ${end(row.name, 28)} ${end(row.now_24h, 18)} ${row.target}`);\n }\n }\n if (htmlPath) {\n out.push(`\\nReport: ${htmlPath}`);\n out.push('Open it and press \"Copy for Claude\" on a leak to hand over the fix with evidence.');\n }\n return `${out.join(\"\\n\")}\\n`;\n}\n\n/** The full text report: the old burn.py default output. */\nexport function printText(report: RawReport): string {\n const out: string[] = [];\n out.push(\n `=== ${report.days}-day burn: ${fixed(report.total / 1e6)}M weighted tokens, ` +\n `${int0(report.session_count)} sessions, ${int0(report.turns)} turns ===`,\n );\n if (report.sources.length > 1) {\n out.push(` ${report.sources.map(([name, pct]) => `${name} ${fixed(pct)}%`).join(\" \")}`);\n }\n\n out.push(\"\\nSPEND BY CONTEXT SIZE OF THE TURN <- the main lever\");\n for (const [label, , pct, turns] of report.buckets) {\n out.push(` ${end(label, 12)} ${start(fixed(pct, 1), 6)}% ${start(int0(turns), 6)} turns`);\n }\n out.push(\n ` --> ${fixed(report.over_300k)}% of spend is on turns carrying more than 300k of context`,\n );\n\n if (report.preamble) {\n out.push(\"\\nALWAYS-RESIDENT PREAMBLE (instructions, memory, skill catalog, tool schemas)\");\n out.push(\n ` p50=${fixed(report.preamble[0] / 1000)}k p90=${fixed(report.preamble[1] / 1000)}k per ` +\n `session -> ${fixed(report.preamble[2])}% of every token read`,\n );\n out.push(\n ` Prune it once, then leave it stable: reads bill at ${fixed(CACHE_READ_RATE, 1)}x but ` +\n `rewrites at ${fixed(CACHE_WRITE_RATE, 2)}x.`,\n );\n }\n\n out.push(\"\\nTOP PROJECTS\");\n for (const [name, pct] of report.projects) {\n out.push(` ${start(fixed(pct, 1), 6)}% ${name.slice(-58)}`);\n }\n\n out.push(\"\\nTOP SESSIONS (the long ones are where the budget goes)\");\n for (const s of report.sessions) {\n out.push(\n ` ${start(fixed(s.share, 1), 5)}% turns=${end(int0(s.turns), 5)} ` +\n `peak=${start(fixed(s.peak / 1000), 4)}k ${start(fixed(s.hours, 1), 4)}h ` +\n `${end(s.source, 6)} ${s.project.slice(-36)} ${s.id} ${(s.title || \"\").slice(0, 50)}`,\n );\n }\n\n out.push(\"\\nTOOL CALLS\");\n for (const [name, value] of report.tools) {\n out.push(` ${end(name, 28)} ${int0(value)}`);\n }\n\n out.push(`\\nLEAK CHECKS (top sessions of the last ${CHECK_HOURS} h; each flag names its fix)`);\n const flagged = report.recent_sessions.filter((s) => s.flags.length);\n for (const s of flagged) {\n out.push(` ${start(fixed(s.share, 1), 5)}% ${s.source} ${s.id} ${s.title || \"\"}`);\n for (const flag of s.flags) out.push(` - ${flag}`);\n }\n if (!flagged.length) out.push(\" none\");\n\n out.push(\"\\nCONFIG CHECKS\");\n for (const line of report.config) out.push(` - ${line}`);\n\n out.push(`\\nBASELINE (last ${CHECK_HOURS} h, ${report.days}-day value, recommended)`);\n for (const row of report.baseline) {\n out.push(\n ` ${end(row.level, 8)} ${end(row.name, 28)} ${end(row.now_24h, 18)} ` +\n `${end(row.value_7d ?? \"\", 8)} ${row.target}`,\n );\n }\n\n if (report.unpriced) {\n out.push(\n `\\nUNPRICED MODELS (counted at 1.0x -- ${fixed(report.unpriced[0])}% of reported spend)`,\n );\n for (const [name, value] of report.unpriced[1]) {\n out.push(` ${end(name, 28)} ${int0(value)} turns`);\n }\n out.push(\" Add a ratio to MODEL_RATE to price these correctly.\");\n }\n return `${out.join(\"\\n\")}\\n`;\n}","/**\n * The live report: Express on 127.0.0.1 with routing-controllers, rebuilding the report on every\n * request. burn.py serve(). Every route is a controller method: no vanilla routers.\n */\n\nimport type { Server } from \"node:http\";\nimport \"reflect-metadata\";\nimport express, { type Request, type Response } from \"express\";\nimport { Controller, Get, Middleware, Req, Res, useExpressServer, type ExpressMiddlewareInterface } from \"routing-controllers\";\nimport { reportView } from \"./core/analyze/view\";\nimport { loadPage, renderHtml } from \"./render/html\";\nimport { loadingPage } from \"./render/loading\";\nimport type { App } from \"./compose\";\nimport type { Source } from \"./core/model\";\nimport { planWeek } from \"./services/usage-client\";\n\nexport interface ServeOptions {\n days: number;\n source: Source | \"all\";\n /** Millions of weighted tokens, or null. */\n weeklyBudget: number | null;\n planUsage: boolean;\n port: number;\n}\n\nexport interface LiveServer {\n url: string;\n port: number;\n close: () => Promise<void>;\n}\n\n/** Serve until the process is stopped. Ctrl-C ends it. */\nexport async function serve(app: App, options: ServeOptions): Promise<void> {\n const live = await startServer(app, options);\n console.log(`Token Furnace live on ${live.url} (Ctrl-C to stop)`);\n console.log(\"The first scan reads every transcript once. The page shows its progress.\");\n await new Promise<void>(() => {}); // the server keeps the loop alive\n}\n\n/** Bind 127.0.0.1 and answer the routes. Port 0 asks the OS for a free port. */\nexport async function startServer(app: App, options: ServeOptions): Promise<LiveServer> {\n const web = express();\n web.disable(\"x-powered-by\");\n useExpressServer(web, {\n controllers: [reportController(app, options, loadPage())],\n middlewares: [LoopbackHostOnly],\n defaultErrorHandler: true,\n classTransformer: false,\n validation: false,\n });\n\n const http = await new Promise<Server>((ready) => {\n const bound = web.listen(options.port, \"127.0.0.1\", () => ready(bound));\n });\n // Scan after the port is bound. The scan yields, so requests are answered while it runs.\n warm(app);\n const port = (http.address() as { port: number }).port;\n return { url: `http://127.0.0.1:${port}`, port, close: () => new Promise((done) => http.close(() => done())) };\n}\n\n/**\n * A Host header other than the loopback name and the port this server listens on gets 403, so a\n * DNS-rebinding page cannot read the report. No CORS headers go out.\n */\n@Middleware({ type: \"before\", priority: 100 })\nclass LoopbackHostOnly implements ExpressMiddlewareInterface {\n use(req: Request, res: Response, next: (error?: unknown) => void): void {\n const port = req.socket.localPort;\n const host = (req.headers.host ?? \"\").toLowerCase();\n if (host !== `127.0.0.1:${port}` && host !== `localhost:${port}`) {\n res.status(403).type(\"text/plain\").send(\"Forbidden\");\n return;\n }\n next();\n }\n}\n\n/** The routes, closed over the app they serve. The catch-all page is declared last. */\nfunction reportController(app: App, options: ServeOptions, page: string) {\n @Controller()\n class ReportController {\n @Get(\"/api/status\")\n status(@Res() res: Response) {\n if (!app.reports.hasScanned) warm(app);\n return res.set(\"Cache-Control\", \"no-store\").json(app.reports.progress);\n }\n\n @Get(\"/api/report\")\n async report(@Req() req: Request, @Res() res: Response) {\n if (!app.reports.hasScanned) {\n warm(app);\n return res.status(202).json({ status: \"scanning\", progress: app.reports.progress });\n }\n const report = await build(app, options, req.query);\n return res.type(\"application/json\").send(JSON.stringify(report ? reportView(report, app.now()) : null));\n }\n\n @Get(\"/dashboard.html\")\n dashboard(@Res() res: Response) {\n return res.type(\"text/html\").send(page); // the raw page, polled for hot reload: no rebuild\n }\n\n @Get(/.*/)\n async index(@Req() req: Request, @Res() res: Response) {\n if (!app.reports.hasScanned) {\n warm(app);\n return res.type(\"text/html\").send(loadingPage()); // the first scan takes minutes: show progress\n }\n const report = await build(app, options, req.query);\n return res.type(\"text/html\").send(report ? renderHtml(report, app.now(), page) : \"No assistant turns.\");\n }\n }\n return ReportController;\n}\n\n/** Start or join the scan without waiting. A failed scan is logged, not an unhandled rejection. */\nfunction warm(app: App): void {\n app.reports.refresh().catch((error) => console.error(\"token-furnace: scan failed:\", error));\n}\n\n/** Rescan in the background when the last scan is over 5 s old. A request never waits for it. */\nfunction rescan(app: App): void {\n if (Date.now() - app.reports.progress.updatedAt > 5_000) warm(app);\n}\n\n/** One report per request, from the transcripts as they are now. */\nasync function build(app: App, options: ServeOptions, query: Record<string, unknown>) {\n const now = app.now();\n const days = positiveInt(query.days, options.days);\n const source = query.source === \"claude\" || query.source === \"codex\" ? query.source : options.source;\n rescan(app); // the answer is the report we have now; the next poll sees the new scan\n return app.reports.getRaw(days, source, {\n weeklyBudget: options.weeklyBudget,\n planWeek: await planWeek(app.env, now, options.planUsage),\n now,\n });\n}\n\nfunction positiveInt(value: unknown, fallback: number): number {\n const parsed = Number.parseInt(String(value ?? \"\"), 10);\n return parsed > 0 ? parsed : fallback;\n}","/**\n * The page `/` serves while the first scan runs: self-contained, so it needs no bundle. It polls\n * /api/status and reloads into the dashboard when the scan is done.\n */\nexport function loadingPage(): string {\n return `<!doctype html>\n<html lang=\"en\"><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n<title>Token Furnace: scanning</title>\n<style>\n :root { color-scheme: light dark; }\n body { font: 16px/1.5 system-ui, sans-serif; display: grid; place-items: center; min-height: 100vh; margin: 0; }\n main { width: min(30rem, 90vw); text-align: center; }\n .spin { width: 3rem; height: 3rem; margin: 0 auto 1.25rem; border: 4px solid #8884; border-top-color: #e8590c;\n border-radius: 50%; animation: turn 0.9s linear infinite; }\n @keyframes turn { to { transform: rotate(360deg); } }\n .bar { height: 0.75rem; background: #8883; border-radius: 0.4rem; overflow: hidden; }\n .bar > div { height: 100%; width: 0; background: #e8590c; transition: width 0.4s; }\n small { opacity: 0.7; }\n</style></head><body><main>\n <div class=\"spin\" role=\"status\" aria-label=\"Scanning\"></div>\n <h1>Scanning your transcripts</h1>\n <p>Please wait. The first scan reads every Claude Code and Codex session once.</p>\n <div class=\"bar\" role=\"progressbar\" aria-valuemin=\"0\" aria-valuemax=\"100\"><div id=\"fill\"></div></div>\n <p id=\"text\">Starting...</p>\n <small id=\"time\"></small>\n</main>\n<script>\n const fill = document.getElementById(\"fill\"), text = document.getElementById(\"text\"), time = document.getElementById(\"time\");\n const fmt = (n) => n.toLocaleString();\n async function tick() {\n try {\n const s = await (await fetch(\"/api/status\", { cache: \"no-store\" })).json();\n if (s.phase === \"ready\") return location.reload();\n const pct = s.bytesTotal ? Math.min(99, Math.round((100 * s.bytesDone) / s.bytesTotal)) : 0;\n fill.style.width = pct + \"%\";\n text.textContent = s.filesTotal ? fmt(s.filesDone) + \" of \" + fmt(s.filesTotal) + \" files (\" + pct + \"%)\" : \"Looking for transcripts...\";\n if (s.startedAt) time.textContent = Math.round((Date.now() - s.startedAt) / 1000) + \" s elapsed\";\n } catch { /* the server is busy or restarting: try again */ }\n setTimeout(tick, 1000);\n }\n tick();\n</script></body></html>`;\n}\n","import { execFileSync } from \"node:child_process\";\nimport { mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport type { Week } from \"../core/model\";\nimport type { Env } from \"../sources/agent-source\";\n\n/** A saved reading is reused for 5 minutes, and one call is tried per minute. burn.py:862 */\nconst REUSE_SECONDS = 300;\nconst RETRY_SECONDS = 60;\n\n/** Last network call in this process: one a minute, so a server does not burn the rate limit. */\nlet lastTry = 0;\n\n/** The saved reading, in the file burn.py writes and a status line can feed. */\nexport function usageCachePath(env: Env): string {\n const base = env.XDG_CACHE_HOME || join(env.HOME || homedir(), \".cache\");\n return join(base, \"token-furnace\", \"usage.json\");\n}\n\n/**\n * The subscription's 7-day window, or null when unavailable. The saved reading is a local file a\n * status line can feed. With `network` true, a login on this machine (the credentials file or the\n * macOS Keychain) triggers one call to api.anthropic.com when the reading is over 5 minutes old,\n * at most once a minute. The token goes there and nowhere else. A failed call keeps the saved\n * reading. No login on the machine means no call.\n */\nexport async function planWeek(env: Env, now: Date, network: boolean): Promise<Week | null> {\n const at = now.getTime() / 1000;\n const path = usageCachePath(env);\n const saved = readJson(path);\n let data = saved?.seven_day ?? null;\n const stale = !data || at - (saved?.fetched ?? 0) >= REUSE_SECONDS;\n if (network && stale && at - lastTry >= RETRY_SECONDS) {\n const token = accessToken(env);\n if (token) {\n lastTry = at;\n const fresh = await fetchWeek(token);\n if (fresh) {\n data = fresh;\n if (!(env.TOKEN_FURNACE_NO_CACHE && env.TOKEN_FURNACE_NO_CACHE !== \"0\")) {\n writeJson(path, { fetched: at, seven_day: data });\n }\n }\n }\n }\n return toWeek(data, now);\n}\n\nasync function fetchWeek(token: string): Promise<Record<string, any> | null> {\n try {\n const response = await fetch(\"https://api.anthropic.com/api/oauth/usage\", {\n headers: { Authorization: `Bearer ${token}`, \"anthropic-beta\": \"oauth-2025-04-20\" },\n signal: AbortSignal.timeout(10_000),\n });\n if (!response.ok) return null;\n const body = (await response.json()) as Record<string, any>;\n return typeof body?.seven_day === \"object\" && body.seven_day !== null ? body.seven_day : null;\n } catch {\n return null; // the endpoint rate-limits; the saved reading stays\n }\n}\n\n/** The Claude Code login token: the credentials file, else the macOS Keychain. burn.py:881 */\nfunction accessToken(env: Env): string | null {\n let creds: string | null = null;\n const home = env.CLAUDE_CONFIG_DIR || join(env.HOME || homedir(), \".claude\");\n try {\n creds = readFileSync(join(home, \".credentials.json\"), \"utf8\");\n } catch {\n try {\n creds = execFileSync(\n \"security\",\n [\"find-generic-password\", \"-s\", \"Claude Code-credentials\", \"-w\"],\n { encoding: \"utf8\", timeout: 5_000 },\n );\n } catch {\n return null;\n }\n }\n try {\n return (JSON.parse(creds).claudeAiOauth.accessToken as string) ?? null;\n } catch {\n return null;\n }\n}\n\n/** The endpoint's reading as a Week: epoch seconds or an ISO string, and only while it runs. */\nfunction toWeek(data: Record<string, any> | null, now: Date): Week | null {\n if (!data) return null;\n const resets =\n typeof data.resets_at === \"number\"\n ? new Date(data.resets_at * 1000)\n : typeof data.resets_at === \"string\"\n ? new Date(data.resets_at)\n : null;\n if (!resets || Number.isNaN(resets.getTime()) || resets <= now) return null;\n const used = Number(data.utilization);\n if (!Number.isFinite(used)) return null;\n return { start: new Date(resets.getTime() - 7 * 86_400_000), resets, used };\n}\n\nfunction readJson(path: string): Record<string, any> | null {\n try {\n const parsed = JSON.parse(readFileSync(path, \"utf8\"));\n return typeof parsed === \"object\" && parsed !== null ? parsed : null;\n } catch {\n return null;\n }\n}\n\nfunction writeJson(path: string, value: unknown): void {\n try {\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, JSON.stringify(value));\n } catch {\n // A cache we cannot write is a slow run, not a wrong one.\n }\n}","/**\n * The retry circuit breaker as a Claude Code PostToolUse hook. Port of scripts/escalate-on-churn.py.\n *\n * Counts edits per file per session. When one file is edited past a threshold, the agent is grinding\n * at a capability level that is not solving the problem. The hook tells it to ESCALATE -- hand the\n * work to a more capable model or a deeper reasoning pass, carrying what has already been tried --\n * rather than attempting another variation at the same level.\n *\n * It never blocks the edit and never tells the agent to abandon the task. A breaker that stops work\n * converts a token problem into an unfinished-work problem. Malformed input is ignored, not raised:\n * a hook that fails the tool call breaks the work it is meant to protect.\n */\n\nimport { readFileSync, writeFileSync } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { basename, join, sep } from \"node:path\";\nimport type { Env } from \"../sources/agent-source\";\n\n/** Edits to one file before the first nudge, then one nudge every EVERY edits after. */\nfunction thresholds(env: Env): { first: number; every: number } {\n const first = Number.parseInt(env.CHURN_FIRST ?? \"4\", 10);\n const every = Number.parseInt(env.CHURN_EVERY ?? \"3\", 10);\n return {\n first: Number.isInteger(first) && first > 0 ? first : 4,\n every: Number.isInteger(every) && every > 0 ? every : 3,\n };\n}\n\nconst MESSAGE = (name: string, n: number): string =>\n `CIRCUIT BREAKER: ${name} has been edited ${n} times this session.\\n` +\n \"If the last two attempts failed for the same underlying reason, stop trying another variation \" +\n \"at this level and ESCALATE:\\n\" +\n \" 1. State the assumption that must be wrong for these attempts to have failed.\\n\" +\n \" 2. Hand the problem to a more capable model or a higher-effort reasoning pass, or to a fresh \" +\n \"deeper investigation pass.\\n\" +\n \" 3. Carry forward what was already tried and why each attempt failed, so the escalated pass \" +\n \"does not repeat them.\\n\" +\n \"Keep working the task -- escalate the capability applied to it, do not abandon it.\";\n\ninterface HookEvent {\n tool_name?: string;\n tool_input?: { file_path?: string };\n session_id?: string;\n}\n\n/** The stdin payload: one JSON object, or several newline-separated for a piped batch. */\nfunction eventsOf(stdin: string): HookEvent[] {\n try {\n const event: unknown = JSON.parse(stdin);\n return event && typeof event === \"object\" && !Array.isArray(event) ? [event as HookEvent] : [];\n } catch {\n // A batch is newline-delimited; one hook payload may itself span several lines.\n }\n const out: HookEvent[] = [];\n for (const line of stdin.split(\"\\n\")) {\n if (!line.trim()) continue;\n try {\n const event = JSON.parse(line) as HookEvent;\n if (event && typeof event === \"object\") out.push(event);\n } catch {\n // never break the tool call on malformed input\n }\n }\n return out;\n}\n\n/** One session, one file, one counter, in the same place the Python version kept it. */\nfunction stateFile(env: Env, session: string): string {\n const key = (session || \"none\").slice(0, 40).replaceAll(sep, \"_\");\n return join(tmpdir(), `agent-churn-${key}.json`);\n}\n\n/** Counts the edit and prints the escalation prompt when the count lands on a threshold. */\nexport function churnOnce(\n event: HookEvent,\n env: Env,\n out: { write(text: string): unknown },\n): void {\n if (event.tool_name !== \"Edit\" && event.tool_name !== \"Write\" && event.tool_name !== \"NotebookEdit\") {\n return;\n }\n const path = event.tool_input?.file_path;\n if (typeof path !== \"string\" || !path) return;\n\n const file = stateFile(env, String(event.session_id ?? \"none\"));\n let state: Record<string, unknown> = {};\n try {\n const parsed: unknown = JSON.parse(readFileSync(file, \"utf8\"));\n if (parsed && typeof parsed === \"object\" && !Array.isArray(parsed)) {\n state = parsed as Record<string, unknown>;\n }\n } catch {\n state = {};\n }\n\n const previous = Number(state[path]);\n const count = (Number.isInteger(previous) ? previous : 0) + 1;\n state[path] = count;\n try {\n writeFileSync(file, JSON.stringify(state)); // a lost counter is cheaper than a failed edit\n } catch {\n /* see above */\n }\n\n const { first, every } = thresholds(env);\n if (count < first || (count - first) % every) return;\n out.write(\n `${JSON.stringify({\n hookSpecificOutput: {\n hookEventName: \"PostToolUse\",\n additionalContext: MESSAGE(basename(path), count),\n },\n })}\\n`,\n );\n}\n\n/** `token-furnace hook churn`. Always 0: a breaker never fails the tool call. */\nexport function runChurnHook(\n stdin: string,\n env: Env = process.env,\n out: { write(text: string): unknown } = process.stdout,\n): number {\n for (const event of eventsOf(stdin)) churnOnce(event, env, out);\n return 0;\n}\n\n/** Reads stdin to the end. Sync on purpose: a hook is a short-lived process, not a server. */\nexport function readStdin(): string {\n try {\n return readFileSync(0, \"utf8\");\n } catch {\n return \"\";\n }\n}\n","import {\n chmodSync,\n copyFileSync,\n existsSync,\n lstatSync,\n mkdirSync,\n readdirSync,\n readFileSync,\n readlinkSync,\n renameSync,\n symlinkSync,\n writeFileSync,\n} from \"node:fs\";\nimport { basename, dirname, join, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { parse as parseToml } from \"smol-toml\";\nimport type { Env } from \"../sources/agent-source\";\n\nexport interface SetupOptions {\n apply?: boolean;\n aggressive?: boolean;\n rollback?: boolean;\n verify?: boolean;\n}\n\nconst SKILLS = [\"token-furnace\", \"prd-creator\", \"prd-manager\"];\n\nconst BEGIN = \"<!-- token-furnace:begin -->\";\nconst END = \"<!-- token-furnace:end -->\";\nconst LINE =\n \"Token discipline, every session: slice uncertain or cross-file work into a compact PRD with the `prd-creator` skill first and execute from that, rather than exploring and implementing in one context (`prd-manager` reports where PRDs stand); retrieve the smallest range that answers the question and **never re-establish a fact you already have** — no confirming grep after a read that answered it; run the smallest test that can falsify the current hypothesis; after two failures with the same cause, stop editing and re-plan. Full policy: `~/.agents/skills/token-furnace/SKILL.md`.\";\n\nfunction createBackupDir(backupRoot: string): string {\n const d = new Date();\n const pad = (n: number) => String(n).padStart(2, \"0\");\n const base = `${d.getFullYear()}${pad(d.getMonth() + 1)}${pad(d.getDate())}-${pad(d.getHours())}${pad(d.getMinutes())}${pad(d.getSeconds())}`;\n let dir = join(backupRoot, base);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n return dir;\n }\n let counter = 1;\n while (existsSync(`${dir}.${counter}`)) {\n counter++;\n }\n dir = `${dir}.${counter}`;\n mkdirSync(dir, { recursive: true });\n return dir;\n}\n\nfunction collapseHome(path: string, home: string): string {\n if (home && path.startsWith(home)) {\n return `~${path.slice(home.length)}`;\n }\n return path;\n}\n\nfunction isPlainObject(v: unknown): v is Record<string, unknown> {\n return Boolean(v) && typeof v === \"object\" && !Array.isArray(v);\n}\n\n/** Resolve TOML keys through the parser so quoted keys and comments cannot hide existing settings. */\nfunction getTomlValue(text: string, table: string, key: string): string | undefined {\n let data: Record<string, unknown>;\n try {\n data = parseToml(text) as Record<string, unknown>;\n } catch {\n return undefined;\n }\n const scope = table ? data[table] : data;\n if (!isPlainObject(scope)) return undefined;\n const v = scope[key];\n if (v === undefined) return undefined;\n return typeof v === \"string\" ? JSON.stringify(v) : String(v);\n}\n\n/** The unquoted name of a `[table]` header line, or null when the line is not one. */\nfunction tableHeaderName(line: string): string | null {\n const t = line.trim();\n if (!t.startsWith(\"[\") || t.startsWith(\"[[\")) return null;\n const close = t.indexOf(\"]\");\n if (close === -1) return null;\n let name = t.slice(1, close).trim();\n if (name.length >= 2 && name.startsWith('\"') && name.endsWith('\"')) {\n name = name.slice(1, -1);\n }\n return name;\n}\n\nfunction setTomlValue(content: string, table: string, key: string, val: string): string {\n const lines = content.length > 0 ? content.split(\"\\n\") : [];\n // Normalize lines to retain original endings if needed or standard \\n\n const linesWithNl = lines.map((l) => `${l}\\n`);\n const assignment = `${key} = ${val}\\n`;\n const hdr = `[${table}]`;\n if (table) {\n const idx = linesWithNl.findIndex((l) => tableHeaderName(l) === table);\n if (idx === -1) {\n if (linesWithNl.length > 0 && !linesWithNl[linesWithNl.length - 1].endsWith(\"\\n\")) {\n linesWithNl.push(\"\\n\");\n }\n linesWithNl.push(\"\\n\", `${hdr}\\n`, assignment);\n } else {\n linesWithNl.splice(idx + 1, 0, assignment);\n }\n } else {\n let i = linesWithNl.findIndex((l) => l.trimStart().startsWith(\"[\"));\n if (i === -1) i = linesWithNl.length;\n const atTable = i < linesWithNl.length;\n while (i > 0 && !linesWithNl[i - 1].trim()) {\n i--;\n }\n linesWithNl.splice(i, 0, assignment, ...(atTable ? [] : [\"\\n\"]));\n }\n return linesWithNl.join(\"\");\n}\n\nexport function runSetup(\n opts: SetupOptions,\n env: Env = process.env,\n out: { write(text: string): unknown } = process.stdout,\n): number {\n const home = env.HOME ?? \"\";\n const apply = Boolean(opts.apply);\n const aggressive = Boolean(opts.aggressive);\n const rollback = Boolean(opts.rollback);\n const verifyOnly = Boolean(opts.verify);\n\n const hub = join(home, \".agents\", \"skills\");\n const claudeDir = join(home, \".claude\");\n const codexDir = join(home, \".codex\");\n const backupRoot = join(home, \".agents\", \"token-furnace-backups\");\n\n const here = dirname(fileURLToPath(import.meta.url));\n const packageRoot = existsSync(join(here, \"SKILL.md\"))\n ? here\n : existsSync(join(here, \"..\", \"SKILL.md\"))\n ? resolve(here, \"..\")\n : resolve(here, \"..\", \"..\");\n const skillsParent = resolve(packageRoot, \"..\");\n\n const tracked: Array<{ label: string; path: string }> = [\n { label: \"claude-settings.json\", path: join(claudeDir, \"settings.json\") },\n { label: \"claude-mcp.json\", path: join(home, \".claude.json\") },\n { label: \"claude-CLAUDE.md\", path: join(claudeDir, \"CLAUDE.md\") },\n { label: \"codex-config.toml\", path: join(codexDir, \"config.toml\") },\n { label: \"codex-AGENTS.md\", path: join(codexDir, \"AGENTS.md\") },\n ];\n\n const say = (s: string) => out.write(` ${s}\\n`);\n const ok = (s: string) => out.write(` \\x1b[32mok\\x1b[0m ${s}\\n`);\n const plan = (s: string) => out.write(` \\x1b[33mwould\\x1b[0m ${s}\\n`);\n const did = (s: string) => out.write(` \\x1b[36mdid\\x1b[0m ${s}\\n`);\n const warn = (s: string) => out.write(` \\x1b[31mskip\\x1b[0m ${s}\\n`);\n const bad = (s: string) => out.write(` \\x1b[31mFAIL\\x1b[0m ${s}\\n`);\n const head = (s: string) => out.write(`\\n\\x1b[1m${s}\\x1b[0m\\n`);\n\n // --- Rollback ---\n if (rollback) {\n let latest = \"\";\n if (existsSync(backupRoot)) {\n const entries = readdirSync(backupRoot).filter((e) => {\n try {\n return lstatSync(join(backupRoot, e)).isDirectory();\n } catch {\n return false;\n }\n }).sort();\n if (entries.length > 0) {\n latest = join(backupRoot, entries[entries.length - 1]);\n }\n }\n if (!latest) {\n out.write(`no backups in ${backupRoot}\\n`);\n return 1;\n }\n out.write(`restoring ${latest}\\n`);\n for (const item of tracked) {\n const backupFile = join(latest, item.label);\n if (existsSync(backupFile)) {\n mkdirSync(dirname(item.path), { recursive: true });\n // Keep the live file before overwriting it, so this rollback is itself reversible.\n if (existsSync(item.path)) {\n copyFileSync(item.path, join(latest, `${item.label}.pre-rollback`));\n }\n copyFileSync(backupFile, item.path);\n } else if (existsSync(item.path)) {\n renameSync(item.path, `${item.path}.token-furnace-removed`);\n }\n }\n out.write(\"restored\\n\");\n return 0;\n }\n\n // --- Verify ---\n const runVerification = (): number => {\n head(\"Verify\");\n let fails = 0;\n\n const claudeSettings = join(claudeDir, \"settings.json\");\n if (existsSync(claudeSettings)) {\n let valid = false;\n let parsed: any = null;\n try {\n parsed = JSON.parse(readFileSync(claudeSettings, \"utf8\"));\n if (parsed && typeof parsed === \"object\") valid = true;\n } catch {}\n if (valid) {\n ok(\"settings.json parses\");\n for (const k of [\"CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS\", \"ENABLE_TOOL_SEARCH\", \"MAX_MCP_OUTPUT_TOKENS\"]) {\n const v = parsed?.env?.[k];\n if (v !== undefined && v !== \"\") {\n ok(`claude ${k}=${v}`);\n } else {\n bad(`claude ${k} missing`);\n fails++;\n }\n }\n } else {\n bad(\"settings.json is not valid JSON\");\n fails++;\n }\n } else {\n bad(`${claudeSettings} missing`);\n fails++;\n }\n\n const codexConfig = join(codexDir, \"config.toml\");\n if (existsSync(codexConfig)) {\n const tomlText = readFileSync(codexConfig, \"utf8\");\n ok(\"config.toml readable\");\n const pairs: Array<{ table: string; key: string }> = [\n { table: \"\", key: \"model_verbosity\" },\n { table: \"\", key: \"tool_output_token_limit\" },\n { table: \"agents\", key: \"max_concurrent_threads_per_session\" },\n { table: \"agents\", key: \"default_subagent_reasoning_effort\" },\n ];\n for (const p of pairs) {\n const v = getTomlValue(tomlText, p.table, p.key);\n const label = p.table ? `${p.table}.${p.key}` : p.key;\n if (v !== undefined) {\n const display = v.startsWith('\"') && v.endsWith('\"') ? v.slice(1, -1) : v;\n ok(`codex ${label}=${display}`);\n } else {\n bad(`codex ${label} missing`);\n fails++;\n }\n }\n } else {\n bad(`${codexConfig} missing`);\n fails++;\n }\n\n for (const s of SKILLS) {\n // token-furnace must always resolve; prd-* are optional, only checked when the\n // installer had them available.\n if (s !== \"token-furnace\" && !existsSync(join(skillsParent, s))) continue;\n for (const d of [join(claudeDir, \"skills\", s), join(codexDir, \"skills\", s)]) {\n const skillFile = join(d, \"SKILL.md\");\n const disp = collapseHome(d, home);\n if (existsSync(skillFile)) {\n ok(`${disp}/SKILL.md readable`);\n } else {\n let isLink = false;\n try {\n isLink = lstatSync(d).isSymbolicLink();\n } catch {}\n if (isLink) bad(`${disp} is a dangling link`);\n else bad(`${disp} missing`);\n fails++;\n }\n }\n }\n\n // Hook check\n let hookWired = false;\n if (existsSync(claudeSettings)) {\n try {\n const cfg = JSON.parse(readFileSync(claudeSettings, \"utf8\"));\n const postToolUse = cfg?.hooks?.PostToolUse;\n if (Array.isArray(postToolUse)) {\n for (const item of postToolUse) {\n if (Array.isArray(item?.hooks)) {\n for (const h of item.hooks) {\n if (\n typeof h?.command === \"string\" &&\n (h.command.includes(\"hook churn\") || h.command.includes(\"escalate-on-churn.py\"))\n ) {\n hookWired = true;\n }\n }\n }\n }\n }\n } catch {}\n }\n if (hookWired) {\n ok(\"PostToolUse escalate-on-churn wired\");\n } else {\n bad(\"PostToolUse escalate-on-churn not wired\");\n fails++;\n }\n\n for (const f of [join(claudeDir, \"CLAUDE.md\"), join(codexDir, \"AGENTS.md\")]) {\n const disp = collapseHome(f, home);\n let carries = false;\n if (existsSync(f)) {\n const content = readFileSync(f, \"utf8\");\n if (content.includes(LINE)) carries = true;\n }\n if (carries) ok(`${disp} carries the line`);\n else {\n bad(`${disp} is missing the token-furnace line`);\n fails++;\n }\n }\n\n let restorable = false;\n let latestDir = \"\";\n if (existsSync(backupRoot)) {\n const list = readdirSync(backupRoot).filter((e) => {\n try {\n return lstatSync(join(backupRoot, e)).isDirectory();\n } catch {\n return false;\n }\n }).sort();\n if (list.length > 0) {\n latestDir = join(backupRoot, list[list.length - 1]);\n if (existsSync(join(latestDir, \"restore.sh\"))) restorable = true;\n }\n }\n if (restorable) {\n ok(`backup restorable: ${collapseHome(latestDir, home)}`);\n } else {\n bad(`no restorable backup in ${collapseHome(backupRoot, home)}`);\n fails++;\n }\n\n if (fails === 0) {\n out.write(\"\\n \\x1b[32mall checks passed\\x1b[0m\\n\");\n return 0;\n }\n out.write(`\\n \\x1b[31m${fails} check(s) failed\\x1b[0m\\n`);\n return 1;\n };\n\n if (verifyOnly) {\n return runVerification();\n }\n\n function shQuote(s: string): string {\n return \"'\" + s.replace(/'/g, \"'\\\\''\") + \"'\";\n }\n\n // Backup is lazy: created once, immediately before the first real mutation. A\n // no-op apply writes nothing, and the snapshot always predates every change.\n let backupDir = \"\";\n function ensureBackup(): void {\n if (backupDir) return;\n backupDir = createBackupDir(backupRoot);\n const restoreScriptLines: string[] = [\n \"#!/usr/bin/env bash\",\n \"set -euo pipefail\",\n 'd=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"',\n ];\n for (const pair of tracked) {\n if (existsSync(pair.path)) {\n copyFileSync(pair.path, join(backupDir, pair.label));\n const qPath = shQuote(pair.path);\n restoreScriptLines.push(\n `if [ -f ${qPath} ]; then cp -p ${qPath} \"$d/${pair.label}.pre-rollback\"; fi`,\n );\n restoreScriptLines.push(`cp -p \"$d/${pair.label}\" ${qPath}`);\n did(`saved ${pair.path}`);\n } else {\n const qPath = shQuote(pair.path);\n const qRem = shQuote(`${pair.path}.token-furnace-removed`);\n restoreScriptLines.push(`if [ -f ${qPath} ]; then mv ${qPath} ${qRem}; fi`);\n say(`absent ${pair.path} (restore will move it aside, not delete)`);\n }\n }\n restoreScriptLines.push('echo \"restored\"');\n const restoreScript = join(backupDir, \"restore.sh\");\n // Raw writeFileSync, not writeConfig: writing the script must not recurse into a backup.\n writeFileSync(restoreScript, restoreScriptLines.join(\"\\n\") + \"\\n\");\n try {\n chmodSync(restoreScript, 0o755);\n } catch {}\n ok(backupDir);\n say(\"undo with: token-furnace setup --rollback\");\n }\n\n // Every config and instruction write snapshots the tracked files first, exactly once.\n function writeConfig(path: string, text: string): void {\n ensureBackup();\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, text);\n }\n\n // --- Backup ---\n head(\"Backup\");\n if (apply) {\n say(\"created before the first change, if a change is needed\");\n } else {\n plan(`back up 5 files to ${backupRoot}/<timestamp>/ with a restore.sh`);\n }\n\n // --- 1. Skills ---\n head(\"1. Skills (both agents)\");\n const linkSkill = (target: string, linkPath: string) => {\n const disp = collapseHome(linkPath, home);\n const dispT = collapseHome(target, home);\n let exists = false;\n let isLink = false;\n try {\n const stat = lstatSync(linkPath);\n exists = true;\n isLink = stat.isSymbolicLink();\n } catch {}\n\n if (exists) {\n let resolved = \"\";\n try {\n resolved = resolve(dirname(linkPath), readlinkSync(linkPath));\n } catch {\n resolved = resolve(linkPath);\n }\n if (resolved === resolve(target)) {\n ok(disp);\n return;\n }\n warn(`${disp} exists and points elsewhere — left alone`);\n return;\n }\n\n if (apply) {\n mkdirSync(dirname(linkPath), { recursive: true });\n ensureBackup();\n symlinkSync(target, linkPath);\n did(disp);\n } else {\n plan(`link ${disp} -> ${dispT}`);\n }\n };\n\n for (const s of SKILLS) {\n const srcPath = s === \"token-furnace\"\n ? (existsSync(join(packageRoot, \"SKILL.md\")) ? packageRoot : join(skillsParent, s))\n : join(skillsParent, s);\n if (!existsSync(srcPath)) {\n warn(`${s} not found`);\n continue;\n }\n const hubPath = join(hub, s);\n linkSkill(srcPath, hubPath);\n linkSkill(hubPath, join(claudeDir, \"skills\", s));\n linkSkill(hubPath, join(codexDir, \"skills\", s));\n }\n\n // --- 2. Always-on instruction ---\n head(\"2. Always-on instruction\");\n const inject = (filePath: string) => {\n const disp = collapseHome(filePath, home);\n let currentContent = \"\";\n if (existsSync(filePath)) {\n currentContent = readFileSync(filePath, \"utf8\");\n if (currentContent.includes(BEGIN)) {\n if (currentContent.includes(LINE)) {\n ok(`${disp} current`);\n return;\n }\n if (apply) {\n const lines = currentContent.split(\"\\n\");\n const outLines: string[] = [];\n let skip = false;\n for (const l of lines) {\n if (l === BEGIN) {\n outLines.push(BEGIN, LINE, END);\n skip = true;\n continue;\n }\n if (l === END) {\n skip = false;\n continue;\n }\n if (!skip) outLines.push(l);\n }\n writeConfig(filePath, outLines.join(\"\\n\"));\n did(`${disp} line replaced`);\n } else {\n plan(`replace the line between markers in ${disp}`);\n }\n return;\n }\n }\n if (apply) {\n const prefix = currentContent.length > 0 ? \"\\n\" : \"\";\n const addition = `${prefix}${BEGIN}\\n${LINE}\\n${END}\\n`;\n writeConfig(filePath, currentContent + addition);\n did(`${disp} line added`);\n } else {\n plan(`append the marked line to ${disp}`);\n }\n };\n inject(join(claudeDir, \"CLAUDE.md\"));\n inject(join(codexDir, \"AGENTS.md\"));\n\n // --- 3. Token-efficient defaults ---\n head(\"3. Token-efficient defaults\");\n\n const claudeSettingsPath = join(claudeDir, \"settings.json\");\n let claudeCfg: any = {};\n let claudeJsonMalformed = false;\n if (existsSync(claudeSettingsPath)) {\n try {\n const parsed = JSON.parse(readFileSync(claudeSettingsPath, \"utf8\"));\n // A non-object top level, or a non-object env/hooks, would throw or silently\n // clobber bytes on write. Treat all of them as malformed and leave the file alone.\n const envOk = parsed?.env === undefined || isPlainObject(parsed?.env);\n const hooksOk = parsed?.hooks === undefined || isPlainObject(parsed?.hooks);\n if (isPlainObject(parsed) && envOk && hooksOk) {\n claudeCfg = parsed;\n } else {\n claudeJsonMalformed = true;\n }\n } catch {\n claudeJsonMalformed = true;\n }\n }\n\n const setClaudeEnv = (k: string, v: string | boolean | number) => {\n if (claudeJsonMalformed) {\n warn(`claude settings.json is malformed JSON — left alone (wanted ${k}=${v})`);\n return;\n }\n const strVal = String(v);\n const cur = claudeCfg?.env?.[k];\n if (cur !== undefined && String(cur) === strVal) {\n ok(`claude ${k}=${strVal}`);\n return;\n }\n if (cur !== undefined && String(cur) !== \"\") {\n warn(`claude ${k} already set to \"${cur}\" — left alone (wanted ${strVal})`);\n return;\n }\n if (apply) {\n if (!claudeCfg.env) claudeCfg.env = {};\n claudeCfg.env[k] = v;\n writeConfig(claudeSettingsPath, JSON.stringify(claudeCfg, null, 2) + \"\\n\");\n did(`claude ${k}=${strVal}`);\n } else {\n plan(`set claude ${k}=${strVal}`);\n }\n };\n\n const setClaudeHook = () => {\n if (claudeJsonMalformed) {\n warn(\"claude settings.json is malformed JSON — left alone (wanted PostToolUse hook)\");\n return;\n }\n const targetCmd = \"npx -y token-furnace hook churn\";\n let replacedLegacy = false;\n let alreadyConfigured = false;\n const postToolUse = claudeCfg?.hooks?.PostToolUse;\n if (Array.isArray(postToolUse)) {\n for (const item of postToolUse) {\n if (Array.isArray(item?.hooks)) {\n for (const h of item.hooks) {\n if (h?.command === targetCmd) {\n alreadyConfigured = true;\n } else if (typeof h?.command === \"string\" && h.command.includes(\"escalate-on-churn.py\")) {\n if (apply) {\n h.command = targetCmd;\n }\n replacedLegacy = true;\n }\n }\n }\n }\n }\n if (replacedLegacy && apply) {\n writeConfig(claudeSettingsPath, JSON.stringify(claudeCfg, null, 2) + \"\\n\");\n did(\"claude PostToolUse replaced legacy escalate-on-churn.py hook\");\n return;\n }\n if (alreadyConfigured) {\n ok(\"claude PostToolUse escalate-on-churn\");\n return;\n }\n if (apply) {\n if (!claudeCfg.hooks) claudeCfg.hooks = {};\n if (!Array.isArray(claudeCfg.hooks.PostToolUse)) claudeCfg.hooks.PostToolUse = [];\n claudeCfg.hooks.PostToolUse.push({\n matcher: \"Edit|Write|NotebookEdit\",\n hooks: [{ type: \"command\", command: targetCmd }],\n });\n writeConfig(claudeSettingsPath, JSON.stringify(claudeCfg, null, 2) + \"\\n\");\n did(\"claude PostToolUse escalate-on-churn\");\n } else {\n plan(\"wire claude PostToolUse escalate-on-churn\");\n }\n };\n\n const codexConfigPath = join(codexDir, \"config.toml\");\n let codexToml = \"\";\n let codexTomlInvalid = false;\n if (existsSync(codexConfigPath)) {\n codexToml = readFileSync(codexConfigPath, \"utf8\");\n try {\n parseToml(codexToml);\n } catch {\n codexTomlInvalid = true;\n warn(\"codex config.toml is not valid TOML — left unchanged\");\n }\n }\n\n const setCodexIfUnset = (table: string, key: string, tomlVal: string, humanVal: string) => {\n if (codexTomlInvalid) return;\n const cur = getTomlValue(codexToml, table, key);\n const label = table ? `${table}.${key}` : key;\n if (cur !== undefined) {\n const display = cur.startsWith('\"') && cur.endsWith('\"') ? cur.slice(1, -1) : cur;\n if (display === humanVal) {\n ok(`codex ${label} = ${humanVal}`);\n return;\n }\n warn(`codex ${label} already \"${display}\" — left alone (wanted ${humanVal})`);\n return;\n }\n if (apply) {\n const candidate = setTomlValue(codexToml, table, key, tomlVal);\n // shortcut: unsupported table layouts are skipped; use a preserving editor if they need support.\n try {\n parseToml(candidate);\n // An apparent table header can be inside a multiline string.\n if (getTomlValue(candidate, table, key) !== tomlVal) throw new Error(\"Setting was not inserted\");\n } catch {\n warn(`codex ${label}: cannot set without risking config — left alone`);\n return;\n }\n codexToml = candidate;\n writeConfig(codexConfigPath, codexToml);\n did(`codex ${label} = ${tomlVal}`);\n } else {\n plan(`set codex ${label} = ${tomlVal}`);\n }\n };\n\n setClaudeEnv(\"CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS\", \"3\");\n setClaudeEnv(\"ENABLE_TOOL_SEARCH\", \"true\");\n setClaudeEnv(\"MAX_MCP_OUTPUT_TOKENS\", \"12000\");\n setClaudeHook();\n\n setCodexIfUnset(\"\", \"model_verbosity\", '\"low\"', \"low\");\n setCodexIfUnset(\"\", \"tool_output_token_limit\", \"10000\", \"10000\");\n setCodexIfUnset(\"agents\", \"max_concurrent_threads_per_session\", \"3\", \"3\");\n setCodexIfUnset(\"agents\", \"default_subagent_reasoning_effort\", '\"medium\"', \"medium\");\n\n head(\" Flagged as risky\");\n if (aggressive) {\n say(\"--aggressive: spawn depth has version-specific reports of behaving one level off.\");\n say(\"Verify after any Claude Code upgrade that subagents still spawn.\");\n setClaudeEnv(\"CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH\", \"1\");\n } else {\n say(\"not set (pass --aggressive to include, after reading SKILL.md):\");\n say(\" CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH=1 may block all spawning on some versions\");\n }\n\n head(\"Never set by this script\");\n say(\"CLAUDE_CODE_EFFORT_LEVEL your reasoning baseline is yours, not a script's\");\n say(\"codex model_reasoning_effort same — not read, not written, not suggested\");\n say(\"codex skills.max_context_tokens truncates the skill catalog; prune skills instead\");\n say(\"codex agents.max_depth not in the current official config reference\");\n\n // Like the original `verify || true`: report failures, never fail or falsely pass the apply.\n if (apply) {\n runVerification();\n if (!backupDir) ok(\"configuration already current (no-op apply; no backup created)\");\n }\n\n head(\"Next\");\n if (apply) {\n say(\"1. Start a fresh session in either agent.\");\n say(\"2. Confirm the token-furnace line is in context.\");\n say(\"3. Re-check any time: token-furnace setup --verify\");\n say(\"4. Unhappy with anything: token-furnace setup --rollback\");\n } else {\n say(\"Dry run. Nothing was written.\");\n say(\"Apply with: token-furnace setup --apply\");\n }\n\n return 0;\n}\n"],"mappings":"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","names":["mkdirSync","writeFileSync","dirname","resolve","existsSync","existsSync","hours","value","start","end","hours","count","key","p","hours","share","median","share","resolve","workers","existsSync","existsSync","fileURLToPath","fileURLToPath","pct","mkdirSync","readFileSync","homedir","dirname","join","readFileSync","writeFileSync","join","count","existsSync","mkdirSync","readFileSync","writeFileSync","dirname","join","fileURLToPath","resolve","mkdirSync","dirname","writeFileSync"]}
|