mirror of
https://github.com/claude-code-best/claude-code.git
synced 2026-06-15 12:55:51 +00:00
Reverse-engineer the missing daemon + remoteControlServer implementation by tracing the call chain from existing code: - src/daemon/main.ts: restore from stub to full supervisor (spawn/monitor workers, exponential backoff restart, graceful shutdown) - src/daemon/workerRegistry.ts: restore from stub to worker dispatcher (remoteControl kind → runBridgeHeadless()) - src/commands/remoteControlServer/: new slash command /remote-control-server (alias /rcs) for managing the daemon from REPL - build.ts + scripts/dev.ts: enable DAEMON feature flag Both official CLI 2.1.92 and our codebase had the command registered in commands.ts but the directory and daemon implementation were missing. The bottom layer (runBridgeHeadless in bridgeMain.ts) was already complete. Co-authored-by: unraid <local@unraid.local>
806 lines
42 KiB
Markdown
806 lines
42 KiB
Markdown
# DEV-LOG
|
||
|
||
## Daemon + Remote Control Server 还原 (2026-04-07)
|
||
|
||
**分支**: `feat/daemon-remote-control-server`
|
||
|
||
### 背景
|
||
|
||
`src/commands.ts` 注册了 `remoteControlServer` 命令(双重门控 `feature('DAEMON') && feature('BRIDGE_MODE')`),但 `src/commands/remoteControlServer/` 目录缺失,`src/daemon/main.ts` 和 `src/daemon/workerRegistry.ts` 均为 stub。官方 CLI 2.1.92 中情况一致——Anthropic 已预留注册点和底层 `runBridgeHeadless()` 实现,但中间层(daemon supervisor + command 入口)未发布。
|
||
|
||
通过逐级反向追踪调用链还原完整实现:
|
||
```
|
||
/remote-control-server (slash command)
|
||
→ spawn: claude daemon start
|
||
→ daemonMain() (supervisor,管理 worker 生命周期)
|
||
→ spawn: claude --daemon-worker=remoteControl
|
||
→ runDaemonWorker('remoteControl')
|
||
→ runBridgeHeadless(opts, signal) ← 已有完整实现
|
||
→ runBridgeLoop() → 接受远程会话
|
||
```
|
||
|
||
### 实现
|
||
|
||
#### 1. Worker Registry(`src/daemon/workerRegistry.ts`)
|
||
|
||
从 stub 还原为 worker 分发器:
|
||
- `runDaemonWorker(kind)` 按 `kind` 分发到不同 worker 实现
|
||
- `runRemoteControlWorker()` 从环境变量(`DAEMON_WORKER_*`)读取配置,构造 `HeadlessBridgeOpts`,调用 `runBridgeHeadless()`
|
||
- 区分 permanent(`EXIT_CODE_PERMANENT = 78`)和 transient 错误,supervisor 据此决定重试或 park
|
||
- SIGTERM/SIGINT 信号处理,通过 `AbortController` 传递给 bridge loop
|
||
|
||
#### 2. Daemon Supervisor(`src/daemon/main.ts`)
|
||
|
||
从 stub 还原为完整 supervisor 进程:
|
||
- `daemonMain(args)` 支持子命令:`start`(启动)、`status`、`stop`、`--help`
|
||
- `runSupervisor()` spawn `remoteControl` worker 子进程,通过环境变量传递配置
|
||
- 指数退避重启(2s → 120s),10s 内连续崩溃 5 次则 park worker
|
||
- permanent exit code(78)直接 park,不重试
|
||
- graceful shutdown:SIGTERM → 转发给 worker → 30s grace → SIGKILL
|
||
- CLI 参数支持:`--dir`、`--spawn-mode`、`--capacity`、`--permission-mode`、`--sandbox`、`--name`
|
||
|
||
#### 3. Remote Control Server 命令(`src/commands/remoteControlServer/`)
|
||
|
||
**`index.ts`** — Command 注册:
|
||
- 类型 `local-jsx`,名称 `/remote-control-server`,别名 `/rcs`
|
||
- 双 feature 门控:`feature('DAEMON') && feature('BRIDGE_MODE')` + `isBridgeEnabled()`
|
||
- lazy load `remoteControlServer.tsx`
|
||
|
||
**`remoteControlServer.tsx`** — REPL 内 UI:
|
||
- 首次调用:前置检查(bridge 可用性 + OAuth token)→ spawn daemon 子进程
|
||
- 再次调用:弹出管理对话框(停止/重启/继续),显示 PID 和最近 5 行日志
|
||
- 模块级 state 跨调用保持 daemon 进程引用
|
||
- graceful stop:SIGTERM → 10s grace → SIGKILL
|
||
|
||
#### 4. Feature Flag 启用
|
||
|
||
`build.ts` / `scripts/dev.ts`:`DEFAULT_BUILD_FEATURES` / `DEFAULT_FEATURES` 新增 `DAEMON`
|
||
|
||
DAEMON 仅有编译时 feature flag 门控,无 GrowthBook gate。
|
||
|
||
### 与 `/remote-control` 的区别
|
||
|
||
| | `/remote-control` | `/remote-control-server` (daemon) |
|
||
|---|---|---|
|
||
| 模式 | 单会话,REPL 内交互式 bridge | 多会话,daemon 持久化服务器 |
|
||
| 生命周期 | 跟 REPL 会话绑定 | 独立后台进程,崩溃自动重启 |
|
||
| 并发 | 1 个远程连接 | 默认 4 个,可配置 `--capacity` |
|
||
| 隔离 | 共享当前目录 | 支持 `worktree` 模式隔离 |
|
||
| 底层 | `initReplBridge()` | `runBridgeHeadless()` → `runBridgeLoop()` |
|
||
|
||
### 修改文件
|
||
|
||
| 文件 | 变更 |
|
||
|------|------|
|
||
| `build.ts` | `DEFAULT_BUILD_FEATURES` 新增 `DAEMON` |
|
||
| `scripts/dev.ts` | `DEFAULT_FEATURES` 新增 `DAEMON` |
|
||
| `src/daemon/main.ts` | 从 stub 还原为 supervisor 实现 |
|
||
| `src/daemon/workerRegistry.ts` | 从 stub 还原为 worker 分发器 |
|
||
| `src/commands/remoteControlServer/index.ts` | **新增** command 注册 |
|
||
| `src/commands/remoteControlServer/remoteControlServer.tsx` | **新增** REPL UI |
|
||
|
||
### 验证
|
||
|
||
| 项目 | 结果 |
|
||
|------|------|
|
||
| `bun run build` | ✅ 成功 (490 files) |
|
||
| tsc 新文件检查 | ✅ 无新增类型错误 |
|
||
|
||
### 使用方式
|
||
|
||
```bash
|
||
# CLI 直接启动 daemon
|
||
bun run dev daemon start
|
||
bun run dev daemon start --spawn-mode=worktree --capacity=8
|
||
|
||
# REPL 内
|
||
/remote-control-server # 或 /rcs
|
||
```
|
||
|
||
前提:需要 Anthropic OAuth 登录(`claude login`)。
|
||
|
||
---
|
||
|
||
## /ultraplan 启用 + GrowthBook Fallback 加固 + Away Summary 改进 (2026-04-06)
|
||
|
||
**分支**: `feat/ultraplan-enablement`
|
||
**Commit**: `feat: enable /ultraplan and harden GrowthBook fallback chain`
|
||
|
||
### 背景
|
||
|
||
`/ultraplan` 是 Claude Code 的高级多代理规划功能:将任务发送到 Claude Code on the web(CCR),由 Opus 进行深度规划,计划完成后返回终端供用户审批和执行。此功能被 3 层门控锁定:`feature('ULTRAPLAN')` 编译 flag + `isEnabled: () => USER_TYPE === 'ant'` + `INTERNAL_ONLY_COMMANDS` 列表。
|
||
|
||
另外发现 GrowthBook fallback 链在 config 未初始化时会抛异常跳过 `LOCAL_GATE_DEFAULTS`,以及 Away Summary 在不支持 DECSET 1004 focus 事件的终端(CMD/PowerShell)上不工作。
|
||
|
||
### 实现
|
||
|
||
#### 1. Ultraplan 启用
|
||
|
||
- `build.ts` / `scripts/dev.ts`: 添加 `ULTRAPLAN` 到默认编译 flag
|
||
- `src/commands.ts`: 将 ultraplan 从 `INTERNAL_ONLY_COMMANDS` 移入公开 `COMMANDS` 列表
|
||
- `src/commands/ultraplan.tsx`: `isEnabled` 改为 `() => true`
|
||
- `src/screens/REPL.tsx`: 添加 `UltraplanChoiceDialog`、`UltraplanLaunchDialog`、`launchUltraplan` 的 import(HEAD 版使用但未 import,构建报 `not defined`)
|
||
|
||
#### 2. 反编译 UltraplanChoiceDialog / UltraplanLaunchDialog
|
||
|
||
REPL.tsx 引用这两个组件但代码库中不存在。从官方 CLI 2.1.92 的 `cli.js` 中定位 minified 函数 `M15`(UltraplanChoiceDialog)和 `P15`(UltraplanLaunchDialog),通过符号映射表反编译为可读 TSX。
|
||
|
||
**`src/components/ultraplan/UltraplanChoiceDialog.tsx`** — 远程计划批准后的选择对话框:
|
||
- 3 个选项:Implement here(注入当前会话)/ Start new session(清空会话重开)/ Cancel(保存到 .md 文件)
|
||
- 可滚动计划预览(ctrl+u/d 翻页,鼠标滚轮),自适应终端高度
|
||
- 选择后标记远程 task 完成、清除 `ultraplanPendingChoice` 状态、归档远程 CCR session
|
||
|
||
**`src/components/ultraplan/UltraplanLaunchDialog.tsx`** — 启动确认对话框:
|
||
- 显示功能说明、时间估计(~10–30 min)、服务条款链接
|
||
- 处理 Remote Control bridge 冲突(选择 run 时自动断开 bridge)
|
||
- 首次使用时持久化 `hasSeenUltraplanTerms` 到全局配置
|
||
|
||
反编译要点:剥离 React Compiler `_c(N)` 缓存数组,还原为标准 `useMemo`/`useCallback`;`useFocusedInputDialog()` 注册 hook 省略(REPL 内部计算 `focusedInputDialog`);GrowthBook 配置查询替换为本地默认值。
|
||
|
||
#### 3. GrowthBook Fallback 加固
|
||
|
||
`src/services/analytics/growthbook.ts`:
|
||
- `getFeatureValue_CACHED_MAY_BE_STALE`: 将 `getLocalGateDefault()` 查找移到 try/catch 外层
|
||
- `checkStatsigFeatureGate_CACHED_MAY_BE_STALE`: 同上,config 读取包裹在 try/catch 中
|
||
|
||
修复前:config 未初始化 → `getGlobalConfig()` 抛异常 → catch 直接返回 `defaultValue` → 跳过 `LOCAL_GATE_DEFAULTS`
|
||
修复后:config 未初始化 → catch 静默 → 继续查 `LOCAL_GATE_DEFAULTS` → 有默认值就用,没有才 fallback
|
||
|
||
#### 4. Away Summary 改进(Windows 终端兼容)
|
||
|
||
**问题**:Away Summary(`feature('AWAY_SUMMARY')` + `tengu_sedge_lantern` gate,上一轮已启用)依赖 DECSET 1004 终端 focus 事件检测用户是否离开。但 Windows 的 CMD 和 PowerShell 不支持此协议,`getTerminalFocusState()` 始终返回 `'unknown'`,原逻辑对 `'unknown'` 状态执行 no-op,导致 Windows 用户永远无法触发离开摘要。
|
||
|
||
**修改**:`src/hooks/useAwaySummary.ts`
|
||
|
||
1. **focus 状态处理**:`'unknown'` 现在视同 `'blurred'`(可能已离开),订阅时即启动 idle timer(5 分钟)
|
||
2. **idle-based 在场检测**:新增 `isLoading` 转换监听作为用户活跃信号替代 focus 事件:
|
||
- 用户发起新 turn(`isLoading` → `true`)→ 说明在场,取消 idle timer + abort 进行中的生成
|
||
- turn 结束(`isLoading` → `false`)→ 重启 idle timer
|
||
- timer 到期且无进行中 turn → 触发 away summary 生成
|
||
3. **兼容性**:仅在 `getTerminalFocusState() === 'unknown'` 时激活 idle 逻辑,支持 DECSET 1004 的终端(iTerm2、Windows Terminal、kitty 等)仍走原有 blur/focus 路径
|
||
|
||
**效果**:Windows CMD/PowerShell 用户离开终端 5 分钟后,系统自动调用 API 生成摘要并作为 `away_summary` 类型的系统消息追加到对话流中,用户回来时直接在 UI 中看到,无需执行任何命令
|
||
|
||
#### 5. Cron 定时任务管理技能
|
||
|
||
`src/skills/bundled/cronManage.ts`(**新增**)+ `src/skills/bundled/index.ts`:
|
||
|
||
KAIROS 定时任务系统(`tengu_kairos_cron` gate,已在上一轮 GrowthBook 启用中开启)提供了 `ScheduleCronTool` 来创建定时任务,但缺少用户可调用的 list/delete 技能。新增两个 bundled skill 补全管理闭环:
|
||
|
||
| 技能 | 用法 | 功能 |
|
||
|------|------|------|
|
||
| `/cron-list` | `/cron-list` | 调用 `CronListTool` 列出所有定时任务,表格显示 ID、Schedule、Prompt、Recurring、Durable |
|
||
| `/cron-delete` | `/cron-delete <job-id>` | 调用 `CronDeleteTool` 按 ID 取消指定定时任务 |
|
||
|
||
两个技能均受 `isKairosCronEnabled()` 门控(`feature('AGENT_TRIGGERS') && tengu_kairos_cron` gate),与 `ScheduleCronTool` 保持一致。
|
||
|
||
#### 6. Fullscreen 门控修复
|
||
|
||
- `src/utils/fullscreen.ts`: `isFullscreenEnvEnabled()` 从无条件返回 `true` 改为 `process.env.USER_TYPE === 'ant'`,避免非 ant 用户意外触发全屏模式
|
||
|
||
### 修改文件
|
||
|
||
| 文件 | 变更 |
|
||
|------|------|
|
||
| `build.ts` | `DEFAULT_BUILD_FEATURES` 新增 `ULTRAPLAN` |
|
||
| `scripts/dev.ts` | `DEFAULT_FEATURES` 新增 `ULTRAPLAN` |
|
||
| `src/commands.ts` | ultraplan 移入公开命令列表 |
|
||
| `src/commands/ultraplan.tsx` | `isEnabled` 移除 ant-only 限制 |
|
||
| `src/components/ultraplan/UltraplanChoiceDialog.tsx` | **新增** 从 2.1.92 反编译 |
|
||
| `src/components/ultraplan/UltraplanLaunchDialog.tsx` | **新增** 从 2.1.92 反编译 |
|
||
| `src/screens/REPL.tsx` | 添加 3 个 import |
|
||
| `src/services/analytics/growthbook.ts` | fallback 链加固 |
|
||
| `src/hooks/useAwaySummary.ts` | idle-based 离开检测 |
|
||
| `src/skills/bundled/index.ts` | 注册 cron 技能 |
|
||
| `src/skills/bundled/cronManage.ts` | **新增** cron list/delete 技能 |
|
||
| `src/utils/fullscreen.ts` | fullscreen 门控修复 |
|
||
|
||
### 验证
|
||
|
||
| 项目 | 结果 |
|
||
|------|------|
|
||
| `bun run build` | ✅ 成功 (480 files) |
|
||
| `bun run lint` | ✅ 仅已有 biome-ignore 警告 |
|
||
| `/ultraplan` 手动测试 | ✅ 命令注册可见、能启动远程会话、能接收回传计划并显示 ChoiceDialog |
|
||
|
||
### Ultraplan 工作流
|
||
|
||
```
|
||
/ultraplan <prompt>
|
||
→ UltraplanLaunchDialog 确认
|
||
→ teleportToRemote 创建 CCR 远程会话
|
||
→ pollForApprovedExitPlanMode 轮询(3s 间隔,30min 超时)
|
||
→ ExitPlanModeScanner 解析事件流
|
||
→ 计划 approved → UltraplanChoiceDialog 显示选择
|
||
→ Implement here / Start new session / Cancel
|
||
```
|
||
|
||
需要 Anthropic OAuth(`/login`)。远程会话在 claude.ai/code 上运行。
|
||
|
||
---
|
||
|
||
## GrowthBook Local Gate Defaults + P0/P1 Feature Enablement (2026-04-06)
|
||
|
||
**分支**: `feat/growthbook-enablement`
|
||
|
||
### 背景
|
||
|
||
Claude Code 使用 GrowthBook(Anthropic 自建 proxy at api.anthropic.com)进行远程功能开关控制,代码中使用 `tengu_*` 前缀命名。在反编译版本中 GrowthBook 不启动(analytics 空实现),导致 70+ 个功能被 gate 拦截。
|
||
|
||
经 4 个并行研究代理深度分析,确认**所有被 gate 控制的功能代码都是真实现**(非 stub)。
|
||
|
||
### 实现方案
|
||
|
||
**Commit 1** (`feat`): 在 `growthbook.ts` 中添加 `LOCAL_GATE_DEFAULTS` 映射表(25+ boolean gates + 2 object config gates),修改 4 个 getter 函数在 `isGrowthBookEnabled() === false` 时查找本地默认值。
|
||
|
||
**Commit 2** (`fix`): 发现 `LOCAL_GATE_DEFAULTS` 在有 API key 的用户环境下无效——因为 `isGrowthBookEnabled()` 返回 `true`(analytics 未禁用),代码走 GrowthBook 路径但缓存为空,直接返回 `defaultValue` 跳过了本地默认值。修复:在 3 个 getter 函数的缓存 miss 路径中插入 `LOCAL_GATE_DEFAULTS` 查找。同时修复 `tengu_onyx_plover` 值类型(`JSON.stringify` → 直接对象)和新增 `tengu_kairos_brief_config` 对象型 gate。
|
||
|
||
修复后的 fallback 链:
|
||
```
|
||
env overrides → config overrides → [GrowthBook 启用?]
|
||
→ 内存缓存 → 磁盘缓存 → LOCAL_GATE_DEFAULTS → defaultValue
|
||
```
|
||
|
||
可通过 `CLAUDE_CODE_DISABLE_LOCAL_GATES=1` 环境变量一键禁用。
|
||
|
||
### 启用的功能
|
||
|
||
**P0 — 纯本地功能(7 个 gate):**
|
||
|
||
| Gate | 功能 |
|
||
|------|------|
|
||
| `tengu_keybinding_customization_release` | 自定义快捷键(~/.claude/keybindings.json) |
|
||
| `tengu_streaming_tool_execution2` | 流式工具执行(边收边执行) |
|
||
| `tengu_kairos_cron` | 定时任务系统 |
|
||
| `tengu_amber_json_tools` | Token 高效 JSON 工具格式(省 ~4.5%) |
|
||
| `tengu_immediate_model_command` | 运行中即时切换模型 |
|
||
| `tengu_basalt_3kr` | MCP 指令增量传输 |
|
||
| `tengu_pebble_leaf_prune` | 会话存储叶剪枝优化 |
|
||
|
||
**P1 — API 依赖功能(8 个 gate):**
|
||
|
||
| Gate | 功能 |
|
||
|------|------|
|
||
| `tengu_session_memory` | 会话记忆(跨会话上下文持久化) |
|
||
| `tengu_passport_quail` | 自动记忆提取 |
|
||
| `tengu_chomp_inflection` | 提示建议 |
|
||
| `tengu_hive_evidence` | 验证代理(对抗性验证) |
|
||
| `tengu_kairos_brief` | Brief 精简输出模式 |
|
||
| `tengu_sedge_lantern` | 离开摘要 |
|
||
| `tengu_onyx_plover` | 自动梦境(记忆巩固) |
|
||
| `tengu_willow_mode` | 空闲返回提示 |
|
||
|
||
**Kill Switch(10 个 gate 保持 true):**
|
||
|
||
`tengu_turtle_carbon`、`tengu_amber_stoat`、`tengu_amber_flint`、`tengu_slim_subagent_claudemd`、`tengu_birch_trellis`、`tengu_collage_kaleidoscope`、`tengu_compact_cache_prefix`、`tengu_kairos_cron_durable`、`tengu_attribution_header`、`tengu_slate_prism`
|
||
|
||
**新增编译 flag:**
|
||
|
||
| Flag | build.ts | dev.ts | 用途 |
|
||
|------|:--------:|:------:|------|
|
||
| `AGENT_TRIGGERS` | ON | ON | 定时任务系统 |
|
||
| `EXTRACT_MEMORIES` | ON | ON | 自动记忆提取 |
|
||
| `VERIFICATION_AGENT` | ON | ON | 对抗性验证代理 |
|
||
| `KAIROS_BRIEF` | ON | ON | Brief 精简模式 |
|
||
| `AWAY_SUMMARY` | ON | ON | 离开摘要 |
|
||
| `ULTRATHINK` | ON | ON | Ultrathink 扩展思考(双重门控修复) |
|
||
| `BUILTIN_EXPLORE_PLAN_AGENTS` | ON | ON | 内置 Explore/Plan agents(双重门控修复) |
|
||
| `LODESTONE` | ON | ON | Deep link 协议注册(双重门控修复) |
|
||
|
||
**排除的编译 flag:**
|
||
- `KAIROS` — 拉入 `useProactive.js`(缺失文件),`KAIROS_BRIEF` 足够
|
||
- `TERMINAL_PANEL` — 拉入 `TerminalCaptureTool`(缺失文件)
|
||
|
||
**双重门控修复说明:**
|
||
部分功能同时被编译 flag 和 GrowthBook gate 控制(双重门控),仅开 GrowthBook gate 不够。
|
||
审计发现 3 个被卡住的:`ULTRATHINK`、`BUILTIN_EXPLORE_PLAN_AGENTS`、`LODESTONE`。
|
||
|
||
### 修改文件
|
||
|
||
| 文件 | 变更 |
|
||
|------|------|
|
||
| `build.ts` | `DEFAULT_BUILD_FEATURES` 新增 8 个编译 flag |
|
||
| `scripts/dev.ts` | `DEFAULT_FEATURES` 新增 8 个编译 flag |
|
||
| `src/services/analytics/growthbook.ts` | 新增 `LOCAL_GATE_DEFAULTS` 映射(27 gates)+ `getLocalGateDefault()` + 修改 4 个 getter 的 fallback 链 |
|
||
| `scripts/verify-gates.ts` | 新增 gate 验证脚本(30 gates) |
|
||
| `docs/features/growthbook-enablement-plan.md` | 完整研究报告和启用计划 |
|
||
| `docs/features/feature-flags-audit-complete.md` | 更新启用状态表 |
|
||
|
||
### 验证
|
||
|
||
| 项目 | 结果 |
|
||
|------|------|
|
||
| `bun run build` | ✅ 成功 (481 files) |
|
||
| `bun test` | ✅ 2106 pass / 23 fail(均为已有问题)/ 0 新增失败 |
|
||
| `verify-gates.ts` | ✅ 30/30 PASS |
|
||
| `/brief` 手动测试 | ✅ 可用(fallback 修复后) |
|
||
|
||
---
|
||
|
||
## Enable SHOT_STATS, TOKEN_BUDGET, PROMPT_CACHE_BREAK_DETECTION (2026-04-05)
|
||
|
||
**PR**: [claude-code-best/claude-code#140](https://github.com/claude-code-best/claude-code/pull/140)
|
||
**分支**: `feat/enable-safe-feature-flags`
|
||
|
||
对 22 个被标记为 "COMPLETE" 的编译时 feature flag 进行实际源码验证(6 个并行子代理 + Codex CLI 独立复核),发现审计报告存在大量误判。最终确认仅 3 个 flag 为真正 compile-only,安全启用。
|
||
|
||
**验证流程:**
|
||
|
||
1. 6 个并行子代理分别检查每个 flag 的 `feature('FLAG_NAME')` 引用点、依赖模块完整性、外部服务依赖
|
||
2. Codex CLI (v0.118.0, 240K tokens) 独立复核,将原 7 个 "compile-only" 进一步缩减为 3 个
|
||
3. 3 个专项代理逐一验证代码路径完整性和运行时安全性
|
||
|
||
**新启用的 3 个 flag:**
|
||
|
||
| Flag | 功能 | 用户可感知效果 |
|
||
|------|------|---------------|
|
||
| `SHOT_STATS` | shot 分布统计 | `/stats` 面板显示 shot 分布和 one-shot rate |
|
||
| `TOKEN_BUDGET` | token 预算目标 | 支持 `+500k` / `spend 2M tokens` 语法,自动续写直到达标,带进度条 |
|
||
| `PROMPT_CACHE_BREAK_DETECTION` | cache key 变化检测 | 内部诊断,`--debug` 模式可见,写 diff 到临时目录 |
|
||
|
||
**修改文件:**
|
||
|
||
| 文件 | 变更 |
|
||
|------|------|
|
||
| `build.ts` | `DEFAULT_BUILD_FEATURES` 新增 3 个 flag |
|
||
| `scripts/dev.ts` | `DEFAULT_FEATURES` 新增 3 个 flag |
|
||
| `package.json` / `bun.lock` | 新增 `openai` 依赖(OpenAI 兼容层需要) |
|
||
|
||
**新增文档:**
|
||
|
||
| 文件 | 说明 |
|
||
|------|------|
|
||
| `docs/features/feature-flags-codex-review.md` | Codex 独立复核报告:修正后的 5 类分类、恢复优先级、三轴分类标准建议 |
|
||
| `docs/features/feature-flags-audit-complete.md` | 标记所有已启用 flag 的状态(`[build: ON]` / `[dev: ON]`) |
|
||
|
||
**Codex 复核关键发现:**
|
||
|
||
- 原 22 个 "COMPLETE" flag 中,8 个核心模块是 stub,3 个依赖远程服务
|
||
- `TEAMMEM`、`AGENT_TRIGGERS`、`EXTRACT_MEMORIES`、`KAIROS_BRIEF` 被降级为"有条件可用"(受 GrowthBook 门控)
|
||
- 建议审计分类标准改为三轴:实现完整度 × 激活条件 × 运行风险
|
||
- 恢复优先级:REACTIVE_COMPACT > BG_SESSIONS > PROACTIVE > CONTEXT_COLLAPSE
|
||
|
||
**验证结果:**
|
||
|
||
- `bun run build` → 475 files ✅
|
||
- `bun test` → 零新增失败 ✅
|
||
- 3 个 flag 代码路径全部完整,无缺失依赖,无 crash 风险 ✅
|
||
|
||
---
|
||
|
||
## /dream 手动触发 + DreamTask 类型补全 (2026-04-04)
|
||
|
||
将 `/dream` 命令从 KAIROS feature gate 中解耦,作为 bundled skill 无条件注册;补全 DreamTask 类型存根。
|
||
|
||
**新增文件:**
|
||
|
||
| 文件 | 说明 |
|
||
|------|------|
|
||
| `src/skills/bundled/dream.ts` | `/dream` skill 注册,调用 `buildConsolidationPrompt()` 生成整理提示词 |
|
||
|
||
**修改文件:**
|
||
|
||
| 文件 | 变更 |
|
||
|------|------|
|
||
| `src/skills/bundled/index.ts` | 导入并注册 `registerDreamSkill()` |
|
||
| `src/components/tasks/src/tasks/DreamTask/DreamTask.ts` | `any` 存根 → 从 `src/tasks/DreamTask/DreamTask.js` 重新导出完整类型 |
|
||
|
||
**新增文档:**
|
||
|
||
| 文件 | 说明 |
|
||
|------|------|
|
||
| `docs/features/auto-dream.md` | Auto Dream 原理、触发机制、使用场景完整说明 |
|
||
|
||
---
|
||
|
||
## Computer Use macOS 适配修复 (2026-04-04)
|
||
|
||
**分支**: `feature/computer-use/mac-support`
|
||
|
||
- **darwin.ts** — 应用枚举改用 Spotlight `mdfind` + `mdls`,获取真实 bundleId(旧方案合成 `com.app.xxx`),覆盖 `/Applications` + `/System/Applications` + CoreServices
|
||
- **index.ts** — 新增 `hotkey` backend fallback,非原生模块不崩溃
|
||
- **toolCalls.ts** — `resolveRequestedApps()` 新增子串模糊匹配(`"Chrome"` → `"Google Chrome"`)
|
||
- **hostAdapter.ts** — `ensureOsPermissions()` 检查 `cu.tcc` 存在性,跨平台 JS backend 安全降级
|
||
- **测试**: 17 个 MCP 工具中 10 个完全通过,6 个在 full tier 应用上通过(IDE click tier 受限为预期行为),`screenshot` 未返回图片(疑似屏幕录制权限问题)
|
||
|
||
---
|
||
|
||
## Computer Use Windows 增强:窗口绑定截图 + UI Automation + OCR (2026-04-03)
|
||
|
||
|
||
在三平台基础实现之上,利用 Windows 原生 API 增强 Computer Use 的 Windows 专属能力。
|
||
|
||
**新增文件:**
|
||
|
||
| 文件 | 行数 | 说明 |
|
||
|------|------|------|
|
||
| `src/utils/computerUse/win32/windowCapture.ts` | — | `PrintWindow` 窗口绑定截图,支持被遮挡/后台窗口 |
|
||
| `src/utils/computerUse/win32/windowEnum.ts` | — | `EnumWindows` 精确窗口枚举(HWND + PID + 标题) |
|
||
| `src/utils/computerUse/win32/uiAutomation.ts` | — | `IUIAutomation` UI 元素树读取、按钮点击、文本写入、坐标识别 |
|
||
| `src/utils/computerUse/win32/ocr.ts` | — | `Windows.Media.Ocr` 截图+文字识别(英语+中文) |
|
||
|
||
**修改文件:**
|
||
|
||
| 文件 | 变更 |
|
||
|------|------|
|
||
| `packages/@ant/computer-use-swift/src/backends/win32.ts` | `listRunning` 改用 EnumWindows;新增 `captureWindowTarget` 窗口级截图 |
|
||
|
||
**验证结果(Windows x64):**
|
||
- 窗口枚举:38 个可见窗口 ✅
|
||
- 窗口截图:VS Code 2575x1415, 444KB ✅(PrintWindow, 即使被遮挡)
|
||
- UI Automation:坐标元素识别 ✅
|
||
- OCR:识别 VS Code 界面文字,34 行 ✅
|
||
|
||
---
|
||
|
||
## Enable Computer Use — macOS + Windows + Linux (2026-04-03)
|
||
|
||
恢复 Computer Use 屏幕操控功能。参考项目仅 macOS,本次扩展为三平台支持。
|
||
|
||
**Phase 1 — MCP server stub 替换:**
|
||
从参考项目复制 `@ant/computer-use-mcp` 完整实现(12 文件,6517 行)。
|
||
|
||
**Phase 2 — 移除 src/ 中 8 处 macOS 硬编码:**
|
||
|
||
| 文件 | 改动 |
|
||
|------|------|
|
||
| `src/main.tsx:1605` | 去掉 `getPlatform() === 'macos'` |
|
||
| `src/utils/computerUse/swiftLoader.ts` | 移除 darwin-only throw |
|
||
| `src/utils/computerUse/executor.ts` | 平台守卫扩展为 darwin+win32+linux;剪贴板按平台分发(pbcopy→PowerShell→xclip);paste 快捷键 command→ctrl |
|
||
| `src/utils/computerUse/drainRunLoop.ts` | 非 darwin 直接执行 fn() |
|
||
| `src/utils/computerUse/escHotkey.ts` | 非 darwin 返回 false(Ctrl+C fallback) |
|
||
| `src/utils/computerUse/hostAdapter.ts` | 非 darwin 权限检查返回 granted |
|
||
| `src/utils/computerUse/common.ts` | platform + screenshotFiltering 动态化 |
|
||
| `src/utils/computerUse/gates.ts` | enabled:true + hasRequiredSubscription→true |
|
||
|
||
**Phase 3 — input/swift 包 dispatcher + backends 三平台架构:**
|
||
|
||
```
|
||
packages/@ant/computer-use-{input,swift}/src/
|
||
├── index.ts ← dispatcher
|
||
├── types.ts ← 共享接口
|
||
└── backends/
|
||
├── darwin.ts ← macOS AppleScript(原样拆出,不改逻辑)
|
||
├── win32.ts ← Windows PowerShell
|
||
└── linux.ts ← Linux xdotool/scrot/xrandr/wmctrl
|
||
```
|
||
|
||
**编译开关:** `CHICAGO_MCP` 加入 DEFAULT_FEATURES + DEFAULT_BUILD_FEATURES
|
||
|
||
**验证结果(Windows x64):**
|
||
- `isSupported: true` ✅
|
||
- 鼠标定位 + 前台窗口信息 ✅
|
||
- 双显示器检测 2560x1440 × 2 ✅
|
||
- 全屏截图 3MB base64 ✅
|
||
- `bun run build` 463 files ✅
|
||
|
||
---
|
||
|
||
## Enable Voice Mode / VOICE_MODE (2026-04-03)
|
||
|
||
恢复 `/voice` 语音输入功能。`src/` 下所有 voice 相关源码已与官方一致(0 行差异),问题出在:① `VOICE_MODE` 编译开关未开,命令不显示;② `audio-capture-napi` 是 SoX 子进程 stub(Windows 不支持),缺少官方原生 `.node` 二进制。
|
||
|
||
**新增文件:**
|
||
|
||
| 文件 | 说明 |
|
||
|------|------|
|
||
| `vendor/audio-capture/{platform}/audio-capture.node` | 6 个平台的原生音频二进制(cpal,来自参考项目) |
|
||
| `vendor/audio-capture-src/index.ts` | 原生模块加载器(按 `${arch}-${platform}` 动态 require `.node`) |
|
||
|
||
---
|
||
|
||
## Enable Claude in Chrome MCP (2026-04-03)
|
||
|
||
恢复 Chrome 浏览器控制功能。`src/` 下所有 claudeInChrome 相关源码已与官方一致(0 行差异),问题出在 `@ant/claude-for-chrome-mcp` 包是 6 行 stub(返回空工具列表和 null server)。
|
||
|
||
**替换文件:**
|
||
|
||
| 文件 | 变更 |
|
||
|------|------|
|
||
| `packages/@ant/claude-for-chrome-mcp/src/index.ts` | 6 行 stub → 15 行完整导出 |
|
||
|
||
**新增文件:**
|
||
|
||
| 文件 | 行数 | 说明 |
|
||
|------|------|------|
|
||
| `packages/@ant/claude-for-chrome-mcp/src/types.ts` | 134 | 类型定义 |
|
||
| `packages/@ant/claude-for-chrome-mcp/src/browserTools.ts` | 546 | 17 个浏览器工具定义 |
|
||
| `packages/@ant/claude-for-chrome-mcp/src/mcpServer.ts` | 96 | MCP Server |
|
||
| `packages/@ant/claude-for-chrome-mcp/src/mcpSocketClient.ts` | 493 | Unix Socket 客户端 |
|
||
| `packages/@ant/claude-for-chrome-mcp/src/mcpSocketPool.ts` | 327 | 多 Profile 连接池 |
|
||
| `packages/@ant/claude-for-chrome-mcp/src/bridgeClient.ts` | 1126 | Bridge WebSocket 客户端 |
|
||
| `packages/@ant/claude-for-chrome-mcp/src/toolCalls.ts` | 301 | 工具调用路由 |
|
||
|
||
**不需要 feature flag,不需要改 dev.ts/build.ts,不改 src/ 下任何文件。**
|
||
|
||
**运行时依赖:** Chrome 浏览器 + Claude in Chrome 扩展(https://claude.ai/chrome)
|
||
|
||
---
|
||
|
||
## OpenAI 接口兼容 (2026-04-03)
|
||
|
||
**分支**: `feature/openai`
|
||
|
||
在 `/login` 流程中新增 "OpenAI Compatible" 选项,支持 Ollama、DeepSeek、vLLM、One API 等兼容 OpenAI Chat Completions API 的第三方服务。用户通过 `/login` 配置后,所有 API 请求自动走 OpenAI 路径。
|
||
|
||
**改动文件(10 个,+384 / -134):**
|
||
|
||
| 文件 | 变更 |
|
||
|------|------|
|
||
| `.github/workflows/ci.yml` | CI runner 从 `ubuntu-latest` 改为 `macos-latest` |
|
||
| `README.md` | TODO 列表新增 "OpenAI 接口兼容" 条目 |
|
||
| `src/components/ConsoleOAuthFlow.tsx` | 新增 `openai_chat_api` OAuth state(含 Base URL / API Key / 3 个模型映射字段);idle 选择列表新增 "OpenAI Compatible" 选项;完整表单 UI(Tab 切换、Enter 保存);保存时写入 `modelType: 'openai'` + env 到 settings.json;OAuth 登录时重置 `modelType` 为 `anthropic` |
|
||
| `src/services/api/openai/index.ts` | 从直接 `yield* adaptOpenAIStreamToAnthropic()` 改为完整流处理循环:累积 content blocks(text/tool_use/thinking)、按 `content_block_stop` yield `AssistantMessage`、同时 yield `StreamEvent` 用于实时显示;错误处理改用新签名 `createAssistantAPIErrorMessage({ content, apiError, error })` |
|
||
| `src/services/api/openai/convertMessages.ts` | 输入类型从 Anthropic SDK `BetaMessageParam[]` 改为内部 `(UserMessage \| AssistantMessage)[]`;通过 `msg.type` 而非 `msg.role` 判断角色;从 `msg.message.content` 读取内容;跳过 `cache_edits` / `server_tool_use` 等内部 block 类型 |
|
||
| `src/services/api/openai/modelMapping.ts` | 移除 `OPENAI_MODEL_MAP` JSON 环境变量 + 缓存机制;新增 `getModelFamily()` 按 haiku/sonnet/opus 分类;解析优先级改为:`OPENAI_MODEL` → `ANTHROPIC_DEFAULT_{FAMILY}_MODEL` → `DEFAULT_MODEL_MAP` → 原名透传 |
|
||
| `src/services/api/openai/__tests__/convertMessages.test.ts` | 测试输入从裸 `{ role, content }` 改为 `makeUserMsg()` / `makeAssistantMsg()` 包装的内部格式 |
|
||
| `src/services/api/openai/__tests__/modelMapping.test.ts` | 测试从 `OPENAI_MODEL_MAP` 改为 `ANTHROPIC_DEFAULT_{HAIKU,SONNET,OPUS}_MODEL`;新增 3 个 env var override 测试 |
|
||
| `src/utils/model/providers.ts` | `getAPIProvider()` 新增最高优先级:从 settings.json `modelType` 字段判断;环境变量 `CLAUDE_CODE_USE_OPENAI` 降为次优先 |
|
||
| `src/utils/settings/types.ts` | `SettingsSchema` 新增 `modelType` 字段:`z.enum(['anthropic', 'openai']).optional()` |
|
||
|
||
**关键设计决策:**
|
||
|
||
1. **`modelType` 存入 settings.json** — 而非纯环境变量,使 `/login` 配置持久化,重启后仍然生效
|
||
2. **复用 `ANTHROPIC_DEFAULT_*_MODEL` 环境变量** — 而非新增 `OPENAI_MODEL_MAP`,与 Custom Platform 共用同一套模型映射配置,减少用户认知负担
|
||
3. **流处理双 yield** — 同时 yield `AssistantMessage`(给消费方处理工具调用)和 `StreamEvent`(给 REPL 实时渲染),与 Anthropic 路径行为对齐
|
||
4. **OAuth 登录重置 modelType** — 用户切换回官方 Anthropic 登录时自动重置为 `anthropic`,避免残留配置导致请求走错误路径
|
||
|
||
**配置方式:**
|
||
|
||
```
|
||
/login → 选择 "OpenAI Compatible" → 填写 Base URL / API Key / 模型名称
|
||
```
|
||
|
||
或手动编辑 `~/.claude/settings.json`:
|
||
|
||
```json
|
||
{
|
||
"modelType": "openai",
|
||
"env": {
|
||
"OPENAI_BASE_URL": "http://localhost:11434/v1",
|
||
"OPENAI_API_KEY": "ollama",
|
||
"ANTHROPIC_DEFAULT_SONNET_MODEL": "qwen3:32b"
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## Enable Remote Control / BRIDGE_MODE (2026-04-03)
|
||
|
||
**PR**: [claude-code-best/claude-code#60](https://github.com/claude-code-best/claude-code/pull/60)
|
||
|
||
Remote Control 功能将本地 CLI 注册为 bridge 环境,生成可分享的 URL(`https://claude.ai/code/session_xxx`),允许从浏览器、手机或其他设备远程查看输出、发送消息、审批工具调用。
|
||
|
||
**改动文件:**
|
||
|
||
| 文件 | 变更 |
|
||
|------|------|
|
||
| `scripts/dev.ts` | `DEFAULT_FEATURES` 加入 `"BRIDGE_MODE"`,dev 模式默认启用 |
|
||
| `src/bridge/peerSessions.ts` | stub → 完整实现:通过 bridge API 发送跨会话消息,含三层安全防护(trim + validateBridgeId 白名单 + encodeURIComponent) |
|
||
| `src/bridge/webhookSanitizer.ts` | stub → 完整实现:正则 redact 8 类 secret(GitHub/Anthropic/AWS/npm/Slack token),先 redact 再截断,失败返回安全占位符 |
|
||
| `src/entrypoints/sdk/controlTypes.ts` | 12 个 `any` stub → `z.infer<ReturnType<typeof XxxSchema>>` 从现有 Zod schema 推导类型 |
|
||
| `src/hooks/useReplBridge.tsx` | `tengu_bridge_system_init` 默认值 `false` → `true`,使 app 端显示 "active" 而非卡在 "connecting" |
|
||
|
||
**关键设计决策:**
|
||
|
||
1. **不改现有代码逻辑** — 只补全 stub、修正默认值、开启编译开关
|
||
2. **`tengu_bridge_system_init`** — Anthropic 通过 GrowthBook 给订阅用户推送 `true`,但我们的 build 收不到推送;改默认值是唯一不侵入其他代码的方案
|
||
3. **`peerSessions.ts` 认证** — 使用 `getBridgeAccessToken()` 获取 OAuth Bearer token,与 `bridgeApi.ts`/`codeSessionApi.ts` 认证模式一致
|
||
4. **`webhookSanitizer.ts` 安全** — fail-closed(出错返回 `[webhook content redacted due to sanitization error]`),不泄露原始内容
|
||
|
||
**验证结果:**
|
||
|
||
- `/remote-control` 命令可见且可用
|
||
- CLI 连接 Anthropic CCR,生成可分享 URL
|
||
- App 端(claude.ai/code)显示 "Remote Control active"
|
||
- 手机端(Claude iOS app)通过 URL 连接,双向消息正常
|
||
|
||

|
||
|
||
---
|
||
|
||
## GrowthBook 自定义服务器适配器 (2026-04-03)
|
||
|
||
GrowthBook 功能开关系统原为 Anthropic 内部构建设计,硬编码 SDK key 和 API 地址,外部构建因 `is1PEventLoggingEnabled()` 门控始终禁用。新增适配器模式,通过环境变量连接自定义 GrowthBook 服务器,无配置时所有 feature 读取返回代码默认值。
|
||
|
||
**修改文件:**
|
||
|
||
| 文件 | 变更 |
|
||
|------|------|
|
||
| `src/constants/keys.ts` | `getGrowthBookClientKey()` 优先读取 `CLAUDE_GB_ADAPTER_KEY` 环境变量 |
|
||
| `src/services/analytics/growthbook.ts` | `isGrowthBookEnabled()` 适配器模式下直接返回 `true`,绕过 1P event logging 门控 |
|
||
| `src/services/analytics/growthbook.ts` | `getGrowthBookClient()` base URL 优先使用 `CLAUDE_GB_ADAPTER_URL` |
|
||
| `docs/internals/growthbook-adapter.mdx` | 新增适配器配置文档,含全部 ~58 个 feature key 列表 |
|
||
|
||
**用法:** `CLAUDE_GB_ADAPTER_URL=https://gb.example.com/ CLAUDE_GB_ADAPTER_KEY=sdk-xxx bun run dev`
|
||
|
||
---
|
||
|
||
## Datadog 日志端点可配置化 (2026-04-03)
|
||
|
||
将 Datadog 硬编码的 Anthropic 内部端点改为环境变量驱动,默认禁用。
|
||
|
||
**修改文件:**
|
||
|
||
| 文件 | 变更 |
|
||
|------|------|
|
||
| `src/services/analytics/datadog.ts` | `DATADOG_LOGS_ENDPOINT` 和 `DATADOG_CLIENT_TOKEN` 从硬编码常量改为读取 `process.env.DATADOG_LOGS_ENDPOINT` / `process.env.DATADOG_API_KEY`,默认空字符串;`initializeDatadog()` 增加守卫:端点或 Token 未配置时直接返回 `false` |
|
||
| `docs/telemetry-remote-config-audit.md` | 更新第 1 节,反映新的环境变量配置方式 |
|
||
|
||
**效果:** 默认不向任何外部发送数据;设置两个环境变量即可接入自己的 Datadog 实例。原有 `DISABLE_TELEMETRY`、privacy level、sink killswitch 等防线保留。
|
||
|
||
**用法:** `DATADOG_LOGS_ENDPOINT=https://http-intake.logs.datadoghq.com/api/v2/logs DATADOG_API_KEY=xxx bun run dev`
|
||
|
||
---
|
||
|
||
## Sentry 错误上报集成 (2026-04-03)
|
||
|
||
恢复反编译过程中被移除的 Sentry 集成。通过 `SENTRY_DSN` 环境变量控制,未设置时所有函数为 no-op,不影响正常运行。
|
||
|
||
**新增文件:**
|
||
|
||
| 文件 | 说明 |
|
||
|------|------|
|
||
| `src/utils/sentry.ts` | 核心模块:`initSentry()`、`captureException()`、`setTag()`、`setUser()`、`closeSentry()`;`beforeSend` 过滤 auth headers 等敏感信息;忽略 ECONNREFUSED/AbortError 等非 actionable 错误 |
|
||
|
||
**修改文件:**
|
||
|
||
| 文件 | 变更 |
|
||
|------|------|
|
||
| `src/utils/errorLogSink.ts` | `logErrorImpl` 末尾调用 `captureException()`,所有经 `logError()` 的错误自动上报 |
|
||
| `src/components/SentryErrorBoundary.ts` | 添加 `componentDidCatch`,React 组件渲染错误上报到 Sentry(含 componentStack) |
|
||
| `src/entrypoints/init.ts` | 网络配置后调用 `initSentry()` |
|
||
| `src/utils/gracefulShutdown.ts` | 优雅关闭时 flush Sentry 事件 |
|
||
| `src/screens/REPL.tsx:2809` | `fireCompanionObserver` 调用增加 `typeof` 防护,BUDDY feature 启用时不报错(TODO: 待实现) |
|
||
| `package.json` | devDependencies 新增 `@sentry/node` |
|
||
|
||
**用法:** `SENTRY_DSN=https://xxx@xxx.ingest.sentry.io/xxx bun run dev`
|
||
|
||
---
|
||
|
||
## 默认关闭自动更新 (2026-04-03)
|
||
|
||
修改 `src/utils/config.ts` — `getAutoUpdaterDisabledReason()`,在原有检查逻辑前插入默认关闭逻辑。未设置 `ENABLE_AUTOUPDATER=1` 时,自动更新始终返回 `{ type: 'config' }` 被禁用。
|
||
|
||
**启用方式:** `ENABLE_AUTOUPDATER=1 bun run dev`
|
||
|
||
**原因:** 本项目为逆向工程/反编译版本,自动更新会覆盖本地修改的代码。
|
||
|
||
**同时新增文档:** `docs/auto-updater.md` — 自动更新机制完整审计,涵盖三种安装类型的更新策略、后台轮询、版本门控、原生安装器架构、文件锁、配置项等。
|
||
|
||
---
|
||
|
||
## WebSearch Bing 适配器补全 (2026-04-03)
|
||
|
||
原始 `WebSearchTool` 仅支持 Anthropic API 服务端搜索(`web_search_20250305` server tool),在非官方 API 端点(第三方代理)下搜索功能不可用。本次改动引入适配器架构,新增 Bing 搜索页面解析作为 fallback。
|
||
|
||
**新增文件:**
|
||
|
||
| 文件 | 说明 |
|
||
|------|------|
|
||
| `src/tools/WebSearchTool/adapters/types.ts` | 适配器接口定义:`WebSearchAdapter`、`SearchResult`、`SearchOptions`、`SearchProgress` |
|
||
| `src/tools/WebSearchTool/adapters/apiAdapter.ts` | API 适配器 — 将原有 `queryModelWithStreaming` 逻辑封装为 `ApiSearchAdapter` |
|
||
| `src/tools/WebSearchTool/adapters/bingAdapter.ts` | Bing 适配器 — 直接抓取 Bing HTML,正则提取搜索结果 |
|
||
| `src/tools/WebSearchTool/adapters/index.ts` | 适配器工厂 — 根据环境变量 / API Base URL 选择后端 |
|
||
| `src/tools/WebSearchTool/__tests__/bingAdapter.test.ts` | Bing 适配器单元测试(32 cases:decodeHtmlEntities、extractBingResults、search mock) |
|
||
| `src/tools/WebSearchTool/__tests__/bingAdapter.integration.ts` | Bing 适配器集成测试 — 真实网络请求验证 |
|
||
|
||
**重构文件:**
|
||
|
||
| 文件 | 变更 |
|
||
|------|------|
|
||
| `src/tools/WebSearchTool/WebSearchTool.ts` | 从直接调用 API 改为 `createAdapter()` 工厂模式;`isEnabled()` 始终返回 true;删除 ~200 行内联 API 调用逻辑 |
|
||
| `src/tools/WebFetchTool/utils.ts` | `skipWebFetchPreflight` 默认值从 `!undefined`(即 true)改为显式 `=== false`,使域名预检默认启用 |
|
||
|
||
**Bing 适配器关键技术细节:**
|
||
|
||
1. **反爬绕过**:使用完整 Edge 浏览器请求头(含 `Sec-Ch-Ua`、`Sec-Fetch-*` 等 13 个标头),避免 Bing 返回 JS 渲染的空页面;`setmkt=en-US` 参数强制美式英语市场,避免 IP 地理定位导致的区域化结果(德语论坛、新加坡金价等不相关内容)
|
||
2. **URL 解码**(`resolveBingUrl()`):Bing 返回的重定向 URL(`bing.com/ck/a?...&u=a1aHR0cHM6Ly9...`)中 `u` 参数为 base64 编码的真实 URL,需解码后使用
|
||
3. **摘要提取**(`extractSnippet()`):三级降级策略 — `b_lineclamp` → `b_caption <p>` → `b_caption` 直接文本
|
||
4. **HTML 实体解码**(`decodeHtmlEntities()`):处理 7 种常见 HTML 实体
|
||
5. **域过滤**:客户端侧 `allowedDomains` / `blockedDomains` 过滤,支持子域名匹配
|
||
|
||
**当前状态**:`adapters/index.ts` 中 `createAdapter()` 硬编码返回 `BingSearchAdapter`,跳过了 API/Bing 自动选择逻辑(原逻辑被注释保留)。未来可通过取消注释恢复自动选择。
|
||
|
||
---
|
||
|
||
## 移除反蒸馏机制 (2026-04-02)
|
||
|
||
项目中发现三处 anti-distillation 相关代码,全部移除。
|
||
|
||
**移除内容:**
|
||
- `src/services/api/claude.ts` — 删除 fake_tools 注入逻辑(原第 302-314 行),该代码通过 `ANTI_DISTILLATION_CC` feature flag 在 API 请求中注入 `anti_distillation: ['fake_tools']`,使服务端在响应中混入虚假工具调用以污染蒸馏数据
|
||
- `src/utils/betas.ts` — 删除 connector-text summarization beta 注入块及 `SUMMARIZE_CONNECTOR_TEXT_BETA_HEADER` 导入,该机制让服务端缓冲工具调用间的 assistant 文本并摘要化返回
|
||
- `src/constants/betas.ts` — 删除 `SUMMARIZE_CONNECTOR_TEXT_BETA_HEADER` 常量定义(原第 23-25 行)
|
||
- `src/utils/streamlinedTransform.ts` — 注释从 "distillation-resistant" 改为 "compact",streamlined 模式本身是有效的输出压缩功能,仅修正描述
|
||
|
||
---
|
||
|
||
## Buddy 命令合入 + Feature Flag 规范修正 (2026-04-02)
|
||
|
||
合入 `pr/smallflyingpig/36` 分支(支持 buddy 命令 + 修复 rehatch),并修正 feature flag 使用方式。
|
||
|
||
**合入内容(来自 PR):**
|
||
- `src/commands/buddy/buddy.ts` — 新增 `/buddy` 命令,支持 hatch / rehatch / pet / mute / unmute 子命令
|
||
- `src/commands/buddy/index.ts` — 从 stub 改为正确的 `Command` 类型导出
|
||
- `src/buddy/companion.ts` — 新增 `generateSeed()`,`getCompanion()` 支持 seed 驱动的可复现 rolling
|
||
- `src/buddy/types.ts` — `CompanionSoul` 增加 `seed?` 字段
|
||
|
||
**合并后修正:**
|
||
- `src/entrypoints/cli.tsx` — PR 硬编码了 `const feature = (name) => name === "BUDDY"`,违反 feature flag 规范,恢复为标准 `import { feature } from 'bun:bundle'`
|
||
- `src/commands.ts` — PR 用静态 `import buddy` 绕过了 feature gate,恢复为 `feature('BUDDY') ? require(...) : null` + 条件展开
|
||
- `src/commands/buddy/buddy.ts` — 删除未使用的 `companionInfoText` 函数和多余的 `Roll`/`SPECIES` import
|
||
- `CLAUDE.md` — 重写 Feature Flag System 章节,明确规范:代码中统一用 `import { feature } from 'bun:bundle'`,启用走环境变量 `FEATURE_<NAME>=1`
|
||
|
||
**用法:** `FEATURE_BUDDY=1 bun run dev`
|
||
|
||
---
|
||
|
||
## Auto Mode 补全 (2026-04-02)
|
||
|
||
反编译丢失了 auto mode 分类器的三个 prompt 模板文件,代码逻辑完整但无法运行。
|
||
|
||
**新增:**
|
||
- `yolo-classifier-prompts/auto_mode_system_prompt.txt` — 主系统提示词
|
||
- `yolo-classifier-prompts/permissions_external.txt` — 外部权限模板(用户规则替换默认值)
|
||
- `yolo-classifier-prompts/permissions_anthropic.txt` — 内部权限模板(用户规则追加)
|
||
|
||
**改动:**
|
||
- `scripts/dev.ts` + `build.ts` — 扫描 `FEATURE_*` 环境变量注入 Bun `--feature`
|
||
- `cli.tsx` — 启动时打印已启用的 feature
|
||
- `permissionSetup.ts` — `AUTO_MODE_ENABLED_DEFAULT` 由 `feature('TRANSCRIPT_CLASSIFIER')` 决定,开 feature 即开 auto mode
|
||
- `docs/safety/auto-mode.mdx` — 补充 prompt 模板章节
|
||
|
||
**用法:** `FEATURE_TRANSCRIPT_CLASSIFIER=1 bun run dev`
|
||
|
||
**注意:** prompt 模板为重建产物。
|
||
|
||
---
|
||
|
||
## USER_TYPE=ant TUI 修复 (2026-04-02)
|
||
|
||
`global.d.ts` 声明的全局函数在反编译版本运行时未定义,导致 `USER_TYPE=ant` 时 TUI 崩溃。
|
||
|
||
修复方式:显式 import / 本地 stub / 全局 stub / 新建 stub 文件。涉及文件:
|
||
`cli.tsx`, `model.ts`, `context.ts`, `effort.ts`, `thinking.ts`, `undercover.ts`, `Spinner.tsx`, `AntModelSwitchCallout.tsx`(新建), `UndercoverAutoCallout.tsx`(新建)
|
||
|
||
注意:
|
||
- `USER_TYPE=ant` 启用 alt-screen 全屏模式,中心区域满屏是预期行为
|
||
- `global.d.ts` 中剩余未 stub 的全局函数(`getAntModels` 等)遇到 `X is not defined` 时按同样模式处理
|
||
|
||
---
|
||
|
||
## /login 添加 Custom Platform 选项 (2026-04-03)
|
||
|
||
在 `/login` 命令的登录方式选择列表中新增 "Custom Platform" 选项(位于第一位),允许用户直接在终端配置第三方 API 兼容服务的 Base URL、API Key 和三种模型映射,保存到 `~/.claude/settings.json`。
|
||
|
||
**修改文件:**
|
||
|
||
| 文件 | 变更 |
|
||
|------|------|
|
||
| `src/components/ConsoleOAuthFlow.tsx` | `OAuthStatus` 类型新增 `custom_platform` state(含 `baseUrl`、`apiKey`、`haikuModel`、`sonnetModel`、`opusModel`、`activeField`);`idle` case Select 选项新增 Custom Platform 并排第一位;新增 `custom_platform` case 渲染 5 字段表单(Tab/Shift+Tab 切换、focus 高亮、Enter 跳转/保存);Select onChange 处理 `custom_platform` 初始状态(从 `process.env` 预填当前值);`OAuthStatusMessageProps` 类型及调用处新增 `onDone` prop |
|
||
| `src/components/ConsoleOAuthFlow.tsx` | 新增 `updateSettingsForSource` import |
|
||
|
||
**UI 交互:**
|
||
- 5 个字段同屏:Base URL、API Key、Haiku Model、Sonnet Model、Opus Model
|
||
- 当前活动字段的标签用 `suggestion` 背景色 + `inverseText` 反色高亮
|
||
- Tab / Shift+Tab 在字段间切换,各自保留输入值
|
||
- 每个字段按 Enter 跳到下一个,最后一个字段 (Opus) 按 Enter 保存
|
||
- 模型字段自动从 `process.env` 读取当前配置作为预填值,无值则空
|
||
- 保存时调用 `updateSettingsForSource('userSettings', { env })` 写入 settings.json,同时更新 `process.env`
|
||
|
||
**保存的 settings.json env 字段:**
|
||
```json
|
||
{
|
||
"ANTHROPIC_BASE_URL": "...",
|
||
"ANTHROPIC_AUTH_TOKEN": "...",
|
||
"ANTHROPIC_DEFAULT_HAIKU_MODEL": "...",
|
||
"ANTHROPIC_DEFAULT_SONNET_MODEL": "...",
|
||
"ANTHROPIC_DEFAULT_OPUS_MODEL": "..."
|
||
}
|
||
```
|
||
|
||
非空字段才写入,保存后立即生效(`onDone()` 触发 `onChangeAPIKey()` 刷新 API 客户端)。
|
||
|