mirror of
https://github.com/sanbuphy/claude-code-source-code.git
synced 2026-04-03 11:34:54 +08:00
Add build infrastructure and QUICKSTART guide
- Build script (scripts/build.mjs) using esbuild with iterative stub creation - Stubs for Bun compile-time intrinsics (feature(), MACRO, bun:bundle) - Stub modules for feature-gated internal code paths - QUICKSTART.md with 3 build options (pre-built, esbuild, Bun) - tsconfig.json, package.json for build tooling Build reaches ~95% — 108 remaining feature-gated modules need Bun runtime for full dead code elimination. See QUICKSTART.md for details. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1 +1,3 @@
|
|||||||
node_modules/
|
node_modules/
|
||||||
|
build-src/
|
||||||
|
dist/
|
||||||
|
|||||||
121
QUICKSTART.md
Normal file
121
QUICKSTART.md
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
# Quick Start — Building from Source
|
||||||
|
|
||||||
|
> **TL;DR**: A full rebuild requires **Bun** (not Node.js) for its compile-time
|
||||||
|
> intrinsics (`feature()`, `MACRO`, `bun:bundle`). A best-effort build with
|
||||||
|
> esbuild gets ~95% there but needs manual fixes for ~108 feature-gated modules.
|
||||||
|
|
||||||
|
## Option A: Run the pre-built CLI (Recommended)
|
||||||
|
|
||||||
|
The npm package already contains a compiled `cli.js`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /path/to/parent/ # where package.json and cli.js live
|
||||||
|
node cli.js --version # → 2.1.88 (Claude Code)
|
||||||
|
node cli.js -p "Hello Claude" # Non-interactive mode
|
||||||
|
|
||||||
|
# Or install globally:
|
||||||
|
npm install -g .
|
||||||
|
claude --version
|
||||||
|
```
|
||||||
|
|
||||||
|
**Authentication required**: Set `ANTROPIC_API_KEY` or run `node cli.js login`.
|
||||||
|
|
||||||
|
## Option B: Build from Source (Best Effort)
|
||||||
|
|
||||||
|
### Prerequisites
|
||||||
|
|
||||||
|
```bash
|
||||||
|
node --version # >= 18
|
||||||
|
npm --version # >= 9
|
||||||
|
```
|
||||||
|
|
||||||
|
### Steps
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd claude-code-2.1.88/
|
||||||
|
|
||||||
|
# 1. Install build dependency
|
||||||
|
npm install --save-dev esbuild
|
||||||
|
|
||||||
|
# 2. Run the build script
|
||||||
|
node scripts/build.mjs
|
||||||
|
|
||||||
|
# 3. If successful, run the output:
|
||||||
|
node dist/cli.js --version
|
||||||
|
```
|
||||||
|
|
||||||
|
### What the Build Script Does
|
||||||
|
|
||||||
|
| Phase | Action |
|
||||||
|
|-------|--------|
|
||||||
|
| **1. Copy** | `src/` → `build-src/` (original untouched) |
|
||||||
|
| **2. Transform** | `feature('X')` → `false` (enables dead code elimination) |
|
||||||
|
| **2b. Transform** | `MACRO.VERSION` → `'2.1.88'` (compile-time version injection) |
|
||||||
|
| **2c. Transform** | `import from 'bun:bundle'` → stub import |
|
||||||
|
| **3. Entry** | Create wrapper that injects MACRO globals |
|
||||||
|
| **4. Bundle** | esbuild with iterative stub creation for missing modules |
|
||||||
|
|
||||||
|
### Known Issues
|
||||||
|
|
||||||
|
The source code uses **Bun compile-time intrinsics** that cannot be fully replicated with esbuild:
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
4. **`bun:ffi`** — Used for native proxy support. Stubbed out.
|
||||||
|
|
||||||
|
5. **TypeScript `import type` from generated files** — Some generated type files are not in the published source.
|
||||||
|
|
||||||
|
### To Fix Remaining Issues
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Check what's still missing:
|
||||||
|
npx esbuild build-src/entry.ts --bundle --platform=node \
|
||||||
|
--packages=external --external:'bun:*' \
|
||||||
|
--log-level=error --log-limit=0 --outfile=/dev/null 2>&1 | \
|
||||||
|
grep "Could not resolve" | sort -u
|
||||||
|
|
||||||
|
# 2. Create stubs for each missing module in build-src/src/:
|
||||||
|
# For JS/TS: create file exporting empty functions
|
||||||
|
# For text: create empty file
|
||||||
|
|
||||||
|
# 3. Re-run:
|
||||||
|
node scripts/build.mjs
|
||||||
|
```
|
||||||
|
|
||||||
|
## Option C: Build with Bun (Full Rebuild — Requires Internal Access)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Install Bun
|
||||||
|
curl -fsSL https://bun.sh/install | bash
|
||||||
|
|
||||||
|
# The real build uses Bun's bundler with compile-time feature flags:
|
||||||
|
# bun build src/entrypoints/cli.tsx \
|
||||||
|
# --define:feature='(flag) => flag === "SOME_FLAG"' \
|
||||||
|
# --define:MACRO.VERSION='"2.1.88"' \
|
||||||
|
# --target=bun \
|
||||||
|
# --outfile=dist/cli.js
|
||||||
|
|
||||||
|
# However, the internal build configuration is not included in the
|
||||||
|
# published package. You'd need access to Anthropic's internal repo.
|
||||||
|
```
|
||||||
|
|
||||||
|
## Project Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
claude-code-2.1.88/
|
||||||
|
├── src/ # Original TypeScript source (1,884 files, 512K LOC)
|
||||||
|
├── stubs/ # Build stubs for Bun compile-time intrinsics
|
||||||
|
│ ├── bun-bundle.ts # feature() stub → always returns false
|
||||||
|
│ ├── macros.ts # MACRO version constants
|
||||||
|
│ └── global.d.ts # Global type declarations
|
||||||
|
├── scripts/
|
||||||
|
│ └── build.mjs # Build script (esbuild-based)
|
||||||
|
├── node_modules/ # 192 npm dependencies
|
||||||
|
├── vendor/ # Native module source stubs
|
||||||
|
├── build-src/ # Created by build script (transformed copy)
|
||||||
|
└── dist/ # Build output (created by build script)
|
||||||
|
```
|
||||||
@@ -745,6 +745,8 @@ This source is **not directly compilable** from this repo alone:
|
|||||||
- The compiled `cli.js` is a self-contained 12MB bundle requiring only Node.js >= 18
|
- The compiled `cli.js` is a self-contained 12MB bundle requiring only Node.js >= 18
|
||||||
- Source maps (`cli.js.map`, 60MB) map back to these source files for debugging
|
- Source maps (`cli.js.map`, 60MB) map back to these source files for debugging
|
||||||
|
|
||||||
|
**See [QUICKSTART.md](QUICKSTART.md) for build instructions and workarounds.**
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|||||||
517
package-lock.json
generated
Normal file
517
package-lock.json
generated
Normal file
@@ -0,0 +1,517 @@
|
|||||||
|
{
|
||||||
|
"name": "@anthropic-ai/claude-code-source",
|
||||||
|
"version": "2.1.88",
|
||||||
|
"lockfileVersion": 3,
|
||||||
|
"requires": true,
|
||||||
|
"packages": {
|
||||||
|
"": {
|
||||||
|
"name": "@anthropic-ai/claude-code-source",
|
||||||
|
"version": "2.1.88",
|
||||||
|
"devDependencies": {
|
||||||
|
"esbuild": "^0.27.4",
|
||||||
|
"typescript": "^6.0.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/aix-ppc64": {
|
||||||
|
"version": "0.27.4",
|
||||||
|
"resolved": "https://registry.npmmirror.com/@esbuild/aix-ppc64/-/aix-ppc64-0.27.4.tgz",
|
||||||
|
"integrity": "sha512-cQPwL2mp2nSmHHJlCyoXgHGhbEPMrEEU5xhkcy3Hs/O7nGZqEpZ2sUtLaL9MORLtDfRvVl2/3PAuEkYZH0Ty8Q==",
|
||||||
|
"cpu": [
|
||||||
|
"ppc64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"aix"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/android-arm": {
|
||||||
|
"version": "0.27.4",
|
||||||
|
"resolved": "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.27.4.tgz",
|
||||||
|
"integrity": "sha512-X9bUgvxiC8CHAGKYufLIHGXPJWnr0OCdR0anD2e21vdvgCI8lIfqFbnoeOz7lBjdrAGUhqLZLcQo6MLhTO2DKQ==",
|
||||||
|
"cpu": [
|
||||||
|
"arm"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"android"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/android-arm64": {
|
||||||
|
"version": "0.27.4",
|
||||||
|
"resolved": "https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.27.4.tgz",
|
||||||
|
"integrity": "sha512-gdLscB7v75wRfu7QSm/zg6Rx29VLdy9eTr2t44sfTW7CxwAtQghZ4ZnqHk3/ogz7xao0QAgrkradbBzcqFPasw==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"android"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/android-x64": {
|
||||||
|
"version": "0.27.4",
|
||||||
|
"resolved": "https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.27.4.tgz",
|
||||||
|
"integrity": "sha512-PzPFnBNVF292sfpfhiyiXCGSn9HZg5BcAz+ivBuSsl6Rk4ga1oEXAamhOXRFyMcjwr2DVtm40G65N3GLeH1Lvw==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"android"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/darwin-arm64": {
|
||||||
|
"version": "0.27.4",
|
||||||
|
"resolved": "https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.27.4.tgz",
|
||||||
|
"integrity": "sha512-b7xaGIwdJlht8ZFCvMkpDN6uiSmnxxK56N2GDTMYPr2/gzvfdQN8rTfBsvVKmIVY/X7EM+/hJKEIbbHs9oA4tQ==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"darwin"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/darwin-x64": {
|
||||||
|
"version": "0.27.4",
|
||||||
|
"resolved": "https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.27.4.tgz",
|
||||||
|
"integrity": "sha512-sR+OiKLwd15nmCdqpXMnuJ9W2kpy0KigzqScqHI3Hqwr7IXxBp3Yva+yJwoqh7rE8V77tdoheRYataNKL4QrPw==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"darwin"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/freebsd-arm64": {
|
||||||
|
"version": "0.27.4",
|
||||||
|
"resolved": "https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.4.tgz",
|
||||||
|
"integrity": "sha512-jnfpKe+p79tCnm4GVav68A7tUFeKQwQyLgESwEAUzyxk/TJr4QdGog9sqWNcUbr/bZt/O/HXouspuQDd9JxFSw==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"freebsd"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/freebsd-x64": {
|
||||||
|
"version": "0.27.4",
|
||||||
|
"resolved": "https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.27.4.tgz",
|
||||||
|
"integrity": "sha512-2kb4ceA/CpfUrIcTUl1wrP/9ad9Atrp5J94Lq69w7UwOMolPIGrfLSvAKJp0RTvkPPyn6CIWrNy13kyLikZRZQ==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"freebsd"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/linux-arm": {
|
||||||
|
"version": "0.27.4",
|
||||||
|
"resolved": "https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.27.4.tgz",
|
||||||
|
"integrity": "sha512-aBYgcIxX/wd5n2ys0yESGeYMGF+pv6g0DhZr3G1ZG4jMfruU9Tl1i2Z+Wnj9/KjGz1lTLCcorqE2viePZqj4Eg==",
|
||||||
|
"cpu": [
|
||||||
|
"arm"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/linux-arm64": {
|
||||||
|
"version": "0.27.4",
|
||||||
|
"resolved": "https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.27.4.tgz",
|
||||||
|
"integrity": "sha512-7nQOttdzVGth1iz57kxg9uCz57dxQLHWxopL6mYuYthohPKEK0vU0C3O21CcBK6KDlkYVcnDXY099HcCDXd9dA==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/linux-ia32": {
|
||||||
|
"version": "0.27.4",
|
||||||
|
"resolved": "https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.27.4.tgz",
|
||||||
|
"integrity": "sha512-oPtixtAIzgvzYcKBQM/qZ3R+9TEUd1aNJQu0HhGyqtx6oS7qTpvjheIWBbes4+qu1bNlo2V4cbkISr8q6gRBFA==",
|
||||||
|
"cpu": [
|
||||||
|
"ia32"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/linux-loong64": {
|
||||||
|
"version": "0.27.4",
|
||||||
|
"resolved": "https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.27.4.tgz",
|
||||||
|
"integrity": "sha512-8mL/vh8qeCoRcFH2nM8wm5uJP+ZcVYGGayMavi8GmRJjuI3g1v6Z7Ni0JJKAJW+m0EtUuARb6Lmp4hMjzCBWzA==",
|
||||||
|
"cpu": [
|
||||||
|
"loong64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/linux-mips64el": {
|
||||||
|
"version": "0.27.4",
|
||||||
|
"resolved": "https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.27.4.tgz",
|
||||||
|
"integrity": "sha512-1RdrWFFiiLIW7LQq9Q2NES+HiD4NyT8Itj9AUeCl0IVCA459WnPhREKgwrpaIfTOe+/2rdntisegiPWn/r/aAw==",
|
||||||
|
"cpu": [
|
||||||
|
"mips64el"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/linux-ppc64": {
|
||||||
|
"version": "0.27.4",
|
||||||
|
"resolved": "https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.27.4.tgz",
|
||||||
|
"integrity": "sha512-tLCwNG47l3sd9lpfyx9LAGEGItCUeRCWeAx6x2Jmbav65nAwoPXfewtAdtbtit/pJFLUWOhpv0FpS6GQAmPrHA==",
|
||||||
|
"cpu": [
|
||||||
|
"ppc64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/linux-riscv64": {
|
||||||
|
"version": "0.27.4",
|
||||||
|
"resolved": "https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.27.4.tgz",
|
||||||
|
"integrity": "sha512-BnASypppbUWyqjd1KIpU4AUBiIhVr6YlHx/cnPgqEkNoVOhHg+YiSVxM1RLfiy4t9cAulbRGTNCKOcqHrEQLIw==",
|
||||||
|
"cpu": [
|
||||||
|
"riscv64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/linux-s390x": {
|
||||||
|
"version": "0.27.4",
|
||||||
|
"resolved": "https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.27.4.tgz",
|
||||||
|
"integrity": "sha512-+eUqgb/Z7vxVLezG8bVB9SfBie89gMueS+I0xYh2tJdw3vqA/0ImZJ2ROeWwVJN59ihBeZ7Tu92dF/5dy5FttA==",
|
||||||
|
"cpu": [
|
||||||
|
"s390x"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/linux-x64": {
|
||||||
|
"version": "0.27.4",
|
||||||
|
"resolved": "https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.27.4.tgz",
|
||||||
|
"integrity": "sha512-S5qOXrKV8BQEzJPVxAwnryi2+Iq5pB40gTEIT69BQONqR7JH1EPIcQ/Uiv9mCnn05jff9umq/5nqzxlqTOg9NA==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/netbsd-arm64": {
|
||||||
|
"version": "0.27.4",
|
||||||
|
"resolved": "https://registry.npmmirror.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.4.tgz",
|
||||||
|
"integrity": "sha512-xHT8X4sb0GS8qTqiwzHqpY00C95DPAq7nAwX35Ie/s+LO9830hrMd3oX0ZMKLvy7vsonee73x0lmcdOVXFzd6Q==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"netbsd"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/netbsd-x64": {
|
||||||
|
"version": "0.27.4",
|
||||||
|
"resolved": "https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.27.4.tgz",
|
||||||
|
"integrity": "sha512-RugOvOdXfdyi5Tyv40kgQnI0byv66BFgAqjdgtAKqHoZTbTF2QqfQrFwa7cHEORJf6X2ht+l9ABLMP0dnKYsgg==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"netbsd"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/openbsd-arm64": {
|
||||||
|
"version": "0.27.4",
|
||||||
|
"resolved": "https://registry.npmmirror.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.4.tgz",
|
||||||
|
"integrity": "sha512-2MyL3IAaTX+1/qP0O1SwskwcwCoOI4kV2IBX1xYnDDqthmq5ArrW94qSIKCAuRraMgPOmG0RDTA74mzYNQA9ow==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"openbsd"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/openbsd-x64": {
|
||||||
|
"version": "0.27.4",
|
||||||
|
"resolved": "https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.27.4.tgz",
|
||||||
|
"integrity": "sha512-u8fg/jQ5aQDfsnIV6+KwLOf1CmJnfu1ShpwqdwC0uA7ZPwFws55Ngc12vBdeUdnuWoQYx/SOQLGDcdlfXhYmXQ==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"openbsd"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/openharmony-arm64": {
|
||||||
|
"version": "0.27.4",
|
||||||
|
"resolved": "https://registry.npmmirror.com/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.4.tgz",
|
||||||
|
"integrity": "sha512-JkTZrl6VbyO8lDQO3yv26nNr2RM2yZzNrNHEsj9bm6dOwwu9OYN28CjzZkH57bh4w0I2F7IodpQvUAEd1mbWXg==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"openharmony"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/sunos-x64": {
|
||||||
|
"version": "0.27.4",
|
||||||
|
"resolved": "https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.27.4.tgz",
|
||||||
|
"integrity": "sha512-/gOzgaewZJfeJTlsWhvUEmUG4tWEY2Spp5M20INYRg2ZKl9QPO3QEEgPeRtLjEWSW8FilRNacPOg8R1uaYkA6g==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"sunos"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/win32-arm64": {
|
||||||
|
"version": "0.27.4",
|
||||||
|
"resolved": "https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.27.4.tgz",
|
||||||
|
"integrity": "sha512-Z9SExBg2y32smoDQdf1HRwHRt6vAHLXcxD2uGgO/v2jK7Y718Ix4ndsbNMU/+1Qiem9OiOdaqitioZwxivhXYg==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"win32"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/win32-ia32": {
|
||||||
|
"version": "0.27.4",
|
||||||
|
"resolved": "https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.27.4.tgz",
|
||||||
|
"integrity": "sha512-DAyGLS0Jz5G5iixEbMHi5KdiApqHBWMGzTtMiJ72ZOLhbu/bzxgAe8Ue8CTS3n3HbIUHQz/L51yMdGMeoxXNJw==",
|
||||||
|
"cpu": [
|
||||||
|
"ia32"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"win32"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/win32-x64": {
|
||||||
|
"version": "0.27.4",
|
||||||
|
"resolved": "https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.27.4.tgz",
|
||||||
|
"integrity": "sha512-+knoa0BDoeXgkNvvV1vvbZX4+hizelrkwmGJBdT17t8FNPwG2lKemmuMZlmaNQ3ws3DKKCxpb4zRZEIp3UxFCg==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"win32"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/esbuild": {
|
||||||
|
"version": "0.27.4",
|
||||||
|
"resolved": "https://registry.npmmirror.com/esbuild/-/esbuild-0.27.4.tgz",
|
||||||
|
"integrity": "sha512-Rq4vbHnYkK5fws5NF7MYTU68FPRE1ajX7heQ/8QXXWqNgqqJ/GkmmyxIzUnf2Sr/bakf8l54716CcMGHYhMrrQ==",
|
||||||
|
"dev": true,
|
||||||
|
"hasInstallScript": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"bin": {
|
||||||
|
"esbuild": "bin/esbuild"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
},
|
||||||
|
"optionalDependencies": {
|
||||||
|
"@esbuild/aix-ppc64": "0.27.4",
|
||||||
|
"@esbuild/android-arm": "0.27.4",
|
||||||
|
"@esbuild/android-arm64": "0.27.4",
|
||||||
|
"@esbuild/android-x64": "0.27.4",
|
||||||
|
"@esbuild/darwin-arm64": "0.27.4",
|
||||||
|
"@esbuild/darwin-x64": "0.27.4",
|
||||||
|
"@esbuild/freebsd-arm64": "0.27.4",
|
||||||
|
"@esbuild/freebsd-x64": "0.27.4",
|
||||||
|
"@esbuild/linux-arm": "0.27.4",
|
||||||
|
"@esbuild/linux-arm64": "0.27.4",
|
||||||
|
"@esbuild/linux-ia32": "0.27.4",
|
||||||
|
"@esbuild/linux-loong64": "0.27.4",
|
||||||
|
"@esbuild/linux-mips64el": "0.27.4",
|
||||||
|
"@esbuild/linux-ppc64": "0.27.4",
|
||||||
|
"@esbuild/linux-riscv64": "0.27.4",
|
||||||
|
"@esbuild/linux-s390x": "0.27.4",
|
||||||
|
"@esbuild/linux-x64": "0.27.4",
|
||||||
|
"@esbuild/netbsd-arm64": "0.27.4",
|
||||||
|
"@esbuild/netbsd-x64": "0.27.4",
|
||||||
|
"@esbuild/openbsd-arm64": "0.27.4",
|
||||||
|
"@esbuild/openbsd-x64": "0.27.4",
|
||||||
|
"@esbuild/openharmony-arm64": "0.27.4",
|
||||||
|
"@esbuild/sunos-x64": "0.27.4",
|
||||||
|
"@esbuild/win32-arm64": "0.27.4",
|
||||||
|
"@esbuild/win32-ia32": "0.27.4",
|
||||||
|
"@esbuild/win32-x64": "0.27.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/typescript": {
|
||||||
|
"version": "6.0.2",
|
||||||
|
"resolved": "https://registry.npmmirror.com/typescript/-/typescript-6.0.2.tgz",
|
||||||
|
"integrity": "sha512-bGdAIrZ0wiGDo5l8c++HWtbaNCWTS4UTv7RaTH/ThVIgjkveJt83m74bBHMJkuCbslY8ixgLBVZJIOiQlQTjfQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"bin": {
|
||||||
|
"tsc": "bin/tsc",
|
||||||
|
"tsserver": "bin/tsserver"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14.17"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
20
package.json
Normal file
20
package.json
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"name": "@anthropic-ai/claude-code-source",
|
||||||
|
"version": "2.1.88",
|
||||||
|
"description": "Claude Code v2.1.88 — decompiled source for research",
|
||||||
|
"type": "module",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"prepare-src": "node scripts/prepare-src.mjs",
|
||||||
|
"build": "npm run prepare-src && node scripts/build.mjs",
|
||||||
|
"check": "npm run prepare-src && tsc --noEmit",
|
||||||
|
"start": "node dist/cli.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18.0.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"esbuild": "^0.27.4",
|
||||||
|
"typescript": "^6.0.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
245
scripts/build.mjs
Normal file
245
scripts/build.mjs
Normal file
@@ -0,0 +1,245 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
/**
|
||||||
|
* build.mjs — Best-effort build of Claude Code v2.1.88 from source
|
||||||
|
*
|
||||||
|
* ⚠️ IMPORTANT: A complete rebuild requires the Bun runtime's compile-time
|
||||||
|
* intrinsics (feature(), MACRO, bun:bundle). This script provides a
|
||||||
|
* best-effort build using esbuild. See KNOWN_ISSUES.md for details.
|
||||||
|
*
|
||||||
|
* What this script does:
|
||||||
|
* 1. Copy src/ → build-src/ (original untouched)
|
||||||
|
* 2. Replace `feature('X')` → `false` (compile-time → runtime)
|
||||||
|
* 3. Replace `MACRO.VERSION` etc → string literals
|
||||||
|
* 4. Replace `import from 'bun:bundle'` → stub
|
||||||
|
* 5. Create stubs for missing feature-gated modules
|
||||||
|
* 6. Bundle with esbuild → dist/cli.js
|
||||||
|
*
|
||||||
|
* Requirements: Node.js >= 18, npm
|
||||||
|
* Usage: node scripts/build.mjs
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { readdir, readFile, writeFile, mkdir, cp, rm, stat } from 'node:fs/promises'
|
||||||
|
import { join, dirname } from 'node:path'
|
||||||
|
import { execSync } from 'node:child_process'
|
||||||
|
import { fileURLToPath } from 'node:url'
|
||||||
|
|
||||||
|
const __dirname = dirname(fileURLToPath(import.meta.url))
|
||||||
|
const ROOT = join(__dirname, '..')
|
||||||
|
const VERSION = '2.1.88'
|
||||||
|
const BUILD = join(ROOT, 'build-src')
|
||||||
|
const ENTRY = join(BUILD, 'entry.ts')
|
||||||
|
|
||||||
|
// ── Helpers ────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
async function* walk(dir) {
|
||||||
|
for (const e of await readdir(dir, { withFileTypes: true })) {
|
||||||
|
const p = join(dir, e.name)
|
||||||
|
if (e.isDirectory() && e.name !== 'node_modules') yield* walk(p)
|
||||||
|
else yield p
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function exists(p) { try { await stat(p); return true } catch { return false } }
|
||||||
|
|
||||||
|
async function ensureEsbuild() {
|
||||||
|
try { execSync('npx esbuild --version', { stdio: 'pipe' }) }
|
||||||
|
catch {
|
||||||
|
console.log('📦 Installing esbuild...')
|
||||||
|
execSync('npm install --save-dev esbuild', { cwd: ROOT, stdio: 'inherit' })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ══════════════════════════════════════════════════════════════════════════════
|
||||||
|
// PHASE 1: Copy source
|
||||||
|
// ══════════════════════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
|
await rm(BUILD, { recursive: true, force: true })
|
||||||
|
await mkdir(BUILD, { recursive: true })
|
||||||
|
await cp(join(ROOT, 'src'), join(BUILD, 'src'), { recursive: true })
|
||||||
|
console.log('✅ Phase 1: Copied src/ → build-src/')
|
||||||
|
|
||||||
|
// ══════════════════════════════════════════════════════════════════════════════
|
||||||
|
// PHASE 2: Transform source
|
||||||
|
// ══════════════════════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
|
let transformCount = 0
|
||||||
|
|
||||||
|
// MACRO replacements
|
||||||
|
const MACROS = {
|
||||||
|
'MACRO.VERSION': `'${VERSION}'`,
|
||||||
|
'MACRO.BUILD_TIME': `''`,
|
||||||
|
'MACRO.FEEDBACK_CHANNEL': `'https://github.com/anthropics/claude-code/issues'`,
|
||||||
|
'MACRO.ISSUES_EXPLAINER': `'https://github.com/anthropics/claude-code/issues/new/choose'`,
|
||||||
|
'MACRO.FEEDBACK_CHANNEL_URL': `'https://github.com/anthropics/claude-code/issues'`,
|
||||||
|
'MACRO.ISSUES_EXPLAINER_URL': `'https://github.com/anthropics/claude-code/issues/new/choose'`,
|
||||||
|
'MACRO.NATIVE_PACKAGE_URL': `'@anthropic-ai/claude-code'`,
|
||||||
|
'MACRO.PACKAGE_URL': `'@anthropic-ai/claude-code'`,
|
||||||
|
'MACRO.VERSION_CHANGELOG': `''`,
|
||||||
|
}
|
||||||
|
|
||||||
|
for await (const file of walk(join(BUILD, 'src'))) {
|
||||||
|
if (!file.match(/\.[tj]sx?$/)) continue
|
||||||
|
|
||||||
|
let src = await readFile(file, 'utf8')
|
||||||
|
let changed = false
|
||||||
|
|
||||||
|
// 2a. feature('X') → false
|
||||||
|
if (/\bfeature\s*\(\s*['"][A-Z_]+['"]\s*\)/.test(src)) {
|
||||||
|
src = src.replace(/\bfeature\s*\(\s*['"][A-Z_]+['"]\s*\)/g, 'false')
|
||||||
|
changed = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2b. MACRO.X → literals
|
||||||
|
for (const [k, v] of Object.entries(MACROS)) {
|
||||||
|
if (src.includes(k)) {
|
||||||
|
src = src.replaceAll(k, v)
|
||||||
|
changed = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2c. Remove bun:bundle import (feature() is already replaced)
|
||||||
|
if (src.includes("from 'bun:bundle'") || src.includes('from "bun:bundle"')) {
|
||||||
|
src = src.replace(/import\s*\{\s*feature\s*\}\s*from\s*['"]bun:bundle['"];?\n?/g, '// feature() replaced with false at build time\n')
|
||||||
|
changed = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2d. Remove type-only import of global.d.ts
|
||||||
|
if (src.includes("import '../global.d.ts'") || src.includes("import './global.d.ts'")) {
|
||||||
|
src = src.replace(/import\s*['"][.\/]*global\.d\.ts['"];?\n?/g, '')
|
||||||
|
changed = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changed) {
|
||||||
|
await writeFile(file, src, 'utf8')
|
||||||
|
transformCount++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(`✅ Phase 2: Transformed ${transformCount} files`)
|
||||||
|
|
||||||
|
// ══════════════════════════════════════════════════════════════════════════════
|
||||||
|
// PHASE 3: Create entry wrapper
|
||||||
|
// ══════════════════════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
|
await writeFile(ENTRY, `#!/usr/bin/env node
|
||||||
|
// Claude Code v${VERSION} — built from source
|
||||||
|
// Copyright (c) Anthropic PBC. All rights reserved.
|
||||||
|
import './src/entrypoints/cli.tsx'
|
||||||
|
`, 'utf8')
|
||||||
|
console.log('✅ Phase 3: Created entry wrapper')
|
||||||
|
|
||||||
|
// ══════════════════════════════════════════════════════════════════════════════
|
||||||
|
// PHASE 4: Iterative stub + bundle
|
||||||
|
// ══════════════════════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
|
await ensureEsbuild()
|
||||||
|
|
||||||
|
const OUT_DIR = join(ROOT, 'dist')
|
||||||
|
await mkdir(OUT_DIR, { recursive: true })
|
||||||
|
const OUT_FILE = join(OUT_DIR, 'cli.js')
|
||||||
|
|
||||||
|
// Run up to 5 rounds of: esbuild → collect missing → create stubs → retry
|
||||||
|
const MAX_ROUNDS = 5
|
||||||
|
let succeeded = false
|
||||||
|
|
||||||
|
for (let round = 1; round <= MAX_ROUNDS; round++) {
|
||||||
|
console.log(`\n🔨 Phase 4 round ${round}/${MAX_ROUNDS}: Bundling...`)
|
||||||
|
|
||||||
|
let esbuildOutput = ''
|
||||||
|
try {
|
||||||
|
esbuildOutput = execSync([
|
||||||
|
'npx esbuild',
|
||||||
|
`"${ENTRY}"`,
|
||||||
|
'--bundle',
|
||||||
|
'--platform=node',
|
||||||
|
'--target=node18',
|
||||||
|
'--format=esm',
|
||||||
|
`--outfile="${OUT_FILE}"`,
|
||||||
|
`--banner:js=$'#!/usr/bin/env node\\n// Claude Code v${VERSION} (built from source)\\n// Copyright (c) Anthropic PBC. All rights reserved.\\n'`,
|
||||||
|
'--packages=external',
|
||||||
|
'--external:bun:*',
|
||||||
|
'--allow-overwrite',
|
||||||
|
'--log-level=error',
|
||||||
|
'--log-limit=0',
|
||||||
|
'--sourcemap',
|
||||||
|
].join(' '), {
|
||||||
|
cwd: ROOT,
|
||||||
|
stdio: ['pipe', 'pipe', 'pipe'],
|
||||||
|
shell: true,
|
||||||
|
}).stderr?.toString() || ''
|
||||||
|
succeeded = true
|
||||||
|
break
|
||||||
|
} catch (e) {
|
||||||
|
esbuildOutput = (e.stderr?.toString() || '') + (e.stdout?.toString() || '')
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse missing modules
|
||||||
|
const missingRe = /Could not resolve "([^"]+)"/g
|
||||||
|
const missing = new Set()
|
||||||
|
let m
|
||||||
|
while ((m = missingRe.exec(esbuildOutput)) !== null) {
|
||||||
|
const mod = m[1]
|
||||||
|
if (!mod.startsWith('node:') && !mod.startsWith('bun:') && !mod.startsWith('/')) {
|
||||||
|
missing.add(mod)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (missing.size === 0) {
|
||||||
|
// No more missing modules but still errors — check what
|
||||||
|
const errLines = esbuildOutput.split('\n').filter(l => l.includes('ERROR')).slice(0, 5)
|
||||||
|
console.log('❌ Unrecoverable errors:')
|
||||||
|
errLines.forEach(l => console.log(' ' + l))
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(` Found ${missing.size} missing modules, creating stubs...`)
|
||||||
|
|
||||||
|
// Create stubs
|
||||||
|
let stubCount = 0
|
||||||
|
for (const mod of missing) {
|
||||||
|
// Resolve relative path from the file that imports it — but since we
|
||||||
|
// don't have that info easily, create stubs at multiple likely locations
|
||||||
|
const cleanMod = mod.replace(/^\.\//, '')
|
||||||
|
|
||||||
|
// Text assets → empty file
|
||||||
|
if (/\.(txt|md|json)$/.test(cleanMod)) {
|
||||||
|
const p = join(BUILD, 'src', cleanMod)
|
||||||
|
await mkdir(dirname(p), { recursive: true }).catch(() => {})
|
||||||
|
if (!await exists(p)) {
|
||||||
|
await writeFile(p, cleanMod.endsWith('.json') ? '{}' : '', 'utf8')
|
||||||
|
stubCount++
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// JS/TS modules → export empty
|
||||||
|
if (/\.[tj]sx?$/.test(cleanMod)) {
|
||||||
|
for (const base of [join(BUILD, 'src'), join(BUILD, 'src', 'src')]) {
|
||||||
|
const p = join(base, cleanMod)
|
||||||
|
await mkdir(dirname(p), { recursive: true }).catch(() => {})
|
||||||
|
if (!await exists(p)) {
|
||||||
|
const name = cleanMod.split('/').pop().replace(/\.[tj]sx?$/, '')
|
||||||
|
const safeName = name.replace(/[^a-zA-Z0-9_$]/g, '_') || 'stub'
|
||||||
|
await writeFile(p, `// Auto-generated stub\nexport default function ${safeName}() {}\nexport const ${safeName} = () => {}\n`, 'utf8')
|
||||||
|
stubCount++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(` Created ${stubCount} stubs`)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (succeeded) {
|
||||||
|
const size = (await stat(OUT_FILE)).size
|
||||||
|
console.log(`\n✅ Build succeeded: ${OUT_FILE}`)
|
||||||
|
console.log(` Size: ${(size / 1024 / 1024).toFixed(1)}MB`)
|
||||||
|
console.log(`\n Usage: node ${OUT_FILE} --version`)
|
||||||
|
console.log(` node ${OUT_FILE} -p "Hello"`)
|
||||||
|
} else {
|
||||||
|
console.error('\n❌ Build failed after all rounds.')
|
||||||
|
console.error(' The transformed source is in build-src/ for inspection.')
|
||||||
|
console.error('\n To fix manually:')
|
||||||
|
console.error(' 1. Check build-src/ for the transformed files')
|
||||||
|
console.error(' 2. Create missing stubs in build-src/src/')
|
||||||
|
console.error(' 3. Re-run: node scripts/build.mjs')
|
||||||
|
process.exit(1)
|
||||||
|
}
|
||||||
115
scripts/prepare-src.mjs
Normal file
115
scripts/prepare-src.mjs
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
/**
|
||||||
|
* prepare-src.mjs — Pre-build source transformation
|
||||||
|
*
|
||||||
|
* This script patches the source tree to make it compilable without Bun:
|
||||||
|
* 1. Replace `import { feature } from 'bun:bundle'` with our stub
|
||||||
|
* 2. Replace `MACRO.X` references with runtime values
|
||||||
|
* 3. Create missing type declarations
|
||||||
|
*/
|
||||||
|
|
||||||
|
import fs from 'node:fs'
|
||||||
|
import path from 'node:path'
|
||||||
|
import { fileURLToPath } from 'node:url'
|
||||||
|
|
||||||
|
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
||||||
|
const ROOT = path.resolve(__dirname, '..')
|
||||||
|
const SRC = path.join(ROOT, 'src')
|
||||||
|
|
||||||
|
const VERSION = '2.1.88'
|
||||||
|
|
||||||
|
// ── Helpers ──────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
function walk(dir, ext = '.ts') {
|
||||||
|
const results = []
|
||||||
|
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
||||||
|
const full = path.join(dir, entry.name)
|
||||||
|
if (entry.isDirectory() && entry.name !== 'node_modules') {
|
||||||
|
results.push(...walk(full, ext))
|
||||||
|
} else if (entry.name.endsWith(ext) || entry.name.endsWith('.tsx')) {
|
||||||
|
results.push(full)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return results
|
||||||
|
}
|
||||||
|
|
||||||
|
function patchFile(filePath) {
|
||||||
|
let src = fs.readFileSync(filePath, 'utf8')
|
||||||
|
let changed = false
|
||||||
|
|
||||||
|
// 1. Replace `import { feature } from 'bun:bundle'` / `"bun:bundle"`
|
||||||
|
if (src.includes("from 'bun:bundle'") || src.includes('from "bun:bundle"')) {
|
||||||
|
src = src.replace(/import\s*\{\s*feature\s*\}\s*from\s*['"]bun:bundle['"]/g,
|
||||||
|
"import { feature } from '../stubs/bun-bundle.js'")
|
||||||
|
// Fix relative depth based on file location
|
||||||
|
const rel = path.relative(SRC, path.dirname(filePath))
|
||||||
|
const depth = rel ? '../'.repeat(rel.split('/').length) : ''
|
||||||
|
if (depth) {
|
||||||
|
src = src.replace("from '../stubs/bun-bundle.js'", `from '${depth}stubs/bun-bundle.js'`)
|
||||||
|
}
|
||||||
|
changed = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Replace MACRO.X with string literals
|
||||||
|
const macroReplacements = {
|
||||||
|
'MACRO.VERSION': `'${VERSION}'`,
|
||||||
|
'MACRO.BUILD_TIME': `'${new Date().toISOString()}'`,
|
||||||
|
'MACRO.FEEDBACK_CHANNEL': `'https://github.com/anthropics/claude-code/issues'`,
|
||||||
|
'MACRO.ISSUES_EXPLAINER': `'https://github.com/anthropics/claude-code/issues/new/choose'`,
|
||||||
|
'MACRO.NATIVE_PACKAGE_URL': `'@anthropic-ai/claude-code'`,
|
||||||
|
'MACRO.PACKAGE_URL': `'@anthropic-ai/claude-code'`,
|
||||||
|
'MACRO.VERSION_CHANGELOG': `''`,
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const [macro, replacement] of Object.entries(macroReplacements)) {
|
||||||
|
if (src.includes(macro)) {
|
||||||
|
// Don't replace inside strings
|
||||||
|
src = src.replace(new RegExp(`(?<![\\w'"])${macro.replace('.', '\\.')}(?![\\w'" ])`, 'g'), replacement)
|
||||||
|
changed = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changed) {
|
||||||
|
fs.writeFileSync(filePath, src, 'utf8')
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Main ─────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
console.log('🔧 Preparing source files...\n')
|
||||||
|
|
||||||
|
const files = walk(SRC)
|
||||||
|
let patched = 0
|
||||||
|
|
||||||
|
for (const file of files) {
|
||||||
|
if (patchFile(file)) {
|
||||||
|
patched++
|
||||||
|
console.log(` patched: ${path.relative(ROOT, file)}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create stub for bun:ffi (only used in upstreamproxy)
|
||||||
|
const ffiStub = path.join(ROOT, 'stubs', 'bun-ffi.ts')
|
||||||
|
if (!fs.existsSync(ffiStub)) {
|
||||||
|
fs.writeFileSync(ffiStub, `// Stub for bun:ffi — not available outside Bun runtime\nexport const ffi = {} as any\nexport function dlopen() { return {} }\n`)
|
||||||
|
console.log(' created: stubs/bun-ffi.ts')
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create global MACRO type declaration
|
||||||
|
const macroDecl = path.join(ROOT, 'stubs', 'global.d.ts')
|
||||||
|
fs.writeFileSync(macroDecl, `// Global compile-time macros (normally injected by Bun bundler)
|
||||||
|
declare const MACRO: {
|
||||||
|
VERSION: string
|
||||||
|
BUILD_TIME: string
|
||||||
|
FEEDBACK_CHANNEL: string
|
||||||
|
ISSUES_EXPLAINER: string
|
||||||
|
NATIVE_PACKAGE_URL: string
|
||||||
|
PACKAGE_URL: string
|
||||||
|
VERSION_CHANGELOG: string
|
||||||
|
}
|
||||||
|
`)
|
||||||
|
console.log(' created: stubs/global.d.ts')
|
||||||
|
|
||||||
|
console.log(`\n✅ Patched ${patched} / ${files.length} source files`)
|
||||||
158
scripts/stub-modules.mjs
Normal file
158
scripts/stub-modules.mjs
Normal file
@@ -0,0 +1,158 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
/**
|
||||||
|
* stub-modules.mjs — Create stub files for all missing feature-gated modules
|
||||||
|
*
|
||||||
|
* Run: node scripts/stub-modules.mjs
|
||||||
|
* Then: npx esbuild build-src/entry.ts --bundle --platform=node --packages=external ...
|
||||||
|
*
|
||||||
|
* Reads esbuild errors, resolves each relative import to its correct absolute
|
||||||
|
* path inside build-src/src/, and creates an empty stub.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { readFile, writeFile, mkdir, stat } from 'node:fs/promises'
|
||||||
|
import { join, dirname, resolve } from 'node:path'
|
||||||
|
import { execSync } from 'node:child_process'
|
||||||
|
|
||||||
|
const ROOT = join(import.meta.dirname, '..')
|
||||||
|
const BUILD_SRC = join(ROOT, 'build-src', 'src')
|
||||||
|
|
||||||
|
async function exists(p) { try { await stat(p); return true } catch { return false } }
|
||||||
|
|
||||||
|
// Parse all missing modules from esbuild output
|
||||||
|
const out = execSync(
|
||||||
|
`npx esbuild "${join(ROOT, 'build-src', 'entry.ts')}" ` +
|
||||||
|
`--bundle --platform=node --packages=external ` +
|
||||||
|
`--external:'bun:*' --log-level=error --log-limit=0 ` +
|
||||||
|
`--outfile=/dev/null 2>&1 || true`,
|
||||||
|
{ cwd: ROOT, shell: true, encoding: 'utf8', maxBuffer: 50 * 1024 * 1024 }
|
||||||
|
)
|
||||||
|
|
||||||
|
const missingRe = /Could not resolve "([^"]+)"/g
|
||||||
|
const errors = [...out.matchAll(/\s+(\S+:\d+:\d+):\s/g)].map(m => m[1])
|
||||||
|
const moduleFiles = new Map() // module → set of importing files
|
||||||
|
|
||||||
|
let match
|
||||||
|
while ((match = missingRe.exec(out)) !== null) {
|
||||||
|
const mod = match[1]
|
||||||
|
if (mod.startsWith('node:') || mod.startsWith('bun:') || mod.startsWith('/')) continue
|
||||||
|
moduleFiles.set(mod, new Set())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now resolve each relative module path to its absolute path
|
||||||
|
// by finding which source file imports it
|
||||||
|
const importRe = /(\S+:\d+:\d+):\s*\d+.*require\(["']([^"']+)["']\)|import.*from\s*["']([^"']+)["']/g
|
||||||
|
|
||||||
|
let stubCount = 0
|
||||||
|
const created = new Set()
|
||||||
|
|
||||||
|
for (const [mod] of moduleFiles) {
|
||||||
|
// For relative imports, we need to find the importing file to resolve the path
|
||||||
|
// Search for the import in the build-src
|
||||||
|
const escapedMod = mod.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
|
||||||
|
const grepResult = execSync(
|
||||||
|
`grep -rl "${escapedMod}" "${BUILD_SRC}" 2>/dev/null || true`,
|
||||||
|
{ encoding: 'utf8', maxBuffer: 10 * 1024 * 1024, shell: true }
|
||||||
|
).trim()
|
||||||
|
|
||||||
|
const importers = grepResult.split('\n').filter(Boolean)
|
||||||
|
|
||||||
|
for (const importer of importers) {
|
||||||
|
const importerDir = dirname(importer)
|
||||||
|
const absPath = resolve(importerDir, mod)
|
||||||
|
|
||||||
|
// Check if it's a .d.ts type file — just create empty
|
||||||
|
if (mod.endsWith('.d.ts')) {
|
||||||
|
if (!created.has(absPath)) {
|
||||||
|
await mkdir(dirname(absPath), { recursive: true }).catch(() => {})
|
||||||
|
if (!await exists(absPath)) {
|
||||||
|
await writeFile(absPath, '// Type stub\nexport {}\n', 'utf8')
|
||||||
|
stubCount++
|
||||||
|
created.add(absPath)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Text assets (.txt, .md)
|
||||||
|
if (/\.(txt|md)$/.test(mod)) {
|
||||||
|
if (!created.has(absPath)) {
|
||||||
|
await mkdir(dirname(absPath), { recursive: true }).catch(() => {})
|
||||||
|
if (!await exists(absPath)) {
|
||||||
|
await writeFile(absPath, '', 'utf8')
|
||||||
|
stubCount++
|
||||||
|
created.add(absPath)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// JS/TS modules
|
||||||
|
if (/\.[tj]sx?$/.test(mod)) {
|
||||||
|
if (!created.has(absPath)) {
|
||||||
|
await mkdir(dirname(absPath), { recursive: true }).catch(() => {})
|
||||||
|
if (!await exists(absPath)) {
|
||||||
|
const name = mod.split('/').pop().replace(/\.[tj]sx?$/, '')
|
||||||
|
const safeName = name.replace(/[^a-zA-Z0-9_$]/g, '_') || 'stub'
|
||||||
|
await writeFile(absPath, `// Auto-generated stub for feature-gated module: ${mod}\nexport default function ${safeName}() { return null }\nexport const ${safeName} = () => null\n`, 'utf8')
|
||||||
|
stubCount++
|
||||||
|
created.add(absPath)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Also try resolving from src root for modules starting with ../
|
||||||
|
if (mod.startsWith('../')) {
|
||||||
|
// Try from several likely locations
|
||||||
|
for (const prefix of ['src', 'src/commands', 'src/components', 'src/services', 'src/tools', 'src/utils']) {
|
||||||
|
const absPath = join(ROOT, 'build-src', prefix, mod)
|
||||||
|
if (!created.has(absPath)) {
|
||||||
|
await mkdir(dirname(absPath), { recursive: true }).catch(() => {})
|
||||||
|
if (!await exists(absPath) && (/\.[tj]sx?$/.test(mod))) {
|
||||||
|
const name = mod.split('/').pop().replace(/\.[tj]sx?$/, '')
|
||||||
|
const safeName = name.replace(/[^a-zA-Z0-9_$]/g, '_') || 'stub'
|
||||||
|
await writeFile(absPath, `// Auto-generated stub for: ${mod}\nexport default function ${safeName}() { return null }\nexport const ${safeName} = () => null\n`, 'utf8')
|
||||||
|
stubCount++
|
||||||
|
created.add(absPath)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`✅ Created ${stubCount} stubs for ${moduleFiles.size} missing modules`)
|
||||||
|
|
||||||
|
// Now try the build
|
||||||
|
console.log('\n🔨 Attempting esbuild bundle...\n')
|
||||||
|
try {
|
||||||
|
const OUT = join(ROOT, 'dist', 'cli.js')
|
||||||
|
await mkdir(dirname(OUT), { recursive: true })
|
||||||
|
|
||||||
|
execSync([
|
||||||
|
'npx esbuild',
|
||||||
|
`"${join(ROOT, 'build-src', 'entry.ts')}"`,
|
||||||
|
'--bundle',
|
||||||
|
'--platform=node',
|
||||||
|
'--target=node18',
|
||||||
|
'--format=esm',
|
||||||
|
`--outfile="${OUT}"`,
|
||||||
|
'--packages=external',
|
||||||
|
'--external:bun:*',
|
||||||
|
'--banner:js=$\'#!/usr/bin/env node\\n// Claude Code v2.1.88 (built from source)\\n// Copyright (c) Anthropic PBC. All rights reserved.\\n\'',
|
||||||
|
'--allow-overwrite',
|
||||||
|
'--log-level=warning',
|
||||||
|
'--sourcemap',
|
||||||
|
].join(' '), {
|
||||||
|
cwd: ROOT,
|
||||||
|
stdio: 'inherit',
|
||||||
|
shell: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
const size = (await stat(OUT)).size
|
||||||
|
console.log(`\n✅ Build succeeded: ${OUT}`)
|
||||||
|
console.log(` Size: ${(size / 1024 / 1024).toFixed(1)}MB`)
|
||||||
|
console.log(` Usage: node ${OUT} --version`)
|
||||||
|
} catch (e) {
|
||||||
|
console.error('\n❌ Build still has errors. Run again to iterate:')
|
||||||
|
console.error(' node scripts/stub-modules.mjs')
|
||||||
|
}
|
||||||
143
scripts/transform.mjs
Normal file
143
scripts/transform.mjs
Normal file
@@ -0,0 +1,143 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
/**
|
||||||
|
* build.mjs — Build Claude Code from source using esbuild
|
||||||
|
*
|
||||||
|
* Strategy:
|
||||||
|
* 1. Copy src/ → build-src/ (working copy)
|
||||||
|
* 2. Transform all `from 'bun:bundle'` imports → `from './stubs/bun-bundle'`
|
||||||
|
* 3. Inject MACRO globals via esbuild --define (replaces MACRO.X at compile time)
|
||||||
|
* 4. Bundle with esbuild into a single cli.js
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { readdir, readFile, writeFile, mkdir, cp, rm } from 'node:fs/promises'
|
||||||
|
import { join, relative, dirname } from 'node:path'
|
||||||
|
import { execSync } from 'node:child_process'
|
||||||
|
import { fileURLToPath } from 'node:url'
|
||||||
|
|
||||||
|
const __dirname = dirname(fileURLToPath(import.meta.url))
|
||||||
|
const ROOT = join(__dirname, '..')
|
||||||
|
|
||||||
|
const VERSION = '2.1.88'
|
||||||
|
|
||||||
|
// ── Step 1: Clean & Create build directory ─────────────────────────────────
|
||||||
|
|
||||||
|
const BUILD_DIR = join(ROOT, 'build-src')
|
||||||
|
await rm(BUILD_DIR, { recursive: true, force: true })
|
||||||
|
await mkdir(BUILD_DIR, { recursive: true })
|
||||||
|
|
||||||
|
// Copy src/ → build-src/
|
||||||
|
await cp(join(ROOT, 'src'), join(BUILD_DIR, 'src'), { recursive: true })
|
||||||
|
// Copy stubs/ → build-src/stubs/
|
||||||
|
await cp(join(ROOT, 'stubs'), join(BUILD_DIR, 'stubs'), { recursive: true })
|
||||||
|
|
||||||
|
console.log('✅ Copied source to build-src/')
|
||||||
|
|
||||||
|
// ── Step 2: Transform imports ──────────────────────────────────────────────
|
||||||
|
|
||||||
|
async function* walkFiles(dir) {
|
||||||
|
for (const entry of await readdir(dir, { withFileTypes: true })) {
|
||||||
|
const full = join(dir, entry.name)
|
||||||
|
if (entry.isDirectory()) yield* walkFiles(full)
|
||||||
|
else if (entry.name.endsWith('.ts') || entry.name.endsWith('.tsx')) yield full
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let transformCount = 0
|
||||||
|
|
||||||
|
for await (const file of walkFiles(join(BUILD_DIR, 'src'))) {
|
||||||
|
let content = await readFile(file, 'utf8')
|
||||||
|
let modified = false
|
||||||
|
|
||||||
|
// Replace bun:bundle import with our stub
|
||||||
|
if (content.includes("from 'bun:bundle'") || content.includes('from "bun:bundle"')) {
|
||||||
|
const rel = relative(dirname(file), join(BUILD_DIR, 'stubs', 'bun-bundle.ts'))
|
||||||
|
const importPath = rel.startsWith('.') ? rel : './' + rel
|
||||||
|
content = content.replace(
|
||||||
|
/import\s*\{\s*feature\s*\}\s*from\s*['"]bun:bundle['"]/g,
|
||||||
|
`import { feature } from '${importPath.replace(/\.ts$/, '.js')}'`
|
||||||
|
)
|
||||||
|
modified = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if (modified) {
|
||||||
|
await writeFile(file, content, 'utf8')
|
||||||
|
transformCount++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`✅ Transformed ${transformCount} files (bun:bundle → stub)`)
|
||||||
|
|
||||||
|
// ── Step 3: Create entrypoint wrapper ──────────────────────────────────────
|
||||||
|
|
||||||
|
const ENTRY = join(BUILD_DIR, 'entry.ts')
|
||||||
|
await writeFile(ENTRY, `
|
||||||
|
// MACRO globals — normally injected by Bun's --define at compile time
|
||||||
|
// We inject them here as globals so MACRO.X references resolve
|
||||||
|
const MACRO = {
|
||||||
|
VERSION: '${VERSION}',
|
||||||
|
BUILD_TIME: '',
|
||||||
|
FEEDBACK_CHANNEL: 'https://github.com/anthropics/claude-code/issues',
|
||||||
|
ISSUES_EXPLAINER: 'https://github.com/anthropics/claude-code/issues/new/choose',
|
||||||
|
FEEDBACK_CHANNEL_URL: 'https://github.com/anthropics/claude-code/issues',
|
||||||
|
ISSUES_EXPLAINER_URL: 'https://github.com/anthropics/claude-code/issues/new/choose',
|
||||||
|
NATIVE_PACKAGE_URL: '@anthropic-ai/claude-code',
|
||||||
|
PACKAGE_URL: '@anthropic-ai/claude-code',
|
||||||
|
VERSION_CHANGELOG: '',
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make it global
|
||||||
|
globalThis.MACRO = MACRO
|
||||||
|
|
||||||
|
// Now load the real entrypoint
|
||||||
|
import './src/entrypoints/cli.tsx'
|
||||||
|
`)
|
||||||
|
|
||||||
|
console.log('✅ Created entry wrapper with MACRO injection')
|
||||||
|
|
||||||
|
// ── Step 4: esbuild bundle ─────────────────────────────────────────────────
|
||||||
|
|
||||||
|
const OUT_FILE = join(ROOT, 'dist', 'cli.js')
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Check if esbuild is available
|
||||||
|
execSync('npx esbuild --version', { stdio: 'pipe' })
|
||||||
|
} catch {
|
||||||
|
console.log('\n📦 Installing esbuild...')
|
||||||
|
execSync('npm install --save-dev esbuild', { cwd: ROOT, stdio: 'inherit' })
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('\n🔨 Bundling with esbuild...')
|
||||||
|
|
||||||
|
try {
|
||||||
|
execSync(`npx esbuild \\
|
||||||
|
"${ENTRY}" \\
|
||||||
|
--bundle \\
|
||||||
|
--platform=node \\
|
||||||
|
--target=node18 \\
|
||||||
|
--format=esm \\
|
||||||
|
--outfile="${OUT_FILE}" \\
|
||||||
|
--banner:js='#!/usr/bin/env node' \\
|
||||||
|
--define:process.env.USER_TYPE='"external"' \\
|
||||||
|
--define:process.env.CLAUDE_CODE_VERSION='"${VERSION}"' \\
|
||||||
|
--external:bun:ffi \\
|
||||||
|
--external:bun:bundle \\
|
||||||
|
--allow-overwrite \\
|
||||||
|
--log-level=info \\
|
||||||
|
--sourcemap \\
|
||||||
|
${process.argv.includes('--minify') ? '--minify' : ''}`, {
|
||||||
|
cwd: ROOT,
|
||||||
|
stdio: 'inherit',
|
||||||
|
shell: true
|
||||||
|
})
|
||||||
|
} catch (e) {
|
||||||
|
console.error('\n❌ esbuild failed. This is expected — the source has complex Bun-specific patterns.')
|
||||||
|
console.error(' The source is primarily meant for reading/analysis, not recompilation.')
|
||||||
|
console.error('\n To proceed with fixing, you would need to:')
|
||||||
|
console.error(' 1. Install Bun runtime (bun.sh)')
|
||||||
|
console.error(' 2. Create a bun build script that uses Bun.defineMacro / feature() natively')
|
||||||
|
console.error(' 3. Or manually resolve each compile-time intrinsic')
|
||||||
|
process.exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`\n✅ Build complete: ${OUT_FILE}`)
|
||||||
|
console.log(` Run with: node ${OUT_FILE}`)
|
||||||
4
stubs/bun-bundle.ts
Normal file
4
stubs/bun-bundle.ts
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
// Stub for bun:bundle — feature() is compile-time in Bun; replaced by build script
|
||||||
|
export function feature(_flag: string): boolean {
|
||||||
|
return false
|
||||||
|
}
|
||||||
11
stubs/global.d.ts
vendored
Normal file
11
stubs/global.d.ts
vendored
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
// Global type for MACRO compile-time constants
|
||||||
|
// These are normally injected by Bun's bundler via --define at compile time
|
||||||
|
declare const MACRO: {
|
||||||
|
VERSION: string
|
||||||
|
BUILD_TIME: string
|
||||||
|
FEEDBACK_CHANNEL: string
|
||||||
|
ISSUES_EXPLAINER: string
|
||||||
|
NATIVE_PACKAGE_URL: string
|
||||||
|
PACKAGE_URL: string
|
||||||
|
VERSION_CHANGELOG: string
|
||||||
|
}
|
||||||
15
stubs/macros.d.ts
vendored
Normal file
15
stubs/macros.d.ts
vendored
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
/**
|
||||||
|
* Compile-time macros injected by Bun's bundler.
|
||||||
|
* These are replaced with string literals during bundling.
|
||||||
|
* For our source build, we provide runtime values.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare const MACRO: {
|
||||||
|
VERSION: string
|
||||||
|
BUILD_TIME: string
|
||||||
|
FEEDBACK_CHANNEL: string
|
||||||
|
ISSUES_EXPLAINER: string
|
||||||
|
NATIVE_PACKAGE_URL: string
|
||||||
|
PACKAGE_URL: string
|
||||||
|
VERSION_CHANGELOG: string
|
||||||
|
}
|
||||||
20
stubs/macros.ts
Normal file
20
stubs/macros.ts
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
// Global compile-time MACRO constants
|
||||||
|
// In the real Bun build, these are injected via --define at compile time.
|
||||||
|
// Here we provide runtime values matching the published v2.1.88.
|
||||||
|
declare global {
|
||||||
|
const MACRO: {
|
||||||
|
VERSION: string
|
||||||
|
BUILD_TIME: string
|
||||||
|
FEEDBACK_CHANNEL: string
|
||||||
|
ISSUES_EXPLAINER: string
|
||||||
|
ISSUES_EXPLAINER_URL: string
|
||||||
|
FEEDBACK_CHANNEL_URL: string
|
||||||
|
NATIVE_PACKAGE_URL: string | null
|
||||||
|
PACKAGE_URL: string
|
||||||
|
VERSION_CHANGELOG: string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is never actually executed — the global is set in the entrypoint wrapper.
|
||||||
|
// But we need it so TypeScript doesn't complain about `MACRO` being undeclared.
|
||||||
|
export {}
|
||||||
3
tools/OverflowTestTool/OverflowTestTool.js
Normal file
3
tools/OverflowTestTool/OverflowTestTool.js
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
// Auto-generated stub
|
||||||
|
export default function OverflowTestTool() {}
|
||||||
|
export const OverflowTestTool = () => {}
|
||||||
3
tools/TerminalCaptureTool/prompt.js
Normal file
3
tools/TerminalCaptureTool/prompt.js
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
// Auto-generated stub
|
||||||
|
export default function prompt() {}
|
||||||
|
export const prompt = () => {}
|
||||||
3
tools/TungstenTool/TungstenTool.js
Normal file
3
tools/TungstenTool/TungstenTool.js
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
// Auto-generated stub
|
||||||
|
export default function TungstenTool() {}
|
||||||
|
export const TungstenTool = () => {}
|
||||||
3
tools/VerifyPlanExecutionTool/constants.js
Normal file
3
tools/VerifyPlanExecutionTool/constants.js
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
// Auto-generated stub
|
||||||
|
export default function constants() {}
|
||||||
|
export const constants = () => {}
|
||||||
3
tools/WorkflowTool/constants.js
Normal file
3
tools/WorkflowTool/constants.js
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
// Auto-generated stub
|
||||||
|
export default function constants() {}
|
||||||
|
export const constants = () => {}
|
||||||
36
tsconfig.json
Normal file
36
tsconfig.json
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "ES2022",
|
||||||
|
"module": "ESNext",
|
||||||
|
"moduleResolution": "bundler",
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"allowSyntheticDefaultImports": true,
|
||||||
|
"strict": false,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"declaration": true,
|
||||||
|
"declarationMap": true,
|
||||||
|
"sourceMap": true,
|
||||||
|
"jsx": "react-jsx",
|
||||||
|
"outDir": "dist",
|
||||||
|
"rootDir": "src",
|
||||||
|
"baseUrl": ".",
|
||||||
|
"paths": {
|
||||||
|
"bun:bundle": ["stubs/bun-bundle.ts"],
|
||||||
|
"src/*": ["src/*"]
|
||||||
|
},
|
||||||
|
"types": ["node"],
|
||||||
|
"lib": ["ES2022", "DOM"],
|
||||||
|
"allowImportingTsExtensions": false,
|
||||||
|
"noEmit": false
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"src/**/*",
|
||||||
|
"stubs/**/*"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"node_modules",
|
||||||
|
"dist"
|
||||||
|
]
|
||||||
|
}
|
||||||
3
types/connectorText.js
Normal file
3
types/connectorText.js
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
// Auto-generated stub
|
||||||
|
export default function connectorText() {}
|
||||||
|
export const connectorText = () => {}
|
||||||
3
utils/attributionHooks.js
Normal file
3
utils/attributionHooks.js
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
// Auto-generated stub
|
||||||
|
export default function attributionHooks() {}
|
||||||
|
export const attributionHooks = () => {}
|
||||||
3
utils/systemThemeWatcher.js
Normal file
3
utils/systemThemeWatcher.js
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
// Auto-generated stub
|
||||||
|
export default function systemThemeWatcher() {}
|
||||||
|
export const systemThemeWatcher = () => {}
|
||||||
3
utils/udsClient.js
Normal file
3
utils/udsClient.js
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
// Auto-generated stub
|
||||||
|
export default function udsClient() {}
|
||||||
|
export const udsClient = () => {}
|
||||||
Reference in New Issue
Block a user