📝 feat: update TypeScript configuration and add API support
- Changed root directory in tsconfig.json to include all source files. - Updated server.json to include npm package configuration for claude-code-explorer-mcp. - Enhanced x402 command to support non-interactive mode. - Refactored x402 command call function to simplify argument handling. - Introduced .mcp.json for MCP server configuration. - Added bunfig.toml for Bun development mode configuration. - Created bridge.md documentation for IDE integration and architecture overview. - Added .npmignore to exclude unnecessary files from npm package. - Implemented build-bundle script for production and development builds. - Developed bun-plugin-shims for Bun preload plugin. - Created ci-build.sh for CI/CD build pipeline. - Added dev.ts for development launcher using Bun's TS runtime. - Implemented package-npm.ts to generate a publishable npm package. - Created test-auth.ts to verify API key configuration. - Developed test-mcp.ts for MCP client/server roundtrip testing. - Implemented test-services.ts to ensure all services initialize correctly. - Added stub.ts for bridge functionality when BRIDGE_MODE is disabled.
This commit is contained in:
138
scripts/build-bundle.ts
Normal file
138
scripts/build-bundle.ts
Normal file
@@ -0,0 +1,138 @@
|
||||
// scripts/build-bundle.ts
|
||||
// Usage: bun scripts/build-bundle.ts [--watch] [--minify] [--no-sourcemap]
|
||||
//
|
||||
// Production build: bun scripts/build-bundle.ts --minify
|
||||
// Dev build: bun scripts/build-bundle.ts
|
||||
// Watch mode: bun scripts/build-bundle.ts --watch
|
||||
|
||||
import * as esbuild from 'esbuild'
|
||||
import { resolve } from 'path'
|
||||
import { chmodSync, readFileSync } from 'fs'
|
||||
|
||||
const ROOT = resolve(import.meta.dir, '..')
|
||||
const watch = process.argv.includes('--watch')
|
||||
const minify = process.argv.includes('--minify')
|
||||
const noSourcemap = process.argv.includes('--no-sourcemap')
|
||||
|
||||
// Read version from package.json for MACRO injection
|
||||
const pkg = JSON.parse(readFileSync(resolve(ROOT, 'package.json'), 'utf-8'))
|
||||
const version = pkg.version || '0.0.0-dev'
|
||||
|
||||
const buildOptions: esbuild.BuildOptions = {
|
||||
entryPoints: [resolve(ROOT, 'src/entrypoints/cli.tsx')],
|
||||
bundle: true,
|
||||
platform: 'node',
|
||||
target: ['node20', 'es2022'],
|
||||
format: 'esm',
|
||||
outdir: resolve(ROOT, 'dist'),
|
||||
outExtension: { '.js': '.mjs' },
|
||||
|
||||
// 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')],
|
||||
|
||||
// Alias bun:bundle to our runtime shim
|
||||
alias: {
|
||||
'bun:bundle': resolve(ROOT, 'src/shims/bun-bundle.ts'),
|
||||
},
|
||||
|
||||
// Don't bundle node built-ins or problematic native packages
|
||||
external: [
|
||||
// Node built-ins (with and without node: prefix)
|
||||
'fs', 'path', 'os', 'crypto', 'child_process', 'http', 'https',
|
||||
'net', 'tls', 'url', 'util', 'stream', 'events', 'buffer',
|
||||
'querystring', 'readline', 'zlib', 'assert', 'tty', 'worker_threads',
|
||||
'perf_hooks', 'async_hooks', 'dns', 'dgram', 'cluster',
|
||||
'string_decoder', 'module', 'vm', 'constants', 'domain',
|
||||
'console', 'process', 'v8', 'inspector',
|
||||
'node:*',
|
||||
// Native addons that can't be bundled
|
||||
'fsevents',
|
||||
],
|
||||
|
||||
jsx: 'automatic',
|
||||
|
||||
// Source maps for production debugging (external .map files)
|
||||
sourcemap: noSourcemap ? false : 'external',
|
||||
|
||||
// Minification for production
|
||||
minify,
|
||||
|
||||
// Tree shaking (on by default, explicit for clarity)
|
||||
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
|
||||
define: {
|
||||
'process.env.USER_TYPE': '"external"',
|
||||
'process.env.NODE_ENV': minify ? '"production"' : '"development"',
|
||||
},
|
||||
|
||||
// Banner: shebang for direct CLI execution
|
||||
banner: {
|
||||
js: '#!/usr/bin/env node\n',
|
||||
},
|
||||
|
||||
// Handle the .js → .ts resolution that the codebase uses
|
||||
resolveExtensions: ['.tsx', '.ts', '.jsx', '.js', '.json'],
|
||||
|
||||
logLevel: 'info',
|
||||
|
||||
// Metafile for bundle analysis
|
||||
metafile: true,
|
||||
}
|
||||
|
||||
async function main() {
|
||||
if (watch) {
|
||||
const ctx = await esbuild.context(buildOptions)
|
||||
await ctx.watch()
|
||||
console.log('Watching for changes...')
|
||||
} else {
|
||||
const startTime = Date.now()
|
||||
const result = await esbuild.build(buildOptions)
|
||||
|
||||
if (result.errors.length > 0) {
|
||||
console.error('Build failed')
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
// Make the output executable
|
||||
const outPath = resolve(ROOT, 'dist/cli.mjs')
|
||||
try {
|
||||
chmodSync(outPath, 0o755)
|
||||
} catch {
|
||||
// chmod may fail on some platforms, non-fatal
|
||||
}
|
||||
|
||||
const elapsed = Date.now() - startTime
|
||||
|
||||
// Print bundle size info
|
||||
if (result.metafile) {
|
||||
const text = await esbuild.analyzeMetafile(result.metafile, { verbose: false })
|
||||
const outFiles = Object.entries(result.metafile.outputs)
|
||||
for (const [file, info] of outFiles) {
|
||||
if (file.endsWith('.mjs')) {
|
||||
const sizeMB = (info.bytes / 1024 / 1024).toFixed(2)
|
||||
console.log(`\n ${file}: ${sizeMB} MB`)
|
||||
}
|
||||
}
|
||||
console.log(`\nBuild complete in ${elapsed}ms → dist/`)
|
||||
|
||||
// Write metafile for further analysis
|
||||
const { writeFileSync } = await import('fs')
|
||||
writeFileSync(
|
||||
resolve(ROOT, 'dist/meta.json'),
|
||||
JSON.stringify(result.metafile),
|
||||
)
|
||||
console.log(' Metafile written to dist/meta.json')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
main().catch(err => {
|
||||
console.error(err)
|
||||
process.exit(1)
|
||||
})
|
||||
Reference in New Issue
Block a user