diff --git a/CLAUDE.md b/CLAUDE.md index d68ad015c..6261a42ae 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -21,11 +21,11 @@ bun run dev:inspect # Pipe mode echo "say hello" | bun run src/entrypoints/cli.tsx -p -# Build (code splitting, outputs dist/cli.js + ~450 chunk files) +# Build (code splitting, outputs dist/cli.js + chunk files) bun run build # Test -bun test # run all tests +bun test # run all tests (2453 tests / 137 files / 0 fail) bun test src/utils/__tests__/hash.test.ts # run single file bun test --coverage # with coverage report @@ -51,26 +51,30 @@ bun run docs:dev ### Runtime & Build - **Runtime**: Bun (not Node.js). All imports, builds, and execution use Bun APIs. -- **Build**: `build.ts` 执行 `Bun.build()` with `splitting: true`,入口 `src/entrypoints/cli.tsx`,输出 `dist/cli.js` + chunk files。默认启用 `AGENT_TRIGGERS_REMOTE`、`CHICAGO_MCP`、`VOICE_MODE` feature。构建后自动替换 `import.meta.require` 为 Node.js 兼容版本(产物 bun/node 都可运行)。 -- **Dev mode**: `scripts/dev.ts` 通过 Bun `-d` flag 注入 `MACRO.*` defines,运行 `src/entrypoints/cli.tsx`。默认启用 `BUDDY`、`TRANSCRIPT_CLASSIFIER`、`BRIDGE_MODE`、`AGENT_TRIGGERS_REMOTE`、`CHICAGO_MCP`、`VOICE_MODE` 六个 feature。 +- **Build**: `build.ts` 执行 `Bun.build()` with `splitting: true`,入口 `src/entrypoints/cli.tsx`,输出 `dist/cli.js` + chunk files。Build 默认启用 19 个 feature(见下方 Feature Flag 段)。构建后自动替换 `import.meta.require` 为 Node.js 兼容版本(产物 bun/node 都可运行)。 +- **Dev mode**: `scripts/dev.ts` 通过 Bun `-d` flag 注入 `MACRO.*` defines,运行 `src/entrypoints/cli.tsx`。默认启用全部 feature。 - **Module system**: ESM (`"type": "module"`), TSX with `react-jsx` transform. -- **Monorepo**: Bun workspaces — internal packages live in `packages/` resolved via `workspace:*`. +- **Monorepo**: Bun workspaces — 14 个 internal packages in `packages/` resolved via `workspace:*`。 - **Lint/Format**: Biome (`biome.json`)。`bun run lint` / `bun run lint:fix` / `bun run format`。 - **Defines**: 集中管理在 `scripts/defines.ts`。当前版本 `2.1.888`。 +- **CI**: GitHub Actions — `ci.yml`(构建+测试)、`release-rcs.yml`(RCS 发布)、`update-contributors.yml`(自动更新贡献者)。 ### Entry & Bootstrap -1. **`src/entrypoints/cli.tsx`** — True entrypoint。`main()` 函数按优先级处理多条快速路径: +1. **`src/entrypoints/cli.tsx`** (323 行) — True entrypoint。`main()` 函数按优先级处理多条快速路径: - `--version` / `-v` — 零模块加载 - `--dump-system-prompt` — feature-gated (DUMP_SYSTEM_PROMPT) - `--claude-in-chrome-mcp` / `--chrome-native-host` + - `--computer-use-mcp` — 独立 MCP server 模式 - `--daemon-worker=` — feature-gated (DAEMON) - - `remote-control` / `rc` / `bridge` — feature-gated (BRIDGE_MODE) - - `daemon` — feature-gated (DAEMON) + - `remote-control` / `rc` / `remote` / `sync` / `bridge` — feature-gated (BRIDGE_MODE) + - `daemon` [subcommand] — feature-gated (DAEMON) - `ps` / `logs` / `attach` / `kill` / `--bg` — feature-gated (BG_SESSIONS) + - `new` / `list` / `reply` — Template job commands + - `environment-runner` / `self-hosted-runner` — BYOC runner - `--tmux` + `--worktree` 组合 - 默认路径:加载 `main.tsx` 启动完整 CLI -2. **`src/main.tsx`** (~4680 行) — Commander.js CLI definition。注册大量 subcommands:`mcp` (serve/add/remove/list...)、`server`、`ssh`、`open`、`auth`、`plugin`、`agents`、`auto-mode`、`doctor`、`update` 等。主 `.action()` 处理器负责权限、MCP、会话恢复、REPL/Headless 模式分发。 +2. **`src/main.tsx`** (~6970 行) — Commander.js CLI definition。注册大量 subcommands:`mcp` (serve/add/remove/list...)、`server`、`ssh`、`open`、`auth`、`plugin`、`agents`、`auto-mode`、`doctor`、`update` 等。主 `.action()` 处理器负责权限、MCP、会话恢复、REPL/Headless 模式分发。 3. **`src/entrypoints/init.ts`** — One-time initialization (telemetry, config, trust dialog)。 ### Core Loop @@ -82,21 +86,28 @@ bun run docs:dev ### API Layer - **`src/services/api/claude.ts`** — Core API client. Builds request params (system prompt, messages, tools, betas), calls the Anthropic SDK streaming endpoint, and processes `BetaRawMessageStreamEvent` events. -- Supports multiple providers: Anthropic direct, AWS Bedrock, Google Vertex, Azure. -- Provider selection in `src/utils/model/providers.ts`. +- **7 providers**: `firstParty` (Anthropic direct), `bedrock` (AWS), `vertex` (Google Cloud), `foundry`, `openai`, `gemini`, `grok` (xAI)。 +- Provider selection in `src/utils/model/providers.ts`。优先级:modelType 参数 > 环境变量 > 默认 firstParty。 ### Tool System - **`src/Tool.ts`** — Tool interface definition (`Tool` type) and utilities (`findToolByName`, `toolMatchesName`). -- **`src/tools.ts`** — Tool registry. Assembles the tool list; some tools are conditionally loaded via `feature()` flags or `process.env.USER_TYPE`. -- **`src/tools//`** — 61 个 tool 目录(如 BashTool, FileEditTool, GrepTool, AgentTool, WebFetchTool, LSPTool, MCPTool 等)。每个 tool 包含 `name`、`description`、`inputSchema`、`call()` 及可选的 React 渲染组件。 +- **`src/tools.ts`** (387 行) — Tool registry. Assembles the tool list; some tools are conditionally loaded via `feature()` flags or `process.env.USER_TYPE`. +- **`src/tools//`** — 55 个 tool 目录。主要分类: + - **文件操作**: FileEditTool, FileReadTool, FileWriteTool, GlobTool, GrepTool + - **Shell/执行**: BashTool, PowerShellTool, REPLTool + - **Agent 系统**: AgentTool, TaskCreateTool, TaskUpdateTool, TaskListTool, TaskGetTool + - **规划**: EnterPlanModeTool, ExitPlanModeV2Tool, VerifyPlanExecutionTool + - **Web/MCP**: WebFetchTool, WebSearchTool, MCPTool, McpAuthTool + - **调度**: CronCreateTool, CronDeleteTool, CronListTool + - **其他**: LSPTool, ConfigTool, SkillTool, EnterWorktreeTool, ExitWorktreeTool 等 - **`src/tools/shared/`** — Tool 共享工具函数。 ### UI Layer (Ink) - **`src/ink.ts`** — Ink render wrapper with ThemeProvider injection. -- **`src/ink/`** — Custom Ink framework (forked/internal): custom reconciler, hooks (`useInput`, `useTerminalSize`, `useSearchHighlight`), virtual list rendering. -- **`src/components/`** — 大量 React 组件(170+ 项),渲染于终端 Ink 环境中。关键组件: +- **`packages/@ant/ink/`** — Custom Ink framework(forked/internal),包含 components、core、hooks、keybindings、theme、utils。注意:不是 `src/ink/`。 +- **`src/components/`** — 149 个组件目录/文件,渲染于终端 Ink 环境中。关键组件: - `App.tsx` — Root provider (AppState, Stats, FpsMetrics) - `Messages.tsx` / `MessageRow.tsx` — Conversation message rendering - `PromptInput/` — User input handling @@ -112,10 +123,30 @@ bun run docs:dev - **`src/state/selectors.ts`** — State selectors. - **`src/bootstrap/state.ts`** — Module-level singletons for session-global state (session ID, CWD, project root, token counts, model overrides, client type, permission mode). +### Workspace Packages + +| Package | 说明 | +|---------|------| +| `packages/@ant/ink/` | Forked Ink 框架(components、hooks、keybindings、theme) | +| `packages/@ant/computer-use-mcp/` | Computer Use MCP server(截图/键鼠/剪贴板/应用管理) | +| `packages/@ant/computer-use-input/` | 键鼠模拟(dispatcher + darwin/win32/linux backend) | +| `packages/@ant/computer-use-swift/` | 截图 + 应用管理(dispatcher + per-platform backend) | +| `packages/@ant/claude-for-chrome-mcp/` | Chrome 浏览器控制(通过 `--chrome` 启用) | +| `packages/remote-control-server/` | 自托管 Remote Control Server(Docker 部署,含 Web UI) | +| `packages/swarm/` | Swarm 解耦模块 | +| `packages/shell/` | Shell 抽象 | +| `packages/audio-capture-napi/` | 原生音频捕获(已恢复) | +| `packages/color-diff-napi/` | 颜色差异计算(完整实现,11 tests) | +| `packages/image-processor-napi/` | 图像处理(已恢复) | +| `packages/modifiers-napi/` | 键盘修饰键检测(stub) | +| `packages/url-handler-napi/` | URL scheme 处理(stub) | + ### Bridge / Remote Control -- **`src/bridge/`** (~35 files) — Remote Control / Bridge 模式。feature-gated by `BRIDGE_MODE`。包含 bridge API、会话管理、JWT 认证、消息传输、权限回调等。Entry: `bridgeMain.ts`。 +- **`src/bridge/`** (~37 files) — Remote Control / Bridge 模式。feature-gated by `BRIDGE_MODE`。包含 bridge API、会话管理、JWT 认证、消息传输、权限回调等。Entry: `bridgeMain.ts`。 +- **`packages/remote-control-server/`** — 自托管 RCS,支持 Docker 部署,含 Web UI 控制面板。通过 `bun run rcs` 启动。 - CLI 快速路径: `claude remote-control` / `claude rc` / `claude bridge`。 +- 详见 `docs/features/remote-control-self-hosting.md`。 ### Daemon Mode @@ -128,91 +159,64 @@ bun run docs:dev ### Feature Flag System -Feature flags control which functionality is enabled at runtime: +Feature flags control which functionality is enabled at runtime. 代码中统一通过 `import { feature } from 'bun:bundle'` 导入,调用 `feature('FLAG_NAME')` 返回 `boolean`。 -- **在代码中使用**: 统一通过 `import { feature } from 'bun:bundle'` 导入,调用 `feature('FLAG_NAME')` 返回 `boolean`。**不要**在 `cli.tsx` 或其他文件里自己定义 `feature` 函数或覆盖这个 import。 -- **启用方式**: 通过环境变量 `FEATURE_=1`。例如 `FEATURE_BUDDY=1 bun run dev` 启用 BUDDY 功能。 -- **Dev 默认 features**: `BUDDY`、`TRANSCRIPT_CLASSIFIER`、`BRIDGE_MODE`、`AGENT_TRIGGERS_REMOTE`、`CHICAGO_MCP`、`VOICE_MODE`(见 `scripts/dev.ts`)。 -- **Build 默认 features**: `AGENT_TRIGGERS_REMOTE`、`CHICAGO_MCP`、`VOICE_MODE`(见 `build.ts`)。 -- **常见 flag**: `BUDDY`, `DAEMON`, `BRIDGE_MODE`, `BG_SESSIONS`, `PROACTIVE`, `KAIROS`, `VOICE_MODE`, `FORK_SUBAGENT`, `SSH_REMOTE`, `DIRECT_CONNECT`, `TEMPLATES`, `CHICAGO_MCP`, `BYOC_ENVIRONMENT_RUNNER`, `SELF_HOSTED_RUNNER`, `COORDINATOR_MODE`, `UDS_INBOX`, `LODESTONE`, `ABLATION_BASELINE` 等。 -- **类型声明**: `src/types/internal-modules.d.ts` 中声明了 `bun:bundle` 模块的 `feature` 函数签名。 +**启用方式**: 环境变量 `FEATURE_=1`。例如 `FEATURE_BUDDY=1 bun run dev`。 + +**Build 默认 features**(19 个,见 `build.ts`): +- 基础: `BUDDY`, `TRANSCRIPT_CLASSIFIER`, `BRIDGE_MODE`, `AGENT_TRIGGERS_REMOTE`, `CHICAGO_MCP`, `VOICE_MODE` +- 统计/缓存: `SHOT_STATS`, `PROMPT_CACHE_BREAK_DETECTION`, `TOKEN_BUDGET` +- P0 本地: `AGENT_TRIGGERS`, `ULTRATHINK`, `BUILTIN_EXPLORE_PLAN_AGENTS`, `LODESTONE` +- P1 API 依赖: `EXTRACT_MEMORIES`, `VERIFICATION_AGENT`, `KAIROS_BRIEF`, `AWAY_SUMMARY`, `ULTRAPLAN` +- P2: `DAEMON` + +**Dev mode 默认**: 全部启用(见 `scripts/dev.ts`)。 + +**类型声明**: `src/types/internal-modules.d.ts` 中声明了 `bun:bundle` 模块的 `feature` 函数签名。 **新增功能的正确做法**: 保留 `import { feature } from 'bun:bundle'` + `feature('FLAG_NAME')` 的标准模式,在运行时通过环境变量或配置控制,不要绕过 feature flag 直接 import。 +### Multi-API 兼容层 + +所有兼容层均采用流适配器模式:将第三方 API 格式转为 Anthropic 内部格式,下游代码完全不改。 + +#### OpenAI 兼容层 + +通过 `CLAUDE_CODE_USE_OPENAI=1` 启用,支持 Ollama/DeepSeek/vLLM 等任意 OpenAI Chat Completions 协议端点。含 DeepSeek thinking mode 支持。 + +- **`src/services/api/openai/`** — client、消息/工具转换、流适配、模型映射 +- 关键环境变量:`CLAUDE_CODE_USE_OPENAI`、`OPENAI_API_KEY`、`OPENAI_BASE_URL`、`OPENAI_MODEL` + +#### Gemini 兼容层 + +通过 `CLAUDE_CODE_USE_GEMINI=1` 启用。独立环境变量体系。 + +- **`src/services/api/gemini/`** — client、模型映射、类型定义 +- 关键环境变量:`GEMINI_API_KEY`(必填)、`GEMINI_MODEL`(直接指定)、`GEMINI_DEFAULT_SONNET_MODEL`/`GEMINI_DEFAULT_OPUS_MODEL`(按能力映射) +- 模型映射优先级:`GEMINI_MODEL` > `GEMINI_DEFAULT_*_MODEL` > `ANTHROPIC_DEFAULT_*_MODEL`(已废弃) > 原样返回 + +#### Grok 兼容层 + +通过 `CLAUDE_CODE_USE_GROK=1` 启用。自定义模型映射支持 xAI Grok API。 + +- **`src/services/api/grok/`** — client、模型映射 + +详见各兼容层的 docs 文档。 + ### Stubbed/Deleted Modules | Module | Status | |--------|--------| -| Computer Use (`@ant/*`) | Restored — `computer-use-swift`, `computer-use-input`, `computer-use-mcp`, `claude-for-chrome-mcp` 均有完整实现,macOS + Windows 可用,Linux 后端待完成 | -| `*-napi` packages | `audio-capture-napi`、`image-processor-napi` 已恢复实现;`color-diff-napi` 完整实现;`url-handler-napi`、`modifiers-napi` 仍为 stub | -| Voice Mode | Restored — `src/voice/`、`src/hooks/useVoiceIntegration.tsx`、`src/services/voiceStreamSTT.ts` 等,Push-to-Talk 语音输入(需 Anthropic OAuth) | -| OpenAI 兼容层 | Restored — `src/services/api/openai/`,支持 Ollama/DeepSeek/vLLM 等任意 OpenAI 协议端点,通过 `CLAUDE_CODE_USE_OPENAI=1` 启用 | +| Computer Use (`@ant/*`) | Restored — macOS + Windows + Linux(后端完整度不一) | +| `*-napi` packages | `audio-capture-napi`、`image-processor-napi` 已恢复;`color-diff-napi` 完整;`modifiers-napi`、`url-handler-napi` 仍为 stub | +| Voice Mode | Restored — Push-to-Talk 语音输入(需 Anthropic OAuth) | +| OpenAI/Gemini/Grok 兼容层 | Restored | +| Remote Control Server | Restored — 自托管 RCS + Web UI | | Analytics / GrowthBook / Sentry | Empty implementations | | Magic Docs / LSP Server | Removed | | Plugins / Marketplace | Removed | | MCP OAuth | Simplified | -### Computer Use - -Feature flag `CHICAGO_MCP`,dev/build 默认启用。实现跨平台屏幕操控(macOS + Windows 可用,Linux 待完成)。 - -- **`packages/@ant/computer-use-mcp/`** — MCP server,注册截图/键鼠/剪贴板/应用管理工具 -- **`packages/@ant/computer-use-input/`** — 键鼠模拟,dispatcher + per-platform backend(`backends/darwin.ts`、`win32.ts`、`linux.ts`) -- **`packages/@ant/computer-use-swift/`** — 截图 + 应用管理,同样 dispatcher + per-platform backend -- **`packages/@ant/claude-for-chrome-mcp/`** — Chrome 浏览器控制(独立于 Computer Use,通过 `--chrome` CLI 参数启用) - -详见 `docs/features/computer-use.md`。 - -### Voice Mode - -Feature flag `VOICE_MODE`,dev/build 默认启用。Push-to-Talk 语音输入,音频通过 WebSocket 流式传输到 Anthropic STT(Nova 3)。需要 Anthropic OAuth(非 API key)。 - -- **`src/voice/voiceModeEnabled.ts`** — 三层门控(feature flag + GrowthBook + OAuth auth) -- **`src/hooks/useVoice.ts`** — React hook 管理录音状态和 WebSocket 连接 -- **`src/services/voiceStreamSTT.ts`** — STT WebSocket 流式传输 - -详见 `docs/features/voice-mode.md`。 - -### OpenAI 兼容层 - -通过 `CLAUDE_CODE_USE_OPENAI=1` 环境变量启用,支持任意 OpenAI Chat Completions 协议端点(Ollama、DeepSeek、vLLM 等)。流适配器模式:在 `queryModel()` 中将 Anthropic 格式请求转为 OpenAI 格式,再将 SSE 流转换回 `BetaRawMessageStreamEvent`,下游代码完全不改。 - -- **`src/services/api/openai/`** — client、消息/工具转换、流适配、模型映射 -- **`src/utils/model/providers.ts`** — 添加 `'openai'` provider 类型(最高优先级) - -关键环境变量:`CLAUDE_CODE_USE_OPENAI`、`OPENAI_API_KEY`、`OPENAI_BASE_URL`、`OPENAI_MODEL`、`OPENAI_DEFAULT_OPUS_MODEL`、`OPENAI_DEFAULT_SONNET_MODEL`、`OPENAI_DEFAULT_HAIKU_MODEL`。详见 `docs/plans/openai-compatibility.md`。 - -### Gemini 兼容层 - -通过 `CLAUDE_CODE_USE_GEMINI=1` 环境变量或 `modelType: "gemini"` 设置启用,支持 Google Gemini API。独立的环境变量体系,不与 OpenAI 或 Anthropic 配置混杂。 - -- **`src/services/api/gemini/`** — client、模型映射、类型定义 -- **`src/utils/model/providers.ts`** — 添加 `'gemini'` provider 类型 -- **`src/utils/managedEnvConstants.ts`** — Gemini 专用的 managed env vars - -关键环境变量: -- `CLAUDE_CODE_USE_GEMINI` - 启用 Gemini provider -- `GEMINI_API_KEY` - API 密钥(必填) -- `GEMINI_BASE_URL` - API 端点(可选,默认 `https://generativelanguage.googleapis.com/v1beta`) -- `GEMINI_MODEL` - 直接指定模型(最高优先级) -- `GEMINI_DEFAULT_HAIKU_MODEL` / `GEMINI_DEFAULT_SONNET_MODEL` / `GEMINI_DEFAULT_OPUS_MODEL` - 按能力级别映射 -- `GEMINI_DEFAULT_HAIKU_MODEL_NAME` / `DESCRIPTION` / `SUPPORTED_CAPABILITIES` - 显示名称和描述 -- `GEMINI_SMALL_FAST_MODEL` - 快速任务使用的模型(可选) - -模型映射优先级(`src/services/api/gemini/modelMapping.ts`): -1. `GEMINI_MODEL` - 直接覆盖 -2. `GEMINI_DEFAULT_*_MODEL` - 独立配置(推荐) -3. `ANTHROPIC_DEFAULT_*_MODEL` - 向后兼容 fallback(已废弃) -4. 原样返回 Anthropic 模型名 - -使用示例: -```bash -export CLAUDE_CODE_USE_GEMINI=1 -export GEMINI_API_KEY="your-api-key" -export GEMINI_DEFAULT_SONNET_MODEL="gemini-2.5-flash" -export GEMINI_DEFAULT_OPUS_MODEL="gemini-2.5-pro" -``` - ### Key Type Files - **`src/types/global.d.ts`** — Declares `MACRO`, `BUILD_TARGET`, `BUILD_ENV` and internal Anthropic-only identifiers. @@ -223,12 +227,13 @@ export GEMINI_DEFAULT_OPUS_MODEL="gemini-2.5-pro" ## Testing - **框架**: `bun:test`(内置断言 + mock) +- **当前状态**: 2453 tests / 137 files / 0 fail / 4015 expect() calls - **单元测试**: 就近放置于 `src/**/__tests__/`,文件名 `.test.ts` - **集成测试**: `tests/integration/` — 4 个文件(cli-arguments, context-build, message-pipeline, tool-chain) - **共享 mock/fixture**: `tests/mocks/`(api-responses, file-system, fixtures/) - **命名**: `describe("functionName")` + `test("behavior description")`,英文 - **Mock 模式**: 对重依赖模块使用 `mock.module()` + `await import()` 解锁(必须内联在测试文件中,不能从共享 helper 导入) -- **当前状态**: ~1623 tests / 114 files (110 unit + 4 integration) / 0 fail(详见 `docs/testing-spec.md`) +- **包测试**: `packages/` 下各包也有独立测试(如 `color-diff-napi` 11 tests) ## Working with This Codebase @@ -240,3 +245,19 @@ export GEMINI_DEFAULT_OPUS_MODEL="gemini-2.5-pro" - **MACRO defines** — 集中管理在 `scripts/defines.ts`。Dev mode 通过 `bun -d` 注入,build 通过 `Bun.build({ define })` 注入。修改版本号等常量只改这个文件。 - **构建产物兼容 Node.js** — `build.ts` 会自动后处理 `import.meta.require`,产物可直接用 `node dist/cli.js` 运行。 - **Biome 配置** — 大量 lint 规则被关闭(decompiled 代码不适合严格 lint)。`.tsx` 文件用 120 行宽 + 强制分号;其他文件 80 行宽 + 按需分号。 +- **Ink 框架在 `packages/@ant/ink/`** — 不是 `src/ink/`(该目录不存在)。Ink 相关的组件、hooks、keybindings 都在 packages 中。 +- **Provider 优先级** — `modelType` 参数 > 环境变量 > 默认 `firstParty`。新增 provider 需在 `src/utils/model/providers.ts` 注册。 + +## Type Safety Guidelines + +本代码库经过系统性类型修复,已消除非测试代码中的所有 `as any`。后续开发应遵守以下规则: + +- **禁止在非测试代码中使用 `as any`** — 测试文件中 `as any` 用于 mock 数据是可以接受的。生产代码中如果遇到类型不匹配,优先用以下方式解决: + - 补充缺失的类型声明或 interface + - 使用 `as unknown as SpecificType` 双重断言(比 `as any` 安全,至少表达了目标类型) + - 使用 `Record` 替代 `any` 访问未知结构的对象 + - 用类型守卫(type guard)收窄联合类型 +- **`msg.request` 模式** — SDK control request 的某些子类型不在 Zod schema 中,访问其属性时使用 `const req = msg.request as Record` 然后通过 `req.propertyName as string` 访问。 +- **Ink 颜色类型** — Text 组件的 `color` prop 是有限联合类型,需要强转时用 `as keyof Theme` 而非 `as any`。 +- **API 兼容层类型** — OpenAI/Gemini/Grok 兼容层的 stream、request body、error 等使用对应的 SDK 类型(如 `ChatCompletionChunk`、`ChatCompletionCreateParamsStreaming`),已在各 `index.ts` 中导入。 +- **Transport 消息类型** — Bridge 的 `transport.write()` / `transport.writeBatch()` 使用 `StdoutMessage` 类型,已在 `src/bridge/` 中导入。