|
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' |
4 | 4 |
|
5 | | -const outdir = "dist"; |
| 5 | +const outdir = 'dist' |
6 | 6 |
|
7 | 7 | // 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 }) |
10 | 10 |
|
11 | 11 | // Default features that match the official CLI build. |
12 | 12 | // 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 | +] |
14 | 21 |
|
15 | 22 | // Collect FEATURE_* env vars → Bun.build features |
16 | 23 | 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])] |
20 | 27 |
|
21 | 28 | // Step 2: Bundle with splitting |
22 | 29 | 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 | +}) |
30 | 37 |
|
31 | 38 | 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) |
37 | 44 | } |
38 | 45 |
|
39 | 46 | // 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);` |
43 | 50 |
|
44 | | -let patched = 0; |
| 51 | +let patched = 0 |
45 | 52 | 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 | + } |
56 | 63 | } |
57 | 64 |
|
58 | 65 | 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 | +) |
61 | 68 |
|
62 | 69 | // 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}/`) |
66 | 73 |
|
67 | 74 | // Step 5: Bundle download-ripgrep script as standalone JS for postinstall |
68 | 75 | 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 | +}) |
73 | 80 | 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 |
79 | 86 | } else { |
80 | | - console.log(`Bundled download-ripgrep script to ${outdir}/`); |
| 87 | + console.log(`Bundled download-ripgrep script to ${outdir}/`) |
81 | 88 | } |
0 commit comments