feat: 补充构建配置,实现 Claude Code 源码编译
添加缺失的项目配置文件,使源码快照可以成功编译和运行: - package.json: 85+ 依赖项 + 构建脚本 - tsconfig.json: TypeScript + JSX + src/ 路径别名 - globals.d.ts: MACRO 构建常量 + bun:bundle 类型声明 - scripts/build.ts: Bun 构建脚本(feature flag polyfill + MACRO 注入 + 内部包 stub + 缺失源文件自动 stub) - BUILD_GUIDE.md: 中文编译文档 - 修 Commander.js v13 的 -d2e 短标志兼容问题 构建脚本通过 missingSourceStubPlugin 插件自动检测并 stub 缺失的源文件, 无需在源码树中手动创建 stub 文件。 构建结果:dist/cli.js (11.7 MB),CLI 可正常启动并显示交互式终端 UI。 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
committed by
liuzenghui
co-authored by
Copilot
parent
16a676ffa3
commit
83fb08926d
@@ -0,0 +1,2 @@
|
|||||||
|
dist
|
||||||
|
node_modules
|
||||||
+207
@@ -0,0 +1,207 @@
|
|||||||
|
# Claude Code 源码编译指南
|
||||||
|
|
||||||
|
> 本文档记录了为 Claude Code 源码快照补充缺失配置文件并成功编译运行的完整过程。
|
||||||
|
|
||||||
|
## 概述
|
||||||
|
|
||||||
|
Claude Code 的源码快照仅包含 `src/` 目录和 `README.md`,缺少所有构建配置文件。本指南涵盖了从零开始恢复构建环境的全部步骤。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 补充的配置文件
|
||||||
|
|
||||||
|
### 1. `package.json`
|
||||||
|
|
||||||
|
项目的核心配置文件,定义了:
|
||||||
|
|
||||||
|
- **包名**: `@anthropic-ai/claude-code`
|
||||||
|
- **入口点**: `src/entrypoints/cli.tsx`
|
||||||
|
- **构建产物**: `dist/cli.js`
|
||||||
|
- **脚本命令**:
|
||||||
|
- `bun run build` — 执行构建脚本
|
||||||
|
- `bun run dev` — 直接运行源码(开发模式)
|
||||||
|
- `bun run typecheck` — TypeScript 类型检查
|
||||||
|
|
||||||
|
**依赖项分为三类:**
|
||||||
|
|
||||||
|
| 分类 | 数量 | 示例 |
|
||||||
|
|------|------|------|
|
||||||
|
| 公开 npm 包 | ~75 个 | `react`, `chalk`, `zod`, `@anthropic-ai/sdk` |
|
||||||
|
| Anthropic 内部包(需 stub) | ~10 个 | `@ant/*`, `@anthropic-ai/sandbox-runtime` |
|
||||||
|
| 开发依赖 | ~13 个 | `typescript`, `@types/react`, `@types/bun` |
|
||||||
|
|
||||||
|
### 2. `tsconfig.json`
|
||||||
|
|
||||||
|
TypeScript 编译配置,关键设置:
|
||||||
|
|
||||||
|
- **模块系统**: ESNext + bundler resolution
|
||||||
|
- **JSX**: `react-jsx`(React 19 的新 JSX 转换)
|
||||||
|
- **路径别名**: `src/*` → `./src/*`(项目中大量使用 `import from 'src/...'` 格式的导入)
|
||||||
|
- **目标**: ESNext(Bun 原生支持)
|
||||||
|
- **类型**: 同时包含 `bun-types` 和 `node` 类型定义
|
||||||
|
|
||||||
|
### 3. `globals.d.ts`
|
||||||
|
|
||||||
|
全局类型声明文件,定义了:
|
||||||
|
|
||||||
|
- **`MACRO` 常量**:构建时注入的宏定义
|
||||||
|
- `MACRO.VERSION` — 版本号
|
||||||
|
- `MACRO.BUILD_TIME` — 构建时间戳
|
||||||
|
- `MACRO.PACKAGE_URL` — npm 包地址
|
||||||
|
- `MACRO.NATIVE_PACKAGE_URL` — 原生包地址
|
||||||
|
- `MACRO.FEEDBACK_CHANNEL` — 反馈渠道
|
||||||
|
- `MACRO.ISSUES_EXPLAINER` — 问题报告说明
|
||||||
|
- `MACRO.VERSION_CHANGELOG` — 版本变更日志
|
||||||
|
|
||||||
|
- **`bun:bundle` 模块**:Bun 构建时特性标志(feature flags)模块的类型声明
|
||||||
|
- **内部包的类型 stub**:为不公开的 Anthropic 内部包提供类型定义
|
||||||
|
|
||||||
|
### 4. `scripts/build.ts`
|
||||||
|
|
||||||
|
核心构建脚本,使用 Bun 的 `Bun.build()` API,处理以下关键问题:
|
||||||
|
|
||||||
|
#### a) `bun:bundle` Feature Flags 处理
|
||||||
|
|
||||||
|
原始代码使用 `import { feature } from 'bun:bundle'` 进行编译时死代码消除。构建脚本通过自定义 Bun 插件为 `feature()` 函数提供 polyfill,所有特性标志在外部构建中默认返回 `false`:
|
||||||
|
|
||||||
|
```
|
||||||
|
PROACTIVE, KAIROS, BRIDGE_MODE, DAEMON, VOICE_MODE,
|
||||||
|
AGENT_TRIGGERS, MONITOR_TOOL, COORDINATOR_MODE,
|
||||||
|
ABLATION_BASELINE, DUMP_SYSTEM_PROMPT, CHICAGO_MCP
|
||||||
|
```
|
||||||
|
|
||||||
|
#### b) `MACRO.*` 构建时常量注入
|
||||||
|
|
||||||
|
通过 `Bun.build()` 的 `define` 选项在编译时替换所有 `MACRO.*` 引用为实际值。
|
||||||
|
|
||||||
|
#### c) 内部包 Stub 插件
|
||||||
|
|
||||||
|
为不公开的 Anthropic 内部包(`@ant/*`、`@anthropic-ai/sandbox-runtime` 等)提供内联 stub,确保编译时所有命名导出都能正确解析,同时不引入运行时依赖。
|
||||||
|
|
||||||
|
#### d) 缺失源文件自动 Stub 插件
|
||||||
|
|
||||||
|
源码快照中缺少部分文件(被 `feature()` 特性标志保护或属于内部模块)。构建脚本通过 `missingSourceStubPlugin` 插件**在构建时自动检测并 stub 这些缺失文件**,无需在源码树中手动创建 stub 文件:
|
||||||
|
|
||||||
|
- 通过 `onResolve` 钩子拦截所有源文件导入,检测目标文件是否存在于磁盘
|
||||||
|
- 不存在的文件自动重定向到虚拟 `missing-source` 命名空间
|
||||||
|
- 对需要特定 named exports 的模块(如 `connectorText`、`protectedNamespace` 等)提供精确 stub
|
||||||
|
- 其余缺失模块返回通用 `export default {}`
|
||||||
|
- `.md` 和 `.txt` 文件返回空字符串,`.d.ts` 文件返回 `export {}`
|
||||||
|
- 构建日志中以 `⚠️ Auto-stubbing missing module:` 标记自动 stub 的模块
|
||||||
|
|
||||||
|
#### e) 外部依赖处理
|
||||||
|
|
||||||
|
所有公开 npm 包标记为 `external`,不打包进产物,运行时从 `node_modules` 解析。
|
||||||
|
|
||||||
|
### 5. 源码修复
|
||||||
|
|
||||||
|
`src/main.tsx` 中的 `-d2e` 短标志格式与 Commander.js v13 不兼容(v13 要求短标志为单个字符),已修改为仅使用 `--debug-to-stderr` 长标志。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 编译步骤
|
||||||
|
|
||||||
|
### 前提条件
|
||||||
|
|
||||||
|
- [Bun](https://bun.sh) ≥ 1.1(推荐 1.3+)
|
||||||
|
- Windows / macOS / Linux
|
||||||
|
|
||||||
|
### 步骤 1:安装依赖
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bun install
|
||||||
|
```
|
||||||
|
|
||||||
|
这将安装约 600+ 个包(含传递依赖),耗时约 1-2 分钟。
|
||||||
|
|
||||||
|
### 步骤 2:执行构建
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bun run build
|
||||||
|
```
|
||||||
|
|
||||||
|
构建脚本将:
|
||||||
|
1. 初始化 `bun:bundle` feature flag polyfill
|
||||||
|
2. 注入 `MACRO.*` 构建时常量
|
||||||
|
3. 为内部 Anthropic 包生成内联 stub
|
||||||
|
4. 自动检测并 stub 源码快照中缺失的源文件
|
||||||
|
5. 打包 `src/entrypoints/cli.tsx` 入口点
|
||||||
|
6. 输出到 `dist/cli.js`(约 11.7 MB)和 `dist/cli.js.map`
|
||||||
|
|
||||||
|
### 步骤 3:验证运行
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 检查版本
|
||||||
|
bun dist/cli.js --version
|
||||||
|
# 输出: 1.0.0-research (Claude Code)
|
||||||
|
|
||||||
|
# 查看帮助
|
||||||
|
bun dist/cli.js --help
|
||||||
|
|
||||||
|
# 启动交互式界面(需要 API Key)
|
||||||
|
bun dist/cli.js
|
||||||
|
```
|
||||||
|
|
||||||
|
### 自定义版本号
|
||||||
|
|
||||||
|
```bash
|
||||||
|
CLAUDE_CODE_VERSION=2.0.0 bun run build
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 构建产物
|
||||||
|
|
||||||
|
| 文件 | 大小 | 说明 |
|
||||||
|
|------|------|------|
|
||||||
|
| `dist/cli.js` | ~11.7 MB | 主程序包(ESM 格式) |
|
||||||
|
| `dist/cli.js.map` | ~38.6 MB | Source Map |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 技术要点
|
||||||
|
|
||||||
|
### 架构概览
|
||||||
|
|
||||||
|
```
|
||||||
|
入口点: src/entrypoints/cli.tsx
|
||||||
|
↓ (动态导入)
|
||||||
|
主程序: src/main.tsx (Commander.js CLI)
|
||||||
|
↓
|
||||||
|
终端 UI: src/ink/ (自定义 Ink 实现 + React 19)
|
||||||
|
↓
|
||||||
|
核心系统:
|
||||||
|
├── src/tools/ (~40 个工具实现)
|
||||||
|
├── src/commands/ (~50 个斜杠命令)
|
||||||
|
├── src/services/ (API、MCP、OAuth、分析)
|
||||||
|
├── src/hooks/ (权限系统)
|
||||||
|
└── src/coordinator/ (多智能体协调)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 关键技术栈
|
||||||
|
|
||||||
|
| 组件 | 技术 |
|
||||||
|
|------|------|
|
||||||
|
| 运行时 | Bun |
|
||||||
|
| 语言 | TypeScript (strict) |
|
||||||
|
| 终端 UI | React 19 + 自定义 Ink fork |
|
||||||
|
| CLI 框架 | Commander.js 13 |
|
||||||
|
| Schema 验证 | Zod v3 |
|
||||||
|
| 协议 | MCP SDK, LSP |
|
||||||
|
| API | Anthropic SDK |
|
||||||
|
| 遥测 | OpenTelemetry 2.x |
|
||||||
|
| 布局引擎 | 纯 TypeScript yoga-layout 实现 |
|
||||||
|
|
||||||
|
### 注意事项
|
||||||
|
|
||||||
|
1. **内部包不可用**:`@ant/*` 系列包和部分 `@anthropic-ai/*` 包不在公共 npm 上发布,相关功能(Chrome 集成、计算机使用、沙箱运行时等)在此构建中不可用。
|
||||||
|
|
||||||
|
2. **Feature Flags 全部禁用**:所有 `bun:bundle` 特性标志默认返回 `false`,这意味着实验性功能(语音、守护进程、协调器模式等)的代码路径已被消除。
|
||||||
|
|
||||||
|
3. **需要 API Key 才能实际使用**:虽然 CLI 可以编译和启动(完整的终端 UI、主题选择等均正常),但实际使用需要 Anthropic API Key 或 OAuth 登录。
|
||||||
|
|
||||||
|
4. **React Reconciler 版本**:项目使用了 `useEffectEvent` Hook,需要 `react-reconciler@0.33.0`(而非 0.31.0),该版本才实现了 `useEffectEvent` 调度器。
|
||||||
|
|
||||||
|
5. **内部包 Stub 需完整方法签名**:某些内部包(如 `@anthropic-ai/sandbox-runtime` 的 `SandboxManager`)的 stub 需要包含完整的静态方法(如 `isSupportedPlatform`、`checkDependencies`、`wrapWithSandbox` 等),否则运行时在访问未定义属性时会报错。构建脚本已为所有已知的内部类提供了完整方法签名。
|
||||||
|
|
||||||
|
6. **非官方构建**:此构建仅用于教育和安全研究目的,不代表 Anthropic 官方发布。
|
||||||
Vendored
+77
@@ -0,0 +1,77 @@
|
|||||||
|
/**
|
||||||
|
* Global type declarations for Claude Code build-time constants.
|
||||||
|
*
|
||||||
|
* MACRO is defined at bundle time via Bun's --define flag.
|
||||||
|
* bun:bundle provides compile-time feature flags for dead code elimination.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Build-time macro constants injected via --define
|
||||||
|
declare const MACRO: {
|
||||||
|
/** Application version string, e.g. "1.0.0" */
|
||||||
|
VERSION: string;
|
||||||
|
/** ISO 8601 build timestamp, e.g. "2026-03-31T00:00:00Z" */
|
||||||
|
BUILD_TIME: string;
|
||||||
|
/** npm package URL, e.g. "@anthropic-ai/claude-code" */
|
||||||
|
PACKAGE_URL: string;
|
||||||
|
/** Native package URL for platform-specific binaries */
|
||||||
|
NATIVE_PACKAGE_URL: string | undefined;
|
||||||
|
/** Feedback channel URL or description */
|
||||||
|
FEEDBACK_CHANNEL: string;
|
||||||
|
/** Instructions for reporting issues */
|
||||||
|
ISSUES_EXPLAINER: string;
|
||||||
|
/** Version changelog content */
|
||||||
|
VERSION_CHANGELOG: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Bun's bundle-time feature flag module
|
||||||
|
declare module "bun:bundle" {
|
||||||
|
/**
|
||||||
|
* Returns true if the named feature flag is enabled at bundle time.
|
||||||
|
* Used for dead code elimination — disabled branches are stripped entirely.
|
||||||
|
*/
|
||||||
|
export function feature(name: string): boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stub declarations for internal Anthropic packages that are not publicly available
|
||||||
|
declare module "@ant/claude-for-chrome-mcp" {
|
||||||
|
const mod: any;
|
||||||
|
export default mod;
|
||||||
|
export const runClaudeInChromeMcpServer: () => Promise<void>;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module "@ant/computer-use-input" {
|
||||||
|
const mod: any;
|
||||||
|
export default mod;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module "@ant/computer-use-mcp" {
|
||||||
|
const mod: any;
|
||||||
|
export default mod;
|
||||||
|
export const runComputerUseMcpServer: () => Promise<void>;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module "@ant/computer-use-swift" {
|
||||||
|
const mod: any;
|
||||||
|
export default mod;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module "@anthropic-ai/claude-agent-sdk" {
|
||||||
|
const mod: any;
|
||||||
|
export default mod;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module "@anthropic-ai/mcpb" {
|
||||||
|
const mod: any;
|
||||||
|
export default mod;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module "@anthropic-ai/sandbox-runtime" {
|
||||||
|
const mod: any;
|
||||||
|
export default mod;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module "color-diff-napi" {
|
||||||
|
export function diff(a: string, b: string): any;
|
||||||
|
const mod: any;
|
||||||
|
export default mod;
|
||||||
|
}
|
||||||
+104
@@ -0,0 +1,104 @@
|
|||||||
|
{
|
||||||
|
"name": "@anthropic-ai/claude-code",
|
||||||
|
"version": "1.0.0-research",
|
||||||
|
"description": "Claude Code CLI - Source snapshot for research",
|
||||||
|
"type": "module",
|
||||||
|
"main": "src/entrypoints/cli.tsx",
|
||||||
|
"bin": {
|
||||||
|
"claude": "dist/cli.js"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"build": "bun run scripts/build.ts",
|
||||||
|
"dev": "bun run src/entrypoints/cli.tsx",
|
||||||
|
"typecheck": "bun x tsc --noEmit"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@alcalzone/ansi-tokenize": "^0.1.0",
|
||||||
|
"@anthropic-ai/bedrock-sdk": "^0.12.0",
|
||||||
|
"@anthropic-ai/sdk": "^0.39.0",
|
||||||
|
"@anthropic-ai/vertex-sdk": "^0.6.0",
|
||||||
|
"@aws-sdk/client-bedrock": "^3.750.0",
|
||||||
|
"@aws-sdk/client-bedrock-runtime": "^3.750.0",
|
||||||
|
"@aws-sdk/client-sts": "^3.750.0",
|
||||||
|
"@azure/identity": "^4.6.0",
|
||||||
|
"@commander-js/extra-typings": "^13.1.0",
|
||||||
|
"@growthbook/growthbook": "^1.4.0",
|
||||||
|
"@modelcontextprotocol/sdk": "^1.11.0",
|
||||||
|
"@opentelemetry/api": "^1.9.0",
|
||||||
|
"@opentelemetry/api-logs": "^0.200.0",
|
||||||
|
"@opentelemetry/core": "^2.0.0",
|
||||||
|
"@opentelemetry/resources": "^2.0.0",
|
||||||
|
"@opentelemetry/sdk-logs": "^0.200.0",
|
||||||
|
"@opentelemetry/sdk-metrics": "^2.0.0",
|
||||||
|
"@opentelemetry/sdk-trace-base": "^2.0.0",
|
||||||
|
"@opentelemetry/semantic-conventions": "^1.28.0",
|
||||||
|
"ajv": "^8.17.0",
|
||||||
|
"asciichart": "^1.5.0",
|
||||||
|
"auto-bind": "^5.0.0",
|
||||||
|
"axios": "^1.7.0",
|
||||||
|
"bidi-js": "^1.0.0",
|
||||||
|
"chalk": "^5.4.0",
|
||||||
|
"chokidar": "^4.0.0",
|
||||||
|
"cli-boxes": "^3.0.0",
|
||||||
|
"code-excerpt": "^4.0.0",
|
||||||
|
"commander": "^13.1.0",
|
||||||
|
"diff": "^7.0.0",
|
||||||
|
"emoji-regex": "^10.4.0",
|
||||||
|
"env-paths": "^3.0.0",
|
||||||
|
"execa": "^9.5.0",
|
||||||
|
"fflate": "^0.8.0",
|
||||||
|
"figures": "^6.1.0",
|
||||||
|
"fuse.js": "^7.0.0",
|
||||||
|
"get-east-asian-width": "^1.3.0",
|
||||||
|
"google-auth-library": "^9.15.0",
|
||||||
|
"highlight.js": "^11.11.0",
|
||||||
|
"https-proxy-agent": "^7.0.0",
|
||||||
|
"ignore": "^7.0.0",
|
||||||
|
"indent-string": "^5.0.0",
|
||||||
|
"jsonc-parser": "^3.3.0",
|
||||||
|
"lodash-es": "^4.17.0",
|
||||||
|
"lru-cache": "^11.0.0",
|
||||||
|
"marked": "^15.0.0",
|
||||||
|
"p-map": "^7.0.0",
|
||||||
|
"picomatch": "^4.0.0",
|
||||||
|
"proper-lockfile": "^4.1.0",
|
||||||
|
"qrcode": "^1.5.0",
|
||||||
|
"react": "^19.0.0",
|
||||||
|
"react-reconciler": "0.33.0",
|
||||||
|
"semver": "^7.6.0",
|
||||||
|
"sharp": "^0.33.0",
|
||||||
|
"shell-quote": "^1.8.0",
|
||||||
|
"signal-exit": "^4.1.0",
|
||||||
|
"stack-utils": "^2.0.0",
|
||||||
|
"strip-ansi": "^7.1.0",
|
||||||
|
"supports-hyperlinks": "^3.1.0",
|
||||||
|
"tree-kill": "^1.2.0",
|
||||||
|
"turndown": "^7.2.0",
|
||||||
|
"type-fest": "^4.30.0",
|
||||||
|
"undici": "^7.3.0",
|
||||||
|
"usehooks-ts": "^3.1.0",
|
||||||
|
"vscode-jsonrpc": "^8.2.0",
|
||||||
|
"vscode-languageserver-protocol": "^3.17.0",
|
||||||
|
"vscode-languageserver-types": "^3.17.0",
|
||||||
|
"wrap-ansi": "^9.0.0",
|
||||||
|
"ws": "^8.18.0",
|
||||||
|
"xss": "^1.0.0",
|
||||||
|
"yaml": "^2.7.0",
|
||||||
|
"zod": "^3.25.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/bun": "^1.2.0",
|
||||||
|
"@types/diff": "^7.0.0",
|
||||||
|
"@types/lodash-es": "^4.17.0",
|
||||||
|
"@types/node": "^22.0.0",
|
||||||
|
"@types/proper-lockfile": "^4.1.0",
|
||||||
|
"@types/qrcode": "^1.5.0",
|
||||||
|
"@types/react": "^19.0.0",
|
||||||
|
"@types/react-reconciler": "^0.28.0",
|
||||||
|
"@types/semver": "^7.5.0",
|
||||||
|
"@types/shell-quote": "^1.7.0",
|
||||||
|
"@types/stack-utils": "^2.0.0",
|
||||||
|
"@types/ws": "^8.5.0",
|
||||||
|
"typescript": "^5.7.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,477 @@
|
|||||||
|
/**
|
||||||
|
* Build script for Claude Code using Bun's bundler API.
|
||||||
|
*
|
||||||
|
* Handles:
|
||||||
|
* - MACRO.* build-time constant injection
|
||||||
|
* - bun:bundle feature flag polyfill (all flags default to false)
|
||||||
|
* - src/ path alias resolution
|
||||||
|
* - Internal Anthropic package stubs
|
||||||
|
*
|
||||||
|
* Usage: bun run scripts/build.ts
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { type BunPlugin } from "bun";
|
||||||
|
import { existsSync, mkdirSync } from "fs";
|
||||||
|
import { dirname, join, relative } from "path";
|
||||||
|
|
||||||
|
const PROJECT_ROOT = join(import.meta.dir, "..");
|
||||||
|
const OUT_DIR = join(PROJECT_ROOT, "dist");
|
||||||
|
|
||||||
|
// Ensure output directory exists
|
||||||
|
mkdirSync(OUT_DIR, { recursive: true });
|
||||||
|
|
||||||
|
// Build-time MACRO values
|
||||||
|
const VERSION = process.env.CLAUDE_CODE_VERSION || "1.0.0-research";
|
||||||
|
const BUILD_TIME = new Date().toISOString();
|
||||||
|
const PACKAGE_URL = "@anthropic-ai/claude-code";
|
||||||
|
const FEEDBACK_CHANNEL = "https://github.com/anthropics/claude-code/issues";
|
||||||
|
const ISSUES_EXPLAINER =
|
||||||
|
"report issues at https://github.com/anthropics/claude-code/issues";
|
||||||
|
const VERSION_CHANGELOG = "";
|
||||||
|
|
||||||
|
// Feature flags — all disabled by default for external builds
|
||||||
|
const FEATURE_FLAGS: Record<string, boolean> = {
|
||||||
|
PROACTIVE: false,
|
||||||
|
KAIROS: false,
|
||||||
|
BRIDGE_MODE: false,
|
||||||
|
DAEMON: false,
|
||||||
|
VOICE_MODE: false,
|
||||||
|
AGENT_TRIGGERS: false,
|
||||||
|
MONITOR_TOOL: false,
|
||||||
|
COORDINATOR_MODE: false,
|
||||||
|
ABLATION_BASELINE: false,
|
||||||
|
DUMP_SYSTEM_PROMPT: false,
|
||||||
|
CHICAGO_MCP: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Plugin to handle `bun:bundle` imports.
|
||||||
|
* The `feature()` function returns false for all flags in external builds.
|
||||||
|
*/
|
||||||
|
const bunBundlePlugin: BunPlugin = {
|
||||||
|
name: "bun-bundle-polyfill",
|
||||||
|
setup(build) {
|
||||||
|
build.onResolve({ filter: /^bun:bundle$/ }, (args) => {
|
||||||
|
return {
|
||||||
|
path: "bun:bundle",
|
||||||
|
namespace: "bun-bundle-polyfill",
|
||||||
|
};
|
||||||
|
});
|
||||||
|
build.onLoad(
|
||||||
|
{ filter: /.*/, namespace: "bun-bundle-polyfill" },
|
||||||
|
(args) => {
|
||||||
|
const featureFnBody = Object.entries(FEATURE_FLAGS)
|
||||||
|
.map(([k, v]) => ` if (name === ${JSON.stringify(k)}) return ${v};`)
|
||||||
|
.join("\n");
|
||||||
|
|
||||||
|
return {
|
||||||
|
contents: `
|
||||||
|
export function feature(name) {
|
||||||
|
${featureFnBody}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
loader: "js",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Plugin to provide inline stubs for internal Anthropic packages.
|
||||||
|
* Each package gets properly named exports to satisfy static analysis.
|
||||||
|
*/
|
||||||
|
const internalPackageStubPlugin: BunPlugin = {
|
||||||
|
name: "internal-package-stubs",
|
||||||
|
setup(build) {
|
||||||
|
// Map of package names to their required value exports
|
||||||
|
const packageExports: Record<string, string[]> = {
|
||||||
|
"@ant/claude-for-chrome-mcp": [
|
||||||
|
"BROWSER_TOOLS[]",
|
||||||
|
"createClaudeForChromeMcpServer",
|
||||||
|
],
|
||||||
|
"@ant/computer-use-input": [],
|
||||||
|
"@ant/computer-use-mcp": [
|
||||||
|
"API_RESIZE_PARAMS{}",
|
||||||
|
"DEFAULT_GRANT_FLAGS{}",
|
||||||
|
"bindSessionContext",
|
||||||
|
"buildComputerUseTools",
|
||||||
|
"createComputerUseMcpServer",
|
||||||
|
"targetImageSize",
|
||||||
|
"getSentinelCategory",
|
||||||
|
],
|
||||||
|
"@ant/computer-use-mcp/sentinelApps": ["getSentinelCategory"],
|
||||||
|
"@ant/computer-use-mcp/types": [
|
||||||
|
"DEFAULT_GRANT_FLAGS{}",
|
||||||
|
"getSentinelCategory",
|
||||||
|
],
|
||||||
|
"@ant/computer-use-swift": [],
|
||||||
|
"@anthropic-ai/claude-agent-sdk": [],
|
||||||
|
"@anthropic-ai/mcpb": [],
|
||||||
|
"@anthropic-ai/sandbox-runtime": [
|
||||||
|
"SandboxManager",
|
||||||
|
"SandboxRuntimeConfigSchema",
|
||||||
|
"SandboxViolationStore",
|
||||||
|
],
|
||||||
|
"@anthropic-ai/foundry-sdk": [],
|
||||||
|
"color-diff-napi": ["ColorDiff", "ColorFile", "getSyntaxTheme"],
|
||||||
|
"modifiers-napi": ["isModifierPressed"],
|
||||||
|
};
|
||||||
|
|
||||||
|
// Match any package in our map (including subpaths like @ant/computer-use-mcp/types)
|
||||||
|
build.onResolve(
|
||||||
|
{ filter: /^(@ant\/|@anthropic-ai\/(sandbox-runtime|claude-agent-sdk|mcpb|foundry-sdk)|color-diff-napi|modifiers-napi)/ },
|
||||||
|
(args) => ({
|
||||||
|
path: args.path,
|
||||||
|
namespace: "internal-stub",
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
build.onLoad(
|
||||||
|
{ filter: /.*/, namespace: "internal-stub" },
|
||||||
|
(args) => {
|
||||||
|
// Find the best matching exports for this path
|
||||||
|
const exports = packageExports[args.path] || [];
|
||||||
|
|
||||||
|
const exportLines = exports
|
||||||
|
.map((name) => {
|
||||||
|
// Array exports (name[])
|
||||||
|
if (name.endsWith("[]")) {
|
||||||
|
const cleanName = name.slice(0, -2);
|
||||||
|
return `export const ${cleanName} = [];`;
|
||||||
|
}
|
||||||
|
// Object exports (name{})
|
||||||
|
if (name.endsWith("{}")) {
|
||||||
|
const cleanName = name.slice(0, -2);
|
||||||
|
return `export const ${cleanName} = {};`;
|
||||||
|
}
|
||||||
|
// ColorDiff/ColorFile need render() method
|
||||||
|
if (name === "ColorDiff" || name === "ColorFile") {
|
||||||
|
return `export class ${name} { constructor(...a){} render(...a){ return null; } static create(...a){ return new ${name}(); } }`;
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
name === "SandboxManager" ||
|
||||||
|
name === "SandboxViolationStore"
|
||||||
|
) {
|
||||||
|
return `export class ${name} {
|
||||||
|
constructor(...a){}
|
||||||
|
static create(...a){ return new ${name}(); }
|
||||||
|
static isSupportedPlatform(){ return false; }
|
||||||
|
static checkDependencies(...a){ return { satisfied: false, missing: [] }; }
|
||||||
|
static wrapWithSandbox(...a){ return a[0]; }
|
||||||
|
static initialize(...a){ return Promise.resolve(); }
|
||||||
|
static updateConfig(...a){}
|
||||||
|
static reset(){ return Promise.resolve(); }
|
||||||
|
static getFsReadConfig(){ return {}; }
|
||||||
|
static getFsWriteConfig(){ return {}; }
|
||||||
|
static getNetworkRestrictionConfig(){ return {}; }
|
||||||
|
static getIgnoreViolations(){ return {}; }
|
||||||
|
static getAllowUnixSockets(){ return false; }
|
||||||
|
static getAllowLocalBinding(){ return false; }
|
||||||
|
static getEnableWeakerNestedSandbox(){ return false; }
|
||||||
|
static getProxyPort(){ return 0; }
|
||||||
|
static getSocksProxyPort(){ return 0; }
|
||||||
|
static getLinuxHttpSocketPath(){ return ''; }
|
||||||
|
static getLinuxSocksSocketPath(){ return ''; }
|
||||||
|
static waitForNetworkInitialization(){ return Promise.resolve(); }
|
||||||
|
static getSandboxViolationStore(){ return new ${name === 'SandboxManager' ? 'SandboxViolationStore' : name}(); }
|
||||||
|
static annotateStderrWithSandboxFailures(...a){ return a[0]; }
|
||||||
|
static cleanupAfterCommand(){ return Promise.resolve(); }
|
||||||
|
dispose(){}
|
||||||
|
}`;
|
||||||
|
}
|
||||||
|
if (name === "SandboxRuntimeConfigSchema") {
|
||||||
|
return `export const ${name} = { parse: (...a) => ({}), safeParse: (...a) => ({ success: true, data: {} }) };`;
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
name.startsWith("create") ||
|
||||||
|
name.startsWith("build") ||
|
||||||
|
name.startsWith("bind") ||
|
||||||
|
name.startsWith("get") ||
|
||||||
|
name === "targetImageSize"
|
||||||
|
) {
|
||||||
|
return `export function ${name}(...args) { return {}; }`;
|
||||||
|
}
|
||||||
|
// Default: export as empty object/array
|
||||||
|
if (name.endsWith("[]")) {
|
||||||
|
const cleanName = name.slice(0, -2);
|
||||||
|
return `export const ${cleanName} = [];`;
|
||||||
|
}
|
||||||
|
return `export const ${name} = {};`;
|
||||||
|
})
|
||||||
|
.join("\n");
|
||||||
|
|
||||||
|
return {
|
||||||
|
contents: `// Stub: ${args.path}\nexport default {};\n${exportLines}\n`,
|
||||||
|
loader: "js",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Plugin to auto-stub missing source files at build time.
|
||||||
|
* When the bundler encounters an import to a file that doesn't exist on disk,
|
||||||
|
* this plugin provides a stub implementation instead of failing the build.
|
||||||
|
* This eliminates the need for physical stub files in the source tree.
|
||||||
|
*/
|
||||||
|
const missingSourceStubPlugin: BunPlugin = {
|
||||||
|
name: "missing-source-stubs",
|
||||||
|
setup(build) {
|
||||||
|
// 需要特定 named exports 的缺失模块(key: 相对路径,不含扩展名)
|
||||||
|
const specificStubs: Record<string, string> = {
|
||||||
|
"src/types/connectorText": [
|
||||||
|
"export default {};",
|
||||||
|
"export function isConnectorTextBlock(block) { return block?.type === 'connector_text'; }",
|
||||||
|
].join("\n"),
|
||||||
|
"src/utils/protectedNamespace": [
|
||||||
|
"export default {};",
|
||||||
|
"export const PROTECTED_NAMESPACE_PREFIXES = [];",
|
||||||
|
"export function isProtectedNamespace(_name) { return false; }",
|
||||||
|
].join("\n"),
|
||||||
|
"src/tools/WorkflowTool/constants": [
|
||||||
|
"export default {};",
|
||||||
|
"export const WORKFLOW_TOOL_NAME = 'workflow';",
|
||||||
|
].join("\n"),
|
||||||
|
"src/utils/filePersistence/types": [
|
||||||
|
"export default {};",
|
||||||
|
"export const DEFAULT_UPLOAD_CONCURRENCY = 5;",
|
||||||
|
"export const FILE_COUNT_LIMIT = 1000;",
|
||||||
|
"export const OUTPUTS_SUBDIR = 'outputs';",
|
||||||
|
].join("\n"),
|
||||||
|
"src/tools/REPLTool/REPLTool": [
|
||||||
|
"export default {};",
|
||||||
|
"export const REPLTool = { name: 'repl', description: 'REPL tool (stub)' };",
|
||||||
|
].join("\n"),
|
||||||
|
|
||||||
|
"src/tools/SuggestBackgroundPRTool/SuggestBackgroundPRTool": [
|
||||||
|
"export default {};",
|
||||||
|
"export const SuggestBackgroundPRTool = { name: 'suggest_background_pr', description: 'stub' };",
|
||||||
|
].join("\n"),
|
||||||
|
"src/tools/TungstenTool/TungstenLiveMonitor": [
|
||||||
|
"export default {};",
|
||||||
|
"export const TungstenLiveMonitor = {};",
|
||||||
|
].join("\n"),
|
||||||
|
"src/tools/TungstenTool/TungstenTool": [
|
||||||
|
"export default {};",
|
||||||
|
"export const TungstenTool = { name: 'tungsten', description: 'Tungsten tool (stub)' };",
|
||||||
|
].join("\n"),
|
||||||
|
"src/tools/VerifyPlanExecutionTool/VerifyPlanExecutionTool": [
|
||||||
|
"export default {};",
|
||||||
|
"export const VerifyPlanExecutionTool = { name: 'verify_plan_execution', description: 'stub' };",
|
||||||
|
].join("\n"),
|
||||||
|
"src/assistant/AssistantSessionChooser": [
|
||||||
|
"export default {};",
|
||||||
|
"export const AssistantSessionChooser = () => null;",
|
||||||
|
].join("\n"),
|
||||||
|
"src/components/agents/SnapshotUpdateDialog": [
|
||||||
|
"export default {};",
|
||||||
|
"export const SnapshotUpdateDialog = () => null;",
|
||||||
|
].join("\n"),
|
||||||
|
"src/commands/assistant/assistant": [
|
||||||
|
"export default {};",
|
||||||
|
"export const NewInstallWizard = () => null;",
|
||||||
|
"export function computeDefaultInstallDir() { return ''; }",
|
||||||
|
].join("\n"),
|
||||||
|
"src/services/remoteManagedSettings/securityCheck": [
|
||||||
|
"export default {};",
|
||||||
|
"export function checkManagedSettingsSecurity() { return { ok: true }; }",
|
||||||
|
"export function handleSecurityCheckResult() {}",
|
||||||
|
].join("\n"),
|
||||||
|
};
|
||||||
|
|
||||||
|
build.onResolve({ filter: /\.(?:ts|tsx|js|jsx|md|txt)$/ }, (args) => {
|
||||||
|
if (args.namespace !== "file") return;
|
||||||
|
|
||||||
|
let basePath: string;
|
||||||
|
if (args.path.startsWith("src/")) {
|
||||||
|
basePath = join(PROJECT_ROOT, args.path);
|
||||||
|
} else if (args.path.startsWith(".") || args.path.startsWith("/")) {
|
||||||
|
if (!args.importer) return;
|
||||||
|
basePath = join(dirname(args.importer), args.path);
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 对 .js/.jsx 导入尝试 .ts/.tsx 变体
|
||||||
|
const candidates = [basePath];
|
||||||
|
if (basePath.endsWith(".js")) {
|
||||||
|
const base = basePath.slice(0, -3);
|
||||||
|
candidates.push(base + ".ts", base + ".tsx", base + ".d.ts");
|
||||||
|
} else if (basePath.endsWith(".jsx")) {
|
||||||
|
const base = basePath.slice(0, -4);
|
||||||
|
candidates.push(base + ".tsx", base + ".ts");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const c of candidates) {
|
||||||
|
if (existsSync(c)) return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 文件不存在 → 重定向到 stub 命名空间
|
||||||
|
let stubKey = relative(PROJECT_ROOT, basePath).replace(/\\/g, "/");
|
||||||
|
if (stubKey.endsWith(".js") || stubKey.endsWith(".jsx")) {
|
||||||
|
stubKey = stubKey.replace(/\.jsx?$/, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
return { path: stubKey, namespace: "missing-source" };
|
||||||
|
});
|
||||||
|
|
||||||
|
build.onLoad({ filter: /.*/, namespace: "missing-source" }, (args) => {
|
||||||
|
const key = args.path;
|
||||||
|
|
||||||
|
if (key.endsWith(".md") || key.endsWith(".txt")) {
|
||||||
|
return { contents: `export default '';`, loader: "js" };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key.endsWith(".d.ts")) {
|
||||||
|
return { contents: `export {};`, loader: "js" };
|
||||||
|
}
|
||||||
|
|
||||||
|
const stubContent = specificStubs[key];
|
||||||
|
if (stubContent !== undefined) {
|
||||||
|
return { contents: stubContent, loader: "js" };
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(` ⚠️ Auto-stubbing missing module: ${key}`);
|
||||||
|
return { contents: `export default {};`, loader: "js" };
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log("🔨 Building Claude Code...");
|
||||||
|
console.log(` Version: ${VERSION}`);
|
||||||
|
console.log(` Build time: ${BUILD_TIME}`);
|
||||||
|
console.log(` Output: ${OUT_DIR}`);
|
||||||
|
console.log(` Feature flags: all disabled (external build)`);
|
||||||
|
console.log("");
|
||||||
|
|
||||||
|
const result = await Bun.build({
|
||||||
|
entrypoints: [join(PROJECT_ROOT, "src/entrypoints/cli.tsx")],
|
||||||
|
outdir: OUT_DIR,
|
||||||
|
target: "bun",
|
||||||
|
format: "esm",
|
||||||
|
splitting: false,
|
||||||
|
sourcemap: "external",
|
||||||
|
minify: false,
|
||||||
|
plugins: [bunBundlePlugin, internalPackageStubPlugin, missingSourceStubPlugin],
|
||||||
|
define: {
|
||||||
|
"MACRO.VERSION": JSON.stringify(VERSION),
|
||||||
|
"MACRO.BUILD_TIME": JSON.stringify(BUILD_TIME),
|
||||||
|
"MACRO.PACKAGE_URL": JSON.stringify(PACKAGE_URL),
|
||||||
|
"MACRO.NATIVE_PACKAGE_URL": "undefined",
|
||||||
|
"MACRO.FEEDBACK_CHANNEL": JSON.stringify(FEEDBACK_CHANNEL),
|
||||||
|
"MACRO.ISSUES_EXPLAINER": JSON.stringify(ISSUES_EXPLAINER),
|
||||||
|
"MACRO.VERSION_CHANGELOG": JSON.stringify(VERSION_CHANGELOG),
|
||||||
|
},
|
||||||
|
external: [
|
||||||
|
// Node.js built-ins
|
||||||
|
"node:*",
|
||||||
|
"fs",
|
||||||
|
"fs/promises",
|
||||||
|
"path",
|
||||||
|
"crypto",
|
||||||
|
"os",
|
||||||
|
"util",
|
||||||
|
"url",
|
||||||
|
"http",
|
||||||
|
"https",
|
||||||
|
"net",
|
||||||
|
"tls",
|
||||||
|
"dns",
|
||||||
|
"stream",
|
||||||
|
"events",
|
||||||
|
"buffer",
|
||||||
|
"child_process",
|
||||||
|
"process",
|
||||||
|
"readline",
|
||||||
|
"tty",
|
||||||
|
"v8",
|
||||||
|
"zlib",
|
||||||
|
"async_hooks",
|
||||||
|
"perf_hooks",
|
||||||
|
// Keep all npm deps external (not bundled)
|
||||||
|
"@alcalzone/ansi-tokenize",
|
||||||
|
"@anthropic-ai/sdk",
|
||||||
|
"@aws-sdk/client-bedrock-runtime",
|
||||||
|
"@commander-js/extra-typings",
|
||||||
|
"@growthbook/growthbook",
|
||||||
|
"@modelcontextprotocol/sdk",
|
||||||
|
"@opentelemetry/*",
|
||||||
|
"ajv",
|
||||||
|
"asciichart",
|
||||||
|
"auto-bind",
|
||||||
|
"axios",
|
||||||
|
"bidi-js",
|
||||||
|
"chalk",
|
||||||
|
"chokidar",
|
||||||
|
"cli-boxes",
|
||||||
|
"code-excerpt",
|
||||||
|
"diff",
|
||||||
|
"emoji-regex",
|
||||||
|
"env-paths",
|
||||||
|
"execa",
|
||||||
|
"figures",
|
||||||
|
"fuse.js",
|
||||||
|
"get-east-asian-width",
|
||||||
|
"google-auth-library",
|
||||||
|
"highlight.js",
|
||||||
|
"https-proxy-agent",
|
||||||
|
"ignore",
|
||||||
|
"indent-string",
|
||||||
|
"jsonc-parser",
|
||||||
|
"lodash-es",
|
||||||
|
"lru-cache",
|
||||||
|
"marked",
|
||||||
|
"p-map",
|
||||||
|
"picomatch",
|
||||||
|
"proper-lockfile",
|
||||||
|
"qrcode",
|
||||||
|
"react",
|
||||||
|
"react-reconciler",
|
||||||
|
"semver",
|
||||||
|
"shell-quote",
|
||||||
|
"signal-exit",
|
||||||
|
"stack-utils",
|
||||||
|
"strip-ansi",
|
||||||
|
"supports-hyperlinks",
|
||||||
|
"tree-kill",
|
||||||
|
"type-fest",
|
||||||
|
"undici",
|
||||||
|
"usehooks-ts",
|
||||||
|
"vscode-jsonrpc",
|
||||||
|
"vscode-languageserver-protocol",
|
||||||
|
"vscode-languageserver-types",
|
||||||
|
"wrap-ansi",
|
||||||
|
"ws",
|
||||||
|
"xss",
|
||||||
|
"zod",
|
||||||
|
"@anthropic-ai/bedrock-sdk",
|
||||||
|
"@anthropic-ai/vertex-sdk",
|
||||||
|
"@anthropic-ai/foundry-sdk",
|
||||||
|
"@azure/identity",
|
||||||
|
"@aws-sdk/client-bedrock",
|
||||||
|
"@aws-sdk/client-sts",
|
||||||
|
"fflate",
|
||||||
|
"yaml",
|
||||||
|
"sharp",
|
||||||
|
"modifiers-napi",
|
||||||
|
"turndown",
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!result.success) {
|
||||||
|
console.error("❌ Build failed!");
|
||||||
|
for (const log of result.logs) {
|
||||||
|
console.error(` ${log.message}`);
|
||||||
|
}
|
||||||
|
process.exit(1);
|
||||||
|
} else {
|
||||||
|
console.log(`✅ Build succeeded!`);
|
||||||
|
console.log(` Output files:`);
|
||||||
|
for (const output of result.outputs) {
|
||||||
|
const sizeKB = (output.size / 1024).toFixed(1);
|
||||||
|
console.log(` ${output.path} (${sizeKB} KB)`);
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-1
@@ -973,7 +973,7 @@ async function run(): Promise<CommanderCommand> {
|
|||||||
// If not provided but flag is present, value will be true
|
// If not provided but flag is present, value will be true
|
||||||
// The actual filtering is handled in debug.ts by parsing process.argv
|
// The actual filtering is handled in debug.ts by parsing process.argv
|
||||||
return true;
|
return true;
|
||||||
}).addOption(new Option('-d2e, --debug-to-stderr', 'Enable debug mode (to stderr)').argParser(Boolean).hideHelp()).option('--debug-file <path>', 'Write debug logs to a specific file path (implicitly enables debug mode)', () => true).option('--verbose', 'Override verbose mode setting from config', () => true).option('-p, --print', 'Print response and exit (useful for pipes). Note: The workspace trust dialog is skipped when Claude is run with the -p mode. Only use this flag in directories you trust.', () => true).option('--bare', 'Minimal mode: skip hooks, LSP, plugin sync, attribution, auto-memory, background prefetches, keychain reads, and CLAUDE.md auto-discovery. Sets CLAUDE_CODE_SIMPLE=1. Anthropic auth is strictly ANTHROPIC_API_KEY or apiKeyHelper via --settings (OAuth and keychain are never read). 3P providers (Bedrock/Vertex/Foundry) use their own credentials. Skills still resolve via /skill-name. Explicitly provide context via: --system-prompt[-file], --append-system-prompt[-file], --add-dir (CLAUDE.md dirs), --mcp-config, --settings, --agents, --plugin-dir.', () => true).addOption(new Option('--init', 'Run Setup hooks with init trigger, then continue').hideHelp()).addOption(new Option('--init-only', 'Run Setup and SessionStart:startup hooks, then exit').hideHelp()).addOption(new Option('--maintenance', 'Run Setup hooks with maintenance trigger, then continue').hideHelp()).addOption(new Option('--output-format <format>', 'Output format (only works with --print): "text" (default), "json" (single result), or "stream-json" (realtime streaming)').choices(['text', 'json', 'stream-json'])).addOption(new Option('--json-schema <schema>', 'JSON Schema for structured output validation. ' + 'Example: {"type":"object","properties":{"name":{"type":"string"}},"required":["name"]}').argParser(String)).option('--include-hook-events', 'Include all hook lifecycle events in the output stream (only works with --output-format=stream-json)', () => true).option('--include-partial-messages', 'Include partial message chunks as they arrive (only works with --print and --output-format=stream-json)', () => true).addOption(new Option('--input-format <format>', 'Input format (only works with --print): "text" (default), or "stream-json" (realtime streaming input)').choices(['text', 'stream-json'])).option('--mcp-debug', '[DEPRECATED. Use --debug instead] Enable MCP debug mode (shows MCP server errors)', () => true).option('--dangerously-skip-permissions', 'Bypass all permission checks. Recommended only for sandboxes with no internet access.', () => true).option('--allow-dangerously-skip-permissions', 'Enable bypassing all permission checks as an option, without it being enabled by default. Recommended only for sandboxes with no internet access.', () => true).addOption(new Option('--thinking <mode>', 'Thinking mode: enabled (equivalent to adaptive), disabled').choices(['enabled', 'adaptive', 'disabled']).hideHelp()).addOption(new Option('--max-thinking-tokens <tokens>', '[DEPRECATED. Use --thinking instead for newer models] Maximum number of thinking tokens (only works with --print)').argParser(Number).hideHelp()).addOption(new Option('--max-turns <turns>', 'Maximum number of agentic turns in non-interactive mode. This will early exit the conversation after the specified number of turns. (only works with --print)').argParser(Number).hideHelp()).addOption(new Option('--max-budget-usd <amount>', 'Maximum dollar amount to spend on API calls (only works with --print)').argParser(value => {
|
}).addOption(new Option('--debug-to-stderr', 'Enable debug mode (to stderr)').argParser(Boolean).hideHelp()).option('--debug-file <path>', 'Write debug logs to a specific file path (implicitly enables debug mode)', () => true).option('--verbose', 'Override verbose mode setting from config', () => true).option('-p, --print', 'Print response and exit (useful for pipes). Note: The workspace trust dialog is skipped when Claude is run with the -p mode. Only use this flag in directories you trust.', () => true).option('--bare', 'Minimal mode: skip hooks, LSP, plugin sync, attribution, auto-memory, background prefetches, keychain reads, and CLAUDE.md auto-discovery. Sets CLAUDE_CODE_SIMPLE=1. Anthropic auth is strictly ANTHROPIC_API_KEY or apiKeyHelper via --settings (OAuth and keychain are never read). 3P providers (Bedrock/Vertex/Foundry) use their own credentials. Skills still resolve via /skill-name. Explicitly provide context via: --system-prompt[-file], --append-system-prompt[-file], --add-dir (CLAUDE.md dirs), --mcp-config, --settings, --agents, --plugin-dir.', () => true).addOption(new Option('--init', 'Run Setup hooks with init trigger, then continue').hideHelp()).addOption(new Option('--init-only', 'Run Setup and SessionStart:startup hooks, then exit').hideHelp()).addOption(new Option('--maintenance', 'Run Setup hooks with maintenance trigger, then continue').hideHelp()).addOption(new Option('--output-format <format>', 'Output format (only works with --print): "text" (default), "json" (single result), or "stream-json" (realtime streaming)').choices(['text', 'json', 'stream-json'])).addOption(new Option('--json-schema <schema>', 'JSON Schema for structured output validation. ' + 'Example: {"type":"object","properties":{"name":{"type":"string"}},"required":["name"]}').argParser(String)).option('--include-hook-events', 'Include all hook lifecycle events in the output stream (only works with --output-format=stream-json)', () => true).option('--include-partial-messages', 'Include partial message chunks as they arrive (only works with --print and --output-format=stream-json)', () => true).addOption(new Option('--input-format <format>', 'Input format (only works with --print): "text" (default), or "stream-json" (realtime streaming input)').choices(['text', 'stream-json'])).option('--mcp-debug', '[DEPRECATED. Use --debug instead] Enable MCP debug mode (shows MCP server errors)', () => true).option('--dangerously-skip-permissions', 'Bypass all permission checks. Recommended only for sandboxes with no internet access.', () => true).option('--allow-dangerously-skip-permissions', 'Enable bypassing all permission checks as an option, without it being enabled by default. Recommended only for sandboxes with no internet access.', () => true).addOption(new Option('--thinking <mode>', 'Thinking mode: enabled (equivalent to adaptive), disabled').choices(['enabled', 'adaptive', 'disabled']).hideHelp()).addOption(new Option('--max-thinking-tokens <tokens>', '[DEPRECATED. Use --thinking instead for newer models] Maximum number of thinking tokens (only works with --print)').argParser(Number).hideHelp()).addOption(new Option('--max-turns <turns>', 'Maximum number of agentic turns in non-interactive mode. This will early exit the conversation after the specified number of turns. (only works with --print)').argParser(Number).hideHelp()).addOption(new Option('--max-budget-usd <amount>', 'Maximum dollar amount to spend on API calls (only works with --print)').argParser(value => {
|
||||||
const amount = Number(value);
|
const amount = Number(value);
|
||||||
if (isNaN(amount) || amount <= 0) {
|
if (isNaN(amount) || amount <= 0) {
|
||||||
throw new Error('--max-budget-usd must be a positive number greater than 0');
|
throw new Error('--max-budget-usd must be a positive number greater than 0');
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "ESNext",
|
||||||
|
"module": "ESNext",
|
||||||
|
"moduleResolution": "bundler",
|
||||||
|
"jsx": "react-jsx",
|
||||||
|
"strict": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"allowImportingTsExtensions": true,
|
||||||
|
"noEmit": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"isolatedModules": true,
|
||||||
|
"declaration": true,
|
||||||
|
"declarationMap": true,
|
||||||
|
"sourceMap": true,
|
||||||
|
"lib": ["ESNext"],
|
||||||
|
"types": ["bun-types", "node"],
|
||||||
|
"paths": {
|
||||||
|
"src/*": ["./src/*"]
|
||||||
|
},
|
||||||
|
"baseUrl": ".",
|
||||||
|
"rootDir": "."
|
||||||
|
},
|
||||||
|
"include": ["src/**/*.ts", "src/**/*.tsx", "scripts/**/*.ts", "globals.d.ts"],
|
||||||
|
"exclude": ["node_modules", "dist"]
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user