Skip to content

Commit 96f6d2c

Browse files
author
unraid
committed
feat: enable SHOT_STATS, PROMPT_CACHE_BREAK_DETECTION, TOKEN_BUDGET feature flags
Enable 3 verified compile-only feature flags in build.ts and dev.ts defaults: - SHOT_STATS: local shot distribution statistics in /stats panel - PROMPT_CACHE_BREAK_DETECTION: internal cache key change diagnostics - TOKEN_BUDGET: support +500k syntax for minimum output token targets All 3 flags verified by 6 parallel sub-agents + independent Codex CLI review. Build passes (475 files), zero new test failures. Also adds: - docs/features/feature-flags-codex-review.md: Codex review findings - Marks all enabled flags in feature-flags-audit-complete.md - Adds openai dependency (needed for OpenAI compat layer)
1 parent 7a2ade0 commit 96f6d2c

7 files changed

Lines changed: 4244 additions & 79 deletions

File tree

build.ts

Lines changed: 58 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,81 +1,88 @@
1-
import { readdir, readFile, writeFile, cp } from "fs/promises";
2-
import { join } from "path";
3-
import { getMacroDefines } from "./scripts/defines.ts";
1+
import { readdir, readFile, writeFile, cp } from 'fs/promises'
2+
import { join } from 'path'
3+
import { getMacroDefines } from './scripts/defines.ts'
44

5-
const outdir = "dist";
5+
const outdir = 'dist'
66

77
// Step 1: Clean output directory
8-
const { rmSync } = await import("fs");
9-
rmSync(outdir, { recursive: true, force: true });
8+
const { rmSync } = await import('fs')
9+
rmSync(outdir, { recursive: true, force: true })
1010

1111
// Default features that match the official CLI build.
1212
// Additional features can be enabled via FEATURE_<NAME>=1 env vars.
13-
const DEFAULT_BUILD_FEATURES = ["AGENT_TRIGGERS_REMOTE", "CHICAGO_MCP", "VOICE_MODE"];
13+
const DEFAULT_BUILD_FEATURES = [
14+
'AGENT_TRIGGERS_REMOTE',
15+
'CHICAGO_MCP',
16+
'VOICE_MODE',
17+
'SHOT_STATS',
18+
'PROMPT_CACHE_BREAK_DETECTION',
19+
'TOKEN_BUDGET',
20+
]
1421

1522
// Collect FEATURE_* env vars → Bun.build features
1623
const envFeatures = Object.keys(process.env)
17-
.filter(k => k.startsWith("FEATURE_"))
18-
.map(k => k.replace("FEATURE_", ""));
19-
const features = [...new Set([...DEFAULT_BUILD_FEATURES, ...envFeatures])];
24+
.filter(k => k.startsWith('FEATURE_'))
25+
.map(k => k.replace('FEATURE_', ''))
26+
const features = [...new Set([...DEFAULT_BUILD_FEATURES, ...envFeatures])]
2027

2128
// Step 2: Bundle with splitting
2229
const result = await Bun.build({
23-
entrypoints: ["src/entrypoints/cli.tsx"],
24-
outdir,
25-
target: "bun",
26-
splitting: true,
27-
define: getMacroDefines(),
28-
features,
29-
});
30+
entrypoints: ['src/entrypoints/cli.tsx'],
31+
outdir,
32+
target: 'bun',
33+
splitting: true,
34+
define: getMacroDefines(),
35+
features,
36+
})
3037

3138
if (!result.success) {
32-
console.error("Build failed:");
33-
for (const log of result.logs) {
34-
console.error(log);
35-
}
36-
process.exit(1);
39+
console.error('Build failed:')
40+
for (const log of result.logs) {
41+
console.error(log)
42+
}
43+
process.exit(1)
3744
}
3845

3946
// Step 3: Post-process — replace Bun-only `import.meta.require` with Node.js compatible version
40-
const files = await readdir(outdir);
41-
const IMPORT_META_REQUIRE = "var __require = import.meta.require;";
42-
const COMPAT_REQUIRE = `var __require = typeof import.meta.require === "function" ? import.meta.require : (await import("module")).createRequire(import.meta.url);`;
47+
const files = await readdir(outdir)
48+
const IMPORT_META_REQUIRE = 'var __require = import.meta.require;'
49+
const COMPAT_REQUIRE = `var __require = typeof import.meta.require === "function" ? import.meta.require : (await import("module")).createRequire(import.meta.url);`
4350

44-
let patched = 0;
51+
let patched = 0
4552
for (const file of files) {
46-
if (!file.endsWith(".js")) continue;
47-
const filePath = join(outdir, file);
48-
const content = await readFile(filePath, "utf-8");
49-
if (content.includes(IMPORT_META_REQUIRE)) {
50-
await writeFile(
51-
filePath,
52-
content.replace(IMPORT_META_REQUIRE, COMPAT_REQUIRE),
53-
);
54-
patched++;
55-
}
53+
if (!file.endsWith('.js')) continue
54+
const filePath = join(outdir, file)
55+
const content = await readFile(filePath, 'utf-8')
56+
if (content.includes(IMPORT_META_REQUIRE)) {
57+
await writeFile(
58+
filePath,
59+
content.replace(IMPORT_META_REQUIRE, COMPAT_REQUIRE),
60+
)
61+
patched++
62+
}
5663
}
5764

5865
console.log(
59-
`Bundled ${result.outputs.length} files to ${outdir}/ (patched ${patched} for Node.js compat)`,
60-
);
66+
`Bundled ${result.outputs.length} files to ${outdir}/ (patched ${patched} for Node.js compat)`,
67+
)
6168

6269
// Step 4: Copy native .node addon files (audio-capture)
63-
const vendorDir = join(outdir, "vendor", "audio-capture");
64-
await cp("vendor/audio-capture", vendorDir, { recursive: true });
65-
console.log(`Copied vendor/audio-capture/ → ${vendorDir}/`);
70+
const vendorDir = join(outdir, 'vendor', 'audio-capture')
71+
await cp('vendor/audio-capture', vendorDir, { recursive: true })
72+
console.log(`Copied vendor/audio-capture/ → ${vendorDir}/`)
6673

6774
// Step 5: Bundle download-ripgrep script as standalone JS for postinstall
6875
const rgScript = await Bun.build({
69-
entrypoints: ["scripts/download-ripgrep.ts"],
70-
outdir,
71-
target: "node",
72-
});
76+
entrypoints: ['scripts/download-ripgrep.ts'],
77+
outdir,
78+
target: 'node',
79+
})
7380
if (!rgScript.success) {
74-
console.error("Failed to bundle download-ripgrep script:");
75-
for (const log of rgScript.logs) {
76-
console.error(log);
77-
}
78-
// Non-fatal — postinstall fallback to bun run scripts/download-ripgrep.ts
81+
console.error('Failed to bundle download-ripgrep script:')
82+
for (const log of rgScript.logs) {
83+
console.error(log)
84+
}
85+
// Non-fatal — postinstall fallback to bun run scripts/download-ripgrep.ts
7986
} else {
80-
console.log(`Bundled download-ripgrep script to ${outdir}/`);
87+
console.log(`Bundled download-ripgrep script to ${outdir}/`)
8188
}

0 commit comments

Comments
 (0)