|
| 1 | +# Quick Start — Building from Source |
| 2 | + |
| 3 | +> **TL;DR**: A full rebuild requires **Bun** (not Node.js) for its compile-time |
| 4 | +> intrinsics (`feature()`, `MACRO`, `bun:bundle`). A best-effort build with |
| 5 | +> esbuild gets ~95% there but needs manual fixes for ~108 feature-gated modules. |
| 6 | +
|
| 7 | +## Option A: Run the pre-built CLI (Recommended) |
| 8 | + |
| 9 | +The npm package already contains a compiled `cli.js`: |
| 10 | + |
| 11 | +```bash |
| 12 | +cd /path/to/parent/ # where package.json and cli.js live |
| 13 | +node cli.js --version # → 2.1.88 (Claude Code) |
| 14 | +node cli.js -p "Hello Claude" # Non-interactive mode |
| 15 | + |
| 16 | +# Or install globally: |
| 17 | +npm install -g . |
| 18 | +claude --version |
| 19 | +``` |
| 20 | + |
| 21 | +**Authentication required**: Set `ANTROPIC_API_KEY` or run `node cli.js login`. |
| 22 | + |
| 23 | +## Option B: Build from Source (Best Effort) |
| 24 | + |
| 25 | +### Prerequisites |
| 26 | + |
| 27 | +```bash |
| 28 | +node --version # >= 18 |
| 29 | +npm --version # >= 9 |
| 30 | +``` |
| 31 | + |
| 32 | +### Steps |
| 33 | + |
| 34 | +```bash |
| 35 | +cd claude-code-2.1.88/ |
| 36 | + |
| 37 | +# 1. Install build dependency |
| 38 | +npm install --save-dev esbuild |
| 39 | + |
| 40 | +# 2. Run the build script |
| 41 | +node scripts/build.mjs |
| 42 | + |
| 43 | +# 3. If successful, run the output: |
| 44 | +node dist/cli.js --version |
| 45 | +``` |
| 46 | + |
| 47 | +### What the Build Script Does |
| 48 | + |
| 49 | +| Phase | Action | |
| 50 | +|-------|--------| |
| 51 | +| **1. Copy** | `src/` → `build-src/` (original untouched) | |
| 52 | +| **2. Transform** | `feature('X')` → `false` (enables dead code elimination) | |
| 53 | +| **2b. Transform** | `MACRO.VERSION` → `'2.1.88'` (compile-time version injection) | |
| 54 | +| **2c. Transform** | `import from 'bun:bundle'` → stub import | |
| 55 | +| **3. Entry** | Create wrapper that injects MACRO globals | |
| 56 | +| **4. Bundle** | esbuild with iterative stub creation for missing modules | |
| 57 | + |
| 58 | +### Known Issues |
| 59 | + |
| 60 | +The source code uses **Bun compile-time intrinsics** that cannot be fully replicated with esbuild: |
| 61 | + |
| 62 | +1. **`feature('FLAG')` from `bun:bundle`** — Bun resolves this at compile time to `true`/`false` and eliminates dead branches. Our transform replaces with `false`, but esbuild still resolves `require()` inside those branches. |
| 63 | + |
| 64 | +2. **`MACRO.X`** — Bun's `--define` replaces these at compile time. We use string replacement, which works for most cases but can miss edge cases in complex expressions. |
| 65 | + |
| 66 | +3. **108 missing modules** — These are feature-gated internal modules (daemon, bridge assistant, context collapse, etc.) that don't exist in the published source. They're normally dead-code-eliminated by Bun but esbuild can't eliminate them because the `require()` calls are still syntactically present. |
| 67 | + |
| 68 | +4. **`bun:ffi`** — Used for native proxy support. Stubbed out. |
| 69 | + |
| 70 | +5. **TypeScript `import type` from generated files** — Some generated type files are not in the published source. |
| 71 | + |
| 72 | +### To Fix Remaining Issues |
| 73 | + |
| 74 | +```bash |
| 75 | +# 1. Check what's still missing: |
| 76 | +npx esbuild build-src/entry.ts --bundle --platform=node \ |
| 77 | + --packages=external --external:'bun:*' \ |
| 78 | + --log-level=error --log-limit=0 --outfile=/dev/null 2>&1 | \ |
| 79 | + grep "Could not resolve" | sort -u |
| 80 | + |
| 81 | +# 2. Create stubs for each missing module in build-src/src/: |
| 82 | +# For JS/TS: create file exporting empty functions |
| 83 | +# For text: create empty file |
| 84 | + |
| 85 | +# 3. Re-run: |
| 86 | +node scripts/build.mjs |
| 87 | +``` |
| 88 | + |
| 89 | +## Option C: Build with Bun (Full Rebuild — Requires Internal Access) |
| 90 | + |
| 91 | +```bash |
| 92 | +# Install Bun |
| 93 | +curl -fsSL https://bun.sh/install | bash |
| 94 | + |
| 95 | +# The real build uses Bun's bundler with compile-time feature flags: |
| 96 | +# bun build src/entrypoints/cli.tsx \ |
| 97 | +# --define:feature='(flag) => flag === "SOME_FLAG"' \ |
| 98 | +# --define:MACRO.VERSION='"2.1.88"' \ |
| 99 | +# --target=bun \ |
| 100 | +# --outfile=dist/cli.js |
| 101 | + |
| 102 | +# However, the internal build configuration is not included in the |
| 103 | +# published package. You'd need access to Anthropic's internal repo. |
| 104 | +``` |
| 105 | + |
| 106 | +## Project Structure |
| 107 | + |
| 108 | +``` |
| 109 | +claude-code-2.1.88/ |
| 110 | +├── src/ # Original TypeScript source (1,884 files, 512K LOC) |
| 111 | +├── stubs/ # Build stubs for Bun compile-time intrinsics |
| 112 | +│ ├── bun-bundle.ts # feature() stub → always returns false |
| 113 | +│ ├── macros.ts # MACRO version constants |
| 114 | +│ └── global.d.ts # Global type declarations |
| 115 | +├── scripts/ |
| 116 | +│ └── build.mjs # Build script (esbuild-based) |
| 117 | +├── node_modules/ # 192 npm dependencies |
| 118 | +├── vendor/ # Native module source stubs |
| 119 | +├── build-src/ # Created by build script (transformed copy) |
| 120 | +└── dist/ # Build output (created by build script) |
| 121 | +``` |
0 commit comments