Enhance build scripts and add new feature flags in bun-bundle

This commit is contained in:
nirholas
2026-03-31 11:06:49 +00:00
parent d35ea47ba7
commit 754fea0e82
3 changed files with 81 additions and 7 deletions

View File

@@ -10,6 +10,9 @@
"claude": "src/entrypoints/cli.tsx"
},
"scripts": {
"build": "bun scripts/build-bundle.ts",
"build:watch": "bun scripts/build-bundle.ts --watch",
"build:prod": "bun scripts/build-bundle.ts --minify",
"typecheck": "tsc --noEmit",
"lint": "biome check src/",
"lint:fix": "biome check --write src/",
@@ -65,6 +68,7 @@
"@types/semver": "^7.5.8",
"@types/stack-utils": "^2.0.3",
"@types/ws": "^8.5.0",
"esbuild": "^0.25.0",
"typescript": "^5.7.0"
},
"engines": {

View File

@@ -6,10 +6,17 @@
// Watch mode: bun scripts/build-bundle.ts --watch
import * as esbuild from 'esbuild'
import { resolve } from 'path'
import { chmodSync, readFileSync } from 'fs'
import { resolve, dirname } from 'path'
import { chmodSync, readFileSync, existsSync } from 'fs'
import { fileURLToPath } from 'url'
const ROOT = resolve(import.meta.dir, '..')
// Bun: import.meta.dir — Node 21+: import.meta.dirname — fallback
const __dir: string =
(import.meta as any).dir ??
(import.meta as any).dirname ??
dirname(fileURLToPath(import.meta.url))
const ROOT = resolve(__dir, '..')
const watch = process.argv.includes('--watch')
const minify = process.argv.includes('--minify')
const noSourcemap = process.argv.includes('--no-sourcemap')
@@ -18,6 +25,44 @@ const noSourcemap = process.argv.includes('--no-sourcemap')
const pkg = JSON.parse(readFileSync(resolve(ROOT, 'package.json'), 'utf-8'))
const version = pkg.version || '0.0.0-dev'
// ── Plugin: resolve bare 'src/' imports (tsconfig baseUrl: ".") ──
// The codebase uses `import ... from 'src/foo/bar.js'` which relies on
// TypeScript's baseUrl resolution. This plugin maps those to real TS files.
const srcResolverPlugin: esbuild.Plugin = {
name: 'src-resolver',
setup(build) {
build.onResolve({ filter: /^src\// }, (args) => {
const basePath = resolve(ROOT, args.path)
// Already exists as-is
if (existsSync(basePath)) {
return { path: basePath }
}
// Strip .js/.jsx and try TypeScript extensions
const withoutExt = basePath.replace(/\.(js|jsx)$/, '')
for (const ext of ['.ts', '.tsx', '.js', '.jsx']) {
const candidate = withoutExt + ext
if (existsSync(candidate)) {
return { path: candidate }
}
}
// Try as directory with index file
const dirPath = basePath.replace(/\.(js|jsx)$/, '')
for (const ext of ['.ts', '.tsx', '.js', '.jsx']) {
const candidate = resolve(dirPath, 'index' + ext)
if (existsSync(candidate)) {
return { path: candidate }
}
}
// Let esbuild handle it (will error if truly missing)
return undefined
})
},
}
const buildOptions: esbuild.BuildOptions = {
entryPoints: [resolve(ROOT, 'src/entrypoints/cli.tsx')],
bundle: true,
@@ -30,8 +75,10 @@ const buildOptions: esbuild.BuildOptions = {
// Single-file output — no code splitting for CLI tools
splitting: false,
// Inject the MACRO global before all other code
inject: [resolve(ROOT, 'src/shims/macro.ts')],
plugins: [srcResolverPlugin],
// Use tsconfig for baseUrl / paths resolution (complements plugin above)
tsconfig: resolve(ROOT, 'tsconfig.json'),
// Alias bun:bundle to our runtime shim
alias: {
@@ -50,6 +97,11 @@ const buildOptions: esbuild.BuildOptions = {
'node:*',
// Native addons that can't be bundled
'fsevents',
'sharp',
'image-processor-napi',
// Anthropic-internal packages (not published externally)
'@anthropic-ai/sandbox-runtime',
'@anthropic-ai/claude-agent-sdk',
],
jsx: 'automatic',
@@ -64,9 +116,14 @@ const buildOptions: esbuild.BuildOptions = {
treeShaking: true,
// Define replacements — inline constants at build time
// Eliminates process.env.USER_TYPE === 'ant' branches (Anthropic-internal code)
// Sets NODE_ENV to production for production builds
// MACRO.* — originally inlined by Bun's bundler at compile time
// process.env.USER_TYPE — eliminates 'ant' (Anthropic-internal) code branches
define: {
'MACRO.VERSION': JSON.stringify(version),
'MACRO.PACKAGE_URL': JSON.stringify('@anthropic-ai/claude-code'),
'MACRO.ISSUES_EXPLAINER': JSON.stringify(
'report issues at https://github.com/anthropics/claude-code/issues'
),
'process.env.USER_TYPE': '"external"',
'process.env.NODE_ENV': minify ? '"production"' : '"development"',
},

View File

@@ -6,6 +6,8 @@
const FEATURE_FLAGS: Record<string, boolean> = {
PROACTIVE: envBool('CLAUDE_CODE_PROACTIVE', false),
KAIROS: envBool('CLAUDE_CODE_KAIROS', false),
KAIROS_BRIEF: envBool('CLAUDE_CODE_KAIROS_BRIEF', false),
KAIROS_GITHUB_WEBHOOKS: envBool('CLAUDE_CODE_KAIROS_GITHUB_WEBHOOKS', false),
BRIDGE_MODE: envBool('CLAUDE_CODE_BRIDGE_MODE', false),
DAEMON: envBool('CLAUDE_CODE_DAEMON', false),
VOICE_MODE: envBool('CLAUDE_CODE_VOICE_MODE', false),
@@ -15,6 +17,17 @@ const FEATURE_FLAGS: Record<string, boolean> = {
ABLATION_BASELINE: false, // always off for external builds
DUMP_SYSTEM_PROMPT: envBool('CLAUDE_CODE_DUMP_SYSTEM_PROMPT', false),
BG_SESSIONS: envBool('CLAUDE_CODE_BG_SESSIONS', false),
HISTORY_SNIP: envBool('CLAUDE_CODE_HISTORY_SNIP', false),
WORKFLOW_SCRIPTS: envBool('CLAUDE_CODE_WORKFLOW_SCRIPTS', false),
CCR_REMOTE_SETUP: envBool('CLAUDE_CODE_CCR_REMOTE_SETUP', false),
EXPERIMENTAL_SKILL_SEARCH: envBool('CLAUDE_CODE_EXPERIMENTAL_SKILL_SEARCH', false),
ULTRAPLAN: envBool('CLAUDE_CODE_ULTRAPLAN', false),
TORCH: envBool('CLAUDE_CODE_TORCH', false),
UDS_INBOX: envBool('CLAUDE_CODE_UDS_INBOX', false),
FORK_SUBAGENT: envBool('CLAUDE_CODE_FORK_SUBAGENT', false),
BUDDY: envBool('CLAUDE_CODE_BUDDY', false),
MCP_SKILLS: envBool('CLAUDE_CODE_MCP_SKILLS', false),
REACTIVE_COMPACT: envBool('CLAUDE_CODE_REACTIVE_COMPACT', false),
}
function envBool(key: string, fallback: boolean): boolean {