✨ Enhance build scripts and add new feature flags in bun-bundle
This commit is contained in:
@@ -10,6 +10,9 @@
|
|||||||
"claude": "src/entrypoints/cli.tsx"
|
"claude": "src/entrypoints/cli.tsx"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"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",
|
"typecheck": "tsc --noEmit",
|
||||||
"lint": "biome check src/",
|
"lint": "biome check src/",
|
||||||
"lint:fix": "biome check --write src/",
|
"lint:fix": "biome check --write src/",
|
||||||
@@ -65,6 +68,7 @@
|
|||||||
"@types/semver": "^7.5.8",
|
"@types/semver": "^7.5.8",
|
||||||
"@types/stack-utils": "^2.0.3",
|
"@types/stack-utils": "^2.0.3",
|
||||||
"@types/ws": "^8.5.0",
|
"@types/ws": "^8.5.0",
|
||||||
|
"esbuild": "^0.25.0",
|
||||||
"typescript": "^5.7.0"
|
"typescript": "^5.7.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
|
|||||||
@@ -6,10 +6,17 @@
|
|||||||
// Watch mode: bun scripts/build-bundle.ts --watch
|
// Watch mode: bun scripts/build-bundle.ts --watch
|
||||||
|
|
||||||
import * as esbuild from 'esbuild'
|
import * as esbuild from 'esbuild'
|
||||||
import { resolve } from 'path'
|
import { resolve, dirname } from 'path'
|
||||||
import { chmodSync, readFileSync } from 'fs'
|
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 watch = process.argv.includes('--watch')
|
||||||
const minify = process.argv.includes('--minify')
|
const minify = process.argv.includes('--minify')
|
||||||
const noSourcemap = process.argv.includes('--no-sourcemap')
|
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 pkg = JSON.parse(readFileSync(resolve(ROOT, 'package.json'), 'utf-8'))
|
||||||
const version = pkg.version || '0.0.0-dev'
|
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 = {
|
const buildOptions: esbuild.BuildOptions = {
|
||||||
entryPoints: [resolve(ROOT, 'src/entrypoints/cli.tsx')],
|
entryPoints: [resolve(ROOT, 'src/entrypoints/cli.tsx')],
|
||||||
bundle: true,
|
bundle: true,
|
||||||
@@ -30,8 +75,10 @@ const buildOptions: esbuild.BuildOptions = {
|
|||||||
// Single-file output — no code splitting for CLI tools
|
// Single-file output — no code splitting for CLI tools
|
||||||
splitting: false,
|
splitting: false,
|
||||||
|
|
||||||
// Inject the MACRO global before all other code
|
plugins: [srcResolverPlugin],
|
||||||
inject: [resolve(ROOT, 'src/shims/macro.ts')],
|
|
||||||
|
// Use tsconfig for baseUrl / paths resolution (complements plugin above)
|
||||||
|
tsconfig: resolve(ROOT, 'tsconfig.json'),
|
||||||
|
|
||||||
// Alias bun:bundle to our runtime shim
|
// Alias bun:bundle to our runtime shim
|
||||||
alias: {
|
alias: {
|
||||||
@@ -50,6 +97,11 @@ const buildOptions: esbuild.BuildOptions = {
|
|||||||
'node:*',
|
'node:*',
|
||||||
// Native addons that can't be bundled
|
// Native addons that can't be bundled
|
||||||
'fsevents',
|
'fsevents',
|
||||||
|
'sharp',
|
||||||
|
'image-processor-napi',
|
||||||
|
// Anthropic-internal packages (not published externally)
|
||||||
|
'@anthropic-ai/sandbox-runtime',
|
||||||
|
'@anthropic-ai/claude-agent-sdk',
|
||||||
],
|
],
|
||||||
|
|
||||||
jsx: 'automatic',
|
jsx: 'automatic',
|
||||||
@@ -64,9 +116,14 @@ const buildOptions: esbuild.BuildOptions = {
|
|||||||
treeShaking: true,
|
treeShaking: true,
|
||||||
|
|
||||||
// Define replacements — inline constants at build time
|
// Define replacements — inline constants at build time
|
||||||
// Eliminates process.env.USER_TYPE === 'ant' branches (Anthropic-internal code)
|
// MACRO.* — originally inlined by Bun's bundler at compile time
|
||||||
// Sets NODE_ENV to production for production builds
|
// process.env.USER_TYPE — eliminates 'ant' (Anthropic-internal) code branches
|
||||||
define: {
|
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.USER_TYPE': '"external"',
|
||||||
'process.env.NODE_ENV': minify ? '"production"' : '"development"',
|
'process.env.NODE_ENV': minify ? '"production"' : '"development"',
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -6,6 +6,8 @@
|
|||||||
const FEATURE_FLAGS: Record<string, boolean> = {
|
const FEATURE_FLAGS: Record<string, boolean> = {
|
||||||
PROACTIVE: envBool('CLAUDE_CODE_PROACTIVE', false),
|
PROACTIVE: envBool('CLAUDE_CODE_PROACTIVE', false),
|
||||||
KAIROS: envBool('CLAUDE_CODE_KAIROS', 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),
|
BRIDGE_MODE: envBool('CLAUDE_CODE_BRIDGE_MODE', false),
|
||||||
DAEMON: envBool('CLAUDE_CODE_DAEMON', false),
|
DAEMON: envBool('CLAUDE_CODE_DAEMON', false),
|
||||||
VOICE_MODE: envBool('CLAUDE_CODE_VOICE_MODE', 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
|
ABLATION_BASELINE: false, // always off for external builds
|
||||||
DUMP_SYSTEM_PROMPT: envBool('CLAUDE_CODE_DUMP_SYSTEM_PROMPT', false),
|
DUMP_SYSTEM_PROMPT: envBool('CLAUDE_CODE_DUMP_SYSTEM_PROMPT', false),
|
||||||
BG_SESSIONS: envBool('CLAUDE_CODE_BG_SESSIONS', 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 {
|
function envBool(key: string, fallback: boolean): boolean {
|
||||||
|
|||||||
Reference in New Issue
Block a user