fix: build.ts
Browse files- scripts/build.ts +207 -0
scripts/build.ts
ADDED
|
@@ -0,0 +1,207 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { chmodSync, existsSync, mkdirSync } from 'fs'
|
| 2 |
+
import { dirname } from 'path'
|
| 3 |
+
|
| 4 |
+
const pkg = await Bun.file(new URL('../package.json', import.meta.url)).json() as {
|
| 5 |
+
name: string
|
| 6 |
+
version: string
|
| 7 |
+
}
|
| 8 |
+
|
| 9 |
+
const args = process.argv.slice(2)
|
| 10 |
+
const compile = args.includes('--compile')
|
| 11 |
+
const dev = args.includes('--dev')
|
| 12 |
+
|
| 13 |
+
const fullExperimentalFeatures = [
|
| 14 |
+
'AGENT_MEMORY_SNAPSHOT',
|
| 15 |
+
'AGENT_TRIGGERS',
|
| 16 |
+
'AGENT_TRIGGERS_REMOTE',
|
| 17 |
+
'AWAY_SUMMARY',
|
| 18 |
+
'BASH_CLASSIFIER',
|
| 19 |
+
'BUDDY',
|
| 20 |
+
'BRIDGE_MODE',
|
| 21 |
+
'BUILTIN_EXPLORE_PLAN_AGENTS',
|
| 22 |
+
'CACHED_MICROCOMPACT',
|
| 23 |
+
'CCR_AUTO_CONNECT',
|
| 24 |
+
'CCR_MIRROR',
|
| 25 |
+
'CCR_REMOTE_SETUP',
|
| 26 |
+
'COMPACTION_REMINDERS',
|
| 27 |
+
'CONNECTOR_TEXT',
|
| 28 |
+
'EXTRACT_MEMORIES',
|
| 29 |
+
'HISTORY_PICKER',
|
| 30 |
+
'HOOK_PROMPTS',
|
| 31 |
+
'KAIROS_BRIEF',
|
| 32 |
+
'KAIROS_CHANNELS',
|
| 33 |
+
'LODESTONE',
|
| 34 |
+
'MCP_RICH_OUTPUT',
|
| 35 |
+
'MESSAGE_ACTIONS',
|
| 36 |
+
'NATIVE_CLIPBOARD_IMAGE',
|
| 37 |
+
'NEW_INIT',
|
| 38 |
+
'POWERSHELL_AUTO_MODE',
|
| 39 |
+
'PROMPT_CACHE_BREAK_DETECTION',
|
| 40 |
+
'QUICK_SEARCH',
|
| 41 |
+
'SHOT_STATS',
|
| 42 |
+
'TEAMMEM',
|
| 43 |
+
'TOKEN_BUDGET',
|
| 44 |
+
'TREE_SITTER_BASH',
|
| 45 |
+
'TREE_SITTER_BASH_SHADOW',
|
| 46 |
+
'TRANSCRIPT_CLASSIFIER',
|
| 47 |
+
'ULTRAPLAN',
|
| 48 |
+
'ULTRATHINK',
|
| 49 |
+
'UNATTENDED_RETRY',
|
| 50 |
+
'VERIFICATION_AGENT',
|
| 51 |
+
'VOICE_MODE',
|
| 52 |
+
] as const
|
| 53 |
+
|
| 54 |
+
function runCommand(cmd: string[]): string | null {
|
| 55 |
+
const proc = Bun.spawnSync({
|
| 56 |
+
cmd,
|
| 57 |
+
cwd: process.cwd(),
|
| 58 |
+
stdout: 'pipe',
|
| 59 |
+
stderr: 'pipe',
|
| 60 |
+
})
|
| 61 |
+
|
| 62 |
+
if (proc.exitCode !== 0) {
|
| 63 |
+
return null
|
| 64 |
+
}
|
| 65 |
+
|
| 66 |
+
return new TextDecoder().decode(proc.stdout).trim() || null
|
| 67 |
+
}
|
| 68 |
+
|
| 69 |
+
function getDevVersion(baseVersion: string): string {
|
| 70 |
+
const timestamp = new Date().toISOString()
|
| 71 |
+
const date = timestamp.slice(0, 10).replaceAll('-', '')
|
| 72 |
+
const time = timestamp.slice(11, 19).replaceAll(':', '')
|
| 73 |
+
const sha = runCommand(['git', 'rev-parse', '--short=8', 'HEAD']) ?? 'unknown'
|
| 74 |
+
return `${baseVersion}-dev.${date}.t${time}.sha${sha}`
|
| 75 |
+
}
|
| 76 |
+
|
| 77 |
+
function getVersionChangelog(): string {
|
| 78 |
+
return (
|
| 79 |
+
runCommand(['git', 'log', '--format=%h %s', '-20']) ??
|
| 80 |
+
'Local development build'
|
| 81 |
+
)
|
| 82 |
+
}
|
| 83 |
+
|
| 84 |
+
const defaultFeatures = ['VOICE_MODE']
|
| 85 |
+
const featureSet = new Set(defaultFeatures)
|
| 86 |
+
for (let i = 0; i < args.length; i += 1) {
|
| 87 |
+
const arg = args[i]
|
| 88 |
+
if (arg === '--feature-set' && args[i + 1]) {
|
| 89 |
+
if (args[i + 1] === 'dev-full') {
|
| 90 |
+
for (const feature of fullExperimentalFeatures) {
|
| 91 |
+
featureSet.add(feature)
|
| 92 |
+
}
|
| 93 |
+
}
|
| 94 |
+
i += 1
|
| 95 |
+
continue
|
| 96 |
+
}
|
| 97 |
+
if (arg === '--feature-set=dev-full') {
|
| 98 |
+
for (const feature of fullExperimentalFeatures) {
|
| 99 |
+
featureSet.add(feature)
|
| 100 |
+
}
|
| 101 |
+
continue
|
| 102 |
+
}
|
| 103 |
+
if (arg === '--feature' && args[i + 1]) {
|
| 104 |
+
featureSet.add(args[i + 1]!)
|
| 105 |
+
i += 1
|
| 106 |
+
continue
|
| 107 |
+
}
|
| 108 |
+
if (arg.startsWith('--feature=')) {
|
| 109 |
+
featureSet.add(arg.slice('--feature='.length))
|
| 110 |
+
}
|
| 111 |
+
}
|
| 112 |
+
const features = [...featureSet]
|
| 113 |
+
|
| 114 |
+
const outfile = compile
|
| 115 |
+
? dev
|
| 116 |
+
? './dist/cli-dev'
|
| 117 |
+
: './dist/cli'
|
| 118 |
+
: dev
|
| 119 |
+
? './cli-dev'
|
| 120 |
+
: './cli'
|
| 121 |
+
const buildTime = new Date().toISOString()
|
| 122 |
+
const version = dev ? getDevVersion(pkg.version) : pkg.version
|
| 123 |
+
|
| 124 |
+
mkdirSync(dirname(outfile), { recursive: true })
|
| 125 |
+
|
| 126 |
+
const externals = [
|
| 127 |
+
'@ant/*',
|
| 128 |
+
'audio-capture-napi',
|
| 129 |
+
'image-processor-napi',
|
| 130 |
+
'modifiers-napi',
|
| 131 |
+
'url-handler-napi',
|
| 132 |
+
]
|
| 133 |
+
|
| 134 |
+
const defines = {
|
| 135 |
+
'process.env.USER_TYPE': JSON.stringify('external'),
|
| 136 |
+
'process.env.CLAUDE_CODE_FORCE_FULL_LOGO': JSON.stringify('true'),
|
| 137 |
+
...(dev
|
| 138 |
+
? { 'process.env.NODE_ENV': JSON.stringify('development') }
|
| 139 |
+
: {}),
|
| 140 |
+
...(dev
|
| 141 |
+
? {
|
| 142 |
+
'process.env.CLAUDE_CODE_EXPERIMENTAL_BUILD': JSON.stringify('true'),
|
| 143 |
+
}
|
| 144 |
+
: {}),
|
| 145 |
+
'process.env.CLAUDE_CODE_VERIFY_PLAN': JSON.stringify('false'),
|
| 146 |
+
'process.env.CCR_FORCE_BUNDLE': JSON.stringify('true'),
|
| 147 |
+
'MACRO.VERSION': JSON.stringify(version),
|
| 148 |
+
'MACRO.BUILD_TIME': JSON.stringify(buildTime),
|
| 149 |
+
'MACRO.PACKAGE_URL': JSON.stringify(pkg.name),
|
| 150 |
+
'MACRO.NATIVE_PACKAGE_URL': 'undefined',
|
| 151 |
+
'MACRO.FEEDBACK_CHANNEL': JSON.stringify('github'),
|
| 152 |
+
'MACRO.ISSUES_EXPLAINER': JSON.stringify(
|
| 153 |
+
'This reconstructed source snapshot does not include Anthropic internal issue routing.',
|
| 154 |
+
),
|
| 155 |
+
'MACRO.VERSION_CHANGELOG': JSON.stringify(
|
| 156 |
+
dev ? getVersionChangelog() : 'https://github.com/paoloanzn/claude-code',
|
| 157 |
+
),
|
| 158 |
+
} as const
|
| 159 |
+
|
| 160 |
+
const cmd = [
|
| 161 |
+
'bun',
|
| 162 |
+
'build',
|
| 163 |
+
'./src/entrypoints/cli.tsx',
|
| 164 |
+
'--compile',
|
| 165 |
+
'--target',
|
| 166 |
+
'bun',
|
| 167 |
+
'--format',
|
| 168 |
+
'esm',
|
| 169 |
+
'--outfile',
|
| 170 |
+
outfile,
|
| 171 |
+
'--minify',
|
| 172 |
+
'--bytecode',
|
| 173 |
+
'--packages',
|
| 174 |
+
'bundle',
|
| 175 |
+
'--conditions',
|
| 176 |
+
'bun',
|
| 177 |
+
]
|
| 178 |
+
|
| 179 |
+
for (const external of externals) {
|
| 180 |
+
cmd.push('--external', external)
|
| 181 |
+
}
|
| 182 |
+
|
| 183 |
+
for (const feature of features) {
|
| 184 |
+
cmd.push(`--feature=${feature}`)
|
| 185 |
+
}
|
| 186 |
+
|
| 187 |
+
for (const [key, value] of Object.entries(defines)) {
|
| 188 |
+
cmd.push('--define', `${key}=${value}`)
|
| 189 |
+
}
|
| 190 |
+
|
| 191 |
+
const proc = Bun.spawnSync({
|
| 192 |
+
cmd,
|
| 193 |
+
cwd: process.cwd(),
|
| 194 |
+
stdout: 'inherit',
|
| 195 |
+
stderr: 'inherit',
|
| 196 |
+
})
|
| 197 |
+
|
| 198 |
+
if (proc.exitCode !== 0) {
|
| 199 |
+
process.exit(proc.exitCode ?? 1)
|
| 200 |
+
}
|
| 201 |
+
|
| 202 |
+
if (existsSync(outfile)) {
|
| 203 |
+
chmodSync(outfile, 0o755)
|
| 204 |
+
}
|
| 205 |
+
|
| 206 |
+
console.log(`Built ${outfile}`)
|
| 207 |
+
|