Compare commits

...

133 Commits

Author SHA1 Message Date
claude-code-best
0a90b218c3 fix: 同步 permissionModeTitle 测试断言与 bypassPermissions 的新 title 值
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-26 15:07:50 +08:00
claude-code-best
de9494c0a3 feat: 添加 RSS 内存指示器并解绑 auto 权限模式与 TRANSCRIPT_CLASSIFIER
- 在 REPL 底栏添加 RSS 内存使用显示,512MB 以下 dimColor,512MB-1GB warning 色,1GB 以上 error 色
- auto 权限模式不再依赖 TRANSCRIPT_CLASSIFIER feature flag,classifier 不可用时 fallback 到 prompting
- Config 面板 defaultPermissionMode 使用类型安全的 permissionModeFromString,显示改用 shortTitle
- bypassPermissions title 缩短为 Bypass 与 shortTitle 一致

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-26 15:01:57 +08:00
claude-code-best
e7e1f7a34d fix: 修复 PowerShellTool.isSearchOrReadCommand 在 input 为 undefined 时崩溃的问题
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-26 15:01:57 +08:00
claude-code-best
9a5998eaef fix: 修复 Config 面板第二次进入时左右键无反应的问题
将左右键枚举值切换从依赖 DOM 焦点的 onKeyDown 改为 useKeybindings 系统,
确保按键在任何焦点状态下都能正确响应。同时修复 isSearchMode 初始值和布局问题。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-26 15:01:57 +08:00
claude-code-best
dff678924e refactor: 将 convertMessagesToLangfuse 参数类型从 unknown 收窄为联合类型
将 readonly unknown[] 改为 readonly LangfuseInputMessage[],
其中 LangfuseInputMessage = UserMessage | AssistantMessage | ChatCompletionMessageParam,
让调用方获得编译期类型检查。
2026-04-26 15:01:57 +08:00
Eric Guo
4591432a1d Fix mintlify validate errors (#367) 2026-04-26 11:07:20 +08:00
WANG HONGXIANG
901628b4d9 fix: 修复 OpenAI provider (gpt-5.4/gpt-5.3-codex等模型)下 内建mcp__plugin_weixin_weixin__reply 微信工具不可见的问题 (#359)
* fix: 修复 OpenAI provider 下 MCP 工具不可见

* docs: 补充 OpenAI MCP 工具列表注释

* fix: 修正 OpenAI Langfuse 输入记录

* refactor: 使用类型守卫收窄 Langfuse role

* fix: 保留 Langfuse OpenAI 数组消息角色

* fix: 合并 Langfuse OpenAI tool_calls

* fix: 修复 OpenAI Langfuse 类型检查
2026-04-26 09:17:09 +08:00
HitMargin
cf33c06021 添加deepseek-v4-pro支持选择max思考深度 (#365)
Co-authored-by: HitMargin <hitmargin@qq.com>
Co-authored-by: Copilot <copilot@github.com>
2026-04-26 09:00:43 +08:00
claude-code-best
e0ca1d054c chore: 1.10.2 2026-04-25 20:37:40 +08:00
claude-code-best
6585d0f67c fix: 禁用 COORDINATOR_MODE 和 TEAMMEM 解决内存溢出问题
COORDINATOR_MODE 的 AgentSummary 每 30s fork 完整消息历史是 GB 级内存泄露的主因,
TEAMMEM 依赖 COORDINATOR_MODE 且邮箱文件无限增长。同时恢复 DAEMON(非主因)。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-25 20:29:52 +08:00
claude-code-best
e4403ff010 fix: 移除 RCS 按 machineName 复用 agent 记录的逻辑
多个同名 acp-link 实例注册到 RCS 时,REST 注册阶段按 machineName
去重导致不同实例共享同一条记录。改为每次注册都创建独立记录,
重连恢复由 WS identify 阶段按 environment_id 精确匹配。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-25 19:27:58 +08:00
claude-code-best
9e61e7a90d chore: 更新 biome 注释 2026-04-25 16:33:02 +08:00
claude-code-best
d03af7bd4e chore: 1.10.0 2026-04-25 14:48:15 +08:00
claude-code-best
e8ef955ff9 docs: 添加 /login 说明 2026-04-25 14:47:43 +08:00
claude-code-best
a8ed0cdce5 fix: 修复构建后 vendor 二进制路径解析错误(ripgrep/audio-capture)
构建后 chunk 文件位于 dist/chunks/(Vite)或 dist/(Bun),vendor 二进制在
dist/vendor/,但 ripgrep 和 audio-capture 的路径解析未考虑 chunks/ 层级,
导致 ENOENT。改用 import.meta.url 路径中 lastIndexOf('dist') 定位 dist 根,
并同步在 build.ts 和 post-build.ts 中添加 ripgrep vendor 文件复制。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-25 14:46:02 +08:00
claude-code-best
1c3b280c6a fix: 尝试修复多轮对话缓存失效 skill 提升的问题 2026-04-25 14:31:32 +08:00
claude-code-best
7a3cc24a00 fix: 尝试修复 nodejs windows 环境的问题 2026-04-25 14:07:45 +08:00
claude-code-best
2e7fc428cd feat: 集成豆包 ASR 语音识别后端,支持 /voice doubao 切换 (#357)
* feat: 集成豆包 ASR 语音识别后端,支持 /voice doubao 切换

- 新增 src/services/doubaoSTT.ts 适配模块,将 doubaoime-asr 的
  AsyncGenerator 协议适配为现有 VoiceStreamConnection 接口
- /voice doubao 启用豆包后端,/voice 使用默认 Anthropic 后端
- 后端选择持久化到 settings.json 的 voiceProvider 字段
- 豆包后端跳过 Anthropic OAuth 认证、语言限制和 Focus Mode
- 豆包后端松手即出结果,跳过 processing 状态
- 凭证文件存放在 ~/.claude/tts/doubao/credentials.json
- doubaoime-asr 作为 optionalDependencies 安装
- 移除 /voice 命令的 claude-ai 可用性限制,所有用户可用

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* docs: 更新 Voice Mode 文档,添加豆包 ASR 后端说明和致谢

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-25 13:57:30 +08:00
claude-code-best
ad09f38fd1 fix: 修复在已有文本前输入斜杠命令无法触发自动补全,以及 Tab 补全覆盖后续文本的问题
当用户在已输入文本前插入 /command 时,光标后的文本包含空格,导致补全逻辑误判命令已有参数而跳过建议。
修复方式:只取光标前的文本(commandInput)进行命令解析和补全生成。

同时修复 Tab 补全斜杠命令时覆盖光标后文本的问题,改为在光标位置拼接补全结果。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-25 09:27:14 +08:00
claude-code-best
b0a3ef90dc chore: 1.9.5 2026-04-25 08:56:31 +08:00
claude-code-best
c07ad4c738 chore: 清理仓库审计问题——修正 CLAUDE.md、删除冗余 yoga-layout、清除 621 个未使用的类型 stub (#354)
- 修正 CLAUDE.md/AGENTS.md 六处过时陈述:modifiers-napi、url-handler-napi 已非 stub,
  Magic Docs/LSP Server/Plugins/Marketplace 已恢复
- 删除未使用的 src/native-ts/yoga-layout/ 冗余副本(2715 行),权威版本保留在 packages/@ant/ink
- 删除 src/ 下 621 个 Auto-generated type stub 文件(全部 export type X = any,无活跃引用)

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-25 08:54:18 +08:00
claude-code-best
e38d45460e fix: 修复 Windows Node.js 构建产物因 stdin.ref() 泄漏导致进程挂起 (#353)
startCapturingEarlyInput() 调用 stdin.ref() 后,如果 Ink 未能接管
(如 raw mode 不支持或 setup 阶段异常),unref() 永远不会被调用,
导致 Node.js 事件循环无法退出。修复包括:
- stopCapturingEarlyInput() 中补充 stdin.unref() 调用
- 新增 10s 安全阀定时器自动清理 leaked ref()
- Ink App.componentWillUnmount 兜底 unref() 非 TTY stdin

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-24 21:16:15 +08:00
claude-code-best
e0c8e9dafc chore: 添加学习文件夹 2026-04-24 20:33:43 +08:00
claude-code-best
047c85fcbf fix: 修复 DeepSeek V4 reasoning_content 回传导致的 400 错误
- 扩大模型名称检测范围,匹配所有 deepseek 模型(V4、R1 等)
- 始终保留 thinking blocks 为 reasoning_content 回传给 API
- 移除有 bug 的 turn boundary 剥离逻辑

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-24 20:33:43 +08:00
claude-code-best
da6d06365d fix: 修复 anthropic 煞笔的四个 bug (#352)
* fix: 移除文件编辑前必须先读取的限制

移除 FileEditTool 和 FileWriteTool 中的 "read before edit" 校验,
允许直接编辑未读取过的文件。保留文件修改过期检测。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* docs: 更新 teach-me 自动写 note 笔记的功能

* fix: 修复 DeepSeek V4 reasoning_content 回传导致的 400 错误

- 扩大模型名称检测范围,匹配所有 deepseek 模型(V4、R1 等)
- 始终保留 thinking blocks 为 reasoning_content 回传给 API
- 移除有 bug 的 turn boundary 剥离逻辑

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* fix: Opus 4.6/4.7 默认推理 effort 从 medium 改为 high

Pro 和 Max/Team 订阅者的 Opus 默认 effort 之前被降级为 medium,
导致用户感知模型「变笨」。恢复为 high。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* fix: 移除 thinkingClearLatched sticky-on 机制

空闲超过 1 小时后 thinkingClearLatched 会被触发且永不重置,
导致每轮 API 调用都清除 thinking 历史。完整移除该 latch 机制,
clearAllThinking 硬编码为 false。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* fix: 移除 numeric_length_anchors 系统指令

删除「工具调用间文字 ≤25 词、最终回复 ≤100 词」的硬性限制。
ablation 测试显示该约束使整体智能下降 3%。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* fix: 修复测试中 reasoning_content 类型断言

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-24 20:07:18 +08:00
claude-code-best
8613d558a8 Merge pull request #350 from YuanyuanMa03/fix-bun-install-readme
docs: clarify Bun setup without duplicate steps
2026-04-24 19:47:35 +08:00
YuanyuanMa03
017c251f78 docs: clarify bun setup without duplicate steps 2026-04-24 18:03:21 +08:00
YYMa
d4223abc34 Merge pull request #1 from YuanyuanMa03/fix-bun-install-readme
docs: correct Bun post-install instructions
2026-04-24 17:40:00 +08:00
YYMa
5125a159d2 docs: correct Bun post-install instructions 2026-04-24 17:36:57 +08:00
claude-code-best
d09f363414 Merge pull request #347 from amDosion/feat/ssh-remote-v2
feat: 启用 SKILL_LEARNING 编译开关
2026-04-24 16:07:10 +08:00
unraid
9d35f98ec7 feat: 启用 SKILL_LEARNING 编译开关
将 SKILL_LEARNING 加入 DEFAULT_BUILD_FEATURES,
构建产物中默认启用技能学习系统。
2026-04-24 15:18:26 +08:00
claude-code-best
eb833da33b fix: 创建 agent 后刷新 loadMarkdownFilesForSubdir 缓存
新建 agent 后 clearAgentDefinitionsCache 漏清底层
loadMarkdownFilesForSubdir 的 memoize 缓存,导致新
agent 不会立即出现在列表中,需要重启才能生效。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-24 15:05:05 +08:00
claude-code-best
eadd32ae47 docs: 同步 AGENTS.md 与 CLAUDE.md 2026-04-24 15:05:05 +08:00
claude-code-best
3c55a8c83f Merge pull request #344 from amDosion/feat/ssh-remote-v2
feat: SSH Remote — 本地 REPL + 远端工具执行
2026-04-24 14:36:11 +08:00
claude-code-best
5582bb47ef docs: 五一 lint 提示 2026-04-24 14:35:39 +08:00
claude-code-best
95bb191977 Merge pull request #341 from YuanyuanMa03/docs/bun-installation-guide
docs: 添加 Bun 安装详细说明
2026-04-24 14:29:39 +08:00
unraid
03811f973b feat: 实现 SSH Remote — 本地 REPL + 远端工具执行
SSH Remote 允许在本地运行交互式 REPL,同时将工具调用(Bash、文件读写等)
通过 SSH 隧道转发到远程主机执行。

核心模块:
- SSHSessionManager: NDJSON 双向通信、权限转发、指数退避重连
- SSHAuthProxy: 本地认证代理 + SSH -R 反向端口转发,nonce 验证
- SSHProbe: 远端主机平台/架构/已有二进制探测
- SSHDeploy: 远端二进制部署(scp)
- createSSHSession: 会话编排(probe → deploy → spawn → attach)

新增选项:
- --remote-bin: 跳过 probe/deploy,使用自定义远端二进制
- ANTHROPIC_AUTH_NONCE: API 请求认证 nonce header

包含 17 个单元测试和完整文档。
2026-04-24 14:25:56 +08:00
YuanyuanMa03
02ab1a0307 docs: 添加 Bun 安装详细说明
- 添加 Linux/macOS/Windows 各平台的安装命令
- 添加安装后的操作步骤(重启终端、验证安装、更新版本)
- 同步更新中英文 README
2026-04-24 12:07:18 +08:00
claude-code-best
2a5b263641 chore: 1.9.4 2026-04-24 10:50:53 +08:00
claude-code-best
f2dd5142b3 refactor: 解耦 BRIDGE_MODE 与 DAEMON,禁用 DAEMON 降低内存占用
- 从 DEFAULT_BUILD_FEATURES 注释掉 DAEMON(内存占用过高)
- remoteControlServer 命令门控从 feature('DAEMON') && feature('BRIDGE_MODE')
  改为仅 feature('BRIDGE_MODE'),bridge 不再依赖 daemon
- --daemon-worker 快速路径改为运行时检测,未启用时输出明确错误提示

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-24 10:01:05 +08:00
claude-code-best
4dcbaf1e66 fix: 修复 ACP 模式下 messageSelector require 失败导致 submitMessage 崩溃
ACP 模式不加载完整的 React/Ink UI 组件,导致 require('src/components/MessageSelector.js')
返回 undefined。添加 try-catch 和 optional chaining fallback。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-24 09:59:23 +08:00
claude-code-best
0b304730d8 docs: 为 DEFAULT_BUILD_FEATURES 每个 feature flag 添加功能注释
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-24 09:26:59 +08:00
claude-code-best
7a0dd3057e chore: 1.9.3 2026-04-23 23:21:43 +08:00
claude-code-best
ca1c87f460 fix: 修复 usePipeIpc 中 require 返回 undefined 导致启动崩溃
将 lazy require() 调用全部替换为静态 import,解决构建产物中
模块加载时序问题导致的 'undefined is not an object' 错误。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-23 23:21:38 +08:00
claude-code-best
fc7a85f5c7 chore: 1.9.2 2026-04-23 23:04:18 +08:00
claude-code-best
5bc12b00b2 chore: 更新版本流水线 2026-04-23 22:55:27 +08:00
claude-code-best
792777d68c chore: 1.9.1 2026-04-23 22:46:51 +08:00
claude-code-best
047634afe6 ci: 删除冗余 release 工作流 2026-04-23 22:45:53 +08:00
claude-code-best
a92af99448 ci: 添加 GitHub Release 和自动生成 changelog 到发布流程 2026-04-23 22:44:02 +08:00
claude-code-best
cfe1552ec9 ci: 统一 typecheck 命令并添加 npm 发布工作流 2026-04-23 22:42:33 +08:00
claude-code-best
9624f880e0 fix: 修复第三方 Anthropic base URL 应使用 ExaSearchAdapter 而非 BingSearchAdapter
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-23 21:52:16 +08:00
claude-code-best
85e5a8cffb chore: 贡献者更新工作流改为每周定时触发
移除 push 触发,仅保留每周一 schedule 触发。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-23 20:17:46 +08:00
claude-code-best
299953b0ee fix: 修复 cliHighlight 类型不兼容问题
loadedGetLanguage 返回类型中 name 字段改为可选,匹配 highlight.js
Language 类型中 name 为 string | undefined 的定义。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-23 20:12:47 +08:00
claude-code-best
7a3fdf6e67 chore: 1.9.0 2026-04-23 20:10:29 +08:00
claude-code-best
b642977afe Merge pull request #335 from realorange1994/feature/cli-highlight
fix: 将 highlight.js 改为静态导入以兼容 Bun --compile 模式
2026-04-23 20:07:27 +08:00
claude-code-best
781188862e Merge pull request #333 from realorange1994/feature/exa-search
feat: 添加 Exa AI 搜索适配器
2026-04-23 20:06:53 +08:00
claude-code-best
b966eef5a9 Merge branch 'main' into feature/exa-search 2026-04-23 20:04:13 +08:00
claude-code-best
c3d63c8fe2 chore: 添加 release 脚本 2026-04-23 19:58:55 +08:00
Bot
7d4c4278c0 fix: 将 highlight.js 改为静态导入以兼容 Bun --compile 模式
- cliHighlight.ts: 使用静态 import 替换 dynamic import('highlight.js'),
  因为编译模式下模块解析指向内部 bunfs 路径导致无法找到
- color-diff-napi/src/index.ts: 同样改为静态导入,移除 createRequire 延迟加载
2026-04-23 18:47:31 +08:00
Bot
93bfdabff1 feat: 添加 Exa AI 搜索适配器
- 新增 ExaSearchAdapter,基于 MCP 协议调用 Exa 搜索 API
- WebSearchTool 支持 num_results、livecrawl、search_type、context_max_characters 等高级选项
- 非 Anthropic 官方 base URL 时默认使用 Exa 适配器
2026-04-23 18:43:41 +08:00
claude-code-best
1173a62301 refactor: 统一 log.ts/debug.ts 的测试 mock 为共享定义
- 新增 tests/mocks/log.ts 和 tests/mocks/debug.ts,覆盖源文件全部实际导出
- 移除旧 mock 中不存在的导出(logToFile、logEvent、getLogFilePath)
- 13 个测试文件改为使用共享 mock,避免定义分散和不一致

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-23 11:39:53 +08:00
claude-code-best
7ea69ca279 fix: 修复 build 过程中的问题 2026-04-23 11:39:46 +08:00
claude-code-best
4e82fb5974 Merge pull request #330 from claude-code-best/feature/improve-v2-final
feat: 整合功能恢复与技能学习闭环 v2 (重构版)
2026-04-22 22:55:20 +08:00
claude-code-best
f43350e600 fix: 修复 4 个测试失败(路径规范化、SDK 签名变更、空消息防护)
- projectContext.test.ts: 使用 realpathSync 处理 macOS /var→/private/var 符号链接
- bedrockClient.test.ts: 适配 Bedrock SDK v0.80 Bearer 认证(原 AWS4-HMAC-SHA256)
- bridge.ts: forwardSessionUpdates 添加 null guard 防止空消息导致 TypeError

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-22 22:52:37 +08:00
unraid
23fcbf9004 feat: 添加 UI 组件增强与测试覆盖
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-22 22:38:10 +08:00
unraid
23bb09d240 feat: 添加 model/provider 层改进
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-22 22:38:10 +08:00
unraid
d208855f07 feat: 添加 builtin-tools 增强与测试覆盖
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-22 22:38:10 +08:00
unraid
7881cc617c feat: 增强 ACP 桥接与权限处理
- 增强 ACP agent 测试覆盖
- 扩展 ACP bridge 测试用例
- 改进 ACP utils 权限管道

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-22 22:38:10 +08:00
unraid
c7e1c50b86 feat: 添加服务层增强与零散改进
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-22 22:38:10 +08:00
unraid
2247026bd5 chore: 添加脚本与构建配置更新
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-22 22:38:10 +08:00
unraid
eec961352b feat: 添加 napi 包测试覆盖与 stub 改进
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-22 22:38:10 +08:00
unraid
fb41513b32 feat: 添加工具类增强与状态管理改进
- 新增 workflowRuns、remoteTriggerAudit、pipeStatus 等工具
- 增强 permissionSetup: auto mode 和 bypass permissions 始终可用
- 新增多组测试覆盖 (modifiers, teamDiscovery, deepLink 等)
- 修复 parseInt 缺少 radix 参数
- 移除多余 biome-ignore 注释

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-22 22:38:10 +08:00
unraid
94c4b37eed feat: 添加 summary 命令 TypeScript 重写与其他命令增强
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-22 22:38:09 +08:00
unraid
6c5df395c3 feat: 添加 compact 缓存与上下文压缩增强
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-22 22:38:09 +08:00
unraid
be97a0b010 feat: 添加 Bedrock API 客户端及 API 层增强
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-22 22:38:09 +08:00
unraid
59f8675fa3 feat: 添加 Windows Terminal swarm 后端及 swarm 增强
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-22 22:38:09 +08:00
unraid
c4775fff58 feat: 添加 autonomy 自主模式命令系统
- 新增 autonomy CLI handler 和交互式面板
- 新增 autonomyCommandSpec 命令规范定义
- 新增 autonomyAuthority 权限控制
- 新增 autonomyStatus 状态管理
- 注册 CLI 子命令 (claude autonomy status/runs/flows/flow)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-22 22:38:09 +08:00
unraid
31b2fdd97a feat: 添加 provider usage 统计与余额查询
- 新增 providerUsage 服务(anthropic/bedrock/openai 适配器)
- 新增余额查询(deepseek/generic poller)
- StatusLine 保留原有 rateLimits 接口不变

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-22 22:38:09 +08:00
unraid
1837df5f88 feat: 添加 skill learning 技能学习闭环系统
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-22 22:38:09 +08:00
unraid
04c7ed4250 chore: 删除废弃文档和残留文件
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-22 22:38:08 +08:00
claude-code-best
711927f01b chore: 更新 lock 文件 2026-04-21 08:20:40 +00:00
claude-code-best
956e98a445 fix: 修复重复依赖声明 2026-04-21 16:16:38 +08:00
claude-code-best
cee62bc654 fix: 修复 model alias 导致无限递归栈溢出
当用户 settings 中配置 model = "opus[1m]" 等 alias 值时,
getDefaultOpusModel() → parseUserSpecifiedModel() → getDefaultOpusModel()
形成无限递归,导致启动时 RangeError: Maximum call stack size exceeded。

在 getDefaultOpusModel/Sonnet/Haiku 的 fallback 路径中增加
isAliasOrAliasWithSuffix 守卫,跳过 alias 值直接使用硬编码默认值。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-21 16:10:16 +08:00
claude-code-best
5fc7c8e13d chore: 添加 highlight.js 包 2026-04-21 12:42:10 +08:00
claude-code-best
300faa18d0 Merge branch 'feature/unknown-llm-feature-test' 2026-04-21 12:06:19 +08:00
claude-code-best
96ec96c720 feat: 添加 ccb update 命令,支持 npm/bun 自动更新
从 package.json 读取当前版本,查询 npm registry 最新版本,
自动检测安装方式(bun 或 npm)执行全局更新。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-20 22:35:57 +08:00
claude-code-best
13a0bfc479 fix: 修复构建产物 import 失效问题 2026-04-20 22:29:44 +08:00
claude-code-best
84f0271813 chore: 1.7.1 2026-04-20 22:13:31 +08:00
claude-code-best
ed4bdb9338 feat: 增强 auto mode 的易用性 (#312)
* feat: poor 模式降级 yolo 审阅模型

* feat: 为多模块添加 Langfuse tracing 支持

在 web search、agent creation、away summary、token estimation、
skill improvement 等模块中集成 Langfuse trace,并透传至
compact/apiQueryHook/execPromptHook 等调用链。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: 让 auto mode 记录回主 trace

* fix: reopen auto mode prompt when classifier is unavailable

* fix: 修复 auto mode 情况下, llm 报错导致弹窗也不打开的问题

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-20 21:13:09 +08:00
claude-code-best
e4ce08fe39 Fixture/langfuse record auto mode data error (#308)
* fix: 修复状态栏 context 计数器在 loading 时闪现为 0 的问题

第三方 API(如智谱)在 message_start 中可能不返回完整 usage 数据,
导致 getCurrentUsage 返回全零 usage 对象,使 ctx 显示为 0%。

双重保护:
- getCurrentUsage: 跳过全零 usage,继续往前找有真实数据的 message
- calculateContextPercentages: totalInputTokens 为 0 时返回 null

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: 外部化 ESM 包使用 createRequire 替代裸 require

color-diff-napi、image-processor-napi、audio-capture-napi 声明
"type": "module" 但使用裸 require(),Node.js ESM 中 require
不可用。改用 createRequire(import.meta.url) 或顶层 import。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: getDefaultSonnetModel 优先使用用户配置的模型,修复第三方 provider 模型不存在错误

当用户通过 ANTHROPIC_MODEL 或 settings 配置了自定义 provider 支持的模型时,
getDefaultSonnetModel/Haiku/Opus 现在会优先使用该配置,而非硬编码 Anthropic 官方模型 ID。
同时改进 Langfuse 可观测性:sideQuery 失败时记录错误信息到 span,
optional 模式下标记 WARNING 而非 ERROR。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: 将 auto_mode classifier 的 side-query span 绑定到父 trace

classifyYoloAction 及 classifyYoloActionXml 接收 parentSpan 参数,
透传给 sideQuery 调用,使 auto_mode 的 side-query span 嵌套在主 agent trace 下。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: 穷鬼模式下跳过 memdir_relevance side-query

Poor mode 启用时不执行 findRelevantMemories 的预取调用,
避免额外的 API token 消耗。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: 添加 test:all 脚本用于完成任务后的全量检查

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: Vite 构建补齐缺失的 feature flags,修复 auto mode 不可见

Vite 构建插件的 DEFAULT_BUILD_FEATURES 缺少 BUDDY、TRANSCRIPT_CLASSIFIER、
BRIDGE_MODE、ACP、BG_SESSIONS、TEMPLATES,导致 feature('TRANSCRIPT_CLASSIFIER')
被替换为 false,auto mode 从 Shift+Tab 循环中消失。与 build.ts 对齐。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: 统一 feature flags 到 defines.ts,修复 Vite 构建缺失 auto mode

将 DEFAULT_BUILD_FEATURES 列表从 build.ts、dev.ts、vite-plugin-feature-flags.ts
三处内联定义统一到 scripts/defines.ts 单一导出。之前的 Vite 插件缺少
TRANSCRIPT_CLASSIFIER 等 feature flag,导致 auto mode 在 Vite 构建中不可见。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-20 13:30:05 +08:00
claude-code-best
92f8a92fbb feat: 正式启用 auto mode (#307)
* fix: 修复settings.json内存状态溢出的问题

* fix: 修复auto mode gate check未处理的promise rejection

在 bypassPermissionsKillswitch.ts 的 useKickOffCheckAndDisableAutoModeIfNeeded
中,void fire-and-forget 调用缺少 .catch() 处理,导致 verifyAutoModeGateAccess
失败时产生 unhandled promise rejection。同时移除 permissionSetup.ts 中冗余的
null check。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: 开放 auto mode 和 bypass mode 给所有用户

通过 Shift+Tab 统一循环:default → acceptEdits → plan → auto → bypassPermissions → default

- 移除 USER_TYPE 分支判断,所有用户使用同一循环路径
- isBypassPermissionsModeAvailable 始终为 true
- isAutoModeAvailable 初始化直接为 true
- 移除 AutoModeOptInDialog 确认流程
- 简化 isAutoModeGateEnabled 仅保留快模式熔断器
- 简化 verifyAutoModeGateAccess 仅检查快模式
- 移除 GrowthBook/Statsig 远程门控
- bypass permissions killswitch 改为 no-op
- 新增 24 个测试覆盖循环逻辑和门控不变量

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: 为sideQuery添加Langfuse追踪

sideQuery 绕过了 claude.ts 的主 API 路径,导致所有走 sideQuery 的调用
(auto mode classifier、permission explainer、session search 等)都没有
Langfuse 记录。现在为每次 sideQuery 调用创建独立 trace 并记录 LLM observation,
未配置 Langfuse 时全部 no-op。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: ACP availableModes 补齐 bypassPermissions 并修正测试 import 路径

- ACP agent availableModes 按条件包含 bypassPermissions(非 root/sandbox)
- 顺序对齐 REPL 循环:default → acceptEdits → plan → auto → bypassPermissions
- 新增 2 个测试验证 availableModes 包含 bypassPermissions 及模式切换
- 修正 getNextPermissionMode.test.ts 和 permissionSetup.test.ts 的 import 路径

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-20 10:20:27 +08:00
claude-code-best
a67e2d0e97 docs: 更新 npm 安装 2026-04-19 22:00:48 +08:00
claude-code-best
8c629858ab chore: 1.6.0 2026-04-19 21:37:35 +08:00
claude-code-best
494eab7204 feat: 接入内建 weixin channel(同 #301 重构版本) (#303)
* feat: 接入 weixin 服务层与命令入口

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>

* feat: 注册内建 weixin channel 插件

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>

* fix: 修正 channel permission relay 路由与能力判定

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>

* fix: 修复 builtin channel 的 ChannelsNotice 误报

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>

* docs: 补充内建 weixin channel 使用说明

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>

* docs: 更新微信 channel 接入计划状态

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>

* fix: 延迟加载 weixin 登录二维码依赖

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>

* fix: 改用 qrcode 生成 weixin 登录二维码

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>

* fix: 修正 vite 构建的 Windows 路径解析

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>

* chore: 删除临时规划文档 wx_channel.md 并还原 package.json 排序

wx_channel.md 内容已整合到 docs/features/channels.md,不再需要。
package.json 中 @ant/model-provider 位置从原始位置被无意移动,还原。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor: 将 weixin 模块从 src/ 迁移至 packages/weixin 工作区包

将 src/services/weixin/ 中的纯业务逻辑迁入 @claude-code-best/weixin
workspace 包,降低 src/ 耦合度。仅保留 server.ts 作为薄适配层。

- 迁移 7 个无修改的纯模块 (types/api/accounts/login/pairing/media/send)
- monitor.ts 内联 PERMISSION_REPLY_RE 正则,解除对 src/ 的依赖
- permissions.ts 本地定义 ChannelPermissionRequestParams 接口
- cli.ts 拆分:serve 子命令通过回调注入,login/access 保留在包内
- server.ts 重写为从 @claude-code-best/weixin 导入
- 新增 cli-serve.ts 作为 serve 入口薄壳

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: 修正 weixin barrel export 中 interface 的导出方式

ChannelPermissionRequestParams 是纯类型,必须用 export type 导出,
否则 Bun 运行时会报 "export not found" 错误。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor: 将 server.ts 迁入 packages/weixin,彻底移除 src/services/weixin/

通过依赖注入(WeixinServerDeps)解耦 src/ 依赖(analytics、config、
MCP channel schema),server.ts 完全移入包内。cli.tsx 入口处一次性
注入所有依赖。

src/services/weixin/ 目录已完全删除。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: 修复 markdownToPlainText 中代码块正则的 ReDoS 风险

用非正则的线性扫描替代 \`\`\`[\s\S]*?\n([\s\S]*?)\`\`\` 匹配,
避免在含有大量重复 \`\`\` 序列的输入上触发多项式回溯。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: 1111 <11111@asd.c>
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-19 21:33:27 +08:00
claude-code-best
b83c3008d0 docs: 更新 discord 地址 2026-04-19 21:21:04 +08:00
claude-code-best
66d2671c98 feat: acp manager (#304)
* feat: acp 控制器第一版

* feat: acp-link 命令二合一
2026-04-19 21:18:18 +08:00
claude-code-best
c7bc8c8636 feat: remote control 支持 auto bind 功能 (#300)
* feat: acp-link 支持 --group 参数指定 channel group

- 添加 --group CLI flag,校验格式 [a-zA-Z0-9_-]+
- 支持 ACP_RCS_GROUP 环境变量 fallback
- 传递 channelGroupId 到 RcsUpstreamClient
- 更新 README 文档说明 --group 和相关环境变量

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: RCS 后端 session 复用与 group 绑定

- storeFindEnvironmentByMachineName 匹配 offline 状态,防止重连创建重复 session
- registerEnvironment 复用已有 session 而非每次新建
- EnvironmentResponse 返回 channel_group_id 字段
- 注册时将 session 绑定到 group ID,支持 web UI 按 group 查询
- apiKeyAuth 不再设置 uuid,由 uuidAuth 统一处理

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: Web UI Token Manager — 多 token 切换与 session 隔离

- 新增 useTokens hook 管理 localStorage token CRUD
- 新增 TokenManagerDialog 弹窗组件(添加/编辑/删除/切换 token)
- api client 支持Bearer token 认证,UUID 跟随 token 变化
- Navbar 添加 token 切换按钮
- 切换 token 时自动 reload,实现 session 数据隔离

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: 修复 useTokens useState 初始化函数签名错误

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-19 13:04:09 +08:00
claude-code-best
673ccd1800 chore: 1.5.0 2026-04-19 12:34:51 +08:00
claude-code-best
d1ab38c089 chore: 移除 pre-commit git hook
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-19 12:31:31 +08:00
claude-code-best
f9d011164a fix: 替换 web 端 crypto.randomUUID 为 uuid 库以支持 HTTP 环境
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-19 10:33:15 +08:00
claude-code-best
481e2a58a9 feat: 恢复 --channels 能力 (#297)
* feat: 恢复  --channels 能力

* docs: 添加 channels 注释
2026-04-19 10:24:34 +08:00
claude-code-best
c5edee431f docs: 文档检查/check 20260419 (#296)
* docs: 修复文档巡检发现的 4 处错误

- daemon.md: 反映实际实现状态(supervisor/worker 已实现而非 stub)
- bridge-mode.md: API 操作数量从 7 修正为 9
- web-search-tool.md: 文件路径从 src/tools/ 修正为 packages/builtin-tools/src/tools/
- remote-control-self-hosting.md: 补充缺失的 RCS_WS_IDLE_TIMEOUT 和 RCS_WS_KEEPALIVE_INTERVAL 配置项

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: 修正 Safety 和 Context 文档中的代码引用和类型错误

- permission-model: 修正规则来源从"五层"到八层,优先级顺序对齐代码
- permission-model: PermissionUpdate 类型改为实际的 addRules/replaceRules 等
- permission-model: 补充 acceptEdits 和 dontAsk 两种权限模式
- permission-model: DENIAL_LIMITS 字段名对齐实际代码
- plan-mode: 工具路径从 src/tools/ 改为 packages/builtin-tools/src/tools/
- compaction: 修正 COMPACTABLE_TOOLS 和 POST_COMPACT_* 的行号
- project-memory: 修正 ENTRYPOINT_NAME 常量的行号
- system-prompt: 修正 SystemPrompt 类型定义文件路径和多个行号引用

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: 修复 introduction 文档中的错误路径和行号引用

- why-this-whitepaper.mdx: BashTool 路径从 src/tools/ 修正为 packages/builtin-tools/src/tools/
- what-is-claude-code.mdx: 移除不存在的 Azure provider,改为实际的 7 种 provider
- architecture-overview.mdx: State 类型行号从 204 修正为 207

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: 修复 conversation/features 文档中的错误

- streaming.mdx: queryStreamRaw → queryModelWithStreaming 函数名修正
- streaming.mdx: Azure 提供商不存在,替换为实际 7 个提供商
- debug-mode.mdx: --inspect-wait 描述错误,实际使用 BUN_INSPECT 环境变量
- buddy.mdx: 补充缺失的 companionReact.ts、CompanionCard.tsx、index.ts

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: 修复文档巡检中的源码引用错误

- feature-flags.mdx: 修正 feature() 兜底描述,实际从 bun:bundle 导入而非 cli.tsx:3 内联
- feature-flags.mdx: 修正工具 require 路径为 @claude-code-best/builtin-tools 包路径
- ant-only-world.mdx: 修正 tools.ts 中 require 路径为包路径
- ant-only-world.mdx: 修正 INTERNAL_ONLY_COMMANDS 行号 (267-295) 和数量 (24+)
- skills.mdx: 修正 COMMANDS memoize 行号 258 → 299
- mcp-protocol.mdx: 修正 fetchToolsForClient LRU 缓存上限 20 → 100
- streaming.mdx: 修正流式事件引用
- file-operations.mdx: 修正工具路径引用
- search-and-navigation.mdx: 修正搜索工具引用
- shell-execution.mdx: 修正 shell 工具引用
- buddy.mdx: 补充缺失的 frontmatter 字段
- debug-mode.mdx: 修正调试模式描述

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: 修正 tools/agent 文档中的文件路径和行号引用

- 修正 TodoWriteTool、AgentTool、ToolSearchTool 等工具路径
  src/tools/ → packages/builtin-tools/src/tools/
- 更新 Tool.ts、tools.ts、BashTool.tsx 中过时的行号引用
- 修正 WebSearchTool/WebFetchTool/EnterWorktreeTool/ExitWorktreeTool 路径
- 修正 AgentTool.tsx 中多行行号引用

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: 修正 feature 文档中的文件路径和行号引用

- ultraplan.md: 更新文件行数(525/349/127)
- fork-subagent.md: 路径迁移 src/tools/ → packages/builtin-tools/
- mcp-skills.md: 修正 getMcpSkillCommands 行号 547→604,client.ts 行号 117→129
- kairos.md: 修正 getBriefSection/getProactiveSection 行号
- proactive.md: 修正 getProactiveSection 行号 860→864

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: 修正顶层文档中的路径迁移和行号引用

- auto-updater.md: config.ts 行号 1735→1737,标注未接入启动流程的函数
- external-dependencies.md: WebSearchTool/WebFetchTool 路径迁移到 builtin-tools 包,Vertex 行号修正
- lsp-integration.md: LSPTool 路径从 src/tools/ 迁移到 packages/builtin-tools/
- stub-recovery-design-1-4.md: 修正 Windows 绝对路径链接为标准代码引用

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: 修正 task 文档中的文件扩展名和路径引用

- task-004: AssistantSessionChooser.ts → .tsx, assistant.ts → .tsx
- task-003: cli.tsx 行号 249→272, markdownConfigLoader.ts 行号 29→35
- lan-pipes: SendMessageTool 路径迁移到 packages/builtin-tools/

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: 补充 computer-use-tools-reference 缺失的 Windows 工具

添加遗漏的 open_terminal 和 activate_window 两个 Windows 专属工具,
修正工具总数 37→39,Windows 工具数 10→12。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: 修正 audit/bash-classifier/token-budget/tree-sitter 文档

- feature-flags-audit: ScheduleCronTool 路径迁移、DAEMON 状态更新为 COMPLETE、assistant 文件标记已补全、UDS 标记已实现
- bash-classifier: BashPermissionRequest 文件路径修正、withRetry 行号移除
- token-budget: attachments.ts 行号范围修正
- tree-sitter-bash: bashPermissions.ts 路径迁移到 packages/builtin-tools

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: 修正 langfuse-monitoring AgentTool 路径迁移

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: 修正 bridgeApi 行号和 Tool.ts 行号引用

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: 修正 Safety/Extensibility 文档中的工具路径迁移和行号引用

- sandbox.mdx: shouldUseSandbox.ts 和 bashPermissions.ts 路径迁移至 packages/builtin-tools
- why-safety-matters.mdx: bashPermissions.ts 路径迁移(3 处)
- plan-mode.mdx: EnterPlanModeTool/prompt.ts 路径迁移
- auto-mode.mdx: Auto mode 指令行号 3464→3481
- hooks.mdx: AgentTool/runAgent.ts 路径迁移
- skills.mdx: SkillTool.ts 路径迁移
- custom-agents.mdx: Agent built-in 目录和 exploreAgent.ts 路径迁移

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: 修正 internals 文档引用计数和路径

- ant-only-world: USER_TYPE 引用计数 465→410+,工具路径迁移到 builtin-tools
- growthbook-ab-testing: growthbook.ts 行数 1156→1258
- hidden-features: 语音模式状态更新(audio-napi 已恢复)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: 修正工具文档中的行号引用

- sub-agents: AgentTool.call 入口行号 340→387
- shell-execution: ShellCommand onTimeout 行号 129→144

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: 修正 feature 文档中的状态、路径和计数

- all-features-guide: 修正 feature flag 启用范围(dev only vs dev+build)
- tier3-stubs: 大量状态修正(stub→已实现),缩减过时条目
- workflow-scripts: 路径迁移到 builtin-tools,状态更新
- web-browser-tool: 工具状态缺失→已实现,路径迁移
- context-collapse: CtxInspectTool 状态缺失→已实现
- computer-use: 行号引用更新,平台分发描述修正
- computer-use-tools-reference: 工具数 39→38
- voice-mode: voiceModeEnabled 行数 55→54

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: 更新 the-loop 查询循环行号引用

query.ts 代码变更后终止原因行号整体偏移约 40 行

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: 补充 feature-flags-audit 完整 build 默认 feature 列表

添加 ULTRATHINK/LODESTONE/ACP/DAEMON 等 19 个缺失的 build 默认 feature,
修正 dev-only 特征标注(UDS_INBOX/LAN_PIPES/BG_SESSIONS/TEMPLATES)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: 修正 feature-flags-audit ConfigTool 路径迁移

ConfigTool 路径从 src/tools/ 迁移到 packages/builtin-tools/src/tools/

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: 修正 feature-flags-audit BashTool 路径迁移

BashTool 路径从 src/tools/ 迁移到 packages/builtin-tools/src/tools/

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: 修正 feature-flags-audit SkillTool 路径迁移

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: 更新 feature-flags-audit WorkflowTool 状态为已实现

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-19 09:30:00 +08:00
claude-code-best
a57ca08566 fix: 修复 node 的 es 版本太高不兼容的构建问题 2026-04-19 09:28:57 +08:00
claude-code-best
6536757428 feat: 对其他 provider 提供 langfuse 监控 2026-04-19 09:09:27 +08:00
claude-code-best
a0dc4540ca fix: 修复服务器两个 / 的问题 2026-04-19 08:55:55 +08:00
claude-code-best
7e4df5c3e9 build: 更改构建逻辑 2026-04-19 08:45:06 +08:00
claude-code-best
4d939e5722 chore: 更新构建 feature 的问题 2026-04-19 08:27:25 +08:00
claude-code-best
2e9aaf4993 feat: ACP 协议版本 remote control (#293)
* fix: 添加 usage 字段缺失时的防御性防护

第三方 API(如智谱 GLM)在某些流式响应中不返回 usage 字段,
导致 usage.input_tokens 访问 undefined 崩溃并连锁影响后续所有请求。

- claude.ts: content_block_stop 创建消息时 fallback 到 EMPTY_USAGE
- LocalAgentTask.tsx: usage 为 undefined 时提前返回
- tokens.ts: getTokenCountFromUsage 加 null guard 和 ?? 0
- cost-tracker.ts: input_tokens/output_tokens 加 ?? 0

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: ACP Plan 展示 — 支持 session/update plan 类型的可视化

补全 PlanUpdate 类型定义(PlanEntry/Priority/Status),新建 PlanView 组件
渲染进度条、状态图标和优先级标签,在 ChatInterface 中处理 plan 更新逻辑。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: 穷鬼模式下跳过 verification agent 以节省 token

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* test: 补充 RCS 后端 + 前端测试覆盖 (+116 tests)

后端新增 3 个测试文件 (70 tests):
- automationState: normalize/snapshot/equals 纯函数
- client-payload: toClientPayload 协议转换
- transport-normalize: normalizePayload + extractContent

前端新增 2 个测试文件 (46 tests):
- utils: formatTime/statusClass/truncate/extractEventText 等
- api-client: getUuid/setUuid/api GET/POST 错误处理

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: RCS ACP 页面添加权限模式选择器 + 权限响应修复

- 新增权限模式选择器 UI(6种模式:默认/自动接受编辑/跳过权限/规划/不询问/自动判断)
- 权限模式通过 ACP _meta 从 web → acp-link → agent 全链路传递
- 修复 PermissionPanel 点击"允许"发送 cancelled 而非 selected 的 bug
- 权限模式和模型选择持久化到 localStorage
- acp-link 直接连接路径同步支持 permissionMode 透传

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: RCS Web UI 重构 + QR 修复 + ACP 扫描自动跳转

- RCS Web UI 组件全面重构: Dialog 迁移 Radix UI, lazy loading,
  主题系统改进, 组件样式优化
- IdentityPanel QR 码显示修复: requestAnimationFrame 延迟绘制
  解决 Radix Dialog Portal 挂载时序问题
- ACP QR 扫描自动跳转: IdentityPanel 扫描 ACP 格式 { url, token }
  后存储 sessionStorage 并跳转 /code/?acp=1
- 新增 ACPDirectView 组件: ACP 直连视图, 用 ACPClient 连接并
  渲染 ACPMain 聊天界面

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: ACP 权限管道改进 — 模式同步 + bypass 检测 + 统一权限流水线

- agent.ts: applySessionMode 同步 appState.toolPermissionContext.mode
- agent.ts: bypassPermissions 可用性检测 (非 root 或 sandbox 环境)
- permissions.ts: createAcpCanUseTool 接入 hasPermissionsToUseTool
  统一权限流水线, 替代原来分散的处理逻辑
- permissions.ts: 支持 onModeChange 回调, 模式变更时实时同步

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: acp-link 支持 permissionMode 默认值传递给 agent

客户端 (Zed/VS Code 等) 的 new_session 不一定携带 permissionMode,
导致 agent 收到 _meta: undefined, permission 回退到 default。

修复: handleNewSession 使用 fallback 链:
  客户端传值 > config.permissionMode > ACP_PERMISSION_MODE 环境变量

使用: ACP_PERMISSION_MODE=auto acp-link claude

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: 更新文档及说明

* fix: 修复类型错误

* chore: 提交脚本

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-18 21:54:22 +08:00
claude-code-best
34154ee3f5 feat: 支持 acp-link 包进行 acp 通用的 remote-control (#292)
* fix: 修复超时问题

* feat: 添加 acp-link 代码

* refactor: 样式重构完成

* feat: RCS 添加 ACP 后端支持

- 新增 ACP WebSocket handler (agent 注册、EventBus 订阅)
- 新增 relay handler (前端 WS → acp-link 透传 + EventBus inbound 转发)
- 新增 SSE event stream 供外部消费者订阅 channel group 事件
- ACP REST 接口无鉴权 (agents、channel-groups)
- WebSocket 端点保留 token 鉴权
- SPA 路由 /acp/ 指向 acp.html

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: 添加 ACP 专属前端界面

- 新增 /acp/ SPA 页面 (agent 列表 + 实时交互)
- Agent 列表按 channel group 分组,显示在线状态
- 通过 RCS WebSocket relay 与 agent 通信
- Vite multi-page 构建 (index.html + acp.html)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: acp-link 支持 RCS relay 双向通信

- rcs-upstream 新增 messageHandler 转发非控制消息
- server.ts 新增虚拟 WS + relay client state 处理 relay ACP 消息
- newSession/loadSession 补充 mcpServers 参数
- 连接成功后显示 ACP Dashboard URL

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor: 移除 FileExplorer 及文件操作相关代码

- 删除 FileExplorer 组件
- ACPMain 移除 Files tab,仅保留 Chat 和 History
- client.ts 移除 listDir/readFile/onFileChanges 等方法
- types.ts 移除 FileItem/FileContent/FileChange 等类型

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: 修复类型问题

* feat: RCS 后端统一 ACP/Bridge 注册逻辑

- store: EnvironmentRecord 增加 capabilities 字段、storeFindEnvironmentByMachineName 复用逻辑
- store: 新增 storeGetSessionOwners,支持未绑定 session 自动 claim
- environment: registerEnvironment 支持 ACP 复用已有记录,返回 session_id
- session: resolveOwnedWebSessionId 支持无 owner session 自动绑定
- acp-ws-handler: 新增 handleIdentify 支持 REST+WS 两步注册
- acp routes: /acp/relay 和 /acp/agents 支持 UUID 认证
- event-bus: 增加 error 类型 payload 日志

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: acp-link 改 REST 注册 + WS identify 两步流程

- rcs-upstream: 新增 registerViaRest() 通过 POST /v1/environments/bridge 注册
- rcs-upstream: WS 连接后发送 identify 替代 register,携带 agentId
- rcs-upstream: 入口链接改为 /code/?sid=${sessionId} 实现用户绑定
- server: 修复心跳跳过 relay 虚拟连接的 bug
- server: maxSessions 配置传入 RCS upstream

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: 前端统一 Chat 组件 + ACP 聊天界面重构

- 新增 chat/ 组件: ChatView, ChatInput, MessageBubble, ToolCallGroup, PermissionPanel, SessionSidebar, CommandMenu
- ACPMain: 重构支持完整 ACP 协议交互(session/prompt/permission)
- rcs-chat-adapter: 统一 bridge session SSE 适配器
- ACPClient: 增强 session 管理、permission 流程、streaming 支持
- index.css: 新增 chat 相关样式、动画、布局
- useCommands: 新增快捷命令 hook

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor: 删除 /acp/ 独立页面,ACP 聊天统一到 /code/:sessionId

- 删除 acp.html、acp-main.tsx 入口文件和 pages/acp/ 目录
- SessionDetail: ACP session 在同一页面渲染 ACPSessionDetail 组件
- App.tsx: ?sid= 参数自动调用 apiBind 绑定用户 UUID
- Dashboard: 统一 session 列表导航,ACP 显示紫色标签
- relay-client: 改用 UUID 认证替代 API token
- EnvironmentList: 显示 workerType 标签(ACP Agent / Claude Code)
- index.ts: 移除 /acp/ SPA 路由,vite.config 移除 acp 入口

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* build: 更新构建及测试修复

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-18 17:59:29 +08:00
claude-code-best
29cc74a170 docs: 更新 CLAUDE.md 2026-04-17 21:37:43 +08:00
claude-code-best
d2b66d9d2c docs: update contributors 2026-04-17 12:45:56 +00:00
claude-code-best
d70e7f7f05 feat: 支持 langfuse 工具调用映射 2026-04-17 20:45:14 +08:00
Cheng Zi Feng
72a2093cd6 feat(remote-control): 优化 Web 展示、状态同步与桥接控制流程 (#288)
Co-authored-by: chengzifeng <chengzifeng@meituan.com>
2026-04-17 16:21:27 +08:00
claude-code-best
b5c299f5d2 build: CI 添加通过过滤 2026-04-17 11:33:57 +08:00
claude-code-best
ac42ce2d67 fix: 解决 node 下 loading 按钮计算错误问题 2026-04-17 10:42:40 +08:00
claude-code-best
c659912517 docs: 更新说明 2026-04-17 10:22:56 +08:00
claude-code-best
a14b7f352b test: 修正 mock 的滥用情况 2026-04-17 10:13:09 +08:00
claude-code-best
c5ab83a3fc fix: 修复 linux 端的安装问题 2026-04-17 09:51:59 +08:00
claude-code-best
03b7f9b453 chore: 1.4.1 2026-04-17 09:45:36 +08:00
claude-code-best
bddd146f25 feat: 重构供应商层次 (#286)
* refactor: 创建 @anthropic-ai/model-provider 包骨架与类型定义

- 新建 workspace 包 packages/@anthropic-ai/model-provider
- 定义 ModelProviderHooks 接口(依赖注入:分析、成本、日志等)
- 定义 ClientFactories 接口(Anthropic/OpenAI/Gemini/Grok 客户端工厂)
- 搬入核心类型:Message 体系、NonNullableUsage、EMPTY_USAGE、SystemPrompt、错误常量
- 主项目 src/types/message.ts 等改为 re-export,保持向后兼容

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor: 提升 OpenAI 转换器和模型映射到 model-provider 包

- 搬入 OpenAI 消息转换(convertMessages)、工具转换(convertTools)、流适配(streamAdapter)
- 搬入 OpenAI 和 Grok 模型映射(resolveOpenAIModel、resolveGrokModel)
- 主项目文件改为 thin re-export proxy

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor: 搬入 Gemini 兼容层到 model-provider 包

- 搬入 Gemini 类型定义、消息转换、工具转换、流适配、模型映射
- 主项目 gemini/ 目录下文件改为 thin re-export proxy

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor: 搬入 errorUtils 并迁移消费者导入到 model-provider

- 搬入 formatAPIError、extractConnectionErrorDetails 等 errorUtils
- 迁移 10 个消费者文件直接从 @anthropic-ai/model-provider 导入
- 更新 emptyUsage、sdkUtilityTypes、systemPromptType 为 re-export proxy

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: compact 模型降级为 -1 模式(Opus→Sonnet, Sonnet→Haiku)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: 添加 agent-loop 绘图

* Revert "feat: compact 模型降级为 -1 模式(Opus→Sonnet, Sonnet→Haiku)"

This reverts commit e458d6391d.

* docs: 添加简化版 agent loop

* fix: 修复 n 快捷键导致关闭的问题

* fix: 修复 node 下 ws 没打包问题

* docs: 修复链接

* test: 添加测试支持

* fix: 修复类型问题(#267) (#271)

* fix: 修复 Bun 的 polyfill 问题

* fix: 类型修复完成

* feat: 统一所有包的类型文件

* fix: 修复构建问题

* test: 修复类型校验 (#279)

* fix: 修复 Bun 的 polyfill 问题

* fix: 类型修复完成

* feat: 统一所有包的类型文件

* fix: 修复构建问题

* fix(remote-control): harden self-hosted session flows (#278)

Co-authored-by: chengzifeng <chengzifeng@meituan.com>

* docs: update contributors

* build: 新增 vite 构建流程

* feat: 添加环境变量支持以覆盖 max_tokens 设置

* feat(langfuse): LLM generation 记录工具定义

将 Anthropic 格式的工具定义转换为 Langfuse 兼容的 OpenAI 格式,
并在 generation 的 input 中以 { messages, tools } 结构传入,
以便在 Langfuse UI 中查看完整的工具定义信息。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: 添加对 ACP 协议的支持 (#284)

* feat: 适配 zed acp 协议

* docs: 完善 acp 文档

* chore: 1.4.0

* conflict: 解决冲突

* feat: 添加测试覆盖率上报

* style: 改名加移动文件夹位置

* refactor: 移动测试用例及实现

* test: 修复测试用例完成

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Cheng Zi Feng <1154238323@qq.com>
Co-authored-by: chengzifeng <chengzifeng@meituan.com>
Co-authored-by: claude-code-best <272536312+claude-code-best@users.noreply.github.com>
2026-04-17 09:33:14 +08:00
claude-code-best
c8d08d235b Feat/integrate lint preview (#285)
* feat: 适配 zed acp 协议

* docs: 完善 acp 文档

* feat: integrate feature branches + daemon/job 命令层级化 + 跨平台后台引擎

Cherry-picked from origin/lint/preview (637c908), excluding lint-only changes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: correct detectMimeFromBase64 to decode raw bytes from base64

Cherry-picked from origin/lint/preview (ee36954).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: daemon 子进程 spawn 跨平台修复 + CliLaunchSpec 集中化重构

Cherry-picked from origin/lint/preview (c5f52cd), excluding lint-only formatting changes.

- 新建 src/utils/cliLaunch.ts: 集中化 CLI 子进程启动层
- 修复 --daemon-worker=kind 等号格式解析
- 修复 daemon/bg fast path 缺少 setShellIfWindows()
- 修复 checkPathExists 用 existsSync 替代 execSync('dir')
- 7 个 spawn 站点迁移到 CliLaunchSpec

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: merge tsconfig.base.json into tsconfig.json with full compiler options

The cherry-pick from 637c908 dropped jsx/strict/etc settings when removing
tsconfig.base.json. This commit restores them in a single tsconfig.json.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: merge tsconfig.base.json into tsconfig.json with full compiler options

The cherry-pick from 637c908 dropped jsx/strict/etc settings when removing
tsconfig.base.json. This commit restores them in a single tsconfig.json.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 20:59:29 +08:00
claude-code-best
a02dc0bded chore: 1.4.0 2026-04-16 20:48:09 +08:00
claude-code-best
3cb1e50b25 feat: 添加对 ACP 协议的支持 (#284)
* feat: 适配 zed acp 协议

* docs: 完善 acp 文档
2026-04-16 20:31:50 +08:00
claude-code-best
cfab161e28 feat(langfuse): LLM generation 记录工具定义
将 Anthropic 格式的工具定义转换为 Langfuse 兼容的 OpenAI 格式,
并在 generation 的 input 中以 { messages, tools } 结构传入,
以便在 Langfuse UI 中查看完整的工具定义信息。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 15:31:18 +08:00
claude-code-best
90027279e6 feat: 添加环境变量支持以覆盖 max_tokens 设置 2026-04-16 13:01:07 +08:00
claude-code-best
3470783ced build: 新增 vite 构建流程 2026-04-16 12:39:19 +08:00
claude-code-best
8169b96250 docs: update contributors 2026-04-16 02:46:47 +00:00
Cheng Zi Feng
fe08cacf8d fix(remote-control): harden self-hosted session flows (#278)
Co-authored-by: chengzifeng <chengzifeng@meituan.com>
2026-04-16 10:46:31 +08:00
claude-code-best
5a4c820e1d test: 修复类型校验 (#279)
* fix: 修复 Bun 的 polyfill 问题

* fix: 类型修复完成

* feat: 统一所有包的类型文件

* fix: 修复构建问题
2026-04-16 10:28:47 +08:00
claude-code-best
1a4e9702c2 fix: 修复类型问题(#267) (#271)
* fix: 修复 Bun 的 polyfill 问题

* fix: 类型修复完成

* feat: 统一所有包的类型文件

* fix: 修复构建问题
2026-04-15 10:54:00 +08:00
claude-code-best
2273a0bcfe docs: 修复链接 2026-04-14 21:19:36 +08:00
claude-code-best
b80483c23e fix: 修复 node 下 ws 没打包问题 2026-04-14 21:19:25 +08:00
claude-code-best
8442aaadd2 fix: 修复 n 快捷键导致关闭的问题 2026-04-14 21:18:36 +08:00
1488 changed files with 75264 additions and 18583 deletions

View File

@@ -41,7 +41,8 @@ All teach-me data is stored under `.claude/skills/teach-me/records/`:
.claude/skills/teach-me/records/
├── learner-profile.md # Cross-topic notes (created on first session)
└── {topic-slug}/
── session.md # Learning state: concepts, status, notes
── session.md # Learning state: concepts, status, notes
└── {topic-slug}-notes.md # Learner-facing summary notes (generated at session end)
```
**Slug**: Topic in kebab-case, 2-5 words. Example: "Python decorators" → `python-decorators`
@@ -275,7 +276,8 @@ Update `session.md` after each round:
When all concepts mastered or user ends session:
1. Update `session.md` with final state.
2. Update `.claude/skills/teach-me/records/learner-profile.md` (keep under 30 lines):
2. **Generate learner-facing notes** — write `{topic-slug}-notes.md` in the topic directory. This is a standalone reference document the learner can review later. See "Notes Generation" below for format.
3. Update `.claude/skills/teach-me/records/learner-profile.md` (keep under 30 lines):
```markdown
# Learner Profile
@@ -293,7 +295,48 @@ Updated: {timestamp}
- Python decorators (8/10 concepts, 2025-01-15)
```
3. Give a brief text summary of what was covered, key insights, and areas for further study.
4. Give a brief text summary of what was covered, key insights, and areas for further study.
## Notes Generation
At session end, generate a learner-facing notes file at `{topic-slug}/{topic-slug}-notes.md`. This file is **written for the learner to review later**, not for the tutor. It should be self-contained and organized as a quick-reference.
### Notes Structure
```markdown
# {Topic} 核心笔记
## 1. {Section Name}
{Key concept, mechanism, or principle}
* **One-line summary**: {what it does / why it matters}
* **Detail**: {brief explanation, 2-4 sentences max}
* **Example** (if applicable): {code snippet, command, or concrete scenario}
---
## 2. {Section Name}
...
---
## n. 实战参数 / Cheat Sheet (if applicable)
{Practical commands, config, or quick-reference table}
| Parameter / Concept | What it does | Tuning tip |
|---------------------|-------------|------------|
| ... | ... | ... |
```
### Notes Writing Rules
1. **Start with "what & why"** before "how". Each section should answer: what is this, why does it exist, what problem does it solve.
2. **Use analogies sparingly but effectively**. Only include an analogy if it clarifies a non-obvious mechanism (e.g., "PagedAttention is like OS virtual memory paging").
3. **Include trade-offs**. Every optimization or design choice has a cost. Always state it (e.g., "TP improves throughput but increases communication latency").
4. **Code / command examples should be minimal**. Under 10 lines, self-contained, with comments explaining the key flags.
5. **Organize by concept dependency**, not by chronological teaching order. Foundation concepts first, advanced ones last.
6. **No quiz questions, no misconceptions, no tutor-side notes**. This is a clean reference document.
7. **Language matches the session**. If the session was in Chinese, notes are in Chinese (technical terms can stay in English).
8. **Keep it under 150 lines**. If it gets too long, the learner won't review it. Be ruthless about cutting fluff.
## Resuming Sessions

View File

@@ -1,22 +0,0 @@
#!/bin/sh
# pre-commit hook: 对暂存的文件运行 Biome 检查
# 仅检查 src/ 下的 .ts/.tsx/.js/.jsx 文件
STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep -E '^src/.*\.(ts|tsx|js|jsx)$')
if [ -z "$STAGED_FILES" ]; then
exit 0
fi
echo "Running Biome lint on staged files..."
# 使用 biome lint 对暂存文件进行检查(仅 lint不格式化不自动修复
echo "$STAGED_FILES" | xargs bunx biome lint --no-errors-on-unmatched
if [ $? -ne 0 ]; then
echo ""
echo "Biome lint failed. Fix errors or use --no-verify to bypass."
exit 1
fi
exit 0

View File

@@ -8,7 +8,7 @@ on:
jobs:
ci:
runs-on: macos-latest
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
@@ -21,10 +21,18 @@ jobs:
run: bun install --frozen-lockfile
- name: Type check
run: bunx tsc --noEmit
run: bun run typecheck
- name: Test
run: bun test
- name: Test with Coverage
run: |
set -o pipefail
bun test --coverage --coverage-reporter=lcov 2>&1 | grep -vE '^\s*(\(pass\)|\(skip\))' | sed '/^.*\/__tests__\/.*:$/d' | cat -s
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v5
with:
file: ./coverage/lcov.info
token: ${{ secrets.CODECOV_TOKEN }}
- name: Build
run: bun run build
run: bun run build:vite

79
.github/workflows/publish-npm.yml vendored Normal file
View File

@@ -0,0 +1,79 @@
name: Publish to npm
on:
push:
tags:
- 'v*'
workflow_dispatch:
inputs:
version:
description: '版本号 (例如: v1.9.0)'
required: true
type: string
permissions:
contents: write
packages: write
id-token: write
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.inputs.version || github.ref }}
- uses: actions/setup-node@v6
with:
node-version: "24"
registry-url: "https://registry.npmjs.org"
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- name: Install dependencies
run: bun install --frozen-lockfile
- name: Type check
run: bun run typecheck
- name: Run tests
run: bun test
- name: Publish to npm
run: npm publish --provenance --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: Generate changelog
id: changelog
run: |
VERSION="${{ github.event.inputs.version || github.ref_name }}"
PREV_TAG=$(git tag --sort=-version:refname | grep -v "^${VERSION#v}$" | head -1)
if [ -n "$PREV_TAG" ]; then
COMMITS=$(git log "${PREV_TAG}..${VERSION}" --pretty=format:"- %s (%h)" --no-merges)
else
COMMITS=$(git log --pretty=format:"- %s (%h)" --no-merges -20)
fi
{
echo "commits<<EOF"
echo "$COMMITS"
echo "EOF"
} >> "$GITHUB_OUTPUT"
- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
name: ${{ github.event.inputs.version || github.ref_name }}
body: |
## What's Changed
${{ steps.changelog.outputs.commits }}
**Full Changelog**: https://github.com/${{ github.repository }}/compare/${{ github.event.inputs.version || github.ref_name }}^...${{ github.event.inputs.version || github.ref_name }}
draft: false
prerelease: ${{ contains(github.event.inputs.version || github.ref_name, 'rc') || contains(github.event.inputs.version || github.ref_name, 'beta') || contains(github.event.inputs.version || github.ref_name, 'alpha') }}

View File

@@ -1,11 +1,8 @@
name: Update Contributors
on:
push:
branches:
- main
schedule:
- cron: '0 0 * * *' # 每更新一次
- cron: '0 0 * * 1' # 每周一更新一次
permissions:
contents: write

19
.gitignore vendored
View File

@@ -13,13 +13,17 @@ src/utils/vendor/
# AI tool runtime directories
.agents/
.claude/
.codex/
.omx/
.docs/task/
# Binary / screenshot files (root only)
/*.png
*.bmp
# Internal system prompt documents
Claude-Opus-*.txt
Claude-Sonnet-*.txt
Claude-Haiku-*.txt
# Agent / tool state dirs
.swarm/
.agents/__pycache__/
@@ -30,3 +34,14 @@ __pycache__/
logs
data
.omc
.codex/*
!.codex/agents/
!.codex/agents/**
!.codex/skills/
!.codex/skills/**
.codex/skills/.system/**
!.codex/prompts/
!.codex/prompts/**
teach-me
credentials.json

78
.impeccable.md Normal file
View File

@@ -0,0 +1,78 @@
# Impeccable Design Context
## Users
**Primary**: Technical teams and enterprises using AI-assisted coding in production workflows.
- DevOps engineers managing remote agents via RCS dashboard
- Development teams collaborating through shared sessions
- Individual developers using terminal CLI daily
**Context**: Used during focused work sessions — debugging, code review, agent orchestration. Users are in "get things done" mode, not browsing. They value efficiency but also appreciate warmth and personality.
**Job to be done**: Make advanced AI coding tools accessible and controllable, especially features that normally require enterprise accounts or Anthropic OAuth.
## Brand Personality
**3 words**: Warm, Considered, Human
**Voice**: Like a knowledgeable colleague who's genuinely enthusiastic about the craft — not a corporate product manager. Community-first, open, slightly playful. Chinese developer community culture (贴吧/discord 温暖氛围).
**Emotional goals**: Confidence (this tool is solid), Warmth (this community is welcoming), Delight (small moments of personality make the difference).
**References**:
- **Anthropic's own design language** — their clean, considered aesthetic with warm undertones. The terra cotta/burnt orange as a human accent. Lots of breathing room. Typography-forward.
- **NOT**: Generic AI product (no ChatGPT blue, no gradient text, no "AI slop"). NOT corporate SaaS (no Salesforce-blue dashboards, no enterprise sterility).
**Anti-references**: Corporate enterprise dashboards, generic AI product pages, anything that looks like it was "designed by committee."
## Aesthetic Direction
**Theme**: Light + Dark dual mode (user/system preference switch)
**Tone**: Anthropomorphic warmth meets terminal precision. The brand orange (Claude's terra cotta) is the thread that ties everything together — it's the human element in a technical world.
**Typography**: Clean, considered, with good hierarchy. Terminal-native for CLI; modern web fonts for Web UI (RCS dashboard, docs). Favor readability and personality.
**Color**:
- Primary: Claude orange family (`#D77757` / terra cotta)
- Accent: Warm neutrals tinted toward orange
- Semantic: Success/Error/Warning following Anthropic's established palette
- Dark mode: Warm dark surfaces (not cold blue-black)
**Differentiation**: The CCB brand sits at the intersection of "serious tool" and "community project." It should feel like Anthropic's design principles applied to an open-source context — less corporate polish, more human craft. The mascot "Clawd" and the playful "踩踩背" naming hint at personality that the design should honor.
**Scope**: All Web UI — RCS control panel, documentation site, landing pages.
## Design Principles
1. **Considered over clever** — Every design choice should feel intentional, not trendy. If it doesn't serve the user, it doesn't ship.
2. **Warmth through subtlety** — Orange tints on neutrals, breathing room in layouts, personality in copy. Not giant emoji or aggressive color.
3. **Density with clarity** — Technical users need information density, but not chaos. Every pixel earns its place.
4. **Community voice** — The design should feel like it was made by people who use it, not by a distant design team. Slightly rough edges are fine if they're honest.
5. **Anthropic's shadow** — When in doubt, follow Anthropic's design instincts — the clean layouts, the generous spacing, the warm color temperature. Then add the community touch.
## Existing Design Assets
### Brand Colors (from theme system)
- Claude Orange: `rgb(215,119,87)` / `#D77757`
- Claude Blue: `rgb(87,105,247)` / `#5769F7`
- Permission Blue: `rgb(87,105,247)`
- Auto Accept Violet: `rgb(135,0,255)`
- Plan Mode Teal: `rgb(0,102,102)`
- Success: `rgb(78,186,101)`
- Error: `rgb(255,107,128)`
- Warning: `rgb(255,193,7)`
### Logo
- CCB text + orange play button icon
- Dark/Light SVG variants in `docs/logo/`
- Favicon: Orange circle `#D97706` with white play triangle
### Mascot
- "Clawd" — terminal-art character with multiple poses
- Theme-aware coloring
### Theme System
- 7 variants: dark, light, dark-ansi, light-ansi, dark-daltonized, light-daltonized, auto
- 89+ semantic color tokens
- Full documentation in `packages/@ant/ink/docs/04-theme-system.md`

1
.npmrc Normal file
View File

@@ -0,0 +1 @@
registry=https://registry.npmjs.org/

357
AGENTS.md Normal file
View File

@@ -0,0 +1,357 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) and other AI coding agents when working with code in this repository.
## Project Overview
This is a **reverse-engineered / decompiled** version of Anthropic's official Claude Code CLI tool. The goal is to restore core functionality while trimming secondary capabilities. Many modules are stubbed or feature-flagged off. TypeScript strict mode is enforced — **`bunx tsc --noEmit` must pass with zero errors**.
## Git Commit Message Convention
使用 **Conventional Commits** 规范:
```
<type>: <描述>
```
常见 type`feat``fix``docs``chore``refactor`
示例:
- `feat: 添加模型 1M 上下文切换`
- `fix: 修复初次登陆的校验问题`
- `chore: remove prefetchOfficialMcpUrls call on startup`
## Commands
```bash
# Install dependencies
bun install
# Dev mode (runs cli.tsx with MACRO defines injected via -d flags)
bun run dev
# Dev mode with debugger (set BUN_INSPECT=9229 to pick port)
bun run dev:inspect
# Pipe mode
echo "say hello" | bun run src/entrypoints/cli.tsx -p
# Build (code splitting, outputs dist/cli.js + chunk files)
bun run build
# Build with Vite (alternative build pipeline)
bun run build:vite
# Test
bun test # run all tests
bun test src/utils/__tests__/hash.test.ts # run single file
bun test --coverage # with coverage report
# Lint & Format (Biome)
bun run lint # check only
bun run lint:fix # auto-fix
bun run format # format all src/
# Health check
bun run health
# Check unused exports
bun run check:unused
# Full check (typecheck + lint + test) — run after completing any task
bun run test:all
bun run typecheck
# Remote Control Server
bun run rcs
# Docs dev server (Mintlify)
bun run docs:dev
```
详细的测试规范、覆盖状态和改进计划见 `docs/testing-spec.md`
## Architecture
### 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。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 — 15 个 workspace 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()` 函数按优先级处理多条快速路径:
- `--version` / `-v` — 零模块加载
- `--dump-system-prompt` — feature-gated (DUMP_SYSTEM_PROMPT)
- `--claude-in-chrome-mcp` / `--chrome-native-host`
- `--computer-use-mcp` — 独立 MCP server 模式
- `--daemon-worker=<kind>` — 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`** (~6981 行) — 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
- **`src/query.ts`** — The main API query function. Sends messages to Claude API, handles streaming responses, processes tool calls, and manages the conversation turn loop.
- **`src/QueryEngine.ts`** — Higher-level orchestrator wrapping `query()`. Manages conversation state, compaction, file history snapshots, attribution, and turn-level bookkeeping. Used by the REPL screen.
- **`src/screens/REPL.tsx`** — The interactive REPL screen (React/Ink component). Handles user input, message display, tool permission prompts, and keyboard shortcuts.
### 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.
- **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; tools are imported from `@claude-code-best/builtin-tools` package. Some tools are conditionally loaded via `feature()` flags or `process.env.USER_TYPE`.
- **`packages/builtin-tools/src/tools/`** — 59 个子目录(含 shared/testing 等工具目录),通过 `@claude-code-best/builtin-tools` 包导出。主要分类:
- **文件操作**: 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/`** / **`packages/builtin-tools/src/tools/shared/`** — Tool 共享工具函数。
### UI Layer (Ink)
- **`src/ink.ts`** — Ink render wrapper with ThemeProvider injection.
- **`packages/@ant/ink/`** — Custom Ink frameworkforked/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
- `permissions/` — Tool permission approval UI
- `design-system/` — 复用 UI 组件Dialog, FuzzyPicker, ProgressBar, ThemeProvider 等)
- Components use React Compiler runtime (`react/compiler-runtime`) — decompiled output has `_c()` memoization calls throughout.
### State Management
- **`src/state/AppState.tsx`** — Central app state type and context provider. Contains messages, tools, permissions, MCP connections, etc.
- **`src/state/AppStateStore.ts`** — Default state and store factory.
- **`src/state/store.ts`** — Zustand-style store for AppState (`createStore`).
- **`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/@ant/model-provider/` | Model provider 抽象层 |
| `packages/builtin-tools/` | 内置工具集60 个 tool 实现,通过 `@claude-code-best/builtin-tools` 导出) |
| `packages/agent-tools/` | Agent 工具集 |
| `packages/acp-link/` | ACP 代理服务器WebSocket → ACP agent 桥接) |
| `packages/cc-knowledge/` | Claude Code 知识库(非 workspace 包) |
| `packages/langfuse-dashboard/` | Langfuse 可观测性面板(非 workspace 包) |
| `packages/mcp-client/` | MCP 客户端库 |
| `packages/mcp-server/` | MCP 服务端库(非 workspace 包) |
| `packages/remote-control-server/` | 自托管 Remote Control ServerDocker 部署,含 Web UI— Web UI 已重构为 React + Vite + Radix UI支持 ACP agent 接入 |
| `packages/swarm/` | Swarm 解耦模块(非 workspace 包) |
| `packages/shell/` | Shell 抽象(非 workspace 包) |
| `packages/audio-capture-napi/` | 原生音频捕获(已恢复) |
| `packages/color-diff-napi/` | 颜色差异计算完整实现11 tests |
| `packages/image-processor-napi/` | 图像处理(已恢复) |
| `packages/modifiers-napi/` | 键盘修饰键检测macOS FFI 实现) |
| `packages/url-handler-napi/` | URL scheme 处理(环境变量 + CLI 参数读取) |
### Bridge / Remote Control
- **`src/bridge/`** — Remote Control / Bridge 模式。feature-gated by `BRIDGE_MODE`。包含 bridge API、会话管理、JWT 认证、消息传输、权限回调等。Entry: `bridgeMain.ts`
- **`packages/remote-control-server/`** — 自托管 RCS支持 Docker 部署,含 Web UI 控制面板React 19 + Vite + Radix UI。支持 ACP agent 通过 acp-link 接入ACP WebSocket handler、relay handler、SSE event stream。通过 `bun run rcs` 启动。
- CLI 快速路径: `claude remote-control` / `claude rc` / `claude bridge`
- 详见 `docs/features/remote-control-self-hosting.md`
### ACP Protocol (Agent Client Protocol)
- **`src/services/acp/`** — ACP agent 实现,包含 `agent.ts`AcpAgent 类)、`bridge.ts`Claude Code ↔ ACP 桥接)、`permissions.ts`(权限处理)、`entry.ts`(入口)。
- **`packages/acp-link/`** — ACP 代理服务器,将 WebSocket 客户端桥接到 ACP agent。提供 `acp-link` CLI 命令,支持自定义端口/HTTPS/认证/会话管理、RCS 集成REST 注册 + WS identify 两步流程、权限模式透传fallback: 客户端传值 > config > `ACP_PERMISSION_MODE` 环境变量)。
- ACP 权限管道改进:`createAcpCanUseTool` 统一权限流水线,`applySessionMode` 模式同步,`bypassPermissions` 可用性检测(非 root/sandbox 环境)。
- ACP Plan 可视化已支持 `session/update plan` 类型的消息展示PlanView 组件,含进度条/状态图标/优先级标签)。
### Daemon Mode
- **`src/daemon/`** — Daemon 模式(长驻 supervisor。feature-gated by `DAEMON`。包含 `main.ts`entry`workerRegistry.ts`worker 管理)。
### Context & System Prompt
- **`src/context.ts`** — Builds system/user context for the API call (git status, date, CLAUDE.md contents, memory files).
- **`src/utils/claudemd.ts`** — Discovers and loads CLAUDE.md files from project hierarchy.
### Feature Flag System
Feature flags control which functionality is enabled at runtime. 代码中统一通过 `import { feature } from 'bun:bundle'` 导入,调用 `feature('FLAG_NAME')` 返回 `boolean`
**启用方式**: 环境变量 `FEATURE_<FLAG_NAME>=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 内部格式,下游代码完全不改。通过 `/login` 命令配置。
#### 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 文档。
### 穷鬼模式Budget Mode
- 通过 `/poor` 命令切换,持久化到 `settings.json`
- 启用后跳过 `extract_memories``prompt_suggestion``verification_agent`,显著减少 token 消耗。
- 实现在 `src/commands/poor/poorMode.ts`
### Stubbed/Deleted Modules
| Module | Status |
|--------|--------|
| Computer Use (`@ant/*`) | Restored — macOS + Windows + Linux后端完整度不一 |
| `*-napi` packages | 全部已恢复/实现:`audio-capture-napi``image-processor-napi` 已恢复;`color-diff-napi` 完整;`modifiers-napi`macOS FFI`url-handler-napi`(环境变量+CLI |
| 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 | Restored — Magic Docs 自动更新 + LSP 服务器管理器 |
| Plugins / Marketplace | Restored — 插件安装/卸载/启用/禁用 + Marketplace 浏览 |
| MCP OAuth | Simplified |
### Key Type Files
- **`src/types/global.d.ts`** — Declares `MACRO`, `BUILD_TARGET`, `BUILD_ENV` and internal Anthropic-only identifiers.
- **`src/types/internal-modules.d.ts`** — Type declarations for `bun:bundle`, `bun:ffi`, `@anthropic-ai/mcpb`.
- **`src/types/message.ts`** — Message type hierarchy (UserMessage, AssistantMessage, SystemMessage, etc.).
- **`src/types/permissions.ts`** — Permission mode and result types.
## Testing
- **框架**: `bun:test`(内置断言 + mock
- **单元测试**: 就近放置于 `src/**/__tests__/`,文件名 `<module>.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")`,英文
- **包测试**: `packages/` 下各包也有独立测试(如 `color-diff-napi` 11 tests
### Mock 使用规范
**只 mock 有副作用的依赖链,不 mock 纯函数/纯数据模块。**
被迫 mock 的根源:`log.ts` / `debug.ts``bootstrap/state.ts`(模块级 `realpathSync` / `randomUUID` 副作用)。必须 mock 的模块:`log.ts``debug.ts``bun:bundle``settings/settings.js``config.ts``auth.ts`、第三方网络库。
**`log.ts``debug.ts` 使用共享 mock**`tests/mocks/log.ts` / `tests/mocks/debug.ts`),不要在测试文件中内联 mock 定义。使用方式:
```ts
import { logMock } from "../../../tests/mocks/log";
mock.module("src/utils/log.ts", logMock);
import { debugMock } from "../../../../tests/mocks/debug";
mock.module("src/utils/debug.ts", debugMock);
```
源文件导出变更时只需更新 `tests/mocks/` 下的对应文件,不需要逐个修改测试。
不要 mock纯函数模块`errors.ts``stringUtils.js`、mock 值与真实实现相同的模块、mock 路径与实际 import 不匹配的模块。
路径规则:统一用 `.ts` 扩展名 + `src/*` 别名路径,禁止双重 mock 同一模块。
### 类型检查
项目使用 TypeScript strict 模式,**tsc 必须零错误**。每次修改后运行:
```bash
bun run typecheck
```
**类型规范**
- 生产代码禁止 `as any`;测试文件中 mock 数据可用 `as any`
- 类型不匹配优先用 `as unknown as SpecificType` 双重断言,或补充 interface
- 未知结构对象用 `Record<string, unknown>` 替代 `any`
- 联合类型用类型守卫type guard收窄不要强转
- `msg.request` 属性访问:`const req = msg.request as Record<string, unknown>`
- Ink `color` prop`as keyof Theme` 而非 `as any`
## Working with This Codebase
- **tsc must pass** — `bun run typecheck` 必须零错误,任何修改都不能引入新的类型错误。
- **Feature flags** — 默认全部关闭(`feature()` 返回 `false`。Dev/build 各有自己的默认启用列表。不要在 `cli.tsx` 中重定义 `feature` 函数。
- **React Compiler output** — Components have decompiled memoization boilerplate (`const $ = _c(N)`). This is normal.
- **`bun:bundle` import** — `import { feature } from 'bun:bundle'` 是 Bun 内置模块,由运行时/构建器解析。不要用自定义函数替代它。**`feature()` 只能直接用在 `if` 语句或三元表达式的条件位置**Bun 编译器限制),不能赋值给变量、不能放在箭头函数体里、不能作为 `&&` 链的一部分。正确:`if (feature('X')) {}``feature('X') ? a : b`
- **`src/` path alias** — tsconfig maps `src/*` to `./src/*`. Imports like `import { ... } from 'src/utils/...'` are valid.
- **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` 注册。
## Design Context
Impeccable 设计上下文保存在 `.impeccable.md` 中。设计 Web UIRCS 控制面板、文档站、着陆页)时必须参考该文件。
### 核心设计原则
1. **Considered over clever** — 每个设计选择都应感觉有意为之,而非追逐潮流
2. **Warmth through subtlety** — 通过橙色色调的中性色、留白布局、有温度的文案来传达温暖
3. **Density with clarity** — 技术用户需要信息密度,但不能混乱
4. **Community voice** — 设计应感觉是由使用者创造的,而非遥远的设计团队
5. **Anthropic's shadow** — 遵循 Anthropic 的设计直觉:干净的布局、充足的间距、温暖的色温
### 品牌色
- 主色Claude Orange `#D77757`terra cotta
- 辅色Claude Blue `#5769F7`
- 暗色模式使用温暖的深色表面(非冷蓝黑色)
### 目标用户
技术团队/企业,在专业工作流中使用 AI 辅助编程。友好的开源社区氛围,非企业 SaaS 风格。
### 视觉参考
Anthropic 公司的设计风格 — 干净、考究、温暖的底色。大量留白,以排版为核心。避免 AI 产品常见的设计套路(渐变文字、玻璃态、霓虹色)。

126
CLAUDE.md
View File

@@ -1,6 +1,6 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
This file provides guidance to Claude Code (claude.ai/code) and other AI coding agents when working with code in this repository.
## Project Overview
@@ -39,10 +39,13 @@ echo "say hello" | bun run src/entrypoints/cli.tsx -p
# Build (code splitting, outputs dist/cli.js + chunk files)
bun run build
# Build with Vite (alternative build pipeline)
bun run build:vite
# Test
bun test # run all tests (2453 tests / 137 files / 0 fail)
bun test # run all tests
bun test src/utils/__tests__/hash.test.ts # run single file
bun test --coverage # with coverage report
bun test --coverage # with coverage report
# Lint & Format (Biome)
bun run lint # check only
@@ -55,6 +58,10 @@ bun run health
# Check unused exports
bun run check:unused
# Full check (typecheck + lint + test) — run after completing any task
bun run test:all
bun run typecheck
# Remote Control Server
bun run rcs
@@ -69,17 +76,19 @@ 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。Build 默认启用 19 个 feature见下方 Feature Flag 段)。构建后自动替换 `import.meta.require` 为 Node.js 兼容版本(产物 bun/node 都可运行)。
- **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 都可运行)。构建时会将 `vendor/audio-capture/``src/utils/vendor/ripgrep/` 复制到 `dist/vendor/` 下。
- **Build (Vite)**: `vite.config.ts` + `scripts/post-build.ts`chunk 输出到 `dist/chunks/`。post-build 同样复制 vendor 文件到 `dist/vendor/`
- **Vendor 路径解析**: 构建后 chunk 文件位于 `dist/``dist/chunks/`vendor 二进制在 `dist/vendor/``src/utils/ripgrep.ts``packages/audio-capture-napi/src/index.ts` 均通过 `import.meta.url` 路径中 `lastIndexOf('dist')` 定位 dist 根目录,再拼接 `vendor/` 子路径,确保不同构建产物层级下路径一致。
- **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 — 14internal packages in `packages/` resolved via `workspace:*`
- **Monorepo**: Bun workspaces — 15workspace 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`** (323 行) — True entrypoint。`main()` 函数按优先级处理多条快速路径:
1. **`src/entrypoints/cli.tsx`** — True entrypoint。`main()` 函数按优先级处理多条快速路径:
- `--version` / `-v` — 零模块加载
- `--dump-system-prompt` — feature-gated (DUMP_SYSTEM_PROMPT)
- `--claude-in-chrome-mcp` / `--chrome-native-host`
@@ -92,7 +101,7 @@ bun run docs:dev
- `environment-runner` / `self-hosted-runner` — BYOC runner
- `--tmux` + `--worktree` 组合
- 默认路径:加载 `main.tsx` 启动完整 CLI
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 模式分发。
2. **`src/main.tsx`** (~6981 行) — 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
@@ -110,8 +119,8 @@ bun run docs:dev
### Tool System
- **`src/Tool.ts`** — Tool interface definition (`Tool` type) and utilities (`findToolByName`, `toolMatchesName`).
- **`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/<ToolName>/`** — 55 tool 目录。主要分类:
- **`src/tools.ts`** — Tool registry. Assembles the tool list; tools are imported from `@claude-code-best/builtin-tools` package. Some tools are conditionally loaded via `feature()` flags or `process.env.USER_TYPE`.
- **`packages/builtin-tools/src/tools/`** — 59子目录(含 shared/testing 等工具目录),通过 `@claude-code-best/builtin-tools` 包导出。主要分类:
- **文件操作**: FileEditTool, FileReadTool, FileWriteTool, GlobTool, GrepTool
- **Shell/执行**: BashTool, PowerShellTool, REPLTool
- **Agent 系统**: AgentTool, TaskCreateTool, TaskUpdateTool, TaskListTool, TaskGetTool
@@ -119,7 +128,7 @@ bun run docs:dev
- **Web/MCP**: WebFetchTool, WebSearchTool, MCPTool, McpAuthTool
- **调度**: CronCreateTool, CronDeleteTool, CronListTool
- **其他**: LSPTool, ConfigTool, SkillTool, EnterWorktreeTool, ExitWorktreeTool 等
- **`src/tools/shared/`** — Tool 共享工具函数。
- **`src/tools/shared/`** / **`packages/builtin-tools/src/tools/shared/`** — Tool 共享工具函数。
### UI Layer (Ink)
@@ -150,22 +159,37 @@ bun run docs:dev
| `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 ServerDocker 部署,含 Web UI |
| `packages/swarm/` | Swarm 解耦模块 |
| `packages/shell/` | Shell 抽象 |
| `packages/@ant/model-provider/` | Model provider 抽象层 |
| `packages/builtin-tools/` | 内置工具集60 个 tool 实现,通过 `@claude-code-best/builtin-tools` 导出) |
| `packages/agent-tools/` | Agent 工具集 |
| `packages/acp-link/` | ACP 代理服务器WebSocket → ACP agent 桥接) |
| `packages/cc-knowledge/` | Claude Code 知识库(非 workspace 包) |
| `packages/langfuse-dashboard/` | Langfuse 可观测性面板(非 workspace 包) |
| `packages/mcp-client/` | MCP 客户端库 |
| `packages/mcp-server/` | MCP 服务端库(非 workspace 包) |
| `packages/remote-control-server/` | 自托管 Remote Control ServerDocker 部署,含 Web UI— Web UI 已重构为 React + Vite + Radix UI支持 ACP agent 接入 |
| `packages/swarm/` | Swarm 解耦模块(非 workspace 包) |
| `packages/shell/` | Shell 抽象(非 workspace 包) |
| `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 |
| `packages/modifiers-napi/` | 键盘修饰键检测(macOS FFI 实现 |
| `packages/url-handler-napi/` | URL scheme 处理(环境变量 + CLI 参数读取 |
### Bridge / Remote Control
- **`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` 启动。
- **`src/bridge/`** — Remote Control / Bridge 模式。feature-gated by `BRIDGE_MODE`。包含 bridge API、会话管理、JWT 认证、消息传输、权限回调等。Entry: `bridgeMain.ts`
- **`packages/remote-control-server/`** — 自托管 RCS支持 Docker 部署,含 Web UI 控制面板React 19 + Vite + Radix UI。支持 ACP agent 通过 acp-link 接入ACP WebSocket handler、relay handler、SSE event stream。通过 `bun run rcs` 启动。
- CLI 快速路径: `claude remote-control` / `claude rc` / `claude bridge`
- 详见 `docs/features/remote-control-self-hosting.md`
### ACP Protocol (Agent Client Protocol)
- **`src/services/acp/`** — ACP agent 实现,包含 `agent.ts`AcpAgent 类)、`bridge.ts`Claude Code ↔ ACP 桥接)、`permissions.ts`(权限处理)、`entry.ts`(入口)。
- **`packages/acp-link/`** — ACP 代理服务器,将 WebSocket 客户端桥接到 ACP agent。提供 `acp-link` CLI 命令,支持自定义端口/HTTPS/认证/会话管理、RCS 集成REST 注册 + WS identify 两步流程、权限模式透传fallback: 客户端传值 > config > `ACP_PERMISSION_MODE` 环境变量)。
- ACP 权限管道改进:`createAcpCanUseTool` 统一权限流水线,`applySessionMode` 模式同步,`bypassPermissions` 可用性检测(非 root/sandbox 环境)。
- ACP Plan 可视化已支持 `session/update plan` 类型的消息展示PlanView 组件,含进度条/状态图标/优先级标签)。
### Daemon Mode
- **`src/daemon/`** — Daemon 模式(长驻 supervisor。feature-gated by `DAEMON`。包含 `main.ts`entry`workerRegistry.ts`worker 管理)。
@@ -196,7 +220,7 @@ Feature flags control which functionality is enabled at runtime. 代码中统一
### Multi-API 兼容层
所有兼容层均采用流适配器模式:将第三方 API 格式转为 Anthropic 内部格式,下游代码完全不改。
所有兼容层均采用流适配器模式:将第三方 API 格式转为 Anthropic 内部格式,下游代码完全不改。通过 `/login` 命令配置。
#### OpenAI 兼容层
@@ -221,18 +245,24 @@ Feature flags control which functionality is enabled at runtime. 代码中统一
详见各兼容层的 docs 文档。
### 穷鬼模式Budget Mode
- 通过 `/poor` 命令切换,持久化到 `settings.json`
- 启用后跳过 `extract_memories``prompt_suggestion``verification_agent`,显著减少 token 消耗。
- 实现在 `src/commands/poor/poorMode.ts`
### Stubbed/Deleted Modules
| Module | Status |
|--------|--------|
| Computer Use (`@ant/*`) | Restored — macOS + Windows + Linux后端完整度不一 |
| `*-napi` packages | `audio-capture-napi``image-processor-napi` 已恢复;`color-diff-napi` 完整;`modifiers-napi``url-handler-napi` 仍为 stub |
| `*-napi` packages | 全部已恢复/实现:`audio-capture-napi``image-processor-napi` 已恢复;`color-diff-napi` 完整;`modifiers-napi`macOS FFI`url-handler-napi`(环境变量+CLI |
| 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 |
| Magic Docs / LSP Server | Restored — Magic Docs 自动更新 + LSP 服务器管理器 |
| Plugins / Marketplace | Restored — 插件安装/卸载/启用/禁用 + Marketplace 浏览 |
| MCP OAuth | Simplified |
### Key Type Files
@@ -245,20 +275,40 @@ Feature flags control which functionality is enabled at runtime. 代码中统一
## Testing
- **框架**: `bun:test`(内置断言 + mock
- **当前状态**: 2472 tests / 138 files / 0 fail
- **单元测试**: 就近放置于 `src/**/__tests__/`,文件名 `<module>.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 导入)
- **包测试**: `packages/` 下各包也有独立测试(如 `color-diff-napi` 11 tests
### Mock 使用规范
**只 mock 有副作用的依赖链,不 mock 纯函数/纯数据模块。**
被迫 mock 的根源:`log.ts` / `debug.ts``bootstrap/state.ts`(模块级 `realpathSync` / `randomUUID` 副作用)。必须 mock 的模块:`log.ts``debug.ts``bun:bundle``settings/settings.js``config.ts``auth.ts`、第三方网络库。
**`log.ts``debug.ts` 使用共享 mock**`tests/mocks/log.ts` / `tests/mocks/debug.ts`),不要在测试文件中内联 mock 定义。使用方式:
```ts
import { logMock } from "../../../tests/mocks/log";
mock.module("src/utils/log.ts", logMock);
import { debugMock } from "../../../../tests/mocks/debug";
mock.module("src/utils/debug.ts", debugMock);
```
源文件导出变更时只需更新 `tests/mocks/` 下的对应文件,不需要逐个修改测试。
不要 mock纯函数模块`errors.ts``stringUtils.js`、mock 值与真实实现相同的模块、mock 路径与实际 import 不匹配的模块。
路径规则:统一用 `.ts` 扩展名 + `src/*` 别名路径,禁止双重 mock 同一模块。
### 类型检查
项目使用 TypeScript strict 模式,**tsc 必须零错误**。每次修改后运行:
```bash
bunx tsc --noEmit
bun run typecheck
```
**类型规范**
@@ -271,7 +321,7 @@ bunx tsc --noEmit
## Working with This Codebase
- **tsc must pass** — `bunx tsc --noEmit` 必须零错误,任何修改都不能引入新的类型错误。
- **tsc must pass** — `bun run typecheck` 必须零错误,任何修改都不能引入新的类型错误。
- **Feature flags** — 默认全部关闭(`feature()` 返回 `false`。Dev/build 各有自己的默认启用列表。不要在 `cli.tsx` 中重定义 `feature` 函数。
- **React Compiler output** — Components have decompiled memoization boilerplate (`const $ = _c(N)`). This is normal.
- **`bun:bundle` import** — `import { feature } from 'bun:bundle'` 是 Bun 内置模块,由运行时/构建器解析。不要用自定义函数替代它。**`feature()` 只能直接用在 `if` 语句或三元表达式的条件位置**Bun 编译器限制),不能赋值给变量、不能放在箭头函数体里、不能作为 `&&` 链的一部分。正确:`if (feature('X')) {}``feature('X') ? a : b`
@@ -281,3 +331,29 @@ bunx tsc --noEmit
- **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` 注册。
## Design Context
Impeccable 设计上下文保存在 `.impeccable.md` 中。设计 Web UIRCS 控制面板、文档站、着陆页)时必须参考该文件。
### 核心设计原则
1. **Considered over clever** — 每个设计选择都应感觉有意为之,而非追逐潮流
2. **Warmth through subtlety** — 通过橙色色调的中性色、留白布局、有温度的文案来传达温暖
3. **Density with clarity** — 技术用户需要信息密度,但不能混乱
4. **Community voice** — 设计应感觉是由使用者创造的,而非遥远的设计团队
5. **Anthropic's shadow** — 遵循 Anthropic 的设计直觉:干净的布局、充足的间距、温暖的色温
### 品牌色
- 主色Claude Orange `#D77757`terra cotta
- 辅色Claude Blue `#5769F7`
- 暗色模式使用温暖的深色表面(非冷蓝黑色)
### 目标用户
技术团队/企业,在专业工作流中使用 AI 辅助编程。友好的开源社区氛围,非企业 SaaS 风格。
### 视觉参考
Anthropic 公司的设计风格 — 干净、考究、温暖的底色。大量留白,以排版为核心。避免 AI 产品常见的设计套路(渐变文字、玻璃态、霓虹色)。

130
README.md
View File

@@ -6,46 +6,52 @@
[![GitHub License](https://img.shields.io/github/license/claude-code-best/claude-code?style=flat-square)](https://github.com/claude-code-best/claude-code/blob/main/LICENSE)
[![Last Commit](https://img.shields.io/github/last-commit/claude-code-best/claude-code?style=flat-square&color=blue)](https://github.com/claude-code-best/claude-code/commits/main)
[![Bun](https://img.shields.io/badge/runtime-Bun-black?style=flat-square&logo=bun)](https://bun.sh/)
[![Discord](https://img.shields.io/badge/Discord-Join-5865F2?style=flat-square&logo=discord)](https://discord.gg/qZU6zS7Q)
[![Discord](https://img.shields.io/badge/Discord-Join-5865F2?style=flat-square&logo=discord)](https://discord.gg/uApuzJWGKX)
> Which Claude do you like? The open source one is the best.
牢 A (Anthropic) 官方 [Claude Code](https://docs.anthropic.com/en/docs/claude-code) CLI 工具的源码反编译/逆向还原项目。目标是将 Claude Code 大部分功能及工程化能力复现 (问就是老佛爷已经付过钱了)。虽然很难绷, 但是它叫做 CCB(踩踩背)...
牢 A (Anthropic) 官方 [Claude Code](https://docs.anthropic.com/en/docs/claude-code) CLI 工具的源码反编译/逆向还原项目。目标是将 Claude Code 大部分功能及工程化能力复现 (问就是老佛爷已经付过钱了)。虽然很难绷, 但是它叫做 CCB(踩踩背)... 而且, 我们实现了企业版或者需要登陆 Claude 账号才能使用的特性, 实现技术普惠
[文档在这里, 支持投稿 PR](https://ccb.agent-aura.top/) | [留影文档在这里](./Friends.md) | [Discord 群组](https://discord.gg/qZU6zS7Q)
> 我们将会在五一期间进行整个代码仓库的 lint 规范化, 这个期间提交的 PR 可能会有非常多的冲突, 所以大的功能请尽量在这之前提交哈
| 特性 | 说明 | 文档 |
|------|------|------|
| **Claude 群控技术** | Pipe IPC 多实例协作:同机 main/sub 自动编排 + LAN 跨机器零配置发现与通讯,`/pipes` 选择面板 + `Shift+↓` 交互 + 消息广播路由 | [Pipe IPC](https://ccb.agent-aura.top/docs/features/pipes-and-lan) / [LAN](https://ccb.agent-aura.top/docs/features/lan-pipes) |
| Remote Control 私有部署 | Docker 自托管 RCS + Web UI | [文档](https://ccb.agent-aura.top/docs/features/remote-control-self-hosting) |
| /dream 记忆整理 | 自动整理和优化记忆文件 | [文档](https://ccb.agent-aura.top/docs/features/auto-dream) |
| Web Search | 内置网页搜索工具 | [文档](https://ccb.agent-aura.top/docs/features/web-browser-tool) |
| 自定义模型供应商 | OpenAI/Anthropic/Gemini/Grok 兼容 | [文档](https://ccb.agent-aura.top/docs/features/custom-platform-login) |
| Voice Mode | Push-to-Talk 语音输入 | [文档](https://ccb.agent-aura.top/docs/features/voice-mode) |
| Computer Use | 屏幕截图、键鼠控制 | [文档](https://ccb.agent-aura.top/docs/features/computer-use) |
| Chrome Use | 浏览器自动化、表单填写、数据抓取 | [魔改版](docs/features/chrome-use-mcp) [原生版](https://ccb.agent-aura.top/docs/features/claude-in-chrome-mcp) |
| Sentry | 企业级错误追踪 | [文档](https://ccb.agent-aura.top/docs/internals/sentry-setup) |
| GrowthBook | 企业级特性开关 | [文档](https://ccb.agent-aura.top/docs/internals/growthbook-adapter) |
| Langfuse 监控 | LLM 调用/工具执行/多 Agent 全链路追踪 | [文档](https://ccb.agent-aura.top/docs/features/langfuse-monitoring) |
| Poor Mode | 穷鬼模式,关闭记忆提取和键入建议 | /poor 可以开关 |
[文档在这里, 支持投稿 PR](https://ccb.agent-aura.top/) | [留影文档在这里](./Friends.md) | [Discord 群组](https://discord.gg/uApuzJWGKX)
- 🔮 [ ] V6 — 大规模重构石山代码全面模块分包全新分支main 封存为历史版本)
| 特性 | 说明 | 文档 |
| --------------------------- | ---------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| **Claude 群控技术** | Pipe IPC 多实例协作:同机 main/sub 自动编排 + LAN 跨机器零配置发现与通讯,`/pipes` 选择面板 + `Shift+↓` 交互 + 消息广播路由 | [Pipe IPC](https://ccb.agent-aura.top/docs/features/uds-inbox) / [LAN](https://ccb.agent-aura.top/docs/features/lan-pipes) |
| **ACP 协议一等一支持** | 支持接入 Zed、Cursor 等 IDE支持会话恢复、Skills、权限桥接 | [文档](https://ccb.agent-aura.top/docs/features/acp-zed) |
| **Remote Control 私有部署** | Docker 自托管远程界面, 可以手机上看 CC | [文档](https://ccb.agent-aura.top/docs/features/remote-control-self-hosting) |
| **Langfuse 监控** | 企业级 Agent 监控, 可以清晰看到每次 agent loop 细节, 可以一键转化为数据集 | [文档](https://ccb.agent-aura.top/docs/features/langfuse-monitoring) |
| **Web Search** | 内置网页搜索工具, 支持 bing 和 brave 搜索 | [文档](https://ccb.agent-aura.top/docs/features/web-browser-tool) |
| **Poor Mode** | 穷鬼模式,关闭记忆提取和键入建议,大幅度减少并发请求 | /poor 可以开关 |
| **Channels 频道通知** | MCP 服务器推送外部消息到会话(飞书/Slack/Discord/微信等),`--channels plugin:name@marketplace` 启用 | [文档](https://ccb.agent-aura.top/docs/features/channels) |
| **自定义模型供应商** | OpenAI/Anthropic/Gemini/Grok 兼容 (`/login`) | [文档](https://ccb.agent-aura.top/docs/features/all-features-guide) |
| Voice Mode | 语音输入,支持豆包语言输入(`/voice doubao` | [文档](https://ccb.agent-aura.top/docs/features/voice-mode) |
| Computer Use | 屏幕截图、键鼠控制 | [文档](https://ccb.agent-aura.top/docs/features/computer-use) |
| Chrome Use | 浏览器自动化、表单填写、数据抓取 | [自托管](https://ccb.agent-aura.top/docs/features/chrome-use-mcp) [原生版](https://ccb.agent-aura.top/docs/features/claude-in-chrome-mcp) |
| Sentry | 企业级错误追踪 | [文档](https://ccb.agent-aura.top/docs/internals/sentry-setup) |
| GrowthBook | 企业级特性开关 | [文档](https://ccb.agent-aura.top/docs/internals/growthbook-adapter) |
| /dream 记忆整理 | 自动整理和优化记忆文件 | [文档](https://ccb.agent-aura.top/docs/features/auto-dream) |
- 🚀 [想要启动项目](#快速开始源码版)
- 🐛 [想要调试项目](#vs-code-调试)
- 📖 [想要学习项目](#teach-me-学习项目)
## ⚡ 快速开始(安装版)
不用克隆仓库, 从 NPM 下载后, 直接使用
```sh
bun i -g claude-code-best
bun pm -g trust claude-code-best
npm i -g claude-code-best
# bun 安装比较多问题, 推荐 npm 装
# bun i -g claude-code-best
# bun pm -g trust claude-code-best @claude-code-best/mcp-chrome-bridge
ccb # 以 nodejs 打开 claude code
ccb-bun # 以 bun 形态打开
ccb update # 更新到最新版本
CLAUDE_BRIDGE_BASE_URL=https://remote-control.claude-code-best.win/ CLAUDE_BRIDGE_OAUTH_TOKEN=test-my-key ccb --remote-control # 我们有自部署的远程控制
```
@@ -56,11 +62,66 @@ CLAUDE_BRIDGE_BASE_URL=https://remote-control.claude-code-best.win/ CLAUDE_BRIDG
一定要最新版本的 bun 啊, 不然一堆奇奇怪怪的 BUG!!! bun upgrade!!!
- 📦 [Bun](https://bun.sh/) >= 1.3.11
**安装 Bun**
```bash
# Linux 和 macOS
curl -fsSL https://bun.sh/install | bash
# Windows (PowerShell)
powershell -c "irm bun.sh/install.ps1 | iex"
```
**安装后的操作:**
1. **让当前终端识别 `bun` 命令**
安装脚本会把 `~/.bun/bin` 写入对应的 shell 配置文件。macOS 默认 zsh 环境通常会看到:
```text
Added "~/.bun/bin" to $PATH in "~/.zshrc"
```
可以按安装脚本提示重启当前 shell
```bash
exec /bin/zsh
```
如果你使用 bash重新加载 bash 配置:
```bash
source ~/.bashrc
```
Windows PowerShell 用户关闭并重新打开 PowerShell 即可。
2. **验证 Bun 是否可用**
```bash
bun --help
bun --version
```
3. **如果已经安装过 Bun更新到最新版本**
```bash
bun upgrade
```
- ⚙️ 常规的配置 CC 的方式, 各大提供商都有自己的配置方式
### 📍 命令执行位置
- 安装或检查 Bun 的命令可以在任意目录执行:
`curl -fsSL https://bun.sh/install | bash`、`bun --help`、`bun --version`、`bun upgrade`
- 安装本项目依赖、启动开发模式、构建项目时,必须先进入本仓库根目录,也就是包含 `package.json` 的目录。
### 📥 安装
```bash
cd /path/to/claude-code
bun install
```
@@ -87,17 +148,17 @@ bun run build
需要填写的字段:
| 📌 字段 | 📝 说明 | 💡 示例 |
|------|------|------|
| Base URL | API 服务地址 | `https://api.example.com/v1` |
| API Key | 认证密钥 | `sk-xxx` |
| Haiku Model | 快速模型 ID | `claude-haiku-4-5-20251001` |
| Sonnet Model | 均衡模型 ID | `claude-sonnet-4-6` |
| Opus Model | 高性能模型 ID | `claude-opus-4-6` |
| 📌 字段 | 📝 说明 | 💡 示例 |
| ------------ | ------------- | ---------------------------- |
| Base URL | API 服务地址 | `https://api.example.com/v1` |
| API Key | 认证密钥 | `sk-xxx` |
| Haiku Model | 快速模型 ID | `claude-haiku-4-5-20251001` |
| Sonnet Model | 均衡模型 ID | `claude-sonnet-4-6` |
| Opus Model | 高性能模型 ID | `claude-opus-4-6` |
- ⌨️ **Tab / Shift+Tab** 切换字段,**Enter** 确认并跳到下一个,最后一个字段按 Enter 保存
> 支持所有 Anthropic API 兼容服务(如 OpenRouter、AWS Bedrock 代理等),只要接口兼容 Messages API 即可。
## Feature Flags
@@ -117,16 +178,17 @@ TUI (REPL) 模式需要真实终端,无法直接通过 VS Code launch 启动
### 步骤
1. **终端启动 inspect 服务**
```bash
bun run dev:inspect
```
会输出类似 `ws://localhost:8888/xxxxxxxx` 的地址。
会输出类似 `ws://localhost:8888/xxxxxxxx` 的地址。
2. **VS Code 附着调试器**
- 在 `src/` 文件中打断点
- F5 → 选择 **"Attach to Bun (TUI debug)"**
## Teach Me 学习项目
我们新加了一个 teach-me skills, 通过问答式引导帮你理解这个项目的任何模块。(调整 [sigma skill 而来](https://github.com/sanyuan0704/sanyuan-skills))
@@ -153,7 +215,7 @@ TUI (REPL) 模式需要真实终端,无法直接通过 VS Code launch 启动
## 相关文档及网站
- **在线文档Mintlify**: [ccb.agent-aura.top](https://ccb.agent-aura.top/) — 文档源码位于 [`docs/`](docs/) 目录,欢迎投稿 PR
- **DeepWiki**: <https://deepwiki.com/claude-code-best/claude-code>
- **DeepWiki**: [https://deepwiki.com/claude-code-best/claude-code](https://deepwiki.com/claude-code-best/claude-code)
## Contributors
@@ -171,6 +233,10 @@ TUI (REPL) 模式需要真实终端,无法直接通过 VS Code launch 启动
</picture>
</a>
## 致谢
- [doubaoime-asr](https://github.com/starccy/doubaoime-asr) — 豆包 ASR 语音识别 SDK为 Voice Mode 提供无需 Anthropic OAuth 的语音输入方案
## 许可证
本项目仅供学习研究用途。Claude Code 的所有权利归 [Anthropic](https://www.anthropic.com/) 所有。

View File

@@ -48,11 +48,64 @@ Sponsor placeholder.
Make sure you're on the latest version of Bun, otherwise you'll run into all sorts of weird bugs. Run `bun upgrade`!
- [Bun](https://bun.sh/) >= 1.3.11
**Install Bun:**
```bash
# Linux and macOS
curl -fsSL https://bun.sh/install | bash
# Windows (PowerShell)
powershell -c "irm bun.sh/install.ps1 | iex"
```
**Post-installation steps:**
1. **Make `bun` available in the current terminal**
The installer adds `~/.bun/bin` to the matching shell configuration file. On macOS with the default zsh shell, you may see:
```text
Added "~/.bun/bin" to $PATH in "~/.zshrc"
```
Restart the current shell as the installer suggests:
```bash
exec /bin/zsh
```
If you use bash, reload the bash configuration:
```bash
source ~/.bashrc
```
Windows PowerShell users can close and reopen PowerShell.
2. **Verify that Bun is available:**
```bash
bun --help
bun --version
```
3. **Update to latest version (if already installed):**
```bash
bun upgrade
```
- Standard Claude Code configuration — each provider has its own setup method
### Command Execution Location
- Bun installation and checking commands can be run from any directory:
`curl -fsSL https://bun.sh/install | bash`, `bun --help`, `bun --version`, `bun upgrade`
- Project dependency installation, development mode, and builds must be run from this repository root, the directory containing `package.json`.
### Install
```bash
cd /path/to/claude-code
bun install
```
@@ -135,7 +188,7 @@ The TUI (REPL) mode requires a real terminal and cannot be launched directly via
## Documentation & Links
- **Online docs (Mintlify)**: [ccb.agent-aura.top](https://ccb.agent-aura.top/) — source in [`docs/`](docs/), PR contributions welcome
- **DeepWiki**: <https://deepwiki.com/claude-code-best/claude-code>
- **DeepWiki**: https://deepwiki.com/claude-code-best/claude-code
## Contributors

128
build.ts
View File

@@ -1,6 +1,7 @@
import { readdir, readFile, writeFile, cp } from 'fs/promises'
import { join } from 'path'
import { getMacroDefines } from './scripts/defines.ts'
import { DEFAULT_BUILD_FEATURES } from './scripts/defines.ts'
const outdir = 'dist'
@@ -8,43 +9,6 @@ const outdir = 'dist'
const { rmSync } = await import('fs')
rmSync(outdir, { recursive: true, force: true })
// Default features that match the official CLI build.
// Additional features can be enabled via FEATURE_<NAME>=1 env vars.
const DEFAULT_BUILD_FEATURES = [
'AGENT_TRIGGERS_REMOTE',
'CHICAGO_MCP',
'VOICE_MODE',
'SHOT_STATS',
'PROMPT_CACHE_BREAK_DETECTION',
'TOKEN_BUDGET',
// P0: local features
'AGENT_TRIGGERS',
'ULTRATHINK',
'BUILTIN_EXPLORE_PLAN_AGENTS',
'LODESTONE',
// P1: API-dependent features
'EXTRACT_MEMORIES',
'VERIFICATION_AGENT',
'KAIROS_BRIEF',
'AWAY_SUMMARY',
'ULTRAPLAN',
// P2: daemon + remote control server
'DAEMON',
// PR-package restored features
'WORKFLOW_SCRIPTS',
'HISTORY_SNIP',
'CONTEXT_COLLAPSE',
'MONITOR_TOOL',
'FORK_SUBAGENT',
// 'UDS_INBOX',
'KAIROS',
'COORDINATOR_MODE',
'LAN_PIPES',
// 'REVIEW_ARTIFACT', // API 请求无响应,需进一步排查 schema 兼容性
// P3: poor mode (disable extract_memories + prompt_suggestion)
'POOR',
]
// Collect FEATURE_* env vars → Bun.build features
const envFeatures = Object.keys(process.env)
.filter(k => k.startsWith('FEATURE_'))
@@ -88,77 +52,45 @@ for (const file of files) {
}
}
// Also patch unguarded globalThis.Bun destructuring from third-party deps
// (e.g. @anthropic-ai/sandbox-runtime) so Node.js doesn't crash at import time.
let bunPatched = 0
const BUN_DESTRUCTURE = /var \{([^}]+)\} = globalThis\.Bun;?/g
const BUN_DESTRUCTURE_SAFE = 'var {$1} = typeof globalThis.Bun !== "undefined" ? globalThis.Bun : {};'
for (const file of files) {
if (!file.endsWith('.js')) continue
const filePath = join(outdir, file)
const content = await readFile(filePath, 'utf-8')
if (BUN_DESTRUCTURE.test(content)) {
await writeFile(
filePath,
content.replace(BUN_DESTRUCTURE, BUN_DESTRUCTURE_SAFE),
)
bunPatched++
}
}
BUN_DESTRUCTURE.lastIndex = 0
console.log(
`Bundled ${result.outputs.length} files to ${outdir}/ (patched ${patched} for Node.js compat)`,
`Bundled ${result.outputs.length} files to ${outdir}/ (patched ${patched} for import.meta.require, ${bunPatched} for Bun destructure)`,
)
// Step 4: Copy native .node addon files (audio-capture)
const vendorDir = join(outdir, 'vendor', 'audio-capture')
await cp('vendor/audio-capture', vendorDir, { recursive: true })
console.log(`Copied vendor/audio-capture/ → ${vendorDir}/`)
// Step 4: Copy native .node addon files (audio-capture) and vendored binaries (ripgrep)
const audioCaptureDir = join(outdir, 'vendor', 'audio-capture')
await cp('vendor/audio-capture', audioCaptureDir, { recursive: true })
console.log(`Copied vendor/audio-capture/ → ${audioCaptureDir}/`)
// Step 5: Bundle download-ripgrep script as standalone JS for postinstall
const rgScript = await Bun.build({
entrypoints: ['scripts/download-ripgrep.ts'],
outdir,
target: 'node',
})
if (!rgScript.success) {
console.error('Failed to bundle download-ripgrep script:')
for (const log of rgScript.logs) {
console.error(log)
}
// Non-fatal — postinstall fallback to bun run scripts/download-ripgrep.ts
} else {
console.log(`Bundled download-ripgrep script to ${outdir}/`)
}
const ripgrepDir = join(outdir, 'vendor', 'ripgrep')
await cp('src/utils/vendor/ripgrep', ripgrepDir, { recursive: true })
console.log(`Copied src/utils/vendor/ripgrep/ → ${ripgrepDir}/`)
// Step 6: Generate cli-bun and cli-node executable entry points
// Step 5: Generate cli-bun and cli-node executable entry points
const cliBun = join(outdir, 'cli-bun.js')
const cliNode = join(outdir, 'cli-node.js')
await writeFile(cliBun, '#!/usr/bin/env bun\nimport "./cli.js"\n')
// Node.js entry needs a Bun API polyfill because Bun.build({ target: 'bun' })
// emits globalThis.Bun references (e.g. Bun.$ shell tag in computer-use-input,
// Bun.which in chunk-ys6smqg9) that crash at import time under plain Node.js.
const NODE_BUN_POLYFILL = `#!/usr/bin/env node
// Bun API polyfill for Node.js runtime
if (typeof globalThis.Bun === "undefined") {
const { execFileSync } = await import("child_process");
const { resolve, delimiter } = await import("path");
const { accessSync, constants: { X_OK } } = await import("fs");
function which(bin) {
const isWin = process.platform === "win32";
const pathExt = isWin ? (process.env.PATHEXT || ".EXE").split(";") : [""];
for (const dir of (process.env.PATH || "").split(delimiter)) {
for (const ext of pathExt) {
const candidate = resolve(dir, bin + ext);
try { accessSync(candidate, X_OK); return candidate; } catch {}
}
}
return null;
}
// Bun.$ is the shell template tag (e.g. $\`osascript ...\`). Only used by
// computer-use-input/darwin — stub it so the top-level destructuring
// \`var { $ } = globalThis.Bun\` doesn't crash.
function $(parts, ...args) {
throw new Error("Bun.$ shell API is not available in Node.js. Use Bun runtime for this feature.");
}
function hash(data, seed) {
let h = ((seed || 0) ^ 0x811c9dc5) >>> 0;
for (let i = 0; i < data.length; i++) {
h ^= data.charCodeAt(i);
h = Math.imul(h, 0x01000193) >>> 0;
}
return h;
}
globalThis.Bun = { which, $, hash };
}
import "./cli.js"
`
await writeFile(cliNode, NODE_BUN_POLYFILL)
// NOTE: when new Bun-specific globals appear in bundled output, add them here.
await writeFile(cliNode, '#!/usr/bin/env node\nimport "./cli.js"\n')
// Make both executable
const { chmodSync } = await import('fs')

2303
bun.lock

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 1.6 MiB

After

Width:  |  Height:  |  Size: 1.6 MiB

View File

@@ -13,14 +13,14 @@ keywords: ["子 Agent", "AgentTool", "任务委派", "forkSubagent", "子进程
```
AI 生成 tool_use: { prompt: "修复 bug", subagent_type: "Explore" }
AgentTool.call() ← 入口AgentTool.tsx:239
AgentTool.call() ← 入口AgentTool.tsx:387
├── 解析 effectiveTypefork vs 命名 agent vs GP 回退)
├── filterDeniedAgents() ← 仅命名 Agent 路径执行:权限过滤
├── 检查 requiredMcpServers ← MCP 依赖验证(最长等 30s
├── assembleToolPool(workerPermissionContext) ← 独立组装工具池
├── createAgentWorktree() ← 可选 worktree 隔离
runAgent() ← 核心执行runAgent.ts:248
runAgent() ← 核心执行runAgent.ts
├── getAgentSystemPrompt() ← 构建 agent 专属 system prompt
├── initializeAgentMcpServers() ← agent 级 MCP 服务器
├── executeSubagentStartHooks() ← Hook 注入
@@ -54,7 +54,7 @@ Fork 实验的门控函数 `isForkSubagentEnabled()` 需要同时满足三个前
Fork 路径的设计核心是 **Prompt Cache 共享**:所有 fork 子进程共享父 Agent 的完整 `assistant` 消息(所有 `tool_use` 块),用相同的占位符 `tool_result` 填充,只有最后一个 `text` 块包含各自的指令。这使得 API 请求前缀字节完全一致,最大化缓存命中。
```typescript
// forkSubagent.ts:142 — 所有 fork 子进程的占位结果
// forkSubagent.ts:93 — 所有 fork 子进程的占位结果
const FORK_PLACEHOLDER_RESULT = 'Fork started — processing in background'
// buildForkedMessages() 构建:
@@ -63,7 +63,7 @@ const FORK_PLACEHOLDER_RESULT = 'Fork started — processing in background'
### Fork 递归防护
Fork 子进程保留 Agent 工具(为了 cache-identical tool defs但通过两道防线防止递归 fork`AgentTool.tsx:332`
Fork 子进程保留 Agent 工具(为了 cache-identical tool defs但通过两道防线防止递归 fork
1. **`querySource` 检查**(压缩安全):`context.options.querySource === 'agent:builtin:fork'`
2. **消息扫描**(降级兜底):检测 `<fork-boilerplate>` 标签
@@ -88,7 +88,7 @@ Fork 子进程保留 Agent 工具(为了 cache-identical tool defs但通
### 内置 Agent
系统预定义了几个内置 Agent`src/tools/AgentTool/builtinAgents.ts`),各有明确的职责和模型配置:
系统预定义了几个内置 Agent`packages/builtin-tools/src/tools/AgentTool/builtInAgents.ts`),各有明确的职责和模型配置:
| Agent | 模型 | 权限 | 用途 |
|-------|------|------|------|
@@ -119,7 +119,7 @@ const workerTools = assembleToolPool(workerPermissionContext, appState.mcp.tools
### 工具过滤的 resolveAgentTools
`runAgent.ts:500-502` 在工具组装后进一步过滤:
`runAgent.ts:508` 在工具组装后进一步过滤:
```typescript
const resolvedTools = useExactTools
@@ -142,7 +142,7 @@ const resolvedTools = useExactTools
## Worktree 隔离机制
`isolation: "worktree"` 参数让子 Agent 在独立的 git worktree 中工作(`AgentTool.tsx:590-593`
`isolation: "worktree"` 参数让子 Agent 在独立的 git worktree 中工作(`AgentTool.tsx:863`
```typescript
const slug = `agent-${earlyAgentId.slice(0, 8)}`
@@ -183,7 +183,7 @@ runAsyncAgentLifecycle() ← 后台执行agentToolUtils.ts
### 同步 Agent前台运行
同步 Agent 的关键特性是 **可后台化**`AgentTool.tsx:818-833`
同步 Agent 的关键特性是 **可后台化**`AgentTool.tsx:1107`
```typescript
const registration = registerAgentForeground({
@@ -218,7 +218,7 @@ const raceResult = await Promise.race([
## MCP 依赖的等待机制
如果 Agent 声明了 `requiredMcpServers``call()` 会等待这些服务器连接完成(`AgentTool.tsx:371-410`
如果 Agent 声明了 `requiredMcpServers``call()` 会等待这些服务器连接完成(`AgentTool.tsx:576`
```typescript
const MAX_WAIT_MS = 30_000 // 最长等 30 秒

View File

@@ -37,7 +37,7 @@ Worktree 文件统一存放在仓库根目录下的 `.claude/worktrees/`
## 创建流程EnterWorktreeTool
`EnterWorktreeTool``src/tools/EnterWorktreeTool/EnterWorktreeTool.ts`)的执行链路:
`EnterWorktreeTool``packages/builtin-tools/src/tools/EnterWorktreeTool/EnterWorktreeTool.ts`)的执行链路:
```
EnterWorktreeTool.call({ name? })
@@ -83,7 +83,7 @@ EnterWorktreeTool.call({ name? })
## 退出流程ExitWorktreeTool
`ExitWorktreeTool``src/tools/ExitWorktreeTool/ExitWorktreeTool.ts`)支持两种退出策略:
`ExitWorktreeTool``packages/builtin-tools/src/tools/ExitWorktreeTool/ExitWorktreeTool.ts`)支持两种退出策略:
### keep保留 worktree

View File

@@ -42,7 +42,7 @@ useInterval(checkForUpdates, 30 * 60 * 1000); // 每 30 分钟
任何更新尝试之前,系统会依次检查:
1. **自动更新是否被禁用?**`getAutoUpdaterDisabledReason()``src/utils/config.ts:1735`
1. **自动更新是否被禁用?**`getAutoUpdaterDisabledReason()``src/utils/config.ts:1737`
- `NODE_ENV === 'development'`
- 设置了 `DISABLE_AUTOUPDATER` 环境变量
- 仅限必要流量模式
@@ -81,7 +81,7 @@ useInterval(checkForUpdates, 30 * 60 * 1000); // 每 30 分钟
`src/utils/autoUpdater.ts:70``assertMinVersion()`
`src/main.tsx:1775` 在启动时调用
定义于 `src/utils/autoUpdater.ts:70`,设计上在启动时调用(当前未接入启动流程)
```typescript
void assertMinVersion();
@@ -200,7 +200,7 @@ Windows 系统使用文件复制而非符号链接。
**文件**: `src/migrations/migrateAutoUpdatesToSettings.ts`
一次性将旧版 `globalConfig.autoUpdates = false` 迁移为 settings 中的 `DISABLE_AUTOUPDATER=1` 环境变量。 `src/main.tsx:325` 在启动时调用
一次性将旧版 `globalConfig.autoUpdates = false` 迁移为 settings 中的 `DISABLE_AUTOUPDATER=1` 环境变量。定义于 `src/migrations/migrateAutoUpdatesToSettings.ts`(当前未接入启动流程)
---
@@ -270,7 +270,7 @@ React hook `useUpdateNotification(updatedVersion)` — 确保每次 semver 变
| `src/utils/releaseNotes.ts` | Changelog 获取、缓存与展示 |
| `src/utils/semver.ts` | Semver 版本比较Bun 原生 + npm 回退) |
| `src/utils/doctorDiagnostic.ts` | 安装类型检测与健康诊断 |
| `src/utils/config.ts:1735` | `getAutoUpdaterDisabledReason()` — 禁用检查逻辑 |
| `src/utils/config.ts:1737` | `getAutoUpdaterDisabledReason()` — 禁用检查逻辑 |
| `src/migrations/migrateAutoUpdatesToSettings.ts` | 旧版配置迁移 |
| `src/screens/Doctor.tsx` | Doctor 命令 UI展示自动更新状态 |

View File

@@ -48,7 +48,7 @@ const messagesForCompact = microcompactResult.messages
MicroCompact 不压缩整个对话,而是**清除旧工具输出的内容**。它维护一个白名单:
```typescript
// src/services/compact/microCompact.ts:41-48
// src/services/compact/microCompact.ts:41-50
const COMPACTABLE_TOOLS = new Set([
FILE_READ_TOOL_NAME, // 'Read' - 文件读取
...SHELL_TOOL_NAMES, // 'Bash' - 命令输出
@@ -143,7 +143,7 @@ const stripped2 = stripReinjectedAttachments(stripped) // 移除会被重新注
压缩后,系统会从摘要中**重新注入关键上下文**
```typescript
// compact.ts:124-132
// compact.ts:126-134
export const POST_COMPACT_TOKEN_BUDGET = 50_000 // 总预算
export const POST_COMPACT_MAX_FILES_TO_RESTORE = 5 // 最多恢复 5 个文件
export const POST_COMPACT_MAX_TOKENS_PER_FILE = 5_000 // 每文件 5K token

View File

@@ -39,7 +39,7 @@ Claude Code 的记忆系统是**纯文件**的——没有数据库、没有向
`MEMORY.md` 是记忆的入口索引,每次对话都完整加载到上下文中:
```typescript
// memdir.ts:35-38
// memdir.ts:34-38
export const ENTRYPOINT_NAME = 'MEMORY.md'
export const MAX_ENTRYPOINT_LINES = 200
export const MAX_ENTRYPOINT_BYTES = 25_000

View File

@@ -20,12 +20,12 @@ buildSystemPromptBlocks() → TextBlockParam[] (分块 + cache_control 标
1. **`getSystemPrompt()`**`src/constants/prompts.ts:444`)—— 收集静态段 + 动态段,插入 `SYSTEM_PROMPT_DYNAMIC_BOUNDARY` 分界标记
2. **`buildEffectiveSystemPrompt()`**`src/utils/systemPrompt.ts:41`)—— 按 Override > Coordinator > Agent > Custom > Default 优先级选择
3. **`buildSystemPromptBlocks()`**`src/services/api/claude.ts:3214`)—— 调用 `splitSysPromptPrefix()` 分块,为每个块附加 `cache_control`
3. **`buildSystemPromptBlocks()`**`src/services/api/claude.ts:3279`)—— 调用 `splitSysPromptPrefix()` 分块,为每个块附加 `cache_control`
## SystemPrompt 品牌类型
```typescript
// src/utils/systemPromptType.ts:8
// packages/@ant/model-provider/src/types/systemPrompt.ts:4
export type SystemPrompt = readonly string[] & {
readonly __brand: 'SystemPrompt'
}
@@ -185,7 +185,7 @@ export function shouldUseGlobalCacheScope(): boolean {
### `getCacheControl()`TTL 决策
`src/services/api/claude.ts:359` 生成的 `cache_control` 对象:
`src/services/api/claude.ts:348` 生成的 `cache_control` 对象:
```typescript
{
@@ -195,14 +195,14 @@ export function shouldUseGlobalCacheScope(): boolean {
}
```
1 小时 TTL 的判定逻辑(`should1hCacheTTL()`,第 394 行):
1 小时 TTL 的判定逻辑(`should1hCacheTTL()`,第 383 行):
- **Bedrock 用户**:通过环境变量 `ENABLE_PROMPT_CACHING_1H_BEDROCK` 启用
- **1P 用户**:通过 GrowthBook 配置的 `allowlist` 数组匹配 `querySource`,支持前缀通配符(如 `"repl_main_thread*"`
- **会话级锁定**:资格判定结果在 bootstrap state 中缓存,防止 GrowthBook 配置中途变化导致同一会话内 TTL 不一致
### 缓存破坏Session-Specific Guidance 的放置
`getSessionSpecificGuidanceSection()``src/constants/prompts.ts:352`)的内容必须放在 `SYSTEM_PROMPT_DYNAMIC_BOUNDARY` **之后**。因为它包含:
`getSessionSpecificGuidanceSection()``src/constants/prompts.ts:354`)的内容必须放在 `SYSTEM_PROMPT_DYNAMIC_BOUNDARY` **之后**。因为它包含:
- 当前会话的 enabledTools 集合
- `isForkSubagentEnabled()` 的运行时判定
- `getIsNonInteractiveSession()` 的结果

View File

@@ -32,7 +32,7 @@ message_stop ← 消息结束
### 事件处理状态机
`src/services/api/claude.ts` 中 `queryStreamRaw()` 函数的事件处理循环实现了一个基于 `switch(part.type)` 的状态机:
`src/services/api/claude.ts` 中 `queryModelWithStreaming()` 函数的事件处理循环实现了一个基于 `switch(part.type)` 的状态机:
| 事件类型 | 处理逻辑 | 状态变更 |
|----------|----------|----------|
@@ -167,10 +167,13 @@ UI 层通过 `useToolCallProgress` hook 实时展示命令输出,而不是等
| Provider | 流式协议 | 特殊处理 |
|----------|----------|----------|
| **Anthropic Direct** | 原生 SSE | 延迟最低TTFT 最快 |
| **firstParty** (Anthropic Direct) | 原生 SSE | 延迟最低TTFT 最快 |
| **AWS Bedrock** | AWS SDK 流式接口 | 需要额外的 beta header 和认证 |
| **Google Vertex** | gRPC → 事件流 | 通过 `getMergedBetas()` 适配 |
| **Azure** | Anthropic 兼容 API | 自定义 base URL |
| **foundry** | Anthropic 兼容 API | 内部部署 |
| **openai** | OpenAI 流式适配器 | 转换为 Anthropic 内部格式 |
| **gemini** | Gemini 流式适配器 | 转换为 Anthropic 内部格式 |
| **grok** (xAI) | Grok 流式适配器 | 转换为 Anthropic 内部格式 |
所有 Provider 通过统一的 `Stream<BetaRawMessageStreamEvent>` 抽象层屏蔽差异。上层代码QueryEngine、REPL不需要关心底层用的是哪个 Provider。

View File

@@ -74,17 +74,17 @@ const toolUpdates = streamingToolExecutor
| 终止原因 | 触发位置 | 机制 |
|----------|---------|------|
| **blocking_limit** | 第 646 行 | Token 计数超过硬限制(非 autocompact 模式)→ 生成 PTL 错误消息 → 返回 |
| **image_error** | 第 980 行 | `ImageSizeError` / `ImageResizeError` 异常 → 直接返回 |
| **model_error** | 第 999 行 | `callModel()` 抛出不可恢复异常 → 生成错误消息 → 返回 |
| **aborted_streaming** | 第 1054 行 | `abortController.signal.aborted`(流式阶段)→ 为未完成的 tool_use 生成合成 tool_result → 返回 |
| **prompt_too_long** | 第 1178/1185 行 | 413 错误且 reactive compact 无法恢复 → 暂扣的错误消息被释放 → 返回 |
| **completed** | 第 1267 行 | API 错误(限流、认证失败等)导致无法继续 → 返回 |
| **stop_hook_prevented** | 第 1282 行 | Stop hook 返回 `preventContinuation: true` → 返回 |
| **completed** | 第 1360 行 | 正常完成AI 未发出 tool_use → `needsFollowUp = false` → 经过 stop hooks → 返回 |
| **aborted_tools** | 第 1518 行 | `abortController.signal.aborted`(工具执行阶段)→ 返回 |
| **hook_stopped** | 第 1523 行 | 工具执行期间 hook 返回 `shouldPreventContinuation` → 返回 |
| **max_turns** | 第 1714 行 | 轮次计数超过 `maxTurns` 限制 → 返回 |
| **blocking_limit** | 第 686 行 | Token 计数超过硬限制(非 autocompact 模式)→ 生成 PTL 错误消息 → 返回 |
| **image_error** | 第 1021 行 | `ImageSizeError` / `ImageResizeError` 异常 → 直接返回 |
| **model_error** | 第 1040 行 | `callModel()` 抛出不可恢复异常 → 生成错误消息 → 返回 |
| **aborted_streaming** | 第 1095 行 | `abortController.signal.aborted`(流式阶段)→ 为未完成的 tool_use 生成合成 tool_result → 返回 |
| **prompt_too_long** | 第 1219/1226 行 | 413 错误且 reactive compact 无法恢复 → 暂扣的错误消息被释放 → 返回 |
| **completed** | 第 1308 行 | API 错误(限流、认证失败等)导致无法继续 → 返回 |
| **stop_hook_prevented** | 第 1323 行 | Stop hook 返回 `preventContinuation: true` → 返回 |
| **completed** | 第 1401 行 | 正常完成AI 未发出 tool_use → `needsFollowUp = false` → 经过 stop hooks → 返回 |
| **aborted_tools** | 第 1559 行 | `abortController.signal.aborted`(工具执行阶段)→ 返回 |
| **hook_stopped** | 第 1564 行 | 工具执行期间 hook 返回 `shouldPreventContinuation` → 返回 |
| **max_turns** | 第 1755 行 | 轮次计数超过 `maxTurns` 限制 → 返回 |
## 继续条件(恢复路径)
@@ -158,7 +158,7 @@ type State = {
- **每一步都产生真实信息**`runTools()` 返回的 `toolResults` 是 API 不可能预知的——命令输出、文件内容、错误信息
- **动态上下文管理**每轮迭代前都重新评估压缩需求autocompact → microcompact → snip基于最新的 token 计数
- **错误即时恢复**工具失败不需要推倒重来——stop hook 可以注入阻塞错误让 AI 修正策略
- **用户可控**`abortController.signal` 在循环的多个检查点被检测(第 1018、1048、1488 行),用户按 ESC 可以优雅中断
- **用户可控**`abortController.signal` 在循环的多个检查点被检测(第 1059、1095、1529 行),用户按 ESC 可以优雅中断
- **成本控制**Token Budget 在每轮终止前检查,防止 AI 无效循环
## 一个完整的迭代示例

View File

@@ -0,0 +1,17 @@
flowchart TB
START((输入)) --> CTX["Context 管理"]
CTX --> LLM["LLM 流式输出"]
LLM --> TC{tool_use?}
TC --> |是| EXEC["执行工具"]
EXEC --> CTX
TC --> |否| DONE((完成))
classDef proc fill:#eef,stroke:#66c,color:#224
classDef decision fill:#fee,stroke:#c66,color:#422
classDef io fill:#eff,stroke:#6cc,color:#244
class CTX,LLM,EXEC proc
class TC decision
class START,DONE io

View File

@@ -0,0 +1,40 @@
flowchart TB
START((输入)) --> CTX["Context 管理"]
CTX --> PRE["Pre-sampling Hook"]
PRE --> LLM["LLM 流式输出"]
LLM --> TC{tool_use?}
TC --> |是| PERM{需权限?}
PERM --> |是| USER["👤 用户审批"]
USER --> |allow| TOOL_PRE
USER --> |deny| DENIED["拒绝"]
PERM --> |否| TOOL_PRE["Pre-tool Hook"]
TOOL_PRE --> EXEC["并发执行工具"]
EXEC --> TOOL_POST["Post-tool Hook"]
TOOL_POST --> CTX
DENIED --> CTX
TC --> |否| POST["Post-sampling Hook"]
POST --> STOP{"Stop Hook"}
STOP --> |不通过| CTX
STOP --> |通过| BUDGET{"Token Budget"}
BUDGET --> |继续| CTX
BUDGET --> |完成| DONE((完成))
subgraph SUB["子 Agent"]
FORK["AgentTool"] --> RECURSE["递归调用"]
end
EXEC -.-> FORK
classDef proc fill:#eef,stroke:#66c,color:#224
classDef decision fill:#fee,stroke:#c66,color:#422
classDef hook fill:#ffe,stroke:#cc6,color:#442
classDef io fill:#eff,stroke:#6cc,color:#244
classDef sub fill:#efe,stroke:#6a6,color:#242
class CTX,LLM,EXEC proc
class TC,PERM,STOP,BUDGET decision
class PRE,TOOL_PRE,TOOL_POST,POST hook
class START,DONE,USER,DENIED io
class FORK,RECURSE sub

View File

@@ -12,7 +12,7 @@ Claude Code 的 Agent 不仅仅来自用户自定义——系统有三类来源
| 来源 | 位置 | 优先级 |
|------|------|--------|
| **Built-in** | `src/tools/AgentTool/built-in/` 硬编码 | 最低(可被覆盖) |
| **Built-in** | `packages/builtin-tools/src/tools/AgentTool/built-in/` 硬编码 | 最低(可被覆盖) |
| **Plugin** | 通过插件系统注册 | 中 |
| **User/Project/Policy** | `.claude/agents/*.md` 或 settings.json | 最高 |
@@ -127,7 +127,7 @@ color: "blue" # 终端中的 Agent 颜色标识
以内置 Explore Agent 为例:
```typescript
// src/tools/AgentTool/built-in/exploreAgent.ts
// packages/builtin-tools/src/tools/AgentTool/built-in/exploreAgent.ts
disallowedTools: [
'Agent', // 不能嵌套调用 Agent
'ExitPlanMode', // 不需要 plan mode

View File

@@ -240,7 +240,7 @@ SDK 非交互模式下信任是隐式的(`getIsNonInteractiveSession()` 为 tr
## Session Hook 的生命周期
Agent 和 Skill 的前置 Hook 通过 `registerFrontmatterHooks()` 注册(调用位置:`src/tools/AgentTool/runAgent.ts`;定义位置:`src/utils/hooks/registerFrontmatterHooks.ts`),绑定到 agent 的 session ID。Agent 结束时通过 `clearSessionHooks()`(定义位置:`src/utils/hooks/sessionHooks.ts`)清理。
Agent 和 Skill 的前置 Hook 通过 `registerFrontmatterHooks()` 注册(调用位置:`packages/builtin-tools/src/tools/AgentTool/runAgent.ts`;定义位置:`src/utils/hooks/registerFrontmatterHooks.ts`),绑定到 agent 的 session ID。Agent 结束时通过 `clearSessionHooks()`(定义位置:`src/utils/hooks/sessionHooks.ts`)清理。
```typescript
// runAgent.ts — 注册 agent 的前置 Hook

View File

@@ -304,7 +304,7 @@ timer.unref?.() // 不阻止进程退出
## 工具发现:从 MCP 到 Tool 接口
`fetchToolsForClient()``client.ts:1745-2000`)使用 `memoizeWithLRU` 缓存(上限 20将 MCP 工具转换为 Claude Code 的统一 Tool 接口:
`fetchToolsForClient()``client.ts:1744-2000`)使用 `memoizeWithLRU` 缓存(上限 100将 MCP 工具转换为 Claude Code 的统一 Tool 接口:
```typescript
const fullyQualifiedName = buildMcpToolName(client.name, tool.name)

View File

@@ -22,7 +22,7 @@ Skill 的核心洞见:**复杂任务的关键不在代码逻辑,而在 Promp
### 1. 内置命令Built-in Commands
硬编码在 `src/commands.ts:258` 的 `COMMANDS` memoize 数组中,包含 70+ 条命令(`/commit`、`/review`、`/compact` 等)。这些是 TypeScript 模块而非 Markdown但实现了相同的 `Command` 接口(`src/types/command.ts`)。
硬编码在 `src/commands.ts:299` 的 `COMMANDS` memoize 数组中,包含 70+ 条命令(`/commit`、`/review`、`/compact` 等)。这些是 TypeScript 模块而非 Markdown但实现了相同的 `Command` 接口(`src/types/command.ts`)。
### 2. Bundled Skills编译时打包
@@ -98,7 +98,7 @@ shell: ["bash"] # Shell 执行环境
## 两条执行路径Inline vs Fork
SkillTool`src/tools/SkillTool/SkillTool.ts:332`)在 `call()` 中根据 `command.context` 分流:
SkillTool`packages/builtin-tools/src/tools/SkillTool/SkillTool.ts:332`)在 `call()` 中根据 `command.context` 分流:
### Inline 模式(默认)

View File

@@ -50,7 +50,7 @@
- **端点**: `{region}-aiplatform.googleapis.com`
- **认证**: `GoogleAuth` + `cloud-platform` scope
- **文件**: `src/services/api/client.ts:228-298`
- **文件**: `src/services/api/client.ts:221-298`
### 4. Azure Foundry
@@ -129,12 +129,12 @@ WebSearch 工具支持直接抓取 Bing 搜索结果页面,也支持通过 Bra
- **Bing 端点**: `https://www.bing.com/search?q={query}&setmkt=en-US`
- **Brave 端点**: `https://api.search.brave.com/res/v1/llm/context?q={query}`
- **文件**:
- `src/tools/WebSearchTool/adapters/bingAdapter.ts`
- `src/tools/WebSearchTool/adapters/braveAdapter.ts`
- `packages/builtin-tools/src/tools/WebSearchTool/adapters/bingAdapter.ts`
- `packages/builtin-tools/src/tools/WebSearchTool/adapters/braveAdapter.ts`
另外还有 Domain Blocklist 查询:
- **端点**: `https://api.anthropic.com/api/web/domain_info?domain={domain}`
- **文件**: `src/tools/WebFetchTool/utils.ts`
- **文件**: `packages/builtin-tools/src/tools/WebFetchTool/utils.ts`
### 15. Google Cloud Storage (自动更新)

201
docs/features/acp-link.md Normal file
View File

@@ -0,0 +1,201 @@
# acp-link — ACP 代理服务器
> 源码目录:`packages/acp-link/`
> PR: #292
> 新增时间2026-04-18
## 一、功能概述
`acp-link` 是一个 ACP (Agent Client Protocol) 代理服务器,将 WebSocket 客户端桥接到 ACP agent 的 stdio 接口。它让 ACP agent如 Claude Code可以通过 WebSocket 远程访问,而不仅限于本地 stdio。
### 核心特性
- **WebSocket → stdio 桥接**:将浏览器/远程客户端的 WebSocket 连接转换为 ACP agent 的 stdin/stdout NDJSON 流
- **会话管理**:创建、加载、恢复、列出、关闭会话
- **权限审批流程**:客户端可远程审批 agent 的工具权限请求
- **RCS 集成**:可与 Remote Control Server (RCS) 连接,将 ACP agent 注册到 RCS 并通过 Web UI 交互
- **HTTPS 支持**:内置自签名证书生成,支持安全连接
- **Token 认证**:自动生成或通过环境变量配置认证 token
## 二、架构
### 独立模式
```
┌──────────────────┐ WebSocket ┌──────────────────┐ stdio/NDJSON ┌──────────────┐
│ 浏览器/客户端 │ ◄──────────────►│ acp-link │ ◄────────────────►│ ACP Agent │
│ (WS Client) │ ws://host:port │ (Proxy Server) │ spawn subprocess │ (Claude等) │
└──────────────────┘ └──────────────────┘ └──────────────┘
```
### RCS 集成模式
```
┌──────────────┐ WebSocket ┌──────────────────┐ stdio/NDJSON ┌──────────────┐
│ RCS Web UI │ ◄──────────────►│ Remote Control │ ◄─────────────────►│ acp-link │
│ (/code/*) │ ACP Relay WS │ Server (RCS) │ ACP events │ + Agent │
└──────────────┘ └──────────────────┘ └──────────────┘
```
### 文件结构
```
packages/acp-link/
├── src/
│ ├── server.ts # 主服务器WS 连接管理、会话管理、权限处理、消息桥接
│ ├── rcs-upstream.ts # RCS 上游客户端REST 注册 + WS identify 两步流程
│ ├── cert.ts # TLS 证书生成(自签名)
│ ├── logger.ts # 日志模块
│ ├── types.ts # JSON-RPC 和 ACP 协议类型定义
│ ├── cli/
│ │ ├── bin.ts # CLI 入口
│ │ ├── command.ts # 命令行参数解析
│ │ ├── app.ts # 应用启动
│ │ └── context.ts # 上下文配置
│ └── __tests__/ # 测试cert, server, types
├── package.json
└── tsconfig.json
```
## 三、安装与使用
### 基本用法
```bash
# 直接运行(在 monorepo 中)
# 注意claude 本身不支持 ACP需要用 ccb-bun --acp 启动 ACP agent
bun packages/acp-link/src/cli/bin.ts ccb-bun -- --acp
# 指定端口和主机
acp-link --port 9000 --host 0.0.0.0 ccb-bun -- --acp
# 启用 HTTPS自签名证书
acp-link --https ccb-bun -- --acp
# 调试模式
acp-link --debug ccb-bun -- --acp
```
### CLI 参考
```
USAGE
acp-link [--port value] [--host value] [--debug] [--no-auth] [--https] <command>...
acp-link --help
acp-link --version
FLAGS
[--port] Port to listen on [default = 9315]
[--host] Host to bind to [default = localhost]
[--debug] Enable debug logging to file
[--no-auth] Disable authentication (dangerous)
[--https] Enable HTTPS with self-signed cert
-h --help Print help information and exit
-v --version Print version information and exit
ARGUMENTS
command... Agent command followed by its arguments (e.g. "ccb-bun -- --acp")
```
## 四、认证
默认启动时自动生成随机 token。客户端连接时需通过 query 参数传递:
```
ws://localhost:9315/ws?token=<your-token>
```
配置固定 token
```bash
ACP_AUTH_TOKEN=my-fixed-token acp-link ccb-bun -- --acp
```
禁用认证(不推荐,仅用于开发):
```bash
acp-link --no-auth ccb-bun -- --acp
```
## 五、RCS 集成
acp-link 支持将 ACP agent 注册到 Remote Control Server通过 Web UI 远程操控。
### 连接方式
```bash
# 通过环境变量配置 RCS 连接
ACP_RCS_URL=http://localhost:3000 \
ACP_RCS_TOKEN=sk-rcs-your-key \
acp-link ccb-bun -- --acp
```
### 注册流程(两步)
1. **REST 注册**:通过 `POST /v1/environments/bridge` 向 RCS 注册环境
2. **WS identify**:建立 WebSocket 连接后发送 `identify` 消息(携带 agentId替代完整 `register`
```
acp-link RCS
│ │
│── POST /v1/environments/bridge ──►│ (REST 注册)
│◄── { agentId, sessionId } ───────│
│ │
│── WS connect ─────────────────►│ (WebSocket)
│── identify { agentId } ────────►│ (WS 标识)
│◄── identified ─────────────────│
│ │
│── ACP events ─────────────────►│ (双向消息转发)
│◄── user prompts/permissions ───│
```
## 六、权限模式
### permissionMode 传递链
权限模式通过整条链路传递Web UI → RCS → acp-link → ACP agent。
支持的权限模式:
- `default` — 每次请求权限确认
- `auto` — 自动判断
- `acceptEdits` — 自动接受编辑
- `plan` — 规划模式
- `dontAsk` — 不询问
- `bypassPermissions` — 绕过权限(需 sandbox 环境)
### fallback 链
当客户端未显式传递 permissionMode 时,使用以下 fallback 链:
```
客户端传值 > config.permissionMode > ACP_PERMISSION_MODE 环境变量
```
示例:
```bash
ACP_PERMISSION_MODE=auto acp-link ccb-bun -- --acp
```
## 七、权限管道2026-04-18 改进)
### 模式同步
`applySessionMode` 在 agent 切换权限模式时同步 `appState.toolPermissionContext.mode`,确保内部权限上下文与 ACP 客户端状态一致。
### 统一权限流水线
`createAcpCanUseTool` 接入 `hasPermissionsToUseTool` 统一权限流水线,替代原来分散的处理逻辑。支持 `onModeChange` 回调,模式变更时实时同步。
### bypass 检测
`bypassPermissions` 模式增加可用性检测 — 仅在非 root 或 sandbox 环境中允许启用,防止权限绕过的安全风险。
## 八、环境变量
| 变量 | 说明 |
|------|------|
| `ACP_AUTH_TOKEN` | 固定认证 token默认自动生成 |
| `ACP_PERMISSION_MODE` | 默认权限模式 fallback |
| `ACP_RCS_URL` | RCS 服务器地址(启用 RCS 集成) |
| `ACP_RCS_TOKEN` | RCS API token |

189
docs/features/acp-zed.md Normal file
View File

@@ -0,0 +1,189 @@
# ACP (Agent Client Protocol) — Zed / IDE 集成
> Feature Flag: `FEATURE_ACP=1`build 和 dev 模式默认启用)
> 实现状态:可用(支持 Zed、Cursor 等 ACP 客户端)
> 源码目录:`src/services/acp/`
## 一、功能概述
ACP (Agent Client Protocol) 是一种标准化的 stdio 协议,允许 IDE 和编辑器通过 stdin/stdout 的 NDJSON 流驱动 AI Agent。CCB 实现了完整的 ACP agent 端,可以被 Zed、Cursor 等支持 ACP 的客户端直接调用。
### 核心特性
- **会话管理**:新建 / 恢复 / 加载 / 分叉 / 关闭会话
- **历史回放**:恢复会话时自动加载并回放对话历史
- **权限桥接**ACP 客户端的权限决策映射到 CCB 的工具权限系统
- **斜杠命令 & Skills**:加载真实命令列表,支持 `/commit``/review` 等 prompt 型 skill
- **Context Window 跟踪**:精确的 usage_update含 model prefix matching
- **Prompt 排队**:支持连续发送多条 prompt自动排队处理
- **模式切换**auto / default / acceptEdits / plan / dontAsk / bypassPermissions
- **模型切换**:运行时切换 AI 模型
## 二、架构
```
┌──────────────┐ NDJSON/stdio ┌──────────────────┐
│ Zed / IDE │ ◄────────────────► │ CCB ACP Agent │
│ (Client) │ stdin / stdout │ (Agent) │
└──────────────┘ │ │
│ entry.ts │ ← stdio → NDJSON stream
│ agent.ts │ ← ACP protocol handler
│ bridge.ts │ ← SDKMessage → ACP SessionUpdate
│ permissions.ts │ ← 权限桥接
│ utils.ts │ ← 通用工具
│ │
│ QueryEngine │ ← 内部查询引擎
└──────────────────┘
```
### 文件职责
| 文件 | 职责 |
|------|------|
| `entry.ts` | 入口,创建 stdio → NDJSON stream启动 `AgentSideConnection` |
| `agent.ts` | 实现 ACP `Agent` 接口:会话 CRUD、prompt、cancel、模式/模型切换 |
| `bridge.ts` | `SDKMessage` → ACP `SessionUpdate` 转换:文本/思考/工具/用量/编辑 diff |
| `permissions.ts` | ACP `requestPermission()` → CCB `CanUseToolFn` 桥接 |
| `utils.ts` | Pushable、流转换、权限模式解析、session fingerprint、路径显示 |
## 三、配置 Zed 编辑器
### 3.1 Zed settings.json 配置
打开 Zed 的 `settings.json``Cmd+,` → Open Settings添加 `agent_servers` 配置:
```json
{
"agent_servers": {
"ccb": {
"type": "custom",
"command": "ccb",
"args": ["--acp"]
}
}
}
```
### 3.3 API 认证配置
CCB 的 ACP agent 在启动时会自动加载 `settings.json` 中的环境变量(`ANTHROPIC_BASE_URL``ANTHROPIC_AUTH_TOKEN` 等)。确保已通过 `/login` 配置好 API 供应商。
也可通过环境变量传入:
```json
{
"agent_servers": {
"claude-code": {
"command": "ccb",
"args": ["--acp"],
"env": {
"ANTHROPIC_BASE_URL": "https://api.example.com/v1",
"ANTHROPIC_AUTH_TOKEN": "sk-xxx"
}
}
}
}
```
### 3.4 在 Zed 中使用
1. 配置完成后重启 Zed
2. 打开任意项目目录
3.`Cmd+'`macOS`Ctrl+'`Linux打开 Agent Panel
4. 在 Agent Panel 顶部的下拉菜单中选择 **claude-code**
5. 开始对话
### 3.5 功能说明
| 功能 | 操作 |
|------|------|
| 对话 | 在 Agent Panel 中直接输入消息 |
| 斜杠命令 | 输入 `/` 查看可用 skills 列表(如 `/commit``/review` |
| 工具权限 | 弹出权限请求时选择 Allow / Reject / Always Allow |
| 模式切换 | 通过 Agent Panel 的设置菜单切换 auto/default/plan 等模式 |
| 模型切换 | 通过 Agent Panel 的设置菜单切换 AI 模型 |
| 会话恢复 | 关闭重开 Zed 后,之前的会话可自动恢复(含历史消息) |
## 四、配置其他 ACP 客户端
ACP 是开放协议,任何支持 ACP 的客户端都可以连接 CCB。通用配置模式
```
命令: ccb --acp
参数: ["--acp"]
通信: stdin/stdout NDJSON
协议版本: ACP v1
```
### 4.1 Cursor
在 Cursor 的设置中配置 MCP / Agent Server使用同样的 `ccb --acp` 命令。
### 4.2 自定义客户端
使用 `@agentclientprotocol/sdk` 可以快速构建 ACP 客户端:
```typescript
import { ClientSideConnection, ndJsonStream } from '@agentclientprotocol/sdk'
// 创建连接(将 ccb --acp 作为子进程启动)
const child = spawn('ccb', ['--acp'])
const stream = ndJsonStream(
Writable.toWeb(child.stdin),
Readable.toWeb(child.stdout),
)
const client = new ClientSideConnection(stream)
// 初始化
await client.initialize({ clientCapabilities: {} })
// 创建会话
const { sessionId } = await client.newSession({
cwd: '/path/to/project',
})
// 发送 prompt
const response = await client.prompt({
sessionId,
prompt: [{ type: 'text', text: 'Hello, explain this project' }],
})
// 监听 session 更新
client.on('sessionUpdate', (update) => {
console.log('Update:', update)
})
```
## 五、ACP 协议支持矩阵
| 方法 | 状态 | 说明 |
|------|------|------|
| `initialize` | ✅ | 返回 agent 信息和能力 |
| `authenticate` | ✅ | 无需认证(自托管) |
| `newSession` | ✅ | 创建新会话 |
| `resumeSession` | ✅ | 恢复已有会话(含历史回放) |
| `loadSession` | ✅ | 加载指定会话(含历史回放) |
| `listSessions` | ✅ | 列出可用会话 |
| `forkSession` | ✅ | 分叉会话 |
| `closeSession` | ✅ | 关闭会话 |
| `prompt` | ✅ | 发送消息,支持排队 |
| `cancel` | ✅ | 取消当前/排队的 prompt |
| `setSessionMode` | ✅ | 切换权限模式 |
| `setSessionModel` | ✅ | 切换 AI 模型 |
| `setSessionConfigOption` | ✅ | 动态修改配置 |
### SessionUpdate 类型
| 类型 | 状态 | 说明 |
|------|------|------|
| `agent_message_chunk` | ✅ | 助手文本消息 |
| `agent_thought_chunk` | ✅ | 思考/推理内容 |
| `user_message_chunk` | ✅ | 用户消息(历史回放) |
| `tool_call` | ✅ | 工具调用开始 |
| `tool_call_update` | ✅ | 工具调用结果/状态更新 |
| `usage_update` | ✅ | token 用量 + context window |
| `plan` | ✅ | TodoWrite → plan entries |
| `available_commands_update` | ✅ | 斜杠命令 & skills 列表 |
| `current_mode_update` | ✅ | 模式切换通知 |
| `config_option_update` | ✅ | 配置更新通知 |

View File

@@ -516,25 +516,37 @@ AI 也可通过 `SnipTool` 自动截断过长的对话:
| Flag | 默认 | 说明 |
|------|------|------|
| `BUDDY` | ✅ dev/build | 伴侣系统 |
| `BRIDGE_MODE` | ✅ dev/build | 远程控制 |
| `VOICE_MODE` | ✅ dev/build | 语音模式 |
| `CHICAGO_MCP` | ✅ dev/build | Computer Use + Chrome |
| `AGENT_TRIGGERS_REMOTE` | ✅ dev/build | 定时任务 |
| `SHOT_STATS` | ✅ dev/build | API 统计 |
| `TOKEN_BUDGET` | ✅ dev/build | Token 预算 |
| `PROMPT_CACHE_BREAK_DETECTION` | ✅ dev/build | 缓存检测 |
| `ULTRAPLAN` | ✅ dev/build | 高级规划 |
| `DAEMON` | ✅ dev/build | 后台守护 |
| `UDS_INBOX` | ✅ dev/build | Pipe IPC |
| `LAN_PIPES` | ✅ dev/build | LAN 群控 |
| `MONITOR_TOOL` | ✅ dev/build | 后台监控 |
| `WORKFLOW_SCRIPTS` | ✅ dev/build | 工作流脚本 |
| `FORK_SUBAGENT` | ✅ dev/build | 子 Agent |
| `KAIROS` | ✅ dev/build | Kairos 调度 |
| `COORDINATOR_MODE` | ✅ dev/build | 多 Worker |
| `HISTORY_SNIP` | ✅ dev/build | 历史管理 |
| `CONTEXT_COLLAPSE` | ✅ dev/build | 上下文折叠 |
| `BUDDY` | ✅ dev only | 伴侣系统 |
| `BRIDGE_MODE` | ✅ dev only | 远程控制 |
| `VOICE_MODE` | ✅ dev+build | 语音模式 |
| `CHICAGO_MCP` | ✅ dev+build | Computer Use + Chrome |
| `AGENT_TRIGGERS_REMOTE` | ✅ dev+build | 定时任务 |
| `SHOT_STATS` | ✅ dev+build | API 统计 |
| `TOKEN_BUDGET` | ✅ dev+build | Token 预算 |
| `PROMPT_CACHE_BREAK_DETECTION` | ✅ dev+build | 缓存检测 |
| `ULTRAPLAN` | ✅ dev+build | 高级规划 |
| `DAEMON` | ✅ dev+build | 后台守护 |
| `UDS_INBOX` | ✅ dev only | Pipe IPC |
| `LAN_PIPES` | ✅ dev only | LAN 群控 |
| `MONITOR_TOOL` | ✅ dev+build | 后台监控 |
| `WORKFLOW_SCRIPTS` | ✅ dev+build | 工作流脚本 |
| `FORK_SUBAGENT` | ✅ dev+build | 子 Agent |
| `KAIROS` | ✅ dev+build | Kairos 调度 |
| `COORDINATOR_MODE` | ✅ dev+build | 多 Worker |
| `HISTORY_SNIP` | ✅ dev+build | 历史管理 |
| `CONTEXT_COLLAPSE` | ✅ dev+build | 上下文折叠 |
| `ULTRATHINK` | ✅ dev+build | 扩展思考 |
| `EXTRACT_MEMORIES` | ✅ dev+build | 自动记忆提取 |
| `VERIFICATION_AGENT` | ✅ dev+build | 验证 Agent |
| `KAIROS_BRIEF` | ✅ dev+build | Brief 模式 |
| `AWAY_SUMMARY` | ✅ dev+build | 离开摘要 |
| `ACP` | ✅ dev+build | ACP 协议 |
| `LODESTONE` | ✅ dev+build | 深度链接 |
| `BUILTIN_EXPLORE_PLAN_AGENTS` | ✅ dev+build | 内置 Explore/Plan agent |
| `AGENT_TRIGGERS` | ✅ dev+build | 本地定时任务 |
| `BG_SESSIONS` | ✅ dev only | 后台会话 |
| `TEMPLATES` | ✅ dev only | 模板系统 |
| `TRANSCRIPT_CLASSIFIER` | ✅ dev only | 对话分类 |
手动启用任意 flag
```bash

View File

@@ -102,6 +102,6 @@ FEATURE_BASH_CLASSIFIER=1 FEATURE_TREE_SITTER_BASH=1 bun run dev
| `src/utils/permissions/bashClassifier.ts` | — | Bash 分类器stubANT-ONLY |
| `src/utils/permissions/yoloClassifier.ts` | 1496 | YOLO 分类器(完整参考实现) |
| `src/utils/classifierApprovals.ts` | — | 分类器审批信号管理 |
| `src/components/permissions/BashPermissionRequest.tsx:261-469` | — | 分类器 UI |
| `src/components/permissions/BashPermissionRequest/BashPermissionRequest.tsx` | — | 分类器 UI |
| `src/hooks/toolPermission/handlers/interactiveHandler.ts` | — | 交互式权限处理 |
| `src/services/api/withRetry.ts:81` | — | API beta 标头 |
| `src/services/api/withRetry.ts` | — | API beta 标头 |

View File

@@ -30,7 +30,7 @@ BRIDGE_MODE 将本地 CLI 注册为"bridge 环境",可从 claude.ai 或其他
文件:`src/bridge/bridgeApi.ts`
Bridge API Client 提供 7 个核心操作:
Bridge API Client 提供 9 个核心操作:
| 操作 | HTTP | 说明 |
|------|------|------|
@@ -137,7 +137,7 @@ FEATURE_BRIDGE_MODE=1 FEATURE_DAEMON=1 bun run dev
| 文件 | 行数 | 职责 |
|------|------|------|
| `src/bridge/bridgeApi.ts` | 540 | API Client核心 |
| `src/bridge/bridgeApi.ts` | 541 | API Client核心 |
| `src/bridge/sessionRunner.ts` | — | 会话运行器 |
| `src/bridge/bridgeConfig.ts` | — | 配置管理 |
| `src/bridge/replBridgeTransport.ts` | — | 传输层 |

View File

@@ -78,10 +78,13 @@ FEATURE_BUDDY=1 bun run dev
| 文件 | 说明 |
|---|---|
| `src/commands/buddy/index.ts` | `/buddy` 命令注册 |
| `src/commands/buddy/buddy.ts` | `/buddy` 命令处理 |
| `src/buddy/companion.ts` | 宠物生成与加载 |
| `src/buddy/companionReact.ts` | 宠物反应系统REPL 每轮查询后触发) |
| `src/buddy/types.ts` | 类型定义(物种、稀有度、属性) |
| `src/buddy/sprites.ts` | 终端像素画渲染 |
| `src/buddy/CompanionSprite.tsx` | React 组件(输入框旁显示) |
| `src/buddy/CompanionCard.tsx` | 宠物信息卡片(`/buddy` 无参数时展示) |
| `src/buddy/useBuddyNotification.tsx` | 启动提示通知 |
| `src/buddy/prompt.ts` | 宠物相关 prompt 模板 |

89
docs/features/channels.md Normal file
View File

@@ -0,0 +1,89 @@
# Channels — 外部频道消息接入
> 启动参数:`--channels` / `--dangerously-load-development-channels`
> 状态:已解除 feature flag 和 OAuth 限制,可直接使用
## 概述
Channel 是一个 MCP 服务器,它将外部事件推送到你运行中的 Claude Code 会话中,以便 Claude 可以在你不在终端时做出反应。详细使用说明请参考以下文档:
- **官方文档**[使用 channels 将事件推送到运行中的会话](https://code.claude.com/docs/zh-CN/channels)
- **飞书插件**[claude-code-feishu-channel](https://github.com/whobot-ai/claude-code-feishu-channel) — 社区首个飞书 Channel 插件,支持双向消息、配对认证、群组聊天、文件附件
本仓库现在内置了 **微信 WeChat channel**,不需要单独安装外部 marketplace 插件。
## 快速开始
```bash
# 启用频道监听plugin 格式)
ccb --channels plugin:feishu@claude-code-feishu-channel
# 启用内置微信 channel
ccb weixin login
ccb --channels plugin:weixin@builtin
# 启用频道监听server 格式)
ccb --channels server:my-slack-bridge
# 同时启用多个频道
ccb --channels plugin:feishu@claude-code-feishu-channel --channels server:discord-bot
# 开发模式(跳过 allowlist 检查,用于测试自定义 channel
ccb --dangerously-load-development-channels server:my-custom-channel
```
## 支持的 Channel
| Channel | 说明 | 来源 |
|---------|------|------|
| **Telegram** | 官方 Telegram Bot 集成 | `/plugin install telegram@claude-plugins-official` |
| **Discord** | 官方 Discord Bot 集成 | `/plugin install discord@claude-plugins-official` |
| **iMessage** | macOS 原生消息 | `/plugin install imessage@claude-plugins-official` |
| **飞书 (Feishu/Lark)** | 双向消息、群组聊天、文件附件 | `/plugin install feishu@claude-code-feishu-channel` |
| **微信 (WeChat)** | 内置 channel支持扫码登录、双向消息、附件透传 | `ccb weixin login` + `ccb --channels plugin:weixin@builtin` |
## 微信内置 Channel
### 登录
```bash
ccb weixin login
```
已登录状态可清除:
```bash
ccb weixin login clear
```
### 会话启用
```bash
ccb --channels plugin:weixin@builtin
```
### 配对授权
首次收到未授权微信用户消息时weixin channel 会回一条 6 位 pairing code。运营侧可在终端执行
```bash
ccb weixin access pair <code>
```
确认后,该微信用户后续消息才会进入 Claude Code 会话。
## 相关文件
| 文件 | 职责 |
|------|------|
| `src/services/mcp/channelNotification.ts` | 频道 gate 逻辑、消息包装 |
| `src/services/mcp/channelAllowlist.ts` | 频道开关(已默认开启) |
| `src/services/mcp/useManageMCPConnections.ts` | MCP 连接管理中的频道注册 |
| `src/components/LogoV2/ChannelsNotice.tsx` | 启动时频道状态提示 |
| `src/main.tsx` | `--channels` 参数解析 |
| `src/interactiveHelpers.tsx` | Dev channels 确认对话框 |
## 参考链接
- [官方 Channels 文档](https://code.claude.com/docs/zh-CN/channels) — 完整使用说明、安全性、Enterprise 控制
- [飞书 Channel 插件](https://github.com/whobot-ai/claude-code-feishu-channel) — 安装配置教程、MCP 工具、Skill 命令参考

View File

@@ -6,7 +6,7 @@
### 第一步:安装 Chrome 扩展
1. 下载扩展https://github.com/hangwin/mcp-chrome/releases(下载最新 zip
1. 下载扩展https://github.com/hangwin/mcp-chrome/releases
2. 解压 zip 文件
3. 打开 Chrome 访问 `chrome://extensions/`
4. 开启右上角「开发者模式」

View File

@@ -2,12 +2,12 @@
## 概览
Computer Use 提供 37 个工具,分为三类:
Computer Use 提供 38 个工具,分为三类:
| 分类 | 平台 | 工具数 | 说明 |
|------|------|--------|------|
| 通用工具 | 全平台 | 24 | 官方 Computer Use 标准能力 |
| Windows 专属工具 | Win32 | 10 | 绑定窗口模式下的增强能力 |
| Windows 专属工具 | Win32 | 11 | 绑定窗口模式下的增强能力 |
| 教学工具 | 全平台 | 3 | 分步引导模式(需 teachMode 开启) |
---
@@ -82,7 +82,7 @@ Computer Use 提供 37 个工具,分为三类:
---
## 二、Windows 专属工具10 个)
## 二、Windows 专属工具12 个)
仅 Windows 平台可见。核心能力:**绑定窗口后的独立操作——不抢占用户鼠标键盘**。
@@ -235,8 +235,19 @@ Computer Use 提供 37 个工具,分为三类:
| 工具 | 参数 | 说明 |
|------|------|------|
| `open_terminal` | `agent`, `command?` | 打开新终端窗口并启动 AI agentclaude/codex/gemini/custom。自动绑定窗口并截图验证 |
| `activate_window` | `click_x?`, `click_y?` | 激活绑定窗口SetForegroundWindow + BringWindowToTop + 点击确保焦点 |
| `prompt_respond` | `response_type`, `arrow_direction?`, `arrow_count?`, `text?` | 处理终端 Yes/No/选择提示 |
**open_terminal agent 类型:**
| agent | 命令 | 说明 |
|-------|------|------|
| `claude` | `claude` | 启动 Claude Code |
| `codex` | `codex` | 启动 Codex |
| `gemini` | `gemini` | 启动 Gemini |
| `custom` | 用户指定 | 自定义命令 |
**response_type 详情:**
| response_type | 操作 | 场景 |

View File

@@ -11,7 +11,7 @@
-`@ant/computer-use-input` 拆为 dispatcher + backendsdarwin + win32
-`@ant/computer-use-swift` 拆为 dispatcher + backendsdarwin + win32
-`CHICAGO_MCP` 编译开关已开
- `src/`有 6 处 macOS 硬编码阻塞
- `src/` 层 macOS 硬编码已移除Phase 2 已完成)
## 2. 阻塞点全景
@@ -19,25 +19,25 @@
| # | 文件:行号 | 阻塞代码 | 影响 |
|---|----------|---------|------|
| 1 | `src/main.tsx:1605` | `getPlatform() === 'macos'` | 整个 CU 初始化被跳过 |
| 1 | `src/main.tsx:2366` | `feature("CHICAGO_MCP")` 门控 | CU 初始化入口 |
### 2.2 加载层
| # | 文件:行号 | 阻塞代码 | 影响 |
|---|----------|---------|------|
| 2 | `src/utils/computerUse/swiftLoader.ts:16` | `process.platform !== 'darwin'` → throw | 截图、应用管理全部不可用 |
| 3 | `src/utils/computerUse/executor.ts:263` | `process.platform !== 'darwin'`throw | 整个 executor 工厂函数不可用 |
| 2 | `src/utils/computerUse/swiftLoader.ts` | macOS-only loader已改为仅 darwin 加载) | 非 darwin 使用 platforms/ 替代 |
| 3 | `src/utils/computerUse/executor.ts:302` | `process.platform !== 'darwin'`cross-platform executor | 非 darwin 走跨平台路径 |
### 2.3 macOS 特有依赖
| # | 文件:行号 | 依赖 | macOS 实现 | 需要替代方案 |
|---|----------|------|-----------|------------|
| 4 | `executor.ts:70-88` | 剪贴板 | `pbcopy`/`pbpaste` | Win: PowerShell `Get/Set-Clipboard`Linux: `xclip`/`wl-copy` |
| 5 | `drainRunLoop.ts:21` | CFRunLoop pump | `cu._drainMainRunLoop()` | 非 darwin直接执行 fn(),不需要 pump |
| 6 | `escHotkey.ts:28` | ESC 热键 | CGEventTap | 非 darwin返回 false已有 Ctrl+C fallback |
| 7 | `hostAdapter.ts:48-54` | 系统权限 | TCC accessibility + screenRecording | Win直接 grantedLinux检查 xdotool |
| 8 | `common.ts:56` | 平台标识 | `platform: 'darwin'` 硬编码 | 动态获取 |
| 9 | `executor.ts:180` | 粘贴快捷键 | `command+v` | Win/Linux`ctrl+v` |
| 4 | `executor.ts:72-96` | 剪贴板 | `pbcopy`/`pbpaste` / PowerShell / xclip | Win: PowerShell `Get/Set-Clipboard`Linux: `xclip`/`wl-copy` |
| 5 | `drainRunLoop.ts` | CFRunLoop pump | `cu._drainMainRunLoop()` | 非 darwin直接执行 fn(),不需要 pump |
| 6 | `escHotkey.ts` | ESC 热键 | CGEventTap | 非 darwin返回 false已有 Ctrl+C fallback |
| 7 | `hostAdapter.ts` | 系统权限 | TCC accessibility + screenRecording | Win直接 grantedLinux检查 xdotool |
| 8 | `common.ts:55-58` | 平台标识 | 动态获取 | 已改为 `process.platform` 分发 |
| 9 | `executor.ts:232` | 粘贴快捷键 | `command`/`ctrl` 分发 | 已按平台分发粘贴快捷键 |
### 2.4 缺失的 Linux 后端
@@ -100,19 +100,19 @@
| 步骤 | 文件 | 改动 |
|------|------|------|
| 2.1 | `src/main.tsx:1605` | `getPlatform() === 'macos'` → 去掉平台限制,或改为 `!== 'unknown'` |
| 2.2 | `src/utils/computerUse/swiftLoader.ts:16-18` | 移除 `process.platform !== 'darwin'` throw。`@ant/computer-use-swift/index.ts` 已有跨平台 dispatch |
| 2.3 | `src/utils/computerUse/executor.ts:263-267` | 移除 `process.platform !== 'darwin'` throw。改为检查 input/swift isSupported |
| 2.4 | `src/utils/computerUse/executor.ts:70-88` | 剪贴板函数按平台分发darwin→pbcopy/pbpastewin32→PowerShell Get/Set-Clipboardlinux→xclip |
| 2.5 | `src/utils/computerUse/executor.ts:180` | `typeViaClipboard``command+v` → 非 darwin 时用 `ctrl+v` |
| 2.6 | `src/utils/computerUse/executor.ts:273` | `const cu = requireComputerUseSwift()` → 改为 `new ComputerUseAPI()`(从 package 直接实例化,不走 swiftLoader throw |
| 2.7 | `src/utils/computerUse/drainRunLoop.ts` | 开头加 `if (process.platform !== 'darwin') return fn()` |
| 2.8 | `src/utils/computerUse/escHotkey.ts` | `registerEscHotkey` 非 darwin 返回 false已有 Ctrl+C fallback |
| 2.9 | `src/utils/computerUse/hostAdapter.ts:48-54` | `ensureOsPermissions` 非 darwin 返回 `{ granted: true }` |
| 2.10 | `src/utils/computerUse/common.ts:56` | `platform: 'darwin'``platform: process.platform === 'win32' ? 'windows' : process.platform === 'linux' ? 'linux' : 'darwin'` |
| 2.11 | `src/utils/computerUse/common.ts:55` | `screenshotFiltering: 'native'` → 非 darwin 时 `'none'`Windows/Linux 截图不支持 per-app 过滤) |
| 2.12 | `src/utils/computerUse/gates.ts:13` | `enabled: false``enabled: true`(无 GrowthBook 时默认可用 |
| 2.13 | `src/utils/computerUse/gates.ts:39-43` | `hasRequiredSubscription()` → 直接返回 `true` |
| 2.1 | `src/main.tsx:2366` | `feature("CHICAGO_MCP")` → 已为跨平台入口 |
| 2.2 | `src/utils/computerUse/swiftLoader.ts` | 已改为仅 darwin 加载,非 darwin 使用 platforms/ |
| 2.3 | `src/utils/computerUse/executor.ts:302-309` | 已改为 cross-platform dispatch非 darwin → createCrossPlatformExecutor |
| 2.4 | `src/utils/computerUse/executor.ts:72-96` | 剪贴板按平台分发darwin→pbcopy/pbpastewin32→PowerShelllinux→xclip |
| 2.5 | `src/utils/computerUse/executor.ts:232` | 粘贴快捷键已按平台分发darwin→command其他→ctrl |
| 2.6 | `src/utils/computerUse/executor.ts:302-309` | 非 darwin 已改为 `createCrossPlatformExecutor()` |
| 2.7 | `src/utils/computerUse/drainRunLoop.ts` | 非 darwin 无需 pump直接执行 fn |
| 2.8 | `src/utils/computerUse/escHotkey.ts` | 非 darwin 返回 false已有 Ctrl+C fallback |
| 2.9 | `src/utils/computerUse/hostAdapter.ts` | 非 darwin 权限检查逻辑已实现 |
| 2.10 | `src/utils/computerUse/common.ts:58` | 已改为动态 `process.platform` 分发 |
| 2.11 | `src/utils/computerUse/common.ts:55` | 已改为 darwin→'native',其他→'none' |
| 2.12 | `src/utils/computerUse/gates.ts:55` | 已更新(需验证 enabled 默认值 |
| 2.13 | `src/utils/computerUse/gates.ts:39` | `hasRequiredSubscription()` 已更新 |
### Phase 3新增 Linux 后端

View File

@@ -25,7 +25,7 @@ CONTEXT_COLLAPSE 让模型内省上下文窗口使用情况,并智能压缩旧
| 折叠核心 | `src/services/contextCollapse/index.ts` | **Stub** — 接口完整(`ContextCollapseStats``CollapseResult``DrainResult`),函数全部空操作 |
| 折叠操作 | `src/services/contextCollapse/operations.ts` | **Stub**`projectView` 为恒等函数 |
| 折叠持久化 | `src/services/contextCollapse/persist.ts` | **Stub**`restoreFromEntries` 为空操作 |
| CtxInspectTool | `src/tools/CtxInspectTool/` | **缺失**目录不存在 |
| CtxInspectTool | `packages/builtin-tools/src/tools/CtxInspectTool/CtxInspectTool.ts` | **实现**上下文内省工具 |
| SnipTool 提示 | `src/tools/SnipTool/prompt.ts` | **Stub** — 空工具名 |
| SnipTool 实现 | `src/tools/SnipTool/SnipTool.ts` | **缺失** |
| force-snip 命令 | `src/commands/force-snip.js` | **缺失** |
@@ -106,7 +106,7 @@ SnipTool 提供手动折叠能力:
| 1 | `services/contextCollapse/index.ts` | 大 | 折叠状态机、LLM 调用、消息压缩 |
| 2 | `services/contextCollapse/operations.ts` | 中 | `projectView()` 消息过滤 |
| 3 | `services/contextCollapse/persist.ts` | 小 | `restoreFromEntries()` 磁盘持久化 |
| 4 | `tools/CtxInspectTool/` | | 上下文内省工具token 计数、已折叠范围 |
| 4 | `tools/CtxInspectTool/` | 已完成 | 上下文内省工具已实现(`packages/builtin-tools/src/tools/CtxInspectTool/` |
| 5 | `tools/SnipTool/SnipTool.ts` | 中 | Snip 工具实现 |
| 6 | `commands/force-snip.js` | 小 | `/force-snip` 命令 |

View File

@@ -0,0 +1,318 @@
# Daemon 重构设计方案
> 分支: `feat/integrate-5-branches`
> 基于: `f41745cb` (= main `11bb3f62` 内容)
> 日期: 2026-04-13
## 一、问题概述
### 1.1 命令结构散乱
当前后台进程相关的命令分布在三个不同的位置,没有统一的命名空间:
| 命令 | 注册位置 | 入口 |
|------|---------|------|
| `claude daemon start/status/stop` | `cli.tsx` 快速路径 L203 | `daemon/main.ts` |
| `claude ps` | `cli.tsx` 快速路径 L220 | `cli/bg.ts` |
| `claude logs <x>` | `cli.tsx` 快速路径 L232 | `cli/bg.ts` |
| `claude attach <x>` | `cli.tsx` 快速路径 L236 | `cli/bg.ts` |
| `claude kill <x>` | `cli.tsx` 快速路径 L238 | `cli/bg.ts` |
| `claude --bg` | `cli.tsx` 快速路径 L244 | `cli/bg.ts` |
| `claude new/list/reply` | `cli.tsx` 快速路径 L250 | `cli/handlers/templateJobs.ts` |
| `claude rollback` | `main.tsx` Commander.js L6525 | `cli/rollback.ts` |
| `claude up` | `main.tsx` Commander.js L6511 | `cli/up.ts` |
**问题**:
- `ps/logs/attach/kill``daemon` 逻辑上都是后台进程管理,但互不关联
- 这些命令都**只有 CLI 入口**REPL 里输入 `/daemon``/ps` 不存在
- `new/list/reply` 是模板任务系统的顶级命令,容易与其他命令冲突(特别是 `list`
### 1.2 Windows 不支持
`--bg``attach` 硬依赖 tmux
- `bg.ts:handleBgFlag()` 第一步就检查 tmux不可用直接报错退出
- `bg.ts:attachHandler()``tmux attach-session`,无 tmux 替代方案
- Windows (包括 VS Code 终端) 完全无法使用后台会话功能
### 1.3 无 REPL 入口
对比 `/mcp` 的双注册模式:
- **CLI**: `claude mcp serve/add/remove/list` (Commander.js, `main.tsx:5760`)
- **REPL**: `/mcp enable/disable/reconnect` (slash command, `commands/mcp/index.ts`)
`daemon`/`bg`/`job` 系列只有 CLI 快速路径REPL 中完全不可用。
## 二、目标
1. **层级化命令结构**: 参照 `/mcp` 模式,将后台管理收归 `/daemon`,模板任务收归 `/job`
2. **跨平台后台会话**: Windows / macOS / Linux 都能启动、附着、终止后台会话
3. **双注册**: CLI (`claude daemon ...`) + REPL (`/daemon ...`) 同时可用
4. **向后兼容**: 旧命令保留但输出 deprecation 提示
## 三、命令结构设计
### 3.1 `/daemon` — 后台进程管理
合并 daemon supervisor + bg sessions 为统一命名空间:
```
claude daemon <subcommand> ← CLI 入口 (cli.tsx 快速路径)
/daemon <subcommand> ← REPL 入口 (slash command, local-jsx)
子命令:
status 综合状态面板 (daemon + 所有会话)
start [--dir <path>] 启动 daemon supervisor
stop 停止 daemon
bg [args...] 启动后台会话
attach [target] 附着到后台会话
logs [target] 查看会话日志
kill [target] 终止会话
(无参数) 等同于 status
```
**CLI 快速路径路由** (`cli.tsx`):
```typescript
// 新: 统一入口
if (feature('DAEMON') && args[0] === 'daemon') {
const sub = args[1] || 'status'
switch (sub) {
case 'start': case 'stop': case 'status':
await daemonMain([sub, ...args.slice(2)])
break
case 'bg':
await bg.handleBgStart(args.slice(2))
break
case 'attach': case 'logs': case 'kill':
await bg[`${sub}Handler`](args[2])
break
}
}
// 向后兼容 (deprecated)
if (feature('BG_SESSIONS') && ['ps','logs','attach','kill'].includes(args[0])) {
console.warn(`[deprecated] Use: claude daemon ${args[0] === 'ps' ? 'status' : args[0]}`)
// ... delegate to daemon subcommand
}
```
**REPL 斜杠命令** (`commands/daemon/index.ts`):
```typescript
const daemon = {
type: 'local-jsx',
name: 'daemon',
description: 'Manage background sessions and daemon',
argumentHint: '[status|start|stop|bg|attach|logs|kill]',
isEnabled: () => feature('DAEMON') || feature('BG_SESSIONS'),
load: () => import('./daemon.js'),
} satisfies Command
```
### 3.2 `/job` — 模板任务管理
```
claude job <subcommand> ← CLI 入口
/job <subcommand> ← REPL 入口
子命令:
list 列出模板和活跃任务
new <template> [args] 从模板创建任务
reply <id> <text> 回复任务
status <id> 查看任务状态
(无参数) 等同于 list
```
### 3.3 独立命令 (不变)
```
claude up 保持顶级 (简短的 bootstrap 命令)
claude rollback [target] 保持顶级 (低频运维命令)
```
## 四、跨平台后台引擎
### 4.1 引擎抽象
```typescript
// src/cli/bg/engine.ts
export interface BgEngine {
readonly name: string
/** 当前平台是否可用 */
available(): Promise<boolean>
/** 启动后台会话 */
start(opts: BgStartOptions): Promise<BgStartResult>
/** 附着到后台会话blocking */
attach(session: SessionEntry): Promise<void>
}
export interface BgStartOptions {
sessionName: string
args: string[]
env: Record<string, string | undefined>
logPath: string
cwd: string
}
export interface BgStartResult {
pid: number
sessionName: string
logPath: string
engineUsed: string
}
```
### 4.2 三种引擎实现
| 引擎 | 平台 | 启动方式 | attach 方式 |
|------|------|---------|------------|
| TmuxEngine | macOS/Linux (有 tmux) | `tmux new-session -d` | `tmux attach-session` |
| DetachedEngine | Windows / 无 tmux 的 macOS/Linux | `spawn({ detached, stdio→logFile })` | `tail -f` 日志文件 |
#### DetachedEngine 详细设计
**启动 (`start`)**:
```typescript
// 1. 打开日志文件 fd
const logFd = fs.openSync(logPath, 'a')
// 2. detached spawn, stdout/stderr 重定向到日志
const child = spawn(process.execPath, execArgs, {
detached: true,
stdio: ['ignore', logFd, logFd],
env,
cwd,
})
child.unref()
fs.closeSync(logFd)
// 3. 写 sessions/<PID>.json
```
**附着 (`attach`)**:
```typescript
// 跨平台 tail -f 实现
// 1. 读取已有日志内容输出到 stdout
// 2. fs.watch(logPath) 监听变化
// 3. 每次变化读取新增内容
// 4. Ctrl+C 退出 tail不杀后台进程
```
#### 引擎选择逻辑
```typescript
// src/cli/bg/engines/index.ts
export async function selectEngine(): Promise<BgEngine> {
if (process.platform === 'win32') {
return new DetachedEngine()
}
const tmux = new TmuxEngine()
if (await tmux.available()) {
return tmux
}
return new DetachedEngine()
}
```
### 4.3 SessionEntry 扩展
```typescript
interface SessionEntry {
// ... 现有字段
engine: 'tmux' | 'detached' // 新增: 记录使用的引擎
tmuxSessionName?: string // tmux 引擎才有
logPath?: string // 两种引擎都有
}
```
`attach` 时根据 `session.engine` 选择对应的 attach 策略。
## 五、文件变更清单
### 新增文件 (10 个)
```
src/cli/bg/engine.ts BgEngine 接口定义
src/cli/bg/engines/tmux.ts TmuxEngine (从 bg.ts 提取)
src/cli/bg/engines/detached.ts DetachedEngine (新实现)
src/cli/bg/engines/index.ts 引擎选择 + re-export
src/cli/bg/tail.ts 跨平台日志 tail (用于 detached attach)
src/commands/daemon/index.ts /daemon REPL 斜杠命令注册
src/commands/daemon/daemon.tsx /daemon 子命令路由 + status UI
src/commands/job/index.ts /job REPL 斜杠命令注册
src/commands/job/job.tsx /job 子命令路由 + UI
docs/features/daemon-restructure-design.md 本设计文档
```
### 修改文件 (6 个)
```
src/cli/bg.ts 重构: handler 函数改为调用 BgEngine
src/entrypoints/cli.tsx 快速路径: daemon 统一入口 + 向后兼容
src/commands.ts 注册 /daemon 和 /job 斜杠命令
src/daemon/main.ts daemonMain() 增加 bg/ps/logs 子命令分发
src/main.tsx Commander.js: 可选注册 daemon/job 子命令
src/cli/handlers/templateJobs.ts 适配 /job 入口 (可能不需改)
```
### 不动的文件
```
src/daemon/state.ts daemon PID 状态管理 (无需改)
src/jobs/state.ts job 状态管理 (无需改)
src/jobs/templates.ts 模板发现 (无需改)
src/jobs/classifier.ts 任务分类器 (无需改)
src/cli/rollback.ts 保持顶级命令 (无需改)
src/cli/up.ts 保持顶级命令 (无需改)
```
## 六、可行性分析
### 6.1 风险评估
| 风险 | 级别 | 缓解措施 |
|------|------|---------|
| cli.tsx 快速路径修改影响启动性能 | 低 | 仅改路由逻辑import 仍然 lazy |
| DetachedEngine 的 attach 在 Windows 上 fs.watch 不可靠 | 中 | 使用轮询 fallback (setInterval + fs.stat) |
| 向后兼容的 deprecation 可能破坏脚本 | 低 | 旧命令保持可用,仅输出 stderr 警告 |
| REPL 中 /daemon bg 需要 spawn 子进程 | 中 | 参考 /assistant 的 NewInstallWizard (已有 spawn 先例) |
| tsc 类型兼容 | 低 | 接口定义清晰,不引入 any |
### 6.2 工作量估计
| Task | 文件数 | 复杂度 |
|------|--------|--------|
| Task 013: BgEngine 抽象 + 引擎实现 | 5 新增 + 1 修改 | 中 |
| Task 014: /daemon 命令层级化 | 3 新增 + 3 修改 | 中 |
| Task 015: /job 命令层级化 | 2 新增 + 2 修改 | 低 |
| Task 016: 向后兼容 + 测试 | 0 新增 + 2 修改 | 低 |
### 6.3 依赖关系
```
Task 013 (BgEngine) ← 无依赖,可独立开发
Task 014 (/daemon) ← 依赖 Task 013 (引擎选择)
Task 015 (/job) ← 无依赖,可与 013 并行
Task 016 (兼容) ← 依赖 Task 014 + 015
```
## 七、设计决策记录
### D1: 为什么 daemon + bg sessions 合为一个命名空间?
用户视角:都是"后台运行的东西"。分开会导致 `claude daemon status` 看 supervisor + `claude ps` 看会话,割裂感强。合并后 `claude daemon status` 一次性展示 supervisor 状态 + 所有会话列表。
### D2: 为什么 rollback/up 不收入 daemon
它们本质是**版本管理/环境初始化**,不是后台进程管理。`claude up` 是同步阻塞的 setup 脚本,不涉及 daemon 或后台会话。保持顶级更直观。
### D3: 为什么 DetachedEngine 的 attach 用 tail 而不是 IPC
1. 日志文件是最简单的跨平台方案,无需额外依赖
2. UDS Pipe IPC 系统 (usePipeIpc) 设计用于实例间通信,不是终端附着
3. tmux attach 的体验(完整 PTY无法在纯 detached 模式下复制tail 是最诚实的替代
### D4: 为什么不用 Windows Terminal 的 tab/pane API
Windows Terminal 的 `wt.exe` 新窗口/标签功能不够通用——用户可能在 VS Code、ConEmu、cmder 等终端中。detached + log 是唯一跨终端方案。

View File

@@ -1,12 +1,12 @@
# DAEMON — 后台守护进程
> Feature Flag: `FEATURE_DAEMON=1`
> 实现状态:主进程和 worker 注册为 StubCLI 路由完整
> 实现状态:Supervisor 和 remoteControl Worker 已实现
> 引用数3
## 一、功能概述
DAEMON 将 Claude Code 变为后台守护进程。主进程supervisor管理多个 worker 进程的生命周期,通过 Unix 域套接字进行 IPC。适用于持续运行的后台服务场景(如配合 BRIDGE_MODE 提供远程控制服务)。
DAEMON 将 Claude Code 变为后台守护进程。主进程supervisor管理多个 worker 进程的生命周期,通过文件系统状态文件进行通信。适用于持续运行的后台服务场景(如配合 BRIDGE_MODE 提供远程控制服务)。
## 二、实现架构
@@ -14,8 +14,9 @@ DAEMON 将 Claude Code 变为后台守护进程。主进程supervisor
| 模块 | 文件 | 状态 |
|------|------|------|
| 守护主进程 | `src/daemon/main.ts` | **Stub**`daemonMain: () => Promise.resolve()` |
| Worker 注册 | `src/daemon/workerRegistry.ts` | **Stub**`runDaemonWorker: () => Promise.resolve()` |
| 守护主进程 | `src/daemon/main.ts` | **已实现**Supervisor 含子命令、Worker 生命周期管理、指数退避重启 |
| Worker 注册 | `src/daemon/workerRegistry.ts` | **已实现**remoteControl Workerheadless bridge |
| Daemon 状态 | `src/daemon/state.ts` | **已实现** — PID/状态文件的读写与查询 |
| CLI 路由 | `src/entrypoints/cli.tsx` | **布线**`--daemon-worker``daemon` 子命令 |
| 命令注册 | `src/commands.ts` | **布线** — DAEMON + BRIDGE_MODE 门控 |
@@ -23,34 +24,49 @@ DAEMON 将 Claude Code 变为后台守护进程。主进程supervisor
```
# 启动守护进程
claude daemon
claude daemon start
# 以 worker 身份启动
claude --daemon-worker=<kind>
# 查看状态(默认子命令)
claude daemon status
claude daemon ps
# 停止守护进程
claude daemon stop
# 以 worker 身份启动(由 supervisor 自动调用)
claude --daemon-worker=remoteControl
# 后台会话管理
claude daemon bg
claude daemon attach <session>
claude daemon logs <session>
claude daemon kill <session>
```
### 2.3 预期架构
### 2.3 架构
```
Supervisor (daemonMain)
├── Worker 1: assistant-mode
│ └── 接收和处理 assistant 会话
├── Worker 2: bridge-sync
│ └── bridge 消息同步
└── Worker 3: proactive
└── 主动任务执行
├── Worker: remoteControl
│ └── runBridgeHeadless() — 远程控制 headless 模式
接收远程会话、处理消息、权限审批
IPC via Unix Domain Sockets
- 生命周期管理(启动、停止、重启)
- 工作分发
- 状态报告
文件系统状态文件 (daemon-state.json)
- PID、CWD、启动时间、Worker 类型
- queryDaemonStatus() / stopDaemonByPid()
```
### 2.4 与 BRIDGE_MODE 的关系
### 2.4 Worker 生命周期管理
Supervisor 为每个 worker 实现:
- **指数退避重启**:初始 2s上限 120s倍数 ×2
- **快速失败检测**10s 内连续崩溃 5 次则 parking不再重启
- **永久错误退出码**78 (EXIT_CODE_PERMANENT) 导致直接 parking
- **优雅关闭**SIGTERM/SIGINT → abort signal → 30s 强制 SIGKILL
### 2.5 与 BRIDGE_MODE 的关系
DAEMON 和 BRIDGE_MODE 常组合使用:
@@ -63,40 +79,39 @@ if (feature('DAEMON') && feature('BRIDGE_MODE')) {
双重门控:两个 feature 都需要开启才能使用远程控制服务器。
## 三、需要补全的内容
| 模块 | 工作量 | 说明 |
|------|--------|------|
| `daemon/main.ts` | 大 | Supervisor 主进程:启动 worker、生命周期管理、IPC |
| `daemon/workerRegistry.ts` | 中 | Worker 类型分发assistant/bridge-sync/proactive |
| Worker 实现 | 大 | 各类型 worker 的具体实现 |
| IPC 协议 | 中 | Supervisor-Worker 通信层 |
## 四、关键设计决策
## 三、关键设计决策
1. **多进程架构**:一个 supervisor + 多个 worker进程隔离
2. **Unix 域套接字 IPC**:本地进程间通信,低延迟
2. **文件系统状态通信**:通过 `daemon-state.json` 文件进行状态共享(非 Unix 域套接字)
3. **与 BRIDGE_MODE 强绑定**:守护进程最常见的用途是提供远程控制服务
4. **CLI 子命令路由**`daemon` 子命令和 `--daemon-worker` 参数在 `cli.tsx` 中路由
5. **Worker 环境变量**supervisor 通过环境变量(`DAEMON_WORKER_*`)向 worker 传递配置
## 、使用方式
## 、使用方式
```bash
# 启用守护进程模式
FEATURE_DAEMON=1 FEATURE_BRIDGE_MODE=1 bun run dev
# 启动守护进程
claude daemon
claude daemon start
# 以特定 worker 启动
claude --daemon-worker=assistant
# 查看状态
claude daemon status
# 停止守护进程
claude daemon stop
# 以特定 worker 启动(通常由 supervisor 自动调用)
claude --daemon-worker=remoteControl
```
## 、文件索引
## 、文件索引
| 文件 | 职责 |
|------|------|
| `src/daemon/main.ts` | Supervisor 主进程stub |
| `src/daemon/workerRegistry.ts` | Worker 注册stub |
| `src/entrypoints/cli.tsx:95,149` | CLI 路由 |
| `src/commands.ts:77` | 命令注册(双重门控) |
| `src/daemon/main.ts` | Supervisor 主进程子命令分发、Worker 生命周期管理、退避重启 |
| `src/daemon/workerRegistry.ts` | Worker 入口remoteControl worker 实现 |
| `src/daemon/state.ts` | Daemon 状态管理PID 文件读写、状态查询 |
| `src/entrypoints/cli.tsx` | CLI 路由 |
| `src/commands.ts` | 命令注册(双重门控) |

View File

@@ -27,13 +27,15 @@ bun run dev:inspect
## 原理
`dev:inspect` 脚本实际执行的是:
`dev:inspect` 脚本实际执行的是 `scripts/dev-debug.ts`
```bash
bun --inspect-wait=localhost:8888/<token> run scripts/dev.ts
```typescript
// scripts/dev-debug.ts
process.env.BUN_INSPECT = "localhost:8888/<token>"
await import("./dev")
```
Bun 的 `--inspect-wait` 参数启动一个 Chrome DevTools Protocol 兼容的 inspect 服务,等待调试器连接后才开始执行。VS Code 的 `bun` 扩展通过 WebSocket 连接到这个地址实现 attach。
通过设置 `BUN_INSPECT` 环境变量启动一个 Chrome DevTools Protocol 兼容的 inspect 服务,然后导入 dev 模式入口。VS Code 的 `bun` 扩展通过 WebSocket 连接到输出的地址实现 attach。
## JetBrains IDE

File diff suppressed because it is too large Load Diff

View File

@@ -1,160 +0,0 @@
# Feature Flags 审查报告 — Codex 复核
> 审查日期: 2026-04-05
> 审查工具: Codex CLI v0.118.0 (本地, full-auto mode)
> 消耗 tokens: 240,306
> 审查范围: docs/feature-flags-audit-complete.md 中标记为 COMPLETE 的 22 个编译时 feature flag
---
## 审查背景
原始审计报告 (`docs/feature-flags-audit-complete.md`) 声称 22 个 feature flag 被标记为 "COMPLETE",只需在 `build.ts` / `scripts/dev.ts` 中启用即可工作。
Claude Code 团队通过 6 个并行子代理实际读取源码后初步发现大量误判,随后将分析结果传递给 Codex CLI 进行独立二次验证。
---
## Codex 发现摘要
### High 级发现
1. **`CONTEXT_COLLAPSE` 不是 COMPLETE**
- `src/services/contextCollapse/index.ts:43``isContextCollapseEnabled()` 硬编码为 `false`
- `src/services/contextCollapse/index.ts:47``applyCollapsesIfNeeded()` 只是原样返回消息
- `src/services/contextCollapse/index.ts:59``recoverFromOverflow()` 也是 no-op
- `src/services/contextCollapse/operations.ts:3``persist.ts:3` 同样是 stub
- 审计报告把 UI/命令文件算进去了,但真正被查询循环消费的是 stub 后端
2. **原分类"真正只需编译开关"的 7 个 flag只有 3 个准确**
-`SHOT_STATS` — 零额外门控compile-only
-`PROMPT_CACHE_BREAK_DETECTION` — 有 try-catch 兜底compile-only
-`TOKEN_BUDGET` — 纯本地计算compile-only
-`TEAMMEM` — 还要求 AutoMem + GrowthBook `tengu_herring_clock` + GitHub repo (`teamMemPaths.ts:73`, `watcher.ts:256`, `watcher.ts:259`)
-`AGENT_TRIGGERS` — 受 `isKairosCronEnabled()` GrowthBook 控制 (`useScheduledTasks.ts:61`, `useScheduledTasks.ts:119`)
-`EXTRACT_MEMORIES` — 受 `tengu_passport_quail` + AutoMem + 非 remote 限制 (`extractMemories.ts:536`, `:545`, `:550`)
-`KAIROS_BRIEF` — 受 `tengu_kairos_brief` + opt-in/kairosActive 限制 (`BriefTool.ts:95`, `:126`, `:132`)
### Medium 级发现
3. **`BG_SESSIONS``BASH_CLASSIFIER` 不适合简单归为"全 stub"**
- `BG_SESSIONS` — 会话注册/清理是真实现 (`concurrentSessions.ts:44`, `:55`),但任务摘要核心是 stub (`taskSummary.ts:2`)
- `BASH_CLASSIFIER` — 权限编排很大一块是真实现 (`bashPermissions.ts` 2621行),但分类后端 `bashClassifier.ts:24` 永远返回 disabled
4. **审计口径问题**
- 把"代码量/周边 UI 很多"误当成"可独立启用"
- `PROACTIVE``index.ts:3` 只有 state stub`commands.ts:64``REPL.tsx:415` 引用缺失文件
- `REACTIVE_COMPACT``reactiveCompact.ts:13` 整块是 stub
- `CACHED_MICROCOMPACT``cachedMicrocompact.ts:22` 全部 stub
---
## Codex 修正后的分类
### 第一类:真正 compile-only3 个)
| Flag | 说明 | Crash 风险 |
|------|------|-----------|
| **SHOT_STATS** | 纯本地 shot 分布统计ant-only 数据路径 | 低 |
| **PROMPT_CACHE_BREAK_DETECTION** | 本地 cache key 变化检测,写 diff 有兜底 | 低 |
| **TOKEN_BUDGET** | 本地 token 预算追踪,纯计算逻辑 | 低 |
### 第二类compile + 运行时条件7 个)
| Flag | 条件 | Crash 风险 |
|------|------|-----------|
| **TEAMMEM** | AutoMem + GrowthBook `tengu_herring_clock` + GitHub repo | 低 (clean no-op) |
| **AGENT_TRIGGERS** | GrowthBook `isKairosCronEnabled()` | 低 (clean no-op) |
| **EXTRACT_MEMORIES** | `tengu_passport_quail` + AutoMem + 非 remote | 低 (clean no-op) |
| **KAIROS_BRIEF** | `tengu_kairos_brief` + opt-in/kairosActive可用 `CLAUDE_CODE_BRIEF=1` 绕过 | 低 |
| **COORDINATOR_MODE** | 需 `CLAUDE_CODE_COORDINATOR_MODE=1``workerAgent.ts` 是 stub 但不阻塞 | 低 |
| **COMMIT_ATTRIBUTION** | 仅对 `isInternal=true` 的 repo 生效 | 低 |
| **VERIFICATION_AGENT** | 受 GrowthBook `tengu_hive_evidence` 双重门控 | 低 |
### 第三类:混合型 — 部分实现 + stub 核心5 个)
| Flag | 真实现部分 | Stub 核心 |
|------|-----------|----------|
| **BG_SESSIONS** | 会话注册/清理 (`concurrentSessions.ts`) | `bg.ts`/`taskSummary.ts`/`udsClient.ts` 全 stub + 依赖 tmux |
| **BASH_CLASSIFIER** | 权限编排 (`bashPermissions.ts` 2621行) | `bashClassifier.ts` 分类后端 stub + 需 API beta |
| **PROACTIVE** | REPL/命令注册框架 | `index.ts` stub + 3 文件缺失 |
| **REACTIVE_COMPACT** | 调用点已在主查询环路 | `reactiveCompact.ts` 22行全 no-op |
| **CACHED_MICROCOMPACT** | 调用点已布线 | `cachedMicrocompact.ts` 全 stub + 需未公开 API |
### 第四类:纯 stub1 个)
| Flag | 问题 |
|------|------|
| **CONTEXT_COLLAPSE** | 3 核心文件全 stub + CtxInspectTool 目录不存在 |
### 第五类依赖远程服务3 个)
| Flag | 依赖 |
|------|------|
| **ULTRAPLAN** | CCR 远程 agent 基础设施 + OAuth |
| **CCR_REMOTE_SETUP** | claude.ai OAuth + GitHub CLI + CCR 后端 |
| **BRIDGE_MODE** (build端) | claude.ai 订阅 + GrowthBook + WebSocket 后端 |
---
## 第三类恢复优先级建议
Codex 推荐的恢复顺序:
1. **REACTIVE_COMPACT** — 收益最直接,调用点在主查询环路,改完最容易立刻见效
2. **BG_SESSIONS** — 已有会话注册基础,补齐摘要和后台运行链路的 ROI 高
3. **PROACTIVE** — 产品面大,但缺文件比 stub 更严重,范围比前两项大
4. **CONTEXT_COLLAPSE** — collapse engine 全 stub恢复成本和设计不确定性都高
5. **BASH_CLASSIFIER** — 若无 API beta 能力不值得优先;若有则升到第 2
6. **CACHED_MICROCOMPACT** — 受未公开 API 约束,最后做
---
## 审计报告分类标准修正建议
Codex 建议将原来的单轴分类COMPLETE/PARTIAL/STUB改为**三轴**
| 轴 | 取值 | 说明 |
|----|------|------|
| **实现完整度** | `full` / `mixed` / `stub` | 活跃调用链上的核心模块是否有真实现 |
| **激活条件** | `compile-only` / `compile+env` / `compile+GrowthBook` / `compile+remote` / `compile+private API` | 启用需要什么 |
| **运行风险** | `safe no-op` / `background IO` / `startup critical` | 启用后条件不满足时的行为 |
**COMPLETE 的最低标准应满足:**
1. 活跃调用链上的核心模块不能是 stub
2. "可启用"不能只看编译 flag还要单列运行时 gate
按此标准,`CONTEXT_COLLAPSE``BG_SESSIONS``BASH_CLASSIFIER``PROACTIVE``REACTIVE_COMPACT``CACHED_MICROCOMPACT` 都应从 COMPLETE 降级。
---
## 已采取的行动
基于审查结果,已将以下 3 个确认安全的 flag 加入默认构建:
**build.ts:**
```typescript
const DEFAULT_BUILD_FEATURES = [
"AGENT_TRIGGERS_REMOTE", "CHICAGO_MCP", "VOICE_MODE",
"SHOT_STATS", "PROMPT_CACHE_BREAK_DETECTION", "TOKEN_BUDGET"
];
```
**scripts/dev.ts:**
```typescript
const DEFAULT_FEATURES = [
"BUDDY", "TRANSCRIPT_CLASSIFIER", "BRIDGE_MODE",
"AGENT_TRIGGERS_REMOTE", "CHICAGO_MCP", "VOICE_MODE",
"SHOT_STATS", "PROMPT_CACHE_BREAK_DETECTION", "TOKEN_BUDGET"
];
```
### 验证结果
| 项目 | 结果 |
|------|------|
| `bun run build` | ✅ 成功 (475 files) |
| `bun test` | ✅ 无新增失败 (23 fail 为已有问题) |
| SHOT_STATS 代码路径 | ✅ 完整 — stats 面板显示 shot 分布 |
| TOKEN_BUDGET 代码路径 | ✅ 完整 — 支持 `+500k` 语法,带进度条 |
| PROMPT_CACHE_BREAK_DETECTION 代码路径 | ✅ 完整 — 内部诊断debug 模式可见 |

View File

@@ -37,7 +37,7 @@ Agent({ subagent_type: "general-purpose", prompt: "..." })
### 3.1 门控与互斥
文件:`src/tools/AgentTool/forkSubagent.ts:32-39`
文件:`packages/builtin-tools/src/tools/AgentTool/forkSubagent.ts:32-39`
```ts
export function isForkSubagentEnabled(): boolean {
@@ -105,7 +105,7 @@ isForkSubagentEnabled() && !subagent_type?
### 3.4 消息构建buildForkedMessages
文件:`src/tools/AgentTool/forkSubagent.ts:107-169`
文件:`packages/builtin-tools/src/tools/AgentTool/forkSubagent.ts:107-169`
构建的消息结构:
@@ -185,11 +185,11 @@ FEATURE_FORK_SUBAGENT=1 bun run dev
| 文件 | 行数 | 职责 |
|------|------|------|
| `src/tools/AgentTool/forkSubagent.ts` | ~210 | 核心定义 + 消息构建 + 递归防护 |
| `src/tools/AgentTool/AgentTool.tsx` | — | Fork 路由 + 强制异步 |
| `src/tools/AgentTool/prompt.ts` | — | "When to Fork" 提示词段落 |
| `src/tools/AgentTool/runAgent.ts` | — | useExactTools 路径 |
| `src/tools/AgentTool/resumeAgent.ts` | — | Fork agent 恢复 |
| `packages/builtin-tools/src/tools/AgentTool/forkSubagent.ts` | ~210 | 核心定义 + 消息构建 + 递归防护 |
| `packages/builtin-tools/src/tools/AgentTool/AgentTool.tsx` | — | Fork 路由 + 强制异步 |
| `packages/builtin-tools/src/tools/AgentTool/prompt.ts` | — | "When to Fork" 提示词段落 |
| `packages/builtin-tools/src/tools/AgentTool/runAgent.ts` | — | useExactTools 路径 |
| `packages/builtin-tools/src/tools/AgentTool/resumeAgent.ts` | — | Fork agent 恢复 |
| `src/constants/xml.ts` | — | XML 标签常量 |
| `src/utils/forkedAgent.ts` | — | CacheSafeParams + ContentReplacementState 克隆 |
| `src/commands/fork/index.ts` | — | /fork 命令stub |

View File

@@ -1,7 +1,7 @@
# KAIROS — 常驻助手模式
> Feature Flag: `FEATURE_KAIROS=1`(及子 Feature
> 实现状态:核心框架完整,部分子模块为 stub
> 实现状态:核心框架完整,部分子模块为 stubproactive/sleep 节奏控制已可用
> 引用数154全库最大
## 一、功能概述
@@ -34,13 +34,13 @@ KAIROS 在系统提示中注入两大段落:
### 2.1 Brief 段落 (`getBriefSection`)
文件:`src/constants/prompts.ts:843-858`
文件:`src/constants/prompts.ts:847-858`
`feature('KAIROS') || feature('KAIROS_BRIEF')` 时注入。Brief 工具(`SendUserMessage`)的结构化消息输出指令。`/brief` toggle 和 `--brief` flag 只控制显示过滤,不影响模型行为。
### 2.2 Proactive/Autonomous Work 段落 (`getProactiveSection`)
文件:`src/constants/prompts.ts:860-914`
文件:`src/constants/prompts.ts:864-918`
`feature('PROACTIVE') || feature('KAIROS')``isProactiveActive()` 时注入。核心行为指令:
@@ -74,8 +74,9 @@ KAIROS 在系统提示中注入两大段落:
SleepTool 是 KAIROS/Proactive 的节奏控制核心。工具描述让模型理解"休眠"概念:
- 工具名:`Sleep`
- 功能:等待指定时间后响应 tick prompt
- 功能:等待指定时间后响应 tick prompt;若队列出现新工作或 proactive 被关闭,会提前唤醒
-`<tick_tag>` 配合实现心跳式自主工作
- 远程控制 surfaces 可通过 `automation_state` 看到 `standby` / `sleeping` 两种状态
### 3.3 Bridge 集成
@@ -172,8 +173,10 @@ FEATURE_KAIROS=1 FEATURE_TOKEN_BUDGET=1 bun run dev
| `src/assistant/AssistantSessionChooser.ts` | — | Session 选择 UIstub |
| `src/tools/BriefTool/` | — | BriefTool 实现stub |
| `src/tools/SleepTool/prompt.ts` | ~30 | SleepTool 工具提示 |
| `src/tools/SleepTool/SleepTool.ts` | ~200 | 休眠/唤醒与 automation metadata |
| `src/services/mcp/channelNotification.ts` | 5 | 频道消息接入stub |
| `src/memdir/memdir.ts` | — | 记忆目录管理stub |
| `src/constants/prompts.ts:552-554,843-914` | 72 | 系统提示注入 |
| `src/constants/prompts.ts:557,847-918` | 72 | 系统提示注入 |
| `src/components/tasks/src/tasks/DreamTask/` | 3 | Dream 任务stub |
| `src/proactive/index.ts` | — | Proactive 核心(stubKAIROS 共享) |
| `src/proactive/index.ts` | — | Proactive 核心KAIROS 共享) |
| `src/utils/sessionState.ts` | — | 向 bridge/CCR 暴露 automation 状态 |

View File

@@ -281,7 +281,7 @@ CLI-B (192.168.50.27) 心跳循环
## SendMessageTool TCP 支持
`src/tools/SendMessageTool/SendMessageTool.ts`
`packages/builtin-tools/src/tools/SendMessageTool/SendMessageTool.ts`
- `to` 字段支持 `tcp:host:port` 格式
- `checkPermissions``tcp:` scheme 返回 `behavior: 'ask'``classifierApprovable: false`

View File

@@ -202,4 +202,4 @@ docker run -d \
| `src/services/langfuse/__tests__/langfuse.test.ts` | 测试568 行) |
| `src/query.ts` | 主查询流程中的 Trace 集成 |
| `src/services/tools/toolExecution.ts` | 工具执行中的观察记录 |
| `src/tools/AgentTool/runAgent.ts` | 子 Agent Trace 创建 |
| `packages/builtin-tools/src/tools/AgentTool/runAgent.ts` | 子 Agent Trace 创建 |

View File

@@ -41,7 +41,7 @@ getMcpSkillCommands() 过滤 → SkillTool 调用
### 2.2 技能筛选
文件:`src/commands.ts:547-558`
文件:`src/commands.ts:604-616`
`getMcpSkillCommands(mcpCommands)` 过滤条件:
@@ -54,7 +54,7 @@ feature('MCP_SKILLS') // feature flag 必须开启
### 2.3 条件加载
文件:`src/services/mcp/client.ts:117-121`
文件:`src/services/mcp/client.ts:129-133`
`fetchMcpSkillsForClient` 通过 `require()` 条件加载feature flag 关闭时不加载任何模块:
@@ -79,8 +79,8 @@ const fetchMcpSkillsForClient = feature('MCP_SKILLS')
| 文件 | 行 | 说明 |
|------|------|------|
| `src/commands.ts` | 547-558, 561-608 | 命令过滤和 SkillTool 命令收集 |
| `src/services/mcp/client.ts` | 117-121, 1394, 1672, 2173-2181, 2346-2358 | 技能获取、缓存清除、连接时获取 |
| `src/commands.ts` | 604-616, 620-633 | 命令过滤和 SkillTool 命令收集 |
| `src/services/mcp/client.ts` | 129-133, 1394, 1672, 2176 | 技能获取、缓存清除、连接时获取 |
| `src/services/mcp/useManageMCPConnections.ts` | 22-26, 682-740 | 实时刷新prompts/resources 变化) |
## 三、关键设计决策

View File

@@ -145,8 +145,8 @@ M 键(或 ← / →)用于在两种路由模式之间切换,**无需展开
```
/pipes — 显示所有实例 + 切换选择面板
/pipes select <name> — 选中某实例(消息会广播到它)
/pipes deselect <name> — 取消选中
/pipes select &lt;name&gt; — 选中某实例(消息会广播到它)
/pipes deselect &lt;name&gt; — 取消选中
/pipes all — 全选
/pipes none — 全部取消
```
@@ -169,7 +169,7 @@ LAN Peers:
Selected: cli-da029538
```
### /attach <name>
### /attach &lt;name&gt;
手动 attach 到一个实例,使其成为你的 slave。
@@ -179,7 +179,7 @@ Selected: cli-da029538
attach 后,对方变为 slave你变为 master。可以向它发送 prompt。通常不需要手动 attach——heartbeat 会自动发现并连接。
### /detach <name>
### /detach &lt;name&gt;
断开与某个 slave 的连接。
@@ -187,7 +187,7 @@ attach 后,对方变为 slave你变为 master。可以向它发送 prompt
/detach cli-04d67950
```
### /send <name> <message>
### /send &lt;name&gt; &lt;message&gt;
向指定 pipe 发送消息(不依赖选择状态,直接指定目标)。
@@ -318,7 +318,7 @@ sub 角色:
| `src/commands/pipes/pipes.ts` | /pipes 命令 |
| `src/commands/attach/attach.ts` | /attach 命令 |
| `src/commands/send/send.ts` | /send 命令 |
| `src/tools/SendMessageTool/SendMessageTool.ts` | AI 发消息工具(含 tcp: 支持) |
| `packages/builtin-tools/src/tools/SendMessageTool/SendMessageTool.ts` | AI 发消息工具(含 tcp: 支持) |
## 后续优化方向

View File

@@ -1,7 +1,7 @@
# PROACTIVE — 主动模式
> Feature Flag: `FEATURE_PROACTIVE=1`(与 `FEATURE_KAIROS=1` 共享功能)
> 实现状态:核心模块全部 Stub布线完整
> 实现状态:核心循环与 SleepTool 已落地,部分外围文档仍在补齐
> 引用数37
## 一、功能概述
@@ -21,13 +21,13 @@ PROACTIVE 实现 Tick 驱动的自主代理。CLI 在用户不输入时也能持
| 模块 | 文件 | 状态 | 说明 |
|------|------|------|------|
| 核心逻辑 | `src/proactive/index.ts` | **Stub** | `activateProactive()``deactivateProactive()``isProactiveActive() => false` |
| 核心逻辑 | `src/proactive/index.ts` | **已实现** | `activateProactive()``deactivateProactive()``pause/resume``nextTickAt` 调度状态 |
| SleepTool 提示 | `src/tools/SleepTool/prompt.ts` | **完整** | 工具提示定义(工具名:`Sleep` |
| 命令注册 | `src/commands.ts:62-65` | **布线** | 动态加载 `./commands/proactive.js` |
| 工具注册 | `src/tools.ts:26-28` | **布线** | SleepTool 动态加载 |
| REPL 集成 | `src/screens/REPL.tsx` | **布线** | tick 驱动逻辑、占位符、页脚 UI |
| 系统提示 | `src/constants/prompts.ts:860-914` | **完整** | 自主工作行为指令(~55 行详细 prompt |
| 会话存储 | `src/utils/sessionStorage.ts:4892-4912` | **布线** | tick 消息注入对话流 |
| REPL 集成 | `src/screens/REPL.tsx` | **已实现** | tick 驱动、standby/sleeping 状态、页脚与 bridge automation metadata 上报 |
| 系统提示 | `src/constants/prompts.ts:864-918` | **完整** | 自主工作行为指令(~55 行详细 prompt |
| 远控状态镜像 | `src/utils/sessionState.ts` | **已实现** | 向 remote-control/CCR 暴露 `automation_state` 元数据 |
### 2.2 系统提示内容
@@ -46,7 +46,7 @@ PROACTIVE 实现 Tick 驱动的自主代理。CLI 在用户不输入时也能持
### 2.3 数据流
```
activateProactive() [需要实现]
activateProactive()
Tick 调度器启动
@@ -62,20 +62,22 @@ Tick 调度器启动
└── 无事可做 → 必须调用 SleepTool
SleepTool 等待 [需要实现]
SleepTool 等待
├── 用户插入新工作 / 队列中有命令 → 立即唤醒
├── proactive 被关闭 → 立即中断
└── 进入休眠时向远端 surfaces 上报 `automation_state = sleeping`
下一个 tick 到达
```
## 三、需要补全的内容
## 三、当前行为补充
| 优先级 | 模块 | 工作量 | 说明 |
|--------|------|--------|------|
| 1 | `src/proactive/index.ts` | 中 | Tick 调度器、activate/deactivate 状态机、pause/resume |
| 2 | `src/tools/SleepTool/SleepTool.ts` | 小 | 工具执行(等待指定时间后触发 tick |
| 3 | `src/commands/proactive.js` | 小 | `/proactive` 斜杠命令处理器 |
| 4 | `src/hooks/useProactive.ts` | 中 | React hookREPL 引用但不存在) |
- `standby`proactive 已开启,当前没有执行中的 turn且已调度下一个 tick。
- `sleeping`:模型显式调用 `SleepTool` 进入等待窗口。
- remote-control/CCR 通过 `external_metadata.automation_state` 接收这两个状态,用于 Web UI 的 Autopilot 状态显示。
- `SleepTool` 现在不是纯定时器;它会在共享命令队列出现新工作时提前醒来。
## 四、关键设计决策
@@ -101,9 +103,11 @@ FEATURE_PROACTIVE=1 FEATURE_KAIROS=1 FEATURE_KAIROS_BRIEF=1 bun run dev
| 文件 | 职责 |
|------|------|
| `src/proactive/index.ts` | 核心逻辑stub |
| `src/proactive/index.ts` | 核心逻辑与 next-tick 状态 |
| `src/tools/SleepTool/prompt.ts` | SleepTool 工具提示 |
| `src/constants/prompts.ts:860-914` | 自主工作系统提示 |
| `src/screens/REPL.tsx` | REPL tick 集成 |
| `src/tools/SleepTool/SleepTool.ts` | 休眠/唤醒执行逻辑 |
| `src/constants/prompts.ts:864-918` | 自主工作系统提示 |
| `src/screens/REPL.tsx` | REPL tick 集成与 automation 状态上报 |
| `src/utils/sessionStorage.ts:4892-4912` | Tick 消息注入 |
| `src/utils/sessionState.ts` | bridge/CCR metadata 镜像 |
| `src/components/PromptInput/PromptInputFooterLeftSide.tsx` | 页脚 UI 状态 |

View File

@@ -13,17 +13,22 @@
┌──────────────────┐ HTTP/SSE │ │ In-Memory │ │
│ Web UI 控制面板 │ ◄─────────────── │ │ Store │ │
│ (/code/*) │ │ └──────────────┘ │
└──────────────────┘ │ ┌──────────────┐ │
│ │ JWT Auth │ │
│ (React + Vite) │ │ ┌──────────────┐ │
└──────────────────┘ │ │ JWT Auth │ │
│ └──────────────┘ │
└──────────────────────┘
┌──────────────────┐ ──────────────┐ │
│ acp-link │ ◄── ACP Relay ─── │ │ ACP Handler │ │
│ + ACP Agent │ WebSocket │ └──────────────┘ │
└──────────────────┘ └──────────────────────┘
```
**RCS 是一个纯内存的中间服务**,它的职责是:
- 接收 Claude Code CLI 的环境注册和工作轮询
- 接收 acp-link 的 ACP agent 注册,支持 WebSocket relay 桥接
- 提供 Web UI 供操作者远程监控和审批
- 通过 WebSocket/SSE 双向传输消息
- 管理会话、环境、权限请求
- 提供 ACP SSE event stream 供外部消费者订阅 channel group 事件
## 前置条件
@@ -99,6 +104,8 @@ docker compose up -d
| `RCS_HEARTBEAT_INTERVAL` | 否 | `20` | 心跳间隔(秒) |
| `RCS_JWT_EXPIRES_IN` | 否 | `3600` | JWT 令牌有效期(秒) |
| `RCS_DISCONNECT_TIMEOUT` | 否 | `300` | 断线判定超时(秒) |
| `RCS_WS_IDLE_TIMEOUT` | 否 | `30` | WebSocket 空闲超时Bun 发送协议级 ping |
| `RCS_WS_KEEPALIVE_INTERVAL` | 否 | `20` | 服务端→客户端 keep_alive 帧间隔(秒),防止反向代理关闭空闲连接 |
### 客户端Claude Code CLI
@@ -138,13 +145,19 @@ bun run dist/cli.js
/remote-control
```
CLI 会向 RCS 注册环境,注册成功后在终端显示连接 URL
环境型 Remote Control例如 `claude remote-control` 子命令)会向 RCS 注册环境,注册成功后在终端显示连接 URL
```
https://rcs.example.com/code?bridge=<environmentId>
```
同时支持 QR 码扫码打开。该 URL 即 Web UI 控制面板入口,在浏览器中打开即可远程操控当前会话。
交互式 REPL 方式(`--remote-control``/remote-control`)在某些桥接模式下也可能直接给出会话 URL
```
https://rcs.example.com/code/session_<id>
```
两种 URL 都可以直接在浏览器打开并远程操控当前会话;只有 environment 模式才会出现在 Web UI 的环境列表中。
若已连接,再次执行 `/remote-control` 会显示对话框,包含以下选项:
- **Disconnect this session** — 断开远程连接
@@ -163,15 +176,69 @@ claude bridge
## Web UI 控制面板
通过 `/remote-control` 命令获取 URL 后,在浏览器打开即可使用。功能:
通过 `/remote-control` 命令获取 URL 后,在浏览器打开即可使用。
- 查看已注册的运行环境
### 技术栈v22026-04-18 重构)
Web UI 已从原生 JS 重构为 **React + Vite + Radix UI**
- **框架**: React 19 + Vite 构建TypeScript
- **UI 组件**: Radix UI primitivesDialog、Tabs、Select、Popover 等)
- **聊天组件**: 完整的 ACP 聊天界面,支持 Plan 可视化、工具调用展示、权限审批
- **AI Elements**: 独立的 AI 交互组件库message、reasoning、tool、code-block、prompt-input 等)
- **ACP 直连**: 支持 QR 码扫描自动跳转 ACP 直连视图(`ACPDirectView`
- **主题系统**: 暗色/亮色主题切换,遵循 Impeccable 设计系统
### 功能
- 查看已注册的运行环境environment 模式),区分 ACP Agent 和 Claude Code 类型
- 创建和管理会话
- 实时查看对话消息和工具调用
- 查看 Autopilot 状态(`standby` / `sleeping`)和自动运行指示
- 查看 authoritative task snapshots 驱动的 Tasks 面板
- 审批 Claude Code 的工具权限请求
- 权限模式选择器6 种模式:默认/自动接受编辑/跳过权限/规划/不询问/自动判断)
- 模型选择器(可选可用模型)
- Plan 可视化(进度条、状态图标、优先级标签)
- ACP QR 扫描自动跳转到 ACP 聊天界面
Web UI 使用 UUID 认证(无需用户账户),适合受信任网络环境。
## ACP 支持
RCS 支持 ACP (Agent Client Protocol) agent 通过 `acp-link` 包接入。
### 架构
```
acp-link ──REST注册──► RCS POST /v1/environments/bridge
acp-link ──WS identify──► RCS WebSocket (携带 agentId)
acp-link ◄──ACP relay──► RCS ◄──Web UI WS──► 浏览器
```
### 后端组件
| 文件 | 职责 |
|------|------|
| `src/routes/acp/index.ts` | ACP REST 路由agents 列表、channel groups、relay |
| `src/transport/acp-ws-handler.ts` | ACP WebSocket 处理agent 注册、心跳、消息转发 |
| `src/transport/acp-relay-handler.ts` | 前端 WS → acp-link 透传 + EventBus inbound 转发 |
| `src/transport/acp-sse-writer.ts` | SSE event stream 供外部消费者订阅 |
### acp-link 连接
详见 [acp-link 文档](./acp-link.md)。
```bash
# 在 RCS 环境中启动 acp-link
# 注意claude 本身不支持 ACP需要用 ccb-bun --acp
ACP_RCS_URL=http://localhost:3000 \
ACP_RCS_TOKEN=sk-rcs-your-key \
acp-link ccb-bun -- --acp
```
ACP session 在 Web UI 中显示品牌色标签,与普通 Claude Code session 区分。
## 工作流程详解
```
@@ -209,6 +276,7 @@ Web UI 使用 UUID 认证(无需用户账户),适合受信任网络环境
9. 双向通信
CLI ──消息/工具调用结果──► RCS ──► Browser
CLI ◄──权限审批/指令───── RCS ◄──── Browser
CLI ──automation_state / task_state──► RCS ──► Browser
10. 心跳保活(每 20 秒)
CLI ──POST /v1/environments/:id/work/:workId/heartbeat──► RCS
@@ -218,6 +286,13 @@ Web UI 使用 UUID 认证(无需用户账户),适合受信任网络环境
## 故障排查
### Web UI 看不到当前 Autopilot 状态
- `standby`proactive 已开启,正在等待下一个 tick
- `sleeping`:模型正在 `SleepTool` 等待窗口中
这两个状态通过 worker `external_metadata.automation_state` 上报。如果页面只显示普通 working spinner优先检查 CLI 和 RCS 之间的 worker metadata PUT 是否成功。
### CLI 无法连接
```
@@ -275,4 +350,3 @@ curl https://rcs.example.com/health
| 依赖 | claude.ai 订阅 + OAuth | 仅需 API Key |
自托管模式的核心优势是:设置 `CLAUDE_BRIDGE_BASE_URL` 后,代码自动调用 `isSelfHostedBridge()` 返回 `true`,跳过所有 GrowthBook 和订阅检查,无需 claude.ai 账户即可使用。

426
docs/features/ssh-remote.md Normal file
View File

@@ -0,0 +1,426 @@
# SSH Remote — 远程主机运行 Claude Code
## 概述
SSH Remote 提供两种方式在远程 Linux 主机上运行 Claude Code
1. **SSH Remote 模块**`ccb ssh <host>`)— 本地 REPL + 远程工具执行,自动部署二进制 + 认证隧道
2. **直接 SSH 运行**`ssh <host> -t ccb`)— 远程已安装 ccb直接启动交互式会话
## 架构
### 方式一SSH Remote 模块(完整模式)
适用场景:远端没有 API 凭据或没有安装 ccb。
```
┌──────────────── 本地 Windows/Mac/Linux ───────────┐
│ │
│ ccb ssh <host> [dir] │
│ │ │
│ ├── 1. SSHProbe: 探测远端平台/架构/已有二进制 │
│ ├── 2. SSHDeploy: 部署 dist/ 到远端 │
│ ├── 3. SSHAuthProxy: 启动本地认证代理 │
│ │ ├─ Unix Socket (Linux/Mac) │
│ │ └─ TCP 127.0.0.1:<port> (Windows) │
│ │ │
│ └── 4. SSH -R 反向隧道 + 启动远端 CLI │
│ ssh -R <remote>:<local> <host> \ │
│ ANTHROPIC_BASE_URL=... \ │
│ ANTHROPIC_AUTH_NONCE=... \ │
│ ccb --output-format stream-json │
│ │
│ ┌─────── 本地 REPL (Ink TUI) ───────┐ │
│ │ 用户输入 → NDJSON → SSH stdin │ │
│ │ SSH stdout → NDJSON → 渲染消息 │ │
│ │ 工具权限请求 → 本地审批 → 回传 │ │
│ └────────────────────────────────────┘ │
└────────────────────────────────────────────────────┘
│ SSH 连接 (加密通道)
┌───────────────── 远端 Linux ──────────────────────┐
│ │
│ ccb (自动部署或已存在) │
│ ├── --output-format stream-json │
│ ├── --input-format stream-json │
│ ├── --verbose -p │
│ │ │
│ ├── API 请求 → ANTHROPIC_BASE_URL │
│ │ → SSH 反向隧道 → 本地 AuthProxy │
│ │ → 注入真实凭据 → api.anthropic.com │
│ │ │
│ └── 工具执行 (Bash/Read/Write/...) │
│ 直接在远端文件系统上操作 │
└────────────────────────────────────────────────────┘
```
### 方式二:直接 SSH 运行(简单模式)
适用场景:远端已安装 ccb 且已有 API 凭据(订阅或 API Key
```
┌─────── 本地终端 ───────┐ ┌──────── 远端 Linux ────────┐
│ │ SSH │ │
│ ssh <host> -t ccb │ ──────→ │ ccb (全局安装) │
│ │ │ ├── 使用远端自身凭据 │
│ 终端直接显示远端 TUI │ ←────── │ ├── 远端文件系统操作 │
│ │ TTY │ └── API 直连 Anthropic │
└─────────────────────────┘ └─────────────────────────────┘
```
### 适用场景对比
| | SSH Remote 模块 | 直接 SSH 运行 |
|---|---|---|
| 远端需要安装 ccb | 不需要(自动部署) | 需要 |
| 远端需要 API 凭据 | 不需要(本地隧道) | 需要 |
| 本地需要安装 ccb | 需要 | 不需要(任何终端) |
| 斜杠命令 | 本地处理 | 远端处理 |
| 网络延迟敏感 | 高NDJSON 双向) | 低(仅 TTY |
| 推荐场景 | 远端无凭据/无安装 | 远端已配置完整 |
---
## 前置准备SSH 密钥配置
两种方式都依赖 SSH 免密连接。以下是完整的密钥配置步骤。
### 1. 生成 SSH 密钥对(本地)
```bash
# 生成 Ed25519 密钥(推荐)
ssh-keygen -t ed25519 -C "your-email@example.com" -f ~/.ssh/id_remote
# 或 RSA 4096 位
ssh-keygen -t rsa -b 4096 -C "your-email@example.com" -f ~/.ssh/id_remote
```
生成两个文件:
- `~/.ssh/id_remote` — 私钥(不可泄露)
- `~/.ssh/id_remote.pub` — 公钥(部署到远端)
### 2. 将公钥部署到远端
```bash
# 方式 Assh-copy-id推荐
ssh-copy-id -i ~/.ssh/id_remote.pub user@remote-host
# 方式 B手动复制
cat ~/.ssh/id_remote.pub | ssh user@remote-host "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"
```
### 3. 配置 SSH Config本地
编辑 `~/.ssh/config`(不存在则创建):
```
Host my-server
HostName 192.168.1.100 # 远端 IP 或域名
User root # 远端用户名
IdentityFile ~/.ssh/id_remote # 私钥路径
ServerAliveInterval 60 # 防止连接超时断开
ServerAliveCountMax 3
```
配置后可直接用别名连接:
```bash
ssh my-server # 等同于 ssh -i ~/.ssh/id_remote root@192.168.1.100
```
### 4. 文件权限设置
#### Linux / macOS
```bash
chmod 700 ~/.ssh
chmod 600 ~/.ssh/config
chmod 600 ~/.ssh/id_remote
chmod 644 ~/.ssh/id_remote.pub
```
#### WindowsOpenSSH 强制 ACL 检查)
```powershell
# 重置 .ssh 目录权限:仅允许当前用户 + SYSTEM
icacls "$env:USERPROFILE\.ssh" /inheritance:r /grant:r "$($env:USERNAME):(OI)(CI)F" /grant "SYSTEM:(OI)(CI)F"
# 修复 config 文件权限
icacls "$env:USERPROFILE\.ssh\config" /inheritance:r /grant:r "$($env:USERNAME):F" /grant "SYSTEM:F"
# 修复私钥权限
icacls "$env:USERPROFILE\.ssh\id_remote" /inheritance:r /grant:r "$($env:USERNAME):F" /grant "SYSTEM:F"
```
> **Windows 常见错误**:如果 `icacls` 显示 `UNKNOWN\UNKNOWN` ACL 条目,需要先移除再重新授权。权限错误会导致 SSH 拒绝使用密钥。
### 5. 验证免密连接
```bash
ssh my-server "echo 'SSH connection OK'"
# 应直接输出 "SSH connection OK",不要求输入密码
```
---
## 使用方式
### 方式一SSH Remote 模块
```bash
# 基本用法 — 自动探测、部署、启动
ccb ssh user@remote-host
# 使用 SSH Config 别名
ccb ssh my-server
# 指定远端工作目录
ccb ssh my-server /home/user/project
# 使用自定义远端二进制(跳过探测/部署)
ccb ssh my-server --remote-bin "bun /opt/ccb/dist/cli.js"
# 权限控制
ccb ssh my-server --permission-mode auto
ccb ssh my-server --dangerously-skip-permissions
# 恢复远端会话
ccb ssh my-server --continue
ccb ssh my-server --resume <session-uuid>
# 选择模型
ccb ssh my-server --model claude-sonnet-4-6-20250514
# 本地测试模式(不连接远端,测试 auth proxy 管道)
ccb ssh localhost --local
```
### 方式二:直接 SSH 运行
```bash
# 启动交互式会话
ssh my-server -t ccb
# 指定工作目录
ssh my-server -t "ccb --cwd /home/user/project"
# 使用特定模型
ssh my-server -t "ccb --model claude-sonnet-4-6-20250514"
```
---
## 构建与部署
### 构建产物
```bash
# 安装依赖
bun install
# 构建(输出到 dist/
bun run build
```
产物说明:
| 文件 | 说明 |
|------|------|
| `dist/cli.js` | Bun 入口(`#!/usr/bin/env bun` |
| `dist/cli-node.js` | Node.js 入口(`#!/usr/bin/env node``import ./cli.js` |
| `dist/cli-bun.js` | Bun 专用入口 |
| `dist/chunk-*.js` | 代码分割 chunk 文件(约 668 个) |
### 运行方式
```bash
# 方式 A通过 bun 直接运行(开发/调试)
bun run dev
# 方式 B运行构建产物bun 运行时)
bun dist/cli.js
# 方式 C运行构建产物node 运行时)
node dist/cli-node.js
# 方式 D全局安装后使用命令名
ccb
```
### 全局安装
在项目根目录执行:
```bash
# bun 全局安装(推荐)
bun install -g .
# 创建的命令:
# ccb → dist/cli-node.js
# ccb-bun → dist/cli-bun.js
# claude-code-best → dist/cli-node.js
# 安装位置:~/.bun/bin/ccb
```
或使用 npm
```bash
npm install -g .
```
验证:
```bash
ccb --version
# → x.x.x (Claude Code)
```
### 远端部署(全流程)
```bash
# 1. 登录远端
ssh my-server
# 2. 克隆或同步项目代码
git clone <repo-url> ~/ccb-project
cd ~/ccb-project
# 3. 安装运行时(如果没有 bun
curl -fsSL https://bun.sh/install | bash
source ~/.bashrc
# 4. 安装依赖 + 构建
bun install
bun run build
# 5. 全局安装
bun install -g .
# 6. 确保非交互式 SSH 可访问 ccb 命令
# bun install -g 安装到 ~/.bun/bin/,但非交互式 SSH 不加载 .bashrc
# 所以 PATH 中不包含 ~/.bun/bin/
# 解决方式(任选其一):
# 方式 A符号链接到系统 PATH推荐
ln -sf ~/.bun/bin/ccb /usr/local/bin/ccb
# 方式 B添加到 /etc/profile.d/(所有用户生效)
echo 'export PATH="$HOME/.bun/bin:$PATH"' > /etc/profile.d/bun-path.sh
# 方式 C添加到 ~/.bash_profile当前用户ssh -t 时生效)
echo 'export PATH="$HOME/.bun/bin:$PATH"' >> ~/.bash_profile
# 7. 验证
ccb --version
# 8. 从本地测试
# (在本地终端)
ssh my-server -t ccb
```
### SSH Remote 自动部署
使用 `ccb ssh <host>` 时,模块自动处理:
1. **SSHProbe** 探测远端 `~/.local/bin/claude``command -v claude`
2. 若二进制不存在或版本不匹配,**SSHDeploy** 通过 `scp` 传输 `dist/` 目录
3. 在远端创建 wrapper 脚本(`~/.local/bin/claude`
4. 无需手动安装
---
## 模块结构
```
src/ssh/
├── createSSHSession.ts — 会话工厂:编排 probe → deploy → proxy → spawn
├── SSHSessionManager.ts — 双向 NDJSON 通信管理 + 权限转发 + 重连
├── SSHAuthProxy.ts — 本地认证代理API 凭据隧道)
├── SSHProbe.ts — 远端主机探测(平台/架构/已有二进制)
├── SSHDeploy.ts — 远端二进制部署scp + wrapper 脚本)
└── __tests__/
└── SSHSessionManager.test.ts — 17 个单元测试
```
## 关键技术细节
### 认证隧道
- **AuthProxy** 在本地监听Unix socket 或 TCP接收远端 CLI 的 API 请求
- 通过 SSH `-R` 反向端口转发隧道到远端
- AuthProxy 注入本地真实凭据API key 或 OAuth token转发到 `api.anthropic.com`
- `ANTHROPIC_AUTH_NONCE` header 防止未授权访问nonce 通过环境变量传递给远端 CLI远端 CLI 在每个 API 请求中携带此 header
### waitForInit vs 存活检查
- **标准模式**`waitForInit` 等待远端 CLI 发送 `{type:'system', subtype:'init'}` JSON 消息
- **`--remote-bin` 模式**:跳过 `waitForInit`print+stream-json 模式下 init 只在首次查询后发送),改用 3 秒进程存活检查
### 重连机制
- `SSHSessionManager` 检测 SSH 连接断开后自动重连
- 重连时在远端 CLI 命令中追加 `--continue` 恢复会话
- 指数退避重试(最多 5 次,间隔 1s → 2s → 4s → 8s → 16s
## Feature Flag
SSH Remote 功能受 `SSH_REMOTE` feature flag 控制:
- **Dev 模式**:默认启用
- **Build 模式**:需在 `build.ts``DEFAULT_BUILD_FEATURES` 中添加 `'SSH_REMOTE'`
- **运行时**`FEATURE_SSH_REMOTE=1` 环境变量
---
## 常见问题
### `ccb: command not found`SSH 远程执行时)
非交互式 SSH 不加载 `.bashrc``~/.bun/bin` 不在 PATH 中。
```bash
# 解决:创建符号链接
ln -sf ~/.bun/bin/ccb /usr/local/bin/ccb
```
### SSH 密钥被拒绝
```
Permission denied (publickey)
```
1. 确认公钥已添加到远端 `~/.ssh/authorized_keys`
2. 确认本地私钥文件权限正确(`chmod 600`
3. 确认 `~/.ssh/config``IdentityFile` 路径正确
4. Windows 用户检查 ACL 权限(见上方 Windows 权限设置)
### SSH 连接超时
```
ssh: connect to host x.x.x.x port 22: Connection timed out
```
1. 确认远端 SSH 服务正在运行:`systemctl status sshd`
2. 确认防火墙允许 22 端口
3. 确认 IP 地址/域名正确
4.`~/.ssh/config` 中添加 `ConnectTimeout 10`
### 403 ForbiddenSSH Remote 模块)
AuthProxy 的 nonce 验证失败。确认:
1. 远端 CLI 版本包含 nonce header 注入修复
2. `ANTHROPIC_AUTH_NONCE` 环境变量正确传递到远端
3. `src/services/api/client.ts``x-auth-nonce` header 已启用
### 远端 CLI 启动后立即退出
```
Remote process exited immediately (code 1)
```
1. 确认远端 `bun` / `node` 运行时可用
2. 手动在远端执行 `ccb --version` 验证安装
3. 检查 `--remote-bin` 路径是否正确
4. 查看 stderr 输出获取详细错误信息

View File

@@ -0,0 +1,310 @@
# Stub 恢复设计 1-4
> 日期2026-04-12
> 目标:基于当前代码边界,为下一阶段 4 个 stub/半 stub 命令面给出可实施的设计方案。
> 排序原则:按建议实施顺序排序,不按问题严重性排序。
## 设计原则
- 先做能独立闭环、收益明确、改动边界清晰的项。
- 大项拆成 `MVP``Phase 2+`,避免一次性掉进大范围恢复。
- 优先复用已有状态、传输层、日志与配置能力,不重造协议。
- 设计以当前仓库实际代码为准,不以旧文档的理想状态为准。
## 1. `claude daemon status` / `claude daemon stop`
### 现状
- `start` 路径已有完整 supervisor + worker 生命周期:
`src/daemon/main.ts`
`src/daemon/workerRegistry.ts`
- `status` / `stop` 目前只是占位输出:
`src/daemon/main.ts`
- `/remote-control-server` 有自己的命令内 UI 状态,但只维护当前进程内的 `daemonProcess`,并不适合作为跨进程 CLI 管理基础:
`src/commands/remoteControlServer/remoteControlServer.tsx`
### 目标
-`claude daemon status``claude daemon stop` 在另一个 CLI 进程中也能正确工作。
- 不依赖 TUI 内存态,不要求当前命令进程就是启动 daemon 的那个进程。
### MVP 方案
- 新增 daemon 状态文件,例如:
`~/.claude/daemon/remote-control.json`
- `start` 时写入:
- supervisor pid
- cwd
- startedAt
- worker kinds
- 最近状态
- `status`
- 读取状态文件
- 用现有进程探测能力验证 pid 是否存活
- 输出 `running / stopped / stale`
- stale 时自动清理状态文件
- `stop`
- 读取 pid
- 发送 `SIGTERM`
- 等待退出
- 超时后 `SIGKILL`
- 清理状态文件
### 代码范围
- 新增 `src/daemon/state.ts`
- 修改 `src/daemon/main.ts`
- 轻量修改 `src/commands/remoteControlServer/remoteControlServer.tsx`,让 UI 尽量读取同一份状态文件
### 验证
1. `claude daemon start`
2. 新开终端执行 `claude daemon status`
3. 执行 `claude daemon stop`
4. 再次执行 `claude daemon status`,确认返回 `stopped` 或清晰的 `stale cleaned`
### 风险
- Windows 信号模型和 Unix 不同,`stop` 需要超时兜底。
- 当前设计默认单 supervisor不处理多实例并发。
### 工作量判断
-
- 适合作为下一步的首选实现项
## 2. `BG_SESSIONS`
### 现状
- fast-path 已接好:
`src/entrypoints/cli.tsx`
- session registry 已有真实实现:
`src/utils/concurrentSessions.ts`
- `exit` 在 bg session 内已会 `tmux detach-client`
`src/commands/exit/exit.tsx`
- 但 CLI handler 仍全空:
`src/cli/bg.ts`
- task summary 仍然是 stub
`src/utils/taskSummary.ts`
### 目标
- 先把 `ps` / `logs` / `kill` 做成真正有用的 session 管理命令。
- 不在第一阶段就强行补完 `attach` / `--bg`
### Phase 2AMVP
- 实现 `ps`
- 从 registry 读取 live sessions
- 展示 pid、kind、sessionId、cwd、name、startedAt、bridgeSessionId
- 如果有 activity/status则一并展示
- 实现 `logs`
- 支持按 `sessionId / pid / name` 查找
- 优先复用本地 transcript/log 读取能力
- 如果 registry 里存在 `logPath`,支持 tail 文件
- 实现 `kill`
- 解析目标 session
- 发退出信号
- 清理 stale registry
### Phase 2B后续
- 实现 `attach`
- 实现 `--bg`
- 实现 `taskSummary` 的中途状态更新
### 为什么要拆
- 现有 registry 记录了 `pid / sessionId / name / logPath`
- 但没有可靠的 tmux attach target
- 所以 `attach``--bg` 不是简单补 handler而是需要补启动/附着元数据设计
### 代码范围
- 修改 `src/cli/bg.ts`
- 修改 `src/utils/concurrentSessions.ts` 以便后续 attach/--bg 扩展
- 修改 `src/utils/taskSummary.ts`
- 复用:
`src/utils/sessionStorage.ts`
`src/utils/udsClient.ts`
### 验证
1. `ps` 能列出 live sessions
2. `logs <sessionId|pid|name>` 能输出对应日志
3. `kill <sessionId|pid|name>` 能结束目标 session
### 风险
- `attach` / `--bg` 第二阶段需要 tmux 元数据设计
- Windows 下 tmux 路径需要明确降级策略
### 工作量判断
- `ps/logs/kill` 中等
- `attach/--bg` 明显更大,应分阶段
## 3. `TEMPLATES`
### 现状
- 命令入口只有 fast-path
`src/entrypoints/cli.tsx`
- handler 是空的:
`src/cli/handlers/templateJobs.ts`
- `markdownConfigLoader` 已把 `templates` 纳入配置目录:
`src/utils/markdownConfigLoader.ts`
- `query / stopHooks` 已预留 job classifier 链路:
`src/query/stopHooks.ts`
- `jobs/classifier.ts` 仍是 stub
`src/jobs/classifier.ts`
### 目标
-`new / list / reply` 做成可用的模板任务系统。
- 第一阶段不碰复杂的自动分类与自动执行。
### MVP 方案
- 模板来源:
`.claude/templates/*.md`
- 模板格式:
复用现有 markdown + frontmatter 解析,不另外设计 DSL
- `list`
- 列出所有模板
- 显示模板名、description、路径
- `new <template> [args...]`
- 解析模板
-`~/.claude/jobs/<job-id>/` 下创建 job 目录
- 写入 `template.md``input.txt``state.json`
- 返回 job id 与目录
- `reply <job-id> <text>`
- 将回复写入 `replies.jsonl``input.txt`
- 更新 `state.json`
### Phase 2
- 恢复 `src/jobs/classifier.ts`
- 让带 `CLAUDE_JOB_DIR` 的 job session 在 turn 完成后自动更新 `state.json`
- 再决定是否补自动 job runner
### 为什么要拆
- 当前证据表明这是“template job commands”不是单纯模板列表
- 但自动 job 运行链路没有足够现成实现,先做文件系统 job lifecycle 更稳
### 代码范围
- 修改 [src/cli/handlers/templateJobs.ts](</e:/Source_code/Claude-code-bast/src/cli/handlers/templateJobs.ts:1>)
- 新增 `src/jobs/state.ts`
- 新增 `src/jobs/templates.ts`
- Phase 2 再改 [src/jobs/classifier.ts](</e:/Source_code/Claude-code-bast/src/jobs/classifier.ts:1>)
### 验证
1. `list` 能列出 `.claude/templates`
2. `new` 能创建 job 目录和状态文件
3. `reply` 能更新 job 内容和状态
4. Phase 2 再验证 classifier 写状态
### 风险
- frontmatter schema 需要先定义最小字段集
- 一旦扩展到“自动运行 job”范围会明显膨胀
### 工作量判断
- MVP 中等
- 完整 job 系统偏大
## 4. `assistant [sessionId]`
### 现状
- attach 主流程其实已经存在:
[src/main.tsx](</e:/Source_code/Claude-code-bast/src/main.tsx:4708>)
- 远端 viewer 所需基础模块已存在:
[src/remote/RemoteSessionManager.ts](</e:/Source_code/Claude-code-bast/src/remote/RemoteSessionManager.ts:1>)
[src/hooks/useAssistantHistory.ts](</e:/Source_code/Claude-code-bast/src/hooks/useAssistantHistory.ts:1>)
[src/assistant/sessionHistory.ts](</e:/Source_code/Claude-code-bast/src/assistant/sessionHistory.ts:1>)
- 真正 stub 的主要是:
[src/assistant/sessionDiscovery.ts](</e:/Source_code/Claude-code-bast/src/assistant/sessionDiscovery.ts:1>)
[src/assistant/AssistantSessionChooser.ts](</e:/Source_code/Claude-code-bast/src/assistant/AssistantSessionChooser.ts:1>)
[src/commands/assistant/assistant.ts](</e:/Source_code/Claude-code-bast/src/commands/assistant/assistant.ts:7>)
[src/assistant/index.ts](</e:/Source_code/Claude-code-bast/src/assistant/index.ts:1>)
### 目标
- 不一次性恢复整个 KAIROS 助手系统。
- 先做“明确 sessionId 的 viewer attach 可用”,再逐步补 discovery / chooser / install。
### Phase 4AMVP
- 只支持 `claude assistant <sessionId>`
-`claude assistant` 无参数模式,先返回明确提示:
- 当前版本需要显式 `sessionId`
- discovery 尚未启用
- 这样可以直接复用现有 attach 分支,不必先恢复 chooser/install wizard
### Phase 4B
- 恢复 `discoverAssistantSessions()`
- 数据来源优先复用现有 sessions / bridge / teleport API而不是新协议
-`claude assistant` 无参数时能拿到候选 session 列表
### Phase 4C
- 恢复 `AssistantSessionChooser`
- 多 session 时可交互选择
### Phase 4D
- 最后考虑 install wizard 辅助函数
- 这部分属于“没有 session 时如何引导”,不是 attach 核心路径
### 为什么要拆
- attach 渲染层与远端消息通道大部分已经在
- 真正缺的是“如何发现目标 session”和“如何交互选择”
- 如果把 `src/assistant/index.ts` 的整套 KAIROS 正常模式也一起拉进来,范围会失控
### 代码范围
- Phase 4A
- [src/main.tsx](</e:/Source_code/Claude-code-bast/src/main.tsx:4708>)
- [src/commands/assistant/index.ts](</e:/Source_code/Claude-code-bast/src/commands/assistant/index.ts:1>)
- Phase 4B
- [src/assistant/sessionDiscovery.ts](</e:/Source_code/Claude-code-bast/src/assistant/sessionDiscovery.ts:1>)
- Phase 4C
- [src/assistant/AssistantSessionChooser.ts](</e:/Source_code/Claude-code-bast/src/assistant/AssistantSessionChooser.ts:1>)
- Phase 4D
- [src/commands/assistant/assistant.ts](</e:/Source_code/Claude-code-bast/src/commands/assistant/assistant.ts:7>)
### 验证
1. `claude assistant <sessionId>` 能进入 remote viewer
2. 历史懒加载工作正常
3. 无参数模式先给出明确提示
4. 后续阶段再分别验证 discovery / chooser / install
### 风险
- 这是四项里范围最大的
- 一旦把 KAIROS 正常模式整体拉入会从“viewer attach”膨胀成“完整 assistant mode 恢复”
### 工作量判断
- Phase 4A 中等
- 4A-4D 全做完很大
## 建议执行顺序
1. `claude daemon status` / `claude daemon stop`
2. `BG_SESSIONS` 先做 `ps/logs/kill`
3. `TEMPLATES` 先做 job 文件系统 MVP
4. `assistant [sessionId]` 先做显式 sessionId attach再补 discovery/chooser/install
## 简短结论
这四项里,最适合立刻实现的是 `daemon status/stop``BG_SESSIONS``TEMPLATES` 适合按 MVP 先补 handler 与文件系统闭环。`assistant [sessionId]` 不能整块硬上应该按“attach → discovery → chooser → install”拆开恢复。

View File

@@ -7,50 +7,13 @@
| Feature | 引用 | 状态 | 类别 | 简要说明 |
|---------|------|------|------|---------|
| CHICAGO_MCP | 16 | N/A | 内部基础设施 | Anthropic 内部 MCP 基础设施,非外部可用 |
| MONITOR_TOOL | 13 | Stub | 工具 | 文件/进程监控工具,检测变更并通知 |
| BG_SESSIONS | 11 | Stub | 会话管理 | 后台会话管理,支持多会话并行 |
| SHOT_STATS | 10 | 实现 | 统计 | 逐 prompt 统计信息收集 |
| EXTRACT_MEMORIES | 7 | 实现 | 记忆 | 自动从对话中提取重要信息作为记忆 |
| TEMPLATES | 6 | Stub | 项目管理 | 项目/提示模板系统 |
| LODESTONE | 6 | N/A | 内部基础设施 | 内部基础设施模块 |
| STREAMLINED_OUTPUT | 1 | — | 输出 | 精简输出模式,减少终端输出量 |
| HOOK_PROMPTS | 1 | — | 钩子 | Hook 提示词,自定义钩子的提示注入 |
| CCR_AUTO_CONNECT | 3 | — | 远程控制 | CCR 自动连接,自动建立远程控制会话 |
| CCR_MIRROR | 4 | — | 远程控制 | CCR 镜像模式,会话状态同步 |
| CCR_REMOTE_SETUP | 1 | — | 远程控制 | CCR 远程设置,初始化远程控制配置 |
| NATIVE_CLIPBOARD_IMAGE | 2 | — | 系统集成 | 原生剪贴板图片,从剪贴板读取图片 |
| CONNECTOR_TEXT | 7 | — | 连接器 | 连接器文本,外部系统文本适配 |
| COMMIT_ATTRIBUTION | 12 | — | Git | Commit 归因,标记 commit 来源 |
| CACHED_MICROCOMPACT | 12 | — | 压缩 | 缓存微压缩,优化 compaction 性能 |
| PROMPT_CACHE_BREAK_DETECTION | 9 | — | 性能 | Prompt cache 中断检测,监控 cache miss |
| MEMORY_SHAPE_TELEMETRY | 3 | — | 遥测 | 记忆形态遥测,记忆使用模式追踪 |
| MCP_RICH_OUTPUT | 3 | — | MCP | MCP 富输出,增强 MCP 工具输出格式 |
| FILE_PERSISTENCE | 3 | — | 持久化 | 文件持久化,跨会话保持状态 |
| TREE_SITTER_BASH_SHADOW | 5 | Shadow | 安全 | Bash AST Shadow 模式(见 tree-sitter-bash.md |
| QUICK_SEARCH | 5 | — | 搜索 | 快速搜索,优化的文件/内容搜索 |
| MESSAGE_ACTIONS | 5 | — | UI | 消息操作,对消息执行后处理动作 |
| DOWNLOAD_USER_SETTINGS | 5 | — | 配置 | 下载用户设置,从服务端同步配置 |
| DIRECT_CONNECT | 5 | — | 网络 | 直连模式,绕过代理直接连接 API |
| VERIFICATION_AGENT | 4 | — | Agent | 验证 Agent专门用于验证代码变更 |
| TERMINAL_PANEL | 4 | — | UI | 终端面板,嵌入式终端输出显示 |
| SSH_REMOTE | 4 | — | 远程 | SSH 远程,通过 SSH 连接远程 Claude |
| REVIEW_ARTIFACT | 4 | — | 审查 | Review Artifact代码审查产出物 |
| REACTIVE_COMPACT | 4 | — | 压缩 | 响应式压缩,基于上下文变化触发 compaction |
| HISTORY_PICKER | 4 | — | UI | 历史选择器,浏览和选择历史对话 |
| UPLOAD_USER_SETTINGS | 2 | — | 配置 | 上传用户设置,同步配置到服务端 |
| POWERSHELL_AUTO_MODE | 2 | — | 平台 | PowerShell 自动模式Windows 权限自动化 |
| OVERFLOW_TEST_TOOL | 2 | — | 测试 | 溢出测试工具,测试上下文溢出处理 |
| NEW_INIT | 2 | — | 初始化 | 新版初始化流程 |
| HARD_FAIL | 2 | — | 错误处理 | 硬失败模式,不可恢复错误直接终止 |
| ENHANCED_TELEMETRY_BETA | 2 | — | 遥测 | 增强遥测 Beta详细的性能指标收集 |
| COWORKER_TYPE_TELEMETRY | 2 | — | 遥测 | 协作者类型遥测,追踪协作模式 |
| BREAK_CACHE_COMMAND | 2 | — | 缓存 | 中断缓存命令,强制刷新 prompt cache |
| AWAY_SUMMARY | 2 | — | 摘要 | 离开摘要,用户返回时总结期间工作 |
| AUTO_THEME | 2 | — | UI | 自动主题,根据终端设置切换主题 |
| ALLOW_TEST_VERSIONS | 2 | — | 版本 | 允许测试版本,跳过版本检查 |
| AGENT_TRIGGERS_REMOTE | 2 | — | Agent | Agent 远程触发,从远程触发 Agent 任务 |
| AGENT_MEMORY_SNAPSHOT | 2 | — | Agent | Agent 记忆快照,保存/恢复 Agent 状态 |
| CHICAGO_MCP | 16 | 已实现 | 工具 | Computer Use + Chrome MCP 控制build 默认启用) |
| MONITOR_TOOL | 13 | 已实现 | 工具 | 后台监控工具,持续监视 shell 输出build 默认启用) |
| BG_SESSIONS | 11 | 部分实现 | 会话管理 | 后台会话注册/清理已实现,任务摘要是 stubdev 默认启用) |
| SHOT_STATS | 10 | 实现 | 统计 | API 调用统计面板build 默认启用) |
| EXTRACT_MEMORIES | 7 | 实现 | 记忆 | 自动记忆提取build 默认启用,受 GrowthBook 门控) |
| TEMPLATES | 6 | 部分实现 | 项目管理 | 项目/提示模板系统dev 默认启用) |
| LODESTONE | 6 | 已实现 | 深度链接 | URL 协议处理器build 默认启用) |
## 单引用 Feature40+ 个)
@@ -66,10 +29,9 @@ BUILDING_CLAUDE_APPS, ANTI_DISTILLATION_CC, AGENT_TRIGGERS, ABLATION_BASELINE
这些 feature 被列为 Tier 3 的原因:
1. **内部基础设施**CHICAGO_MCP, LODESTONEAnthropic 内部使用,外部无法运行
2. **纯 Stub 且引用低**MONITOR_TOOL, BG_SESSIONS需要大量工作才能实现
3. **实验性功能**SHOT_STATS, EXTRACT_MEMORIES尚在概念阶段
4. **辅助功能**STREAMLINED_OUTPUT, HOOK_PROMPTS影响范围小
5. **CCR 系列**:依赖远程控制基础设施,需要 BRIDGE_MODE 先完善
1. **已实现但影响范围小**CHICAGO_MCP, LODESTONE, SHOT_STATS, EXTRACT_MEMORIES, MONITOR_TOOL已在 build/dev 默认启用,主要作为其他功能的基础设施
2. **部分实现**BG_SESSIONS, TEMPLATES核心注册已实现但部分功能如任务摘要仍是 stub
3. **辅助功能**STREAMLINED_OUTPUT, HOOK_PROMPTS影响范围小
4. **CCR 系列**:依赖远程控制基础设施,需要 BRIDGE_MODE 先完善
如需深入了解某个 Tier 3 feature可以在代码库中搜索 `feature('FEATURE_NAME')` 查看具体使用场景。

View File

@@ -191,7 +191,7 @@ FEATURE_TOKEN_BUDGET=1 bun run dev
| `src/query/tokenBudget.ts` | 93 | 预算追踪器 + continue/stop 决策 |
| `src/bootstrap/state.ts:724-743` | 20 | turn 级 token 快照状态 |
| `src/constants/prompts.ts:538-551` | 14 | 系统提示注入 |
| `src/utils/attachments.ts:3829-3845` | 17 | API attachment 附加 |
| `src/utils/attachments.ts:3830-3844` | 17 | API attachment 附加 |
| `src/query.ts:280,1311-1358` | 48 | 主循环集成 |
| `src/screens/REPL.tsx:2897,2963,2138` | 20 | REPL 提交/完成/取消处理 |
| `src/components/Spinner.tsx:319-338` | 20 | 进度条 UI |

View File

@@ -158,4 +158,4 @@ FEATURE_TREE_SITTER_BASH_SHADOW=1 bun run dev
| `src/utils/bash/bashParser.ts` | 4437 | 纯 TS bash 解析器 |
| `src/utils/bash/ast.ts` | 2680 | 安全分析器(核心) |
| `src/utils/bash/treeSitterAnalysis.ts` | 507 | AST 分析辅助 |
| `src/tools/BashTool/bashPermissions.ts:1670-1810` | ~140 | 权限集成 + Shadow 遥测 |
| `packages/builtin-tools/src/tools/BashTool/bashPermissions.ts` | ~140 | 权限集成 + Shadow 遥测 |

View File

@@ -22,16 +22,16 @@ ULTRAPLAN 在用户输入中检测 "ultraplan" 关键字时,自动进入增强
| 模块 | 文件 | 行数 | 状态 |
|------|------|------|------|
| 命令处理器 | `src/commands/ultraplan.tsx` | 472 | **完整** |
| CCR 会话 | `src/utils/ultraplan/ccrSession.ts` | 350 | **完整** |
| 关键字检测 | `src/utils/ultraplan/keyword.ts` | 128 | **完整** |
| 命令处理器 | `src/commands/ultraplan.tsx` | 525 | **完整** |
| CCR 会话 | `src/utils/ultraplan/ccrSession.ts` | 349 | **完整** |
| 关键字检测 | `src/utils/ultraplan/keyword.ts` | 127 | **完整** |
| 嵌入式提示 | `src/utils/ultraplan/prompt.txt` | 1 | **完整** |
| REPL 对话框 | `src/screens/REPL.tsx` | — | **布线** |
| 关键字高亮 | `src/components/PromptInput/PromptInput.tsx` | — | **布线** |
### 2.2 关键字检测
文件:`src/utils/ultraplan/keyword.ts`128 行)
文件:`src/utils/ultraplan/keyword.ts`127 行)
`findUltraplanTriggerPositions(text)` 智能过滤:
- 排除引号内的 "ultraplan"
@@ -41,7 +41,7 @@ ULTRAPLAN 在用户输入中检测 "ultraplan" 关键字时,自动进入增强
### 2.3 CCR 远程会话
文件:`src/utils/ultraplan/ccrSession.ts`350 行)
文件:`src/utils/ultraplan/ccrSession.ts`349 行)
`ExitPlanModeScanner` 类实现完整的事件状态机:
- `pollForApprovedExitPlanMode()` — 3 秒轮询间隔
@@ -99,9 +99,9 @@ FEATURE_ULTRAPLAN=1 bun run dev
| 文件 | 行数 | 职责 |
|------|------|------|
| `src/commands/ultraplan.tsx` | 472 | 斜杠命令处理器 |
| `src/utils/ultraplan/ccrSession.ts` | 350 | CCR 远程会话管理 |
| `src/utils/ultraplan/keyword.ts` | 128 | 关键字检测和替换 |
| `src/commands/ultraplan.tsx` | 525 | 斜杠命令处理器 |
| `src/utils/ultraplan/ccrSession.ts` | 349 | CCR 远程会话管理 |
| `src/utils/ultraplan/keyword.ts` | 127 | 关键字检测和替换 |
| `src/utils/ultraplan/prompt.txt` | 1 | 嵌入式提示 |
| `src/utils/processUserInput/processUserInput.ts:468` | — | 关键字重定向 |
| `src/components/PromptInput/PromptInput.tsx` | — | 彩虹高亮 |

View File

@@ -1,27 +1,32 @@
# VOICE_MODE — 语音输入
> Feature Flag: `FEATURE_VOICE_MODE=1`
> 实现状态:完整可用(需要 Anthropic OAuth
> 实现状态:完整可用(双后端:Anthropic OAuth / 豆包 ASR
> 引用数46
## 一、功能概述
VOICE_MODE 实现"按键说话"Push-to-Talk语音输入。用户按住空格键录音音频通过 WebSocket 流式传输到 Anthropic STT 端点Nova 3,实时转录显示在终端中。
VOICE_MODE 实现"按键说话"Push-to-Talk语音输入。用户按住空格键录音音频流式传输到 STT 后端,实时转录显示在终端中。支持两个后端:
- **Anthropic STT默认**:通过 WebSocket 流式传输到 Nova 3 端点,需要 Anthropic OAuth
- **豆包 ASRDoubao**:通过 `doubaoime-asr` 包的 AsyncGenerator 协议流式识别,使用独立凭证文件,无需 Anthropic OAuth
### 核心特性
- **Push-to-Talk**:长按空格键录音,释放后自动发送
- **流式转录**:录音过程中实时显示中间转录结果
- **无缝集成**:转录文本直接作为用户消息提交到对话
- **双后端切换**:通过 `/voice` 命令参数选择 STT 后端,持久化到 settings.json
## 二、用户交互
| 操作 | 行为 |
|------|------|
| 长按空格 | 开始录音,显示录音状态 |
| 释放空格 | 停止录音,等待最终转录 |
| 转录完成 | 自动插入到输入框并提交 |
| `/voice` 命令 | 切换语音模式开关 |
| 释放空格 | 停止录音,转录结果自动提交 |
| `/voice` | 切换语音模式开关(默认使用 Anthropic 后端) |
| `/voice doubao` | 启用语音模式并使用豆包 ASR 后端 |
| `/voice anthropic` | 切换回 Anthropic STT 后端 |
### UI 反馈
@@ -35,26 +40,37 @@ VOICE_MODE 实现"按键说话"Push-to-Talk语音输入。用户按住空
文件:`src/voice/voiceModeEnabled.ts`
层检查:
层检查函数
```ts
// Anthropic 后端(需要 OAuth
isVoiceModeEnabled() = hasVoiceAuth() && isVoiceGrowthBookEnabled()
// 豆包后端 / 通用可用性检查(不需要 OAuth
isVoiceAvailable() = isVoiceGrowthBookEnabled()
```
1. **Feature Flag**`feature('VOICE_MODE')` — 编译时/运行时开关
2. **GrowthBook Kill-Switch**`!getFeatureValue_CACHED_MAY_BE_STALE('tengu_amber_quartz_disabled', false)` — 紧急关闭开关(默认 false = 未禁用)
3. **Auth 检查**`hasVoiceAuth()` — 需要 Anthropic OAuth token非 API key
3. **Auth 检查(仅 Anthropic**`hasVoiceAuth()` — 需要 Anthropic OAuth token非 API key
4. **Provider 检查**`voiceProvider` 设置决定使用哪个后端,豆包后端跳过 OAuth 检查
### 3.2 核心模块
| 模块 | 职责 |
|------|------|
| `src/voice/voiceModeEnabled.ts` | Feature flag + GrowthBook + Auth 三层门控 |
| `src/hooks/useVoice.ts` | React hook 管理录音状态和 WebSocket 连接 |
| `src/services/voiceStreamSTT.ts` | WebSocket 流式传输到 Anthropic STT |
| `src/hooks/useVoice.ts` | React hook 管理录音状态和后端连接 |
| `src/services/voiceStreamSTT.ts` | Anthropic WebSocket 流式 STT |
| `src/services/doubaoSTT.ts` | 豆包 ASR 适配器AsyncGenerator → VoiceStreamConnection |
| `src/commands/voice/voice.ts` | `/voice` 命令实现,处理后端选择和持久化 |
| `src/hooks/useVoiceEnabled.ts` | 语音启用状态 hook根据 provider 决定是否跳过 OAuth |
| `src/utils/settings/types.ts` | `voiceProvider: 'anthropic' | 'doubao'` 设置类型定义 |
### 3.3 数据流
#### Anthropic 后端
```
用户按下空格键
@@ -79,20 +95,108 @@ WebSocket 连接到 Anthropic STT 端点
转录文本 → 插入输入框 → 自动提交
```
#### 豆包 ASR 后端
```
用户按下空格键
useVoice hook 激活(检测到 voiceProvider === 'doubao'
macOS 原生音频 / SoX 开始录音
connectDoubaoStream() 创建 AudioChunkQueue + VoiceStreamConnection
├──→ onReady 立即触发(无需等待握手)
音频数据通过 AudioChunkQueue 传入 transcribeRealtime()
├──→ INTERIM_RESULT → 实时显示中间转录
├──→ FINAL_RESULT → 显示最终转录
用户释放空格键
finalize() 立即返回(豆包在录音过程中已返回结果,无需等待)
转录文本 → 插入输入框 → 自动提交
```
### 3.4 音频录制
支持两种音频后端:
支持两种音频后端(两个 STT 后端共享)
- **macOS 原生音频**:优先使用,低延迟
- **SoXSound eXchange**:回退方案,跨平台
音频流通过 WebSocket 发送到 Anthropic 的 Nova 3 STT 模型。
### 3.5 豆包 ASR 适配器设计
文件:`src/services/doubaoSTT.ts`
豆包后端使用适配器模式,将 `doubaoime-asr` 的 AsyncGenerator 协议桥接到 `VoiceStreamConnection` 接口:
**AudioChunkQueue** — push 式异步队列:
- 实现 `AsyncIterable<Uint8Array>` 接口
- `push(chunk)` 将音频数据入队,`push(null)` 发送结束信号
- 内部维护等待者waiting和缓冲队列chunks两个状态
**connectDoubaoStream()** — 连接入口:
- 动态导入 `doubaoime-asr`optionalDependencies
-`~/.claude/tts/doubao/credentials.json` 加载凭证
- 创建 AudioChunkQueue 和 VoiceStreamConnection
- 立即触发 `onReady`(避免与 useVoice 的音频缓冲死锁)
- `finalize()` 立即返回(豆包在录音过程中已返回结果)
- 后台 async IIFE 消费 `transcribeRealtime` generator映射响应类型到回调
**响应类型映射**
| doubaoime-asr ResponseType | 回调映射 |
|----------------------------|----------|
| SESSION_STARTED | 日志记录 |
| VAD_START | 日志记录 |
| INTERIM_RESULT | `onTranscript(text, false)` |
| FINAL_RESULT | `onTranscript(text, true)` |
| ERROR | `onError(errorMsg)` |
| SESSION_FINISHED | 日志记录 |
### 3.6 后端选择逻辑
文件:`src/hooks/useVoice.ts`
```ts
// 判断当前 provider
isDoubaoProvider() settings.voiceProvider
// handleKeyEvent 中的可用性检查
const sttAvailable = isDoubaoProvider()
? isDoubaoAvailableSync() // 乐观检查(首次返回 true
: isVoiceStreamAvailable() // Anthropic WebSocket 检查
// attemptConnect 中的连接函数选择
const connectFn = isDoubaoProvider()
? connectDoubaoStream
: connectVoiceStream
```
豆包后端的特殊处理:
- 跳过 `getVoiceKeyterms()` 调用(豆包无需关键词提示)
- 跳过 Focus Mode`if (!enabled || !focusMode || isDoubaoProvider())`
## 四、关键设计决策
1. **OAuth 独占**:语音模式使用 `voice_stream` 端点claude.ai仅 Anthropic OAuth 用户可用。API key、Bedrock、Vertex 用户无法使用
2. **GrowthBook 负向门控**`tengu_amber_quartz_disabled` 默认 `false`,新安装自动可用(无需等 GrowthBook 初始化)
3. **Keychain 缓存**`getClaudeAIOAuthTokens()` 首次调用访问 macOS keychain~20-50ms后续缓存命中
4. **独立于主 feature flag**`isVoiceGrowthBookEnabled()` 在 feature flag 关闭时短路返回 `false`,不触发任何模块加载
1. **双后端共存**:豆包后端作为独立适配器与 Anthropic 后端并存,不替换原有流程,通过 `voiceProvider` 设置切换
2. **设置持久化**`voiceProvider` 存储在 `settings.json`,通过 `/voice` 命令修改,跨会话生效
3. **OAuth 独占Anthropic**Anthropic 后端使用 `voice_stream` 端点claude.ai仅 OAuth 用户可用
4. **豆包无需 OAuth**:豆包后端使用独立凭证文件,不依赖 Anthropic 认证,通过 `isVoiceAvailable()` 放宽门控
5. **GrowthBook 负向门控**`tengu_amber_quartz_disabled` 默认 `false`,新安装自动可用
6. **onReady 立即触发**:豆包后端在连接建立后立即触发 `onReady`,避免与 useVoice 音频缓冲的时序死锁Anthropic 需要等待 WebSocket 握手)
7. **finalize() 立即返回**:豆包在录音过程中已返回所有结果,用户抬手时无需等待处理
8. **乐观可用性检查**`isDoubaoAvailableSync()` 在首次调用时返回 `true`,实际导入错误在 `connectDoubaoStream` 中处理
9. **optionalDependencies**`doubaoime-asr` 作为可选依赖,安装失败不影响 Anthropic 后端
## 五、使用方式
@@ -100,26 +204,60 @@ WebSocket 连接到 Anthropic STT 端点
# 启用 feature
FEATURE_VOICE_MODE=1 bun run dev
# 在 REPL 中使用
# 在 REPL 中使用 Anthropic 后端
# 1. 确保已通过 OAuth 登录claude.ai 订阅)
# 2. 按住空格键说话
# 3. 释放空格键等待转录
# 4. 或使用 /voice 命令切换开关
# 2. 输入 /voice 启用
# 3. 按住空格键说话
# 4. 释放空格键等待转录
# 在 REPL 中使用豆包 ASR 后端
# 1. 确保 doubaoime-asr 已安装bun add doubaoime-asr
# 2. 配置凭证文件:~/.claude/tts/doubao/credentials.json
# 3. 输入 /voice doubao 启用
# 4. 按住空格键说话
# 5. 释放空格键,转录结果即刻显示
# 切换后端
/voice doubao # 切换到豆包 ASR
/voice anthropic # 切换回 Anthropic STT
/voice # 关闭语音模式
```
### 豆包凭证配置
凭证文件路径:`~/.claude/tts/doubao/credentials.json`
```json
{
"deviceId": "...",
"installId": "...",
"cdid": "...",
"openudid": "...",
"clientudid": "...",
"token": "..."
}
```
## 六、外部依赖
| 依赖 | 说明 |
|------|------|
| Anthropic OAuth | claude.ai 订阅登录,非 API key |
| GrowthBook | `tengu_amber_quartz_disabled` 紧急关闭 |
| macOS 原生音频 或 SoX | 音频录制 |
| Nova 3 STT | 语音转文本模型 |
| 依赖 | 说明 | 适用后端 |
|------|------|----------|
| Anthropic OAuth | claude.ai 订阅登录,非 API key | Anthropic |
| GrowthBook | `tengu_amber_quartz_disabled` 紧急关闭 | 通用 |
| macOS 原生音频 或 SoX | 音频录制 | 通用 |
| Nova 3 STT | Anthropic 语音转文本模型 | Anthropic |
| doubaoime-asr | 豆包 ASR SDKoptionalDependencies | 豆包 |
| 凭证文件 | `~/.claude/tts/doubao/credentials.json` | 豆包 |
## 七、文件索引
| 文件 | 行数 | 职责 |
|------|------|------|
| `src/voice/voiceModeEnabled.ts` | 55 | 三层门控逻辑 |
| `src/hooks/useVoice.ts` | — | React hook录音状态 + WebSocket |
| `src/services/voiceStreamSTT.ts` | — | STT WebSocket 流式传输 |
| 文件 | 职责 |
|------|------|
| `src/voice/voiceModeEnabled.ts` | 三层门控逻辑 + `isVoiceAvailable()` |
| `src/hooks/useVoice.ts` | React hook录音状态 + 后端选择 + 连接管理 |
| `src/hooks/useVoiceEnabled.ts` | 语音启用状态 hook按 provider 决定 OAuth 检查) |
| `src/services/voiceStreamSTT.ts` | Anthropic STT WebSocket 流式传输 |
| `src/services/doubaoSTT.ts` | 豆包 ASR 适配器AudioChunkQueue + connectDoubaoStream |
| `src/commands/voice/voice.ts` | `/voice` 命令(开关 + 后端选择) |
| `src/commands/voice/index.ts` | 命令注册(去除 availability 限制) |
| `src/utils/settings/types.ts` | `voiceProvider` 类型定义 |

View File

@@ -1,7 +1,7 @@
# WEB_BROWSER_TOOL — 浏览器工具
> Feature Flag: `FEATURE_WEB_BROWSER_TOOL=1`
> 实现状态:核心实现缺失,面板为 Stub布线完整
> 实现状态:核心工具已实现,面板为 Stub布线完整
> 引用数4
## 一、功能概述
@@ -14,8 +14,8 @@ WEB_BROWSER_TOOL 让模型可以启动浏览器实例、导航网页、与页面
| 模块 | 文件 | 状态 |
|------|------|------|
| 浏览器面板 | `src/tools/WebBrowserTool/WebBrowserPanel.ts` | **Stub** — 返回 null |
| 浏览器工具 | `src/tools/WebBrowserTool/WebBrowserTool.ts` | **缺失** |
| 浏览器面板 | `packages/builtin-tools/src/tools/WebBrowserTool/WebBrowserPanel.ts` | **Stub** — 返回 null |
| 浏览器工具 | `packages/builtin-tools/src/tools/WebBrowserTool/WebBrowserTool.ts` | **已实现** |
| REPL 集成 | `src/screens/REPL.tsx` | **布线** — 渲染 WebBrowserPanel |
| 工具注册 | `src/tools.ts` | **布线** — 动态加载 |
| WebView 检测 | `src/main.tsx` | **布线**`'WebView' in Bun` 检测 |
@@ -44,8 +44,8 @@ WebBrowserPanel 在 REPL 侧边显示浏览器状态
| 模块 | 工作量 | 说明 |
|------|--------|------|
| `WebBrowserTool.ts` | | 工具 schema + Bun WebView API 执行 |
| `WebBrowserPanel.tsx` | 中 | REPL 侧边栏浏览器状态面板 |
| `WebBrowserTool.ts` | ✅ 已实现 | 工具 schema + Bun WebView API 执行 |
| `WebBrowserPanel.tsx` | 中 | REPL 侧边栏浏览器状态面板(仍为 Stub |
## 四、关键设计决策
@@ -63,7 +63,7 @@ FEATURE_WEB_BROWSER_TOOL=1 bun run dev
| 文件 | 职责 |
|------|------|
| `src/tools/WebBrowserTool/WebBrowserPanel.ts` | 面板组件stub |
| `src/tools/WebBrowserTool/WebBrowserTool.ts` | 工具实现(缺失 |
| `src/screens/REPL.tsx:273,4582` | 面板渲染 |
| `packages/builtin-tools/src/tools/WebBrowserTool/WebBrowserPanel.ts` | 面板组件stub |
| `packages/builtin-tools/src/tools/WebBrowserTool/WebBrowserTool.ts` | 工具实现(已实现 |
| `src/screens/REPL.tsx:471,5676` | 面板渲染 |
| `src/tools.ts:115-116` | 工具注册 |

View File

@@ -34,16 +34,16 @@ WebSearchTool.call()
| 模块 | 文件 | 说明 |
|------|------|------|
| 工具入口 | `src/tools/WebSearchTool/WebSearchTool.ts` | `buildTool()` 定义schema、权限、执行、输出格式化 |
| 工具 prompt | `src/tools/WebSearchTool/prompt.ts` | 搜索工具的系统提示词 |
| UI 渲染 | `src/tools/WebSearchTool/UI.tsx` | 搜索结果的终端渲染组件 |
| 适配器接口 | `src/tools/WebSearchTool/adapters/types.ts` | `WebSearchAdapter` 接口、`SearchResult`/`SearchOptions`/`SearchProgress` 类型 |
| 适配器工厂 | `src/tools/WebSearchTool/adapters/index.ts` | `createAdapter()` 工厂函数,选择后端 |
| API 适配器 | `src/tools/WebSearchTool/adapters/apiAdapter.ts` | 封装原有 `queryModelWithStreaming` 逻辑,使用 server tool |
| Bing 适配器 | `src/tools/WebSearchTool/adapters/bingAdapter.ts` | Bing HTML 抓取 + 正则解析 |
| Brave 适配器 | `src/tools/WebSearchTool/adapters/braveAdapter.ts` | Brave LLM Context API 适配与结果映射 |
| 单元测试 | `src/tools/WebSearchTool/__tests__/bingAdapter.test.ts`, `src/tools/WebSearchTool/__tests__/braveAdapter*.test.ts`, `src/tools/WebSearchTool/__tests__/adapterFactory.test.ts` | Bing / Brave 解析与工厂逻辑测试 |
| 集成测试 | `src/tools/WebSearchTool/__tests__/bingAdapter.integration.ts`, `src/tools/WebSearchTool/__tests__/braveAdapter.integration.ts` | 真实网络请求验证 |
| 工具入口 | `packages/builtin-tools/src/tools/WebSearchTool/WebSearchTool.ts` | `buildTool()` 定义schema、权限、执行、输出格式化 |
| 工具 prompt | `packages/builtin-tools/src/tools/WebSearchTool/prompt.ts` | 搜索工具的系统提示词 |
| UI 渲染 | `packages/builtin-tools/src/tools/WebSearchTool/UI.tsx` | 搜索结果的终端渲染组件 |
| 适配器接口 | `packages/builtin-tools/src/tools/WebSearchTool/adapters/types.ts` | `WebSearchAdapter` 接口、`SearchResult`/`SearchOptions`/`SearchProgress` 类型 |
| 适配器工厂 | `packages/builtin-tools/src/tools/WebSearchTool/adapters/index.ts` | `createAdapter()` 工厂函数,选择后端 |
| API 适配器 | `packages/builtin-tools/src/tools/WebSearchTool/adapters/apiAdapter.ts` | 封装原有 `queryModelWithStreaming` 逻辑,使用 server tool |
| Bing 适配器 | `packages/builtin-tools/src/tools/WebSearchTool/adapters/bingAdapter.ts` | Bing HTML 抓取 + 正则解析 |
| Brave 适配器 | `packages/builtin-tools/src/tools/WebSearchTool/adapters/braveAdapter.ts` | Brave LLM Context API 适配与结果映射 |
| 单元测试 | `packages/builtin-tools/src/tools/WebSearchTool/__tests__/bingAdapter.test.ts`, `packages/builtin-tools/src/tools/WebSearchTool/__tests__/braveAdapter*.test.ts`, `packages/builtin-tools/src/tools/WebSearchTool/__tests__/adapterFactory.test.ts` | Bing / Brave 解析与工厂逻辑测试 |
| 集成测试 | `packages/builtin-tools/src/tools/WebSearchTool/__tests__/bingAdapter.integration.ts`, `packages/builtin-tools/src/tools/WebSearchTool/__tests__/braveAdapter.integration.ts` | 真实网络请求验证 |
### 2.3 数据流
@@ -176,13 +176,13 @@ interface SearchProgress {
| 文件 | 职责 |
|------|------|
| `src/tools/WebSearchTool/WebSearchTool.ts` | 工具定义入口 |
| `src/tools/WebSearchTool/prompt.ts` | 搜索工具 prompt |
| `src/tools/WebSearchTool/UI.tsx` | 终端 UI 渲染 |
| `src/tools/WebSearchTool/adapters/types.ts` | 适配器接口 |
| `src/tools/WebSearchTool/adapters/index.ts` | 适配器工厂 |
| `src/tools/WebSearchTool/adapters/apiAdapter.ts` | API 服务端搜索适配器 |
| `src/tools/WebSearchTool/adapters/bingAdapter.ts` | Bing HTML 解析适配器 |
| `src/tools/WebSearchTool/__tests__/bingAdapter.test.ts` | 单元测试 (32 cases) |
| `src/tools/WebSearchTool/__tests__/bingAdapter.integration.ts` | 集成测试 |
| `packages/builtin-tools/src/tools/WebSearchTool/WebSearchTool.ts` | 工具定义入口 |
| `packages/builtin-tools/src/tools/WebSearchTool/prompt.ts` | 搜索工具 prompt |
| `packages/builtin-tools/src/tools/WebSearchTool/UI.tsx` | 终端 UI 渲染 |
| `packages/builtin-tools/src/tools/WebSearchTool/adapters/types.ts` | 适配器接口 |
| `packages/builtin-tools/src/tools/WebSearchTool/adapters/index.ts` | 适配器工厂 |
| `packages/builtin-tools/src/tools/WebSearchTool/adapters/apiAdapter.ts` | API 服务端搜索适配器 |
| `packages/builtin-tools/src/tools/WebSearchTool/adapters/bingAdapter.ts` | Bing HTML 解析适配器 |
| `packages/builtin-tools/src/tools/WebSearchTool/__tests__/bingAdapter.test.ts` | 单元测试 (32 cases) |
| `packages/builtin-tools/src/tools/WebSearchTool/__tests__/bingAdapter.integration.ts` | 集成测试 |
| `src/tools.ts` | 工具注册 |

View File

@@ -14,17 +14,17 @@ WORKFLOW_SCRIPTS 实现基于文件的多步自动化工作流。用户可以定
| 模块 | 文件 | 状态 |
|------|------|------|
| WorkflowTool | `src/tools/WorkflowTool/WorkflowTool.ts` | **Stub**空对象 |
| Workflow 权限 | `src/tools/WorkflowTool/WorkflowPermissionRequest.ts` | **Stub**返回 null |
| 常量 | `src/tools/WorkflowTool/constants.ts` | **Stub**工具名 |
| 命令创建 | `src/tools/WorkflowTool/createWorkflowCommand.ts` | **Stub**空操作 |
| 捆绑工作流 | `src/tools/WorkflowTool/bundled/` | **缺失**目录不存在 |
| WorkflowTool | `packages/builtin-tools/src/tools/WorkflowTool/WorkflowTool.ts` | **部分实现**tool schema + 渲染完整call 返回运行时缺失提示 |
| Workflow 权限 | `packages/builtin-tools/src/tools/WorkflowTool/WorkflowPermissionRequest.tsx` | **部分实现**权限请求组件 |
| 常量 | `packages/builtin-tools/src/tools/WorkflowTool/constants.ts` | **实现** — 工具名 + 目录名 + 文件扩展名常量 |
| 命令创建 | `packages/builtin-tools/src/tools/WorkflowTool/createWorkflowCommand.ts` | **实现**扫描 .claude/workflows/ 目录创建 Command 对象 |
| 捆绑工作流 | `packages/builtin-tools/src/tools/WorkflowTool/bundled/index.ts` | **实现**内置工作流初始化 |
| 本地工作流任务 | `src/tasks/LocalWorkflowTask/LocalWorkflowTask.ts` | **Stub** — 类型 + 空操作 |
| UI 任务组件 | `src/components/tasks/src/tasks/LocalWorkflowTask/` | **Stub** — 空导出 |
| 详情对话框 | `src/components/tasks/WorkflowDetailDialog.ts` | **Stub** — 返回 null |
| 任务注册 | `src/tasks.ts` | **布线** — 动态加载 |
| 工具注册 | `src/tools.ts` | **布线**包含 bundled 工作流初始化 |
| 命令注册 | `src/commands.ts` | **布线**`/workflows` 命令 |
| 工具注册 | `src/tools.ts` | **布线**动态加载 + bundled 工作流初始化 (行 131-134,235) |
| 命令注册 | `src/commands.ts` | **布线**`/workflows` 命令 (行 93-95,395,460) |
### 2.2 预期数据流
@@ -69,13 +69,9 @@ steps:
| 优先级 | 模块 | 工作量 | 说明 |
|--------|------|--------|------|
| 1 | `WorkflowTool.ts` | 大 | Schema 定义 + 多步执行引擎 |
| 2 | `bundled/index.js` | | 内置工作流定义initBundledWorkflows |
| 3 | `createWorkflowCommand.ts` | 中 | 从文件解析创建命令对象 |
| 4 | `LocalWorkflowTask.ts` | 大 | 步骤协调、kill/skip/retry |
| 5 | `WorkflowDetailDialog.ts` | 中 | 进度详情 UI |
| 6 | `WorkflowPermissionRequest.ts` | 小 | 权限对话框 |
| 7 | `constants.ts` | 小 | 工具名常量 |
| 1 | `WorkflowTool.ts` call 方法 | 中 | 实际工作流执行逻辑(当前返回运行时缺失提示) |
| 2 | `LocalWorkflowTask.ts` | | 步骤协调、kill/skip/retry |
| 3 | `WorkflowDetailDialog.ts` | 中 | 进度详情 UI |
## 四、关键设计决策
@@ -95,11 +91,12 @@ FEATURE_WORKFLOW_SCRIPTS=1 bun run dev
| 文件 | 职责 |
|------|------|
| `src/tools/WorkflowTool/WorkflowTool.ts` | 工具定义(stub |
| `src/tools/WorkflowTool/WorkflowPermissionRequest.ts` | 权限对话框stub |
| `src/tools/WorkflowTool/constants.ts` | 常量stub |
| `src/tools/WorkflowTool/createWorkflowCommand.ts` | 命令创建(stub |
| `packages/builtin-tools/src/tools/WorkflowTool/WorkflowTool.ts` | 工具定义(部分实现 |
| `packages/builtin-tools/src/tools/WorkflowTool/WorkflowPermissionRequest.tsx` | 权限请求组件 |
| `packages/builtin-tools/src/tools/WorkflowTool/constants.ts` | 常量定义 |
| `packages/builtin-tools/src/tools/WorkflowTool/createWorkflowCommand.ts` | 命令创建(已实现 |
| `packages/builtin-tools/src/tools/WorkflowTool/bundled/index.ts` | 内置工作流初始化 |
| `src/tasks/LocalWorkflowTask/LocalWorkflowTask.ts` | 任务协调stub |
| `src/components/tasks/WorkflowDetailDialog.ts` | 详情对话框stub |
| `src/tools.ts:127-132` | 工具注册 |
| `src/commands.ts:86-89` | 命令注册 |
| `src/tools.ts:131-134,235` | 工具注册 |
| `src/commands.ts:93-95,395,460` | 命令注册 |

View File

@@ -17,7 +17,7 @@ keywords: ["Ant 特权", "USER_TYPE", "身份门控", "内部功能", "Anthropic
`BUILD_TARGET` 等构建时常量在反编译版本中已被移除。`USER_TYPE` 通过 Bun 的 `--define` 或环境变量注入Bun 会进行**常量折叠**——所有 `process.env.USER_TYPE === 'ant'` 在外部构建中直接变为 `false`,后续代码被 DCE 移除。但在反编译版本中,这些代码保留完整。
`USER_TYPE === 'ant'` 在代码库中出现 **377+ 次**含 `=== 'ant'` 291 次、`(process.env.USER_TYPE) === 'ant'` 86 次),另有 `!== 'ant'` 53、其他引用约 35 次,总计 **465 处引用**控制着工具、命令、API、UI 等方方面面。
`USER_TYPE === 'ant'` 在代码库中出现 **351+ 次**跨 163 个文件),另有 `!== 'ant'` 59(跨 38 个文件),总计 **410+ 处引用**控制着工具、命令、API、UI 等方方面面。
## Ant-Only 工具
@@ -25,10 +25,10 @@ keywords: ["Ant 特权", "USER_TYPE", "身份门控", "内部功能", "Anthropic
| 工具 | 代码位置 | 用途 |
|------|---------|------|
| **REPLTool** | `src/tools/REPLTool/` | 高级 REPL 模式——在 VM 中包装 Bash/Read/Edit/Glob/Grep/Agent 等工具 |
| **SuggestBackgroundPRTool** | `src/tools/SuggestBackgroundPRTool/` | 建议在后台创建 PR |
| **ConfigTool** | `src/tools/ConfigTool/` | 交互式配置编辑器,包含 Gates 标签页用于覆盖 GrowthBook flags |
| **TungstenTool** | `src/tools/TungstenTool/` | 基于 tmux 的终端面板工具(反编译版中已 stub |
| **REPLTool** | `packages/builtin-tools/src/tools/REPLTool/` | 高级 REPL 模式——在 VM 中包装 Bash/Read/Edit/Glob/Grep/Agent 等工具 |
| **SuggestBackgroundPRTool** | `packages/builtin-tools/src/tools/SuggestBackgroundPRTool/` | 建议在后台创建 PR |
| **ConfigTool** | `packages/builtin-tools/src/tools/ConfigTool/` | 交互式配置编辑器,包含 Gates 标签页用于覆盖 GrowthBook flags |
| **TungstenTool** | `packages/builtin-tools/src/tools/TungstenTool/` | 基于 tmux 的终端面板工具(反编译版中已 stub |
```typescript
// src/tools.ts 第 14-24 行——条件导入 + Dead Code Elimination 标记
@@ -36,18 +36,18 @@ keywords: ["Ant 特权", "USER_TYPE", "身份门控", "内部功能", "Anthropic
/* eslint-disable custom-rules/no-process-env-top-level, @typescript-eslint/no-require-imports */
const REPLTool =
process.env.USER_TYPE === 'ant'
? require('./tools/REPLTool/REPLTool.js').REPLTool
? require('@claude-code-best/builtin-tools/tools/REPLTool/REPLTool.js').REPLTool
: null
const SuggestBackgroundPRTool =
process.env.USER_TYPE === 'ant'
? require('./tools/SuggestBackgroundPRTool/SuggestBackgroundPRTool.js')
? require('@claude-code-best/builtin-tools/tools/SuggestBackgroundPRTool/SuggestBackgroundPRTool.js')
.SuggestBackgroundPRTool
: null
```
## Ant-Only 命令
`src/commands.ts` 注册了 **28** 个仅在内部构建中可用的斜杠命令(`INTERNAL_ONLY_COMMANDS`lines 225-254),在 `USER_TYPE === 'ant' && !IS_DEMO` 时才加载line 343-345
`src/commands.ts` 注册了 **24+** 个仅在内部构建中可用的斜杠命令(`INTERNAL_ONLY_COMMANDS`lines 267-295),在 `USER_TYPE === 'ant' && !IS_DEMO` 时才加载line 400-401
<AccordionGroup>
<Accordion title="调试类">
@@ -74,7 +74,7 @@ const SuggestBackgroundPRTool =
- `summary` — 生成摘要
- `subscribePr` — 订阅 PR需要 `KAIROS_GITHUB_WEBHOOKS` feature flag
- `forceSnip` — 强制截断历史(需要 `HISTORY_SNIP` feature flag
- `ultraplan` — 超级规划(需要 `ULTRAPLAN` feature flag
- `ultraplan` — 超级规划(需要 `ULTRAPLAN` feature flag,单独注册于 `commands.ts:396`
</Accordion>
<Accordion title="基础设施类">
- `backfillSessions` — 回填会话数据

View File

@@ -15,17 +15,19 @@ Claude Code 使用 Bun 打包器的 `bun:bundle` 模块提供编译时特性门
import { feature } from 'bun:bundle'
const SleepTool = feature('PROACTIVE') || feature('KAIROS')
? require('./tools/SleepTool/SleepTool.js').SleepTool
? require('@claude-code-best/builtin-tools/tools/SleepTool/SleepTool.js').SleepTool
: null
```
在 Anthropic 的内部构建中,`feature()` 在打包时被求值——返回 `true` 的代码会被保留,返回 `false` 的代码会被 **Dead Code Elimination (DCE)** 彻底移除。
在我们的反编译版本中,这个函数被兜底为
在我们的反编译版本中,`feature` 从 `bun:bundle` 导入(声明在 `src/types/internal-modules.d.ts`),在运行时始终返回 `false`
```typescript
// src/entrypoints/cli.tsx 第 3 行
const feature = (_name: string) => false;
// src/types/internal-modules.d.ts
declare module 'bun:bundle' {
export function feature(name: string): boolean;
}
```
这意味着所有 88+ 个 feature flag 后的代码**在运行时永远不会执行**,但代码本身完整保留,可以阅读和分析。
@@ -79,7 +81,7 @@ Feature flags 在代码中主要有三种使用模式:
```typescript
// src/tools.ts — 最常见的模式
const MonitorTool = feature('MONITOR_TOOL')
? require('./tools/MonitorTool/MonitorTool.js').MonitorTool
? require('@claude-code-best/builtin-tools/tools/MonitorTool/MonitorTool.js').MonitorTool
: null
```

View File

@@ -19,7 +19,7 @@ keywords: ["GrowthBook", "A/B 测试", "运行时门控", "tengu", "渐进式发
## 集成架构
GrowthBook 的完整实现位于 `src/services/analytics/growthbook.ts`1156 行),工作流程如下:
GrowthBook 的完整实现位于 `src/services/analytics/growthbook.ts`1258 行),工作流程如下:
<Steps>
<Step title="启动时获取远程配置">

View File

@@ -84,7 +84,7 @@ keywords: ["隐藏功能", "未公开功能", "秘密功能", "Claude Code 彩
<Accordion title="VOICE_MODE语音交互">
**门控**: `feature('VOICE_MODE')`
代码中存在语音输入模式的注册点,核心实现依赖 `audio-napi` 包(在反编译版本中已 stub
代码中存在语音输入模式的注册点,核心实现依赖 `audio-capture-napi` 包(已恢复
- 通过 `/voice` 命令激活
- "按住说话"hold-to-talk交互模式

View File

@@ -64,24 +64,27 @@ Claude Code 从上到下分为五个层次,每一层职责清晰、边界分
needsFollowUp ? continue : return { reason }
```
完整的状态机通过 `State` 类型(`src/query.ts:204`)在迭代间传递,包含 10 个字段messages、autoCompactTracking、maxOutputTokensRecoveryCount 等)。
完整的状态机通过 `State` 类型(`src/query.ts:207`)在迭代间传递,包含 10 个字段messages、autoCompactTracking、maxOutputTokensRecoveryCount 等)。
### 4. 工具层(`src/tools.ts` → `src/Tool.ts`
`getAllBaseTools()``src/tools.ts:191`)组装 50+ 工具列表,经过 `filterToolsByDenyRules()` 权限过滤后传给 API。
`getAllBaseTools()``src/tools.ts:195`)组装 50+ 工具列表,经过 `filterToolsByDenyRules()` 权限过滤后传给 API。
每个工具实现 `Tool<Input, Output, Progress>` 接口(`src/Tool.ts:362`),核心方法链:
每个工具实现 `Tool<Input, Output, Progress>` 接口(`src/Tool.ts:368`),核心方法链:
```
validateInput() → canUseTool()UI 层)→ checkPermissions() → call() → ToolResult
```
### 5. 通信层(`src/services/api/claude.ts`
API 客户端支持 4 种 Provider
- **Anthropic Direct**:默认
API 客户端支持 7 种 Provider
- **Anthropic Direct (firstParty)**:默认
- **AWS Bedrock**`ANTHROPIC_BEDROCK_BASE_URL`
- **Google Vertex**`ANTHROPIC_VERTEX_PROJECT_ID`
- **Azure**:通过自定义 base URL
- **Foundry**`ANTHROPIC_CODE_USE_FOUNDRY`
- **OpenAI**:兼容层
- **Gemini**:兼容层
- **Grok (xAI)**:兼容层
`deps.callModel()` 发起流式请求,返回 `BetaRawMessageStreamEvent` 事件流。支持 Prompt Cache`cache_control`、thinking blocks、multi-turn tool use。

View File

@@ -53,7 +53,7 @@ Claude Code 是一个**运行在本地终端中的 agentic coding system**。它
│ 实际执行: 读文件、运行命令、搜索代码... │
├─────────────────────────────────────────────────────────┤
│ 6. 通信层 (claude.ts → Anthropic API) │
│ 流式 HTTP, 支持 Bedrock/Vertex/Azure 多 provider │
│ 流式 HTTP, 支持 Bedrock/Vertex/Foundry 等 7 种 provider │
└─────────────────────────────────────────────────────────┘
```

View File

@@ -49,7 +49,7 @@ AI 没有真正的"记忆"Claude Code 通过精心分层营造了这个幻觉
### 3. 工具系统的权限双轨制
`src/tools/BashTool/shouldUseSandbox.ts` 展示了一个精巧的双重安全模型:
`packages/builtin-tools/src/tools/BashTool/shouldUseSandbox.ts` 展示了一个精巧的双重安全模型:
- **应用层**:权限规则决定"能不能执行"(白名单/黑名单/用户确认)
- **OS 层**:沙箱决定"执行时能做什么"(文件系统/网络/进程隔离)

View File

@@ -65,7 +65,7 @@ ENABLE_LSP_TOOL=1 bun run dev
```
┌─────────────────────────────────────────────────────┐
│ LSP Tool │
│ src/tools/LSPTool/LSPTool.ts
packages/builtin-tools/src/tools/LSPTool/LSPTool.ts│
│ (Claude 可调用的工具9 种操作) │
└──────────────────────┬──────────────────────────────┘
@@ -128,10 +128,10 @@ LSP 服务器会异步推送 `textDocument/publishDiagnostics` 通知,经去
| `src/services/lsp/config.ts` | 从插件加载 LSP 服务器配置 |
| `src/services/lsp/LSPDiagnosticRegistry.ts` | 诊断信息注册、去重、容量限制 |
| `src/services/lsp/passiveFeedback.ts` | 注册 `publishDiagnostics` 通知处理器 |
| `src/tools/LSPTool/LSPTool.ts` | LSP Tool 实现(暴露给 Claude |
| `src/tools/LSPTool/schemas.ts` | 输入 schema9 种操作的 discriminated union |
| `src/tools/LSPTool/formatters.ts` | 各操作结果的格式化 |
| `src/tools/LSPTool/prompt.ts` | Tool 描述文本 |
| `packages/builtin-tools/src/tools/LSPTool/LSPTool.ts` | LSP Tool 实现(暴露给 Claude |
| `packages/builtin-tools/src/tools/LSPTool/schemas.ts` | 输入 schema9 种操作的 discriminated union |
| `packages/builtin-tools/src/tools/LSPTool/formatters.ts` | 各操作结果的格式化 |
| `packages/builtin-tools/src/tools/LSPTool/prompt.ts` | Tool 描述文本 |
| `src/utils/plugins/lspPluginIntegration.ts` | 从插件加载、验证、环境变量解析、作用域管理 |
## LSP Tool 支持的操作
@@ -200,9 +200,9 @@ LSP 服务器通过插件提供。插件的 `manifest.json` 中可以声明 LSP
|------|------|------|------|
| `command` | string | 是 | LSP 服务器可执行命令(不含空格) |
| `args` | string[] | 否 | 命令行参数 |
| `extensionToLanguage` | Record<string, string> | 是 | 文件扩展名到语言 ID 的映射(至少一个) |
| `extensionToLanguage` | `Record<string, string>` | 是 | 文件扩展名到语言 ID 的映射(至少一个) |
| `transport` | `"stdio"` \| `"socket"` | 否 | 通信方式,默认 `stdio` |
| `env` | Record<string, string> | 否 | 启动服务器时设置的环境变量 |
| `env` | `Record<string, string>` | 否 | 启动服务器时设置的环境变量 |
| `initializationOptions` | unknown | 否 | 传给服务器的初始化选项 |
| `settings` | unknown | 否 | 通过 `workspace/didChangeConfiguration` 传递的设置 |
| `workspaceFolder` | string | 否 | 工作区目录路径 |

View File

@@ -137,7 +137,7 @@ Auto mode 可通过以下方式激活:
### 进入时Full Instructions
注入到对话中的指令(`messages.ts:3464`
注入到对话中的指令(`messages.ts:3481`
> Auto mode is active. The user chose continuous, autonomous execution. You should:
>

View File

@@ -18,17 +18,19 @@ keywords: ["权限模型", "Allow Ask Deny", "PermissionRule", "checkPermissions
这些行为由 `PermissionResult` 类型定义(`src/utils/permissions/PermissionResult.ts`)。
## 权限规则的五层来源
## 权限规则的来源
规则从 5 个来源汇聚(`PERMISSION_RULE_SOURCES``permissions.ts:109`),优先级从高到低:
规则从 8 个来源汇聚(`PERMISSION_RULE_SOURCES``permissions.ts:109`),优先级从低到高(后者覆盖前者)
```
1. session — 用户在当前对话中手动授权("Always allow"
2. cliArg — 命令行 --allow/--deny 参数
3. command — Skill 工具的 allowedTools 白名单
4. projectSettings — .claude/settings.json团队共享
5. userSettings — ~/.claude/settings.json跨项目
6. policySettings — 企业管理员下发的策略(用户不可覆盖)
1. userSettings — ~/.claude/settings.json跨项目
2. projectSettings — .claude/settings.json团队共享
3. localSettings — .claude/settings.local.jsongitignored个人覆盖
4. flagSettings — --settings 命令行参数
5. policySettings — 企业管理员下发的策略(用户不可覆盖
6. cliArg — 命令行 --allow/--deny 参数
7. command — Skill 工具的 allowedTools 白名单
8. session — 用户在当前对话中手动授权("Always allow"
```
每个来源维护三个数组:`alwaysAllowRules[source]`、`alwaysAskRules[source]`、`alwaysDenyRules[source]`。
@@ -65,7 +67,7 @@ MCP 工具使用 `getToolNameForPermissionCheck()` 获取匹配名称,支持
**2. 命令模式匹配**BashTool 的 `checkPermissions()`
BashTool 通过 `preparePermissionMatcher()``Tool.ts:514`)解析命令模式:
BashTool 通过 `preparePermissionMatcher()``Tool.ts:520`)解析命令模式:
```json
{"tool": "Bash", "ruleContent": "git *"} → 匹配 "git commit -m 'fix'"
```
@@ -120,7 +122,9 @@ Read/Edit/Write 工具通过 `getPath()` 提取文件路径,与 `ruleContent`
|------|---------------------|---------|------|
| **Default** | `'default'` | 日常使用 | 敏感操作逐一确认 |
| **Plan Mode** | `'plan'` | 探索阶段 | 只能读不能写(`isReadOnly()` 检查) |
| **Auto** | `'auto'` | 信任 AI | 通过 transcript classifier 自动决策 |
| **Accept Edits** | `'acceptEdits'` | 快速迭代 | 工作区内文件编辑自动放行,其他操作仍需确认 |
| **Don't Ask** | `'dontAsk'` | 减少打断 | 尽量自动决策,减少确认弹窗 |
| **Auto** | `'auto'` | 信任 AI | 通过 transcript classifier 自动决策(需 `TRANSCRIPT_CLASSIFIER` feature flag |
| **Bypass** | `'bypassPermissions'` | 完全信任 | 所有操作自动放行(需显式 `--dangerously-skip-permissions` |
Plan Mode 切换由 `EnterPlanModeTool.call()` 触发:
@@ -143,8 +147,8 @@ context.setAppState(prev => ({
```typescript
const DENIAL_LIMITS = {
maxDenialsPerTool: 3, // 同一工具连续拒绝上限
cooldownPeriodMs: 30_000, // 冷却期 30 秒
maxConsecutive: 3, // 同一工具连续拒绝上限
maxTotal: 20, // 总拒绝上限
}
```
@@ -162,9 +166,12 @@ const DENIAL_LIMITS = {
```typescript
type PermissionUpdate =
| { type: 'addRule', behavior, rule, destination }
| { type: 'removeRule', behavior, rule, destination }
| { type: 'setMode', mode, destination }
| { type: 'addRules', destination, rules, behavior }
| { type: 'replaceRules', destination, rules, behavior }
| { type: 'removeRules', destination, rules, behavior }
| { type: 'setMode', destination, mode }
| { type: 'addDirectories', destination, directories }
| { type: 'removeDirectories', destination, directories }
```
当用户在 Ask 对话框中选择 "Always allow",系统调用 `persistPermissionUpdates()` 将规则写入对应层级的 settings 文件project/user/managed同时更新内存中的 `toolPermissionContext`。

View File

@@ -16,13 +16,13 @@ keywords: ["Plan Mode", "计划模式", "EnterPlanMode", "ExitPlanMode", "prepar
<Steps>
<Step title="EnterPlanMode — 进入计划模式">
AI 自主判断(或用户触发)任务需要规划,调用 `EnterPlanModeTool``src/tools/EnterPlanModeTool/EnterPlanModeTool.ts:36`)。该工具需要**用户审批**`checkPermissions` 返回 `ask`)。
AI 自主判断(或用户触发)任务需要规划,调用 `EnterPlanModeTool``packages/builtin-tools/src/tools/EnterPlanModeTool/EnterPlanModeTool.ts:36`)。该工具需要**用户审批**`checkPermissions` 返回 `ask`)。
</Step>
<Step title="探索阶段 — 只读工具集">
权限模式切换为 `'plan'`AI 只能使用 `isReadOnly()` 为 true 的工具Read、Grep、Glob、Agent 等)。写操作被自动拒绝。
</Step>
<Step title="ExitPlanMode — 提交方案审批">
AI 完成探索后,调用 `ExitPlanModeV2Tool``src/tools/ExitPlanModeTool/ExitPlanModeV2Tool.ts:147`),将计划文件提交给用户审阅。这是第二个**需要用户审批**的节点。
AI 完成探索后,调用 `ExitPlanModeV2Tool``packages/builtin-tools/src/tools/ExitPlanModeTool/ExitPlanModeV2Tool.ts:147`),将计划文件提交给用户审阅。这是第二个**需要用户审批**的节点。
</Step>
<Step title="恢复执行 — 全部工具权限">
用户批准后权限模式恢复为进入前的状态AI 按计划执行。
@@ -107,7 +107,7 @@ if (isTeammate()) {
## 什么时候该用计划模式
`EnterPlanModeTool` 的 Prompt`src/tools/EnterPlanModeTool/prompt.ts`)定义了两套触发标准——外部版本更积极(鼓励规划),内部版本更克制(仅在真正模糊时使用):
`EnterPlanModeTool` 的 Prompt`packages/builtin-tools/src/tools/EnterPlanModeTool/prompt.ts`)定义了两套触发标准——外部版本更积极(鼓励规划),内部版本更克制(仅在真正模糊时使用):
| 场景 | 外部版本 | 内部版本 |
|------|---------|---------|

View File

@@ -166,7 +166,7 @@ keywords: ["沙箱", "sandbox", "权限", "Bash", "PowerShell", "bubblewrap", "s
5. 这条命令没有被显式排除
6. 这次调用没有被允许以 `dangerouslyDisableSandbox` 绕过
对应入口在 `src/tools/BashTool/shouldUseSandbox.ts` 和 `src/utils/sandbox/sandbox-adapter.ts`。
对应入口在 `packages/builtin-tools/src/tools/BashTool/shouldUseSandbox.ts` 和 `src/utils/sandbox/sandbox-adapter.ts`。
### 3. PowerShell 只在支持平台上走
@@ -518,11 +518,11 @@ REPL / CLI 启动
如果你想继续顺着源码深入,推荐按下面顺序看:
1. `src/tools/BashTool/shouldUseSandbox.ts`
1. `packages/builtin-tools/src/tools/BashTool/shouldUseSandbox.ts`
2. `src/utils/Shell.ts`
3. `src/utils/sandbox/sandbox-adapter.ts`
4. `src/utils/permissions/permissions.ts`
5. `src/tools/BashTool/bashPermissions.ts`
5. `packages/builtin-tools/src/tools/BashTool/bashPermissions.ts`
6. `src/utils/permissions/pathValidation.ts`
7. `src/utils/permissions/filesystem.ts`

View File

@@ -61,7 +61,7 @@ Claude 的 System Prompt 中包含安全指令——这是"软性"约束,依
| `deny` | 直接拒绝 | 匹配 deny 规则 |
| `ask` | 弹窗确认 | 未匹配任何规则 或 匹配 ask 规则 |
以 BashTool 为例(`src/tools/BashTool/bashPermissions.ts``bashToolHasPermission()` 执行了极其细致的检查链:
以 BashTool 为例(`packages/builtin-tools/src/tools/BashTool/bashPermissions.ts``bashToolHasPermission()` 执行了极其细致的检查链:
1. **AST 安全解析**:用 tree-sitter 解析 bash AST检测命令注入`$()`、反引号等)
2. **语义检查**:识别危险命令(`eval`、`exec`、`source` 等)
@@ -169,7 +169,7 @@ Bash("rm -rf node_modules") → ⚠️ 需确认(不可逆)
攻击cd /malicious/dir && git status
/malicious/dir 包含 bare repo + 恶意钩子
防御bashToolHasPermission() 检测 cd + git 组合
强制 require approvalsrc/tools/BashTool/bashPermissions.ts:2209
强制 require approvalpackages/builtin-tools/src/tools/BashTool/bashPermissions.ts:2209
```
### 场景3管道注入
@@ -178,5 +178,5 @@ Bash("rm -rf node_modules") → ⚠️ 需确认(不可逆)
攻击echo 'x' | xargs printf '%s' >> /etc/passwd
splitCommand 会剥离重定向,导致路径检查遗漏
防御:即使管道段独立检查通过,仍对原始命令重新验证路径约束
检查重定向目标中的危险模式(反引号、$()bashPermissions.ts:1992-2056
检查重定向目标中的危险模式(反引号、$()packages/builtin-tools/src/tools/BashTool/bashPermissions.ts:1992-2056
```

View File

@@ -0,0 +1,77 @@
# Task 001: daemon status / stop
> 来源: [stub-recovery-design-1-4.md](../features/stub-recovery-design-1-4.md) 第 1 项
> 优先级: P0 (首选实现项)
> 工作量: 小
> 状态: DONE
## 目标
`claude daemon status``claude daemon stop` 在任意 CLI 进程中都能正确工作,不依赖 TUI 内存态。
## 背景
- `start` 路径已有完整 supervisor + worker 生命周期 (`src/daemon/main.ts`, `src/daemon/workerRegistry.ts`)
- `status` / `stop` 目前只是占位输出 (`src/daemon/main.ts:49`)
- `/remote-control-server` 有自己的命令内 UI 状态,但只维护当前进程内的 `daemonProcess`,不适合跨进程管理
## 实现方案
### 新增文件
| 文件 | 说明 |
|------|------|
| `src/daemon/state.ts` | daemon 状态文件读写模块 |
### 修改文件
| 文件 | 改动 |
|------|------|
| `src/daemon/main.ts` | `start` 写入状态文件;`status`/`stop` 调用 state 模块 |
| `src/commands/remoteControlServer/remoteControlServer.tsx` | 读取同一份状态文件(轻量改动) |
### 状态文件
路径: `~/.claude/daemon/remote-control.json`
```json
{
"pid": 12345,
"cwd": "/path/to/project",
"startedAt": "2026-04-12T10:00:00Z",
"workerKinds": ["bridge", "rcs"],
"lastStatus": "running"
}
```
### status 逻辑
1. 读取状态文件
2. 用进程探测验证 pid 是否存活
3. 输出 `running` / `stopped` / `stale`
4. stale 时自动清理状态文件
### stop 逻辑
1. 读取 pid
2. 发送 `SIGTERM`
3. 等待退出(超时兜底)
4. 超时后 `SIGKILL`
5. 清理状态文件
## 验证步骤
- [ ] `claude daemon start` 正常启动并写入状态文件
- [ ] 新开终端执行 `claude daemon status`,显示 `running`
- [ ] 执行 `claude daemon stop`daemon 正常退出
- [ ] 再次执行 `claude daemon status`,返回 `stopped``stale cleaned`
- [ ] Windows 下 stop 超时兜底正常工作
## 风险
- Windows 信号模型和 Unix 不同,`stop` 需要超时兜底
- 当前设计默认单 supervisor不处理多实例并发
## 依赖
无外部依赖,可独立实施。

View File

@@ -0,0 +1,80 @@
# Task 002: BG_SESSIONS — ps / logs / kill
> 来源: [stub-recovery-design-1-4.md](../features/stub-recovery-design-1-4.md) 第 2 项
> 优先级: P1
> 工作量: 中等
> 状态: DONE
> 阶段: Phase 2A (MVP)
## 目标
`ps` / `logs` / `kill` 做成真正有用的 session 管理命令。不在第一阶段补完 `attach` / `--bg`
## 背景
- fast-path 已接好 (`src/entrypoints/cli.tsx:218`)
- session registry 已有真实实现 (`src/utils/concurrentSessions.ts`)
- `exit` 在 bg session 内已会 `tmux detach-client` (`src/commands/exit/exit.tsx:20`)
- CLI handler 仍全空 (`src/cli/bg.ts`)
- task summary 仍然是 stub (`src/utils/taskSummary.ts`)
## 实现方案
### 修改文件
| 文件 | 改动 |
|------|------|
| `src/cli/bg.ts` | 实现 `ps` / `logs` / `kill` handler |
| `src/utils/concurrentSessions.ts` | 扩展以便后续 attach/--bg 使用 |
| `src/utils/taskSummary.ts` | 补充基础实现 |
### 复用模块
- `src/utils/sessionStorage.ts` — session 存储
- `src/utils/udsClient.ts` — UDS 通信
### ps 命令
- 从 registry 读取 live sessions
- 展示: pid, kind, sessionId, cwd, name, startedAt, bridgeSessionId
- 如果有 activity/status一并展示
### logs 命令
- 支持按 `sessionId` / `pid` / `name` 查找
- 优先复用本地 transcript/log 读取能力
- 如果 registry 里存在 `logPath`,支持 tail 文件
### kill 命令
- 解析目标 session
- 发退出信号
- 清理 stale registry
## 验证步骤
- [ ] `ps` 能列出当前 live sessions
- [ ] `logs <sessionId|pid|name>` 能输出对应日志
- [ ] `kill <sessionId|pid|name>` 能结束目标 session 并清理 registry
- [ ] 无 live session 时各命令有明确提示
## Phase 2B (后续)
- [ ] 实现 `attach`
- [ ] 实现 `--bg`
- [ ] 实现 `taskSummary` 的中途状态更新
### 为什么拆分
- 现有 registry 记录了 `pid / sessionId / name / logPath`
- 但没有可靠的 tmux attach target
- `attach``--bg` 需要补启动/附着元数据设计,不是简单补 handler
## 风险
- `attach` / `--bg` 第二阶段需要 tmux 元数据设计
- Windows 下 tmux 路径需要明确降级策略
## 依赖
- Task 001 (daemon 状态管理可复用模式,但非硬性依赖)

View File

@@ -0,0 +1,87 @@
# Task 003: TEMPLATES — job 文件系统 MVP
> 来源: [stub-recovery-design-1-4.md](../features/stub-recovery-design-1-4.md) 第 3 项
> 优先级: P2
> 工作量: 中等
> 状态: DONE
> 阶段: MVP
## 目标
`new` / `list` / `reply` 做成可用的模板任务系统。第一阶段不碰复杂的自动分类与自动执行。
## 背景
- 命令入口只有 fast-path (`src/entrypoints/cli.tsx:272`)
- handler 是空的 (`src/cli/handlers/templateJobs.ts`)
- `markdownConfigLoader` 已把 `templates` 纳入配置目录 (`src/utils/markdownConfigLoader.ts:35`)
- `query/stopHooks` 已预留 job classifier 链路 (`src/query/stopHooks.ts:103`)
- `jobs/classifier.ts` 仍是 stub (`src/jobs/classifier.ts`)
## 实现方案
### 新增文件
| 文件 | 说明 |
|------|------|
| `src/jobs/state.ts` | job 状态管理 |
| `src/jobs/templates.ts` | 模板解析与列表 |
### 修改文件
| 文件 | 改动 |
|------|------|
| `src/cli/handlers/templateJobs.ts` | 实现 `new` / `list` / `reply` handler |
### 模板来源
`.claude/templates/*.md`
### 模板格式
复用现有 markdown + frontmatter 解析,不另外设计 DSL。
### list 命令
- 列出所有模板
- 显示: 模板名, description, 路径
### new 命令
- 解析模板
-`~/.claude/jobs/<job-id>/` 下创建 job 目录
- 写入 `template.md`, `input.txt`, `state.json`
- 返回 job id 与目录路径
### reply 命令
- 将回复写入 `replies.jsonl``input.txt`
- 更新 `state.json`
## 验证步骤
- [ ] `list` 能列出 `.claude/templates` 下的所有模板
- [ ] `new <template> [args...]` 能创建 job 目录和状态文件
- [ ] `reply <job-id> <text>` 能更新 job 内容和状态
- [ ] frontmatter schema 最小字段集已定义
## Phase 2 (后续)
- [ ] 恢复 `src/jobs/classifier.ts`
- [ ] 让带 `CLAUDE_JOB_DIR` 的 job session 在 turn 完成后自动更新 `state.json`
- [ ] 再决定是否补自动 job runner
### 为什么拆分
- 当前是 "template job commands",不是单纯模板列表
- 自动 job 运行链路没有足够现成实现
- 先做文件系统 job lifecycle 更稳
## 风险
- frontmatter schema 需要先定义最小字段集
- 一旦扩展到"自动运行 job",范围会明显膨胀
## 依赖
无硬性依赖,可独立实施。

View File

@@ -0,0 +1,103 @@
# Task 004: assistant [sessionId] — 分阶段恢复
> 来源: [stub-recovery-design-1-4.md](../features/stub-recovery-design-1-4.md) 第 4 项
> 优先级: P3
> 工作量: Phase 4A 中等4A-4D 全做完很大
> 状态: Phase 4A DONE, 4B-4D TODO
## 目标
不一次性恢复整个 KAIROS 助手系统。先做"明确 sessionId 的 viewer attach 可用",再逐步补 discovery / chooser / install。
## 背景
- attach 主流程已存在 (`src/main.tsx:4708`)
- 远端 viewer 所需基础模块已存在:
- `src/remote/RemoteSessionManager.ts`
- `src/hooks/useAssistantHistory.ts`
- `src/assistant/sessionHistory.ts`
- 真正 stub 的主要是:
- `src/assistant/sessionDiscovery.ts`
- `src/assistant/AssistantSessionChooser.tsx`
- `src/commands/assistant/assistant.tsx:7`
- `src/assistant/index.ts`
## 分阶段实现
### Phase 4A: MVP — 显式 sessionId attach
**修改文件:**
| 文件 | 改动 |
|------|------|
| `src/main.tsx` | 确保 attach 分支可用 |
| `src/commands/assistant/index.ts` | 实现显式 sessionId 参数入口 |
**行为:**
- `claude assistant <sessionId>` — 进入 remote viewer
- `claude assistant` (无参数) — 返回明确提示: 当前版本需要显式 sessionIddiscovery 尚未启用
**验证:**
- [ ] `claude assistant <sessionId>` 能进入 remote viewer
- [ ] 历史懒加载工作正常
- [ ] 无参数模式给出明确提示
### Phase 4B: session discovery
**修改文件:**
| 文件 | 改动 |
|------|------|
| `src/assistant/sessionDiscovery.ts` | 恢复 `discoverAssistantSessions()` |
**行为:**
- 数据来源优先复用现有 sessions / bridge / teleport API不新增协议
- `claude assistant` 无参数时能拿到候选 session 列表
**验证:**
- [ ] 无参数调用能列出可用 sessions
- [ ] 数据来源复用现有通道
### Phase 4C: session chooser
**修改文件:**
| 文件 | 改动 |
|------|------|
| `src/assistant/AssistantSessionChooser.ts` | 恢复交互式选择器 |
**行为:**
- 多 session 时可交互选择
**验证:**
- [ ] 多个 session 时弹出选择器
- [ ] 选择后正确 attach
### Phase 4D: install wizard
**修改文件:**
| 文件 | 改动 |
|------|------|
| `src/commands/assistant/assistant.ts` | 恢复 install wizard 辅助函数 |
**行为:**
- 没有 session 时如何引导用户
**验证:**
- [ ] 无可用 session 时引导用户创建/连接
## 为什么拆分
- attach 渲染层与远端消息通道大部分已在
- 真正缺的是"如何发现目标 session"和"如何交互选择"
- 如果把 `src/assistant/index.ts` 的整套 KAIROS 正常模式也一起拉进来,范围会失控
## 风险
- 这是四项里范围最大的
- 一旦把 KAIROS 正常模式整体拉入,会从"viewer attach"膨胀成"完整 assistant mode 恢复"
## 依赖
- Task 002 的 session registry 模式可复用

View File

@@ -0,0 +1,196 @@
# Task 013: BgEngine 跨平台后台引擎抽象
> 设计文档: [daemon-restructure-design.md](../features/daemon-restructure-design.md) § 四
> 依赖: 无
> 分支: `feat/integrate-5-branches`
## 目标
`src/cli/bg.ts` 中硬编码的 tmux 逻辑提取为引擎抽象层,实现 TmuxEngine + DetachedEngine使后台会话功能在 Windows / macOS / Linux 上都能工作。
## 背景
当前 `bg.ts``handleBgFlag()``attachHandler()` 直接调用 tmux 命令。Windows 上 `--bg` 直接报错退出。需要一个引擎抽象层,根据平台和可用工具自动选择最佳方案。
## 文件清单
### 新增
| 文件 | 说明 |
|------|------|
| `src/cli/bg/engine.ts` | BgEngine 接口 + BgStartOptions/BgStartResult 类型 |
| `src/cli/bg/engines/tmux.ts` | TmuxEngine: 从 `bg.ts` 提取 tmux 相关逻辑 |
| `src/cli/bg/engines/detached.ts` | DetachedEngine: spawn({ detached }) + logFile 重定向 |
| `src/cli/bg/engines/index.ts` | selectEngine() 自动选择 + re-export |
| `src/cli/bg/tail.ts` | 跨平台日志 tail: fs.watch + 轮询 fallback |
### 修改
| 文件 | 变更 |
|------|------|
| `src/cli/bg.ts` | `handleBgFlag()` 改为调用 `selectEngine().start()``attachHandler()` 改为调用 `engine.attach()` |
## 实现方案
### 1. BgEngine 接口 (`src/cli/bg/engine.ts`)
```typescript
export interface BgEngine {
readonly name: string
available(): Promise<boolean>
start(opts: BgStartOptions): Promise<BgStartResult>
attach(session: SessionEntry): Promise<void>
}
export interface BgStartOptions {
sessionName: string
args: string[] // CLI args (去除 --bg)
env: Record<string, string | undefined>
logPath: string
cwd: string
}
export interface BgStartResult {
pid: number
sessionName: string
logPath: string
engineUsed: 'tmux' | 'detached'
}
```
### 2. TmuxEngine (`src/cli/bg/engines/tmux.ts`)
`bg.ts:handleBgFlag()``bg.ts:attachHandler()` 提取:
- `available()`: `execFileNoThrow('tmux', ['-V'])` 返回 code === 0
- `start()`: `tmux new-session -d -s <name> <cmd>`
- `attach()`: `tmux attach-session -t <session.tmuxSessionName>`
### 3. DetachedEngine (`src/cli/bg/engines/detached.ts`)
```typescript
export class DetachedEngine implements BgEngine {
readonly name = 'detached'
async available(): Promise<boolean> {
return true // 总是可用
}
async start(opts: BgStartOptions): Promise<BgStartResult> {
const logFd = openSync(opts.logPath, 'a')
const child = spawn(process.execPath, [process.argv[1]!, ...opts.args], {
detached: true,
stdio: ['ignore', logFd, logFd],
env: opts.env,
cwd: opts.cwd,
})
child.unref()
closeSync(logFd)
return {
pid: child.pid!,
sessionName: opts.sessionName,
logPath: opts.logPath,
engineUsed: 'detached',
}
}
async attach(session: SessionEntry): Promise<void> {
// 委托给 tail.ts
await tailLog(session.logPath!)
}
}
```
### 4. 日志 Tail (`src/cli/bg/tail.ts`)
```typescript
/**
* 跨平台实时日志输出。Ctrl+C 退出,不杀后台进程。
*
* 策略:
* 1. 读取已有内容输出
* 2. fs.watch() 监听文件变化 (主方案)
* 3. 如果 fs.watch 不可靠 (某些 Windows 网络驱动器)fallback 到 500ms 轮询
*/
export async function tailLog(logPath: string): Promise<void>
```
### 5. 引擎选择 (`src/cli/bg/engines/index.ts`)
```typescript
export async function selectEngine(): Promise<BgEngine> {
if (process.platform === 'win32') {
return new DetachedEngine()
}
const tmux = new TmuxEngine()
if (await tmux.available()) {
return tmux
}
return new DetachedEngine()
}
```
### 6. bg.ts 重构
`handleBgFlag()` 改名为 `handleBgStart()`,内部逻辑:
```typescript
export async function handleBgStart(args: string[]): Promise<void> {
const engine = await selectEngine()
const sessionName = `claude-bg-${randomUUID().slice(0, 8)}`
const logPath = join(getClaudeConfigHomeDir(), 'sessions', 'logs', `${sessionName}.log`)
const result = await engine.start({
sessionName,
args: filteredArgs,
env: { ...process.env, CLAUDE_CODE_SESSION_KIND: 'bg', ... },
logPath,
cwd: process.cwd(),
})
console.log(`Background session started: ${result.sessionName}`)
console.log(` Engine: ${result.engineUsed}`)
console.log(` Log: ${result.logPath}`)
console.log(` Use \`claude daemon attach ${result.sessionName}\` to reconnect.`)
}
```
`attachHandler()` 根据 `session.engine` 字段选择引擎:
```typescript
export async function attachHandler(target: string | undefined): Promise<void> {
// ... 找到 session
if (session.engine === 'tmux' && session.tmuxSessionName) {
const tmux = new TmuxEngine()
await tmux.attach(session)
} else {
const detached = new DetachedEngine()
await detached.attach(session)
}
}
```
## SessionEntry 扩展
`sessions/<PID>.json` 新增 `engine` 字段:
```json
{
"pid": 12345,
"engine": "detached",
"logPath": "~/.claude/sessions/logs/claude-bg-a1b2c3d4.log",
"sessionId": "...",
"cwd": "..."
}
```
兼容旧格式: 如果 `engine` 字段缺失,检查 `tmuxSessionName` 存在则为 `tmux`,否则为 `detached`
## 验证清单
- [ ] Windows: `claude daemon bg` 启动后台会话,无 tmux 依赖
- [ ] Windows: `claude daemon attach <name>` 以 tail 模式附着Ctrl+C 退出不杀进程
- [ ] macOS/Linux (有 tmux): 行为与当前一致
- [ ] macOS/Linux (无 tmux): 自动 fallback 到 detached 引擎
- [ ] `claude daemon status` 正确显示 engine 类型
- [ ] 旧格式 session JSON (无 engine 字段) 兼容
- [ ] tsc --noEmit 零错误
- [ ] bun test 通过

View File

@@ -0,0 +1,275 @@
# Task 014: /daemon 命令层级化
> 设计文档: [daemon-restructure-design.md](../features/daemon-restructure-design.md) § 三.1
> 依赖: Task 013 (BgEngine 抽象)
> 分支: `feat/integrate-5-branches`
## 目标
将散落的 `daemon start/stop/status` + `ps/logs/attach/kill` + `--bg` 统一收归 `/daemon` 命名空间,实现 CLI + REPL 双注册。
## 背景
当前这些命令注册在两个互不关联的位置:
- `cli.tsx:203-212`: `daemon [start|status|stop]``daemon/main.ts`
- `cli.tsx:217-246`: `ps|logs|attach|kill|--bg``cli/bg.ts`
需要合并为统一的 `claude daemon <subcommand>` 入口,并新增 REPL `/daemon` 斜杠命令。
## 文件清单
### 新增
| 文件 | 说明 |
|------|------|
| `src/commands/daemon/index.ts` | `/daemon` REPL 斜杠命令注册 (type: local-jsx) |
| `src/commands/daemon/daemon.tsx` | `/daemon` 子命令路由 + status UI 组件 |
### 修改
| 文件 | 变更 |
|------|------|
| `src/entrypoints/cli.tsx` | 统一 daemon 快速路径: `daemon <sub>` 路由到对应 handler。旧命令 `ps/logs/attach/kill` 保留但输出 deprecation 警告后代理 |
| `src/commands.ts` | 注册 `/daemon` 斜杠命令 (feature-gated: DAEMON \|\| BG_SESSIONS) |
| `src/daemon/main.ts` | `daemonMain()` 扩展: 支持 `bg/attach/logs/kill/ps` 子命令 (委托给 bg.ts handlers) |
## 实现方案
### 1. CLI 快速路径统一 (`cli.tsx`)
**改前** (两段独立路由):
```typescript
// 段 1: daemon
if (feature('DAEMON') && args[0] === 'daemon') {
await daemonMain(args.slice(1))
}
// 段 2: bg sessions
if (feature('BG_SESSIONS') && ['ps','logs','attach','kill'].includes(args[0])) {
// ...switch/case
}
```
**改后** (统一入口):
```typescript
// 统一 daemon 入口 — 合并 daemon supervisor + bg sessions
if (
(feature('DAEMON') || feature('BG_SESSIONS')) &&
args[0] === 'daemon'
) {
profileCheckpoint('cli_daemon_path')
const { enableConfigs } = await import('../utils/config.js')
enableConfigs()
const { initSinks } = await import('../utils/sinks.js')
initSinks()
const { daemonMain } = await import('../daemon/main.js')
await daemonMain(args.slice(1))
return
}
// --bg 快捷方式 → daemon bg
if (
feature('BG_SESSIONS') &&
(args.includes('--bg') || args.includes('--background'))
) {
profileCheckpoint('cli_daemon_path')
const { enableConfigs } = await import('../utils/config.js')
enableConfigs()
const bg = await import('../cli/bg.js')
await bg.handleBgStart(args.filter(a => a !== '--bg' && a !== '--background'))
return
}
// 向后兼容: ps/logs/attach/kill → daemon <sub> (deprecated)
if (
feature('BG_SESSIONS') &&
['ps', 'logs', 'attach', 'kill'].includes(args[0] ?? '')
) {
const mapped = args[0] === 'ps' ? 'status' : args[0]
console.error(`[deprecated] Use: claude daemon ${mapped} ${args.slice(1).join(' ')}`.trim())
const { enableConfigs } = await import('../utils/config.js')
enableConfigs()
const { daemonMain } = await import('../daemon/main.js')
await daemonMain([args[0]!, ...args.slice(1)])
return
}
```
### 2. daemonMain 扩展 (`daemon/main.ts`)
```typescript
export async function daemonMain(args: string[]): Promise<void> {
const subcommand = args[0] || 'status'
switch (subcommand) {
// --- Supervisor 管理 ---
case 'start':
await runSupervisor(args.slice(1))
break
case 'stop':
await handleDaemonStop()
break
// --- 会话管理 (委托给 bg.ts) ---
case 'status':
case 'ps':
await showUnifiedStatus() // 新: daemon 状态 + 会话列表
break
case 'bg':
const bg = await import('../cli/bg.js')
await bg.handleBgStart(args.slice(1))
break
case 'attach':
const bg2 = await import('../cli/bg.js')
await bg2.attachHandler(args[1])
break
case 'logs':
const bg3 = await import('../cli/bg.js')
await bg3.logsHandler(args[1])
break
case 'kill':
const bg4 = await import('../cli/bg.js')
await bg4.killHandler(args[1])
break
case '--help': case '-h': case 'help':
printHelp()
break
default:
console.error(`Unknown daemon subcommand: ${subcommand}`)
printHelp()
process.exitCode = 1
}
}
```
### 3. 统一状态面板 (`showUnifiedStatus`)
```typescript
async function showUnifiedStatus(): Promise<void> {
// 1. Daemon supervisor 状态
const daemonResult = queryDaemonStatus()
console.log('=== Daemon Supervisor ===')
switch (daemonResult.status) {
case 'running':
console.log(` Status: running (PID: ${daemonResult.state!.pid})`)
console.log(` Workers: ${daemonResult.state!.workerKinds.join(', ')}`)
break
case 'stopped':
console.log(' Status: stopped')
break
case 'stale':
console.log(' Status: stale (cleaned up)')
break
}
// 2. 后台会话列表
console.log('\n=== Background Sessions ===')
const bg = await import('../cli/bg.js')
await bg.psHandler([])
}
```
### 4. REPL 斜杠命令注册
**`src/commands/daemon/index.ts`**:
```typescript
import type { Command } from '../../commands.js'
import { feature } from 'bun:bundle'
const daemon = {
type: 'local-jsx',
name: 'daemon',
description: 'Manage background sessions and daemon',
argumentHint: '[status|start|stop|bg|attach|logs|kill]',
isEnabled: () => {
if (feature('DAEMON')) return true
if (feature('BG_SESSIONS')) return true
return false
},
load: () => import('./daemon.js'),
} satisfies Command
export default daemon
```
**`src/commands/daemon/daemon.tsx`**:
```typescript
export async function call(
onDone: LocalJSXCommandOnDone,
context: LocalJSXCommandContext,
args: string,
): Promise<React.ReactNode> {
const parts = args.trim().split(/\s+/)
const sub = parts[0] || 'status'
switch (sub) {
case 'status':
case 'ps':
// 调用 showUnifiedStatus捕获输出
// 返回文本结果
break
case 'bg':
// REPL 中启动后台会话
break
case 'start':
case 'stop':
case 'attach':
case 'logs':
case 'kill':
// 委托给对应 handler
break
default:
onDone(`Unknown: ${sub}. Use: status|start|stop|bg|attach|logs|kill`)
return null
}
}
```
**`src/commands.ts`** 添加:
```typescript
// 条件导入
const daemonCmd =
feature('DAEMON') || feature('BG_SESSIONS')
? require('./commands/daemon/index.js').default
: null
// COMMANDS 数组中添加
...(daemonCmd ? [daemonCmd] : []),
```
### 5. 更新 help 文本 (`daemon/main.ts`)
```
Claude Code Daemon — background process management
USAGE
claude daemon [subcommand]
SUBCOMMANDS
status Show daemon and session status (default)
start Start the daemon supervisor
stop Stop the daemon
bg Start a background session
attach Attach to a background session
logs Show session logs
kill Kill a session
help Show this help
REPL
/daemon [subcommand] Same commands available in interactive mode
```
## 验证清单
- [ ] `claude daemon` (无参数) 显示统一状态面板
- [ ] `claude daemon status` 显示 supervisor + 会话列表
- [ ] `claude daemon start/stop` 与当前行为一致
- [ ] `claude daemon bg` 启动后台会话 (调用 BgEngine)
- [ ] `claude daemon attach/logs/kill <target>` 功能正常
- [ ] `claude ps` 输出 deprecation 警告 + 正常工作
- [ ] `claude logs/attach/kill` 同上
- [ ] `claude --bg` 快捷方式正常
- [ ] REPL 中 `/daemon` 可用tab 补全显示
- [ ] REPL 中 `/daemon status` 显示状态信息
- [ ] tsc --noEmit 零错误
- [ ] bun test 通过

View File

@@ -0,0 +1,177 @@
# Task 015: /job 命令层级化
> 设计文档: [daemon-restructure-design.md](../features/daemon-restructure-design.md) § 三.2
> 依赖: 无 (可与 Task 013 并行)
> 分支: `feat/integrate-5-branches`
## 目标
`claude new/list/reply` 收归 `/job` 命名空间,实现 CLI + REPL 双注册。
## 背景
当前 `new`, `list`, `reply` 是顶级 CLI 命令 (`cli.tsx:250-261`),容易与其他命令冲突(特别是 `list` 这种通用词)。需要收归 `claude job <subcommand>` 并新增 REPL `/job` 入口。
## 文件清单
### 新增
| 文件 | 说明 |
|------|------|
| `src/commands/job/index.ts` | `/job` REPL 斜杠命令注册 |
| `src/commands/job/job.tsx` | `/job` 子命令路由 |
### 修改
| 文件 | 变更 |
|------|------|
| `src/entrypoints/cli.tsx` | 新增 `job` 快速路径 + 旧 `new/list/reply` deprecation 代理 |
| `src/commands.ts` | 注册 `/job` 斜杠命令 |
### 不动
| 文件 | 说明 |
|------|------|
| `src/cli/handlers/templateJobs.ts` | 内部 handler 不变,只是被调用方式变了 |
| `src/jobs/state.ts` | job 状态管理不变 |
| `src/jobs/templates.ts` | 模板发现不变 |
| `src/jobs/classifier.ts` | 任务分类器不变 |
## 实现方案
### 1. CLI 快速路径 (`cli.tsx`)
**改后**:
```typescript
// 新: claude job <subcommand>
if (
feature('TEMPLATES') &&
args[0] === 'job'
) {
profileCheckpoint('cli_templates_path')
const { templatesMain } = await import('../cli/handlers/templateJobs.js')
await templatesMain(args.slice(1))
process.exit(0)
}
// 向后兼容 (deprecated)
if (
feature('TEMPLATES') &&
(args[0] === 'new' || args[0] === 'list' || args[0] === 'reply')
) {
console.error(`[deprecated] Use: claude job ${args[0]} ${args.slice(1).join(' ')}`.trim())
profileCheckpoint('cli_templates_path')
const { templatesMain } = await import('../cli/handlers/templateJobs.js')
await templatesMain(args)
process.exit(0)
}
```
### 2. templateJobs.ts 新增 status 子命令
在现有 `switch` 中增加:
```typescript
case 'status':
handleStatus(args.slice(1))
break
```
```typescript
function handleStatus(args: string[]): void {
const jobId = args[0]
if (!jobId) {
console.error('Usage: claude job status <job-id>')
process.exitCode = 1
return
}
const state = readJobState(jobId)
if (!state) {
console.error(`Job not found: ${jobId}`)
process.exitCode = 1
return
}
console.log(`Job: ${state.jobId}`)
console.log(` Template: ${state.templateName}`)
console.log(` Status: ${state.status}`)
console.log(` Created: ${state.createdAt}`)
console.log(` Updated: ${state.updatedAt}`)
}
```
### 3. REPL 斜杠命令
**`src/commands/job/index.ts`**:
```typescript
import type { Command } from '../../commands.js'
import { feature } from 'bun:bundle'
const job = {
type: 'local-jsx',
name: 'job',
description: 'Manage template jobs',
argumentHint: '[list|new|reply|status]',
isEnabled: () => {
if (feature('TEMPLATES')) return true
return false
},
load: () => import('./job.js'),
} satisfies Command
export default job
```
**`src/commands/job/job.tsx`**:
```typescript
export async function call(
onDone: LocalJSXCommandOnDone,
_context: LocalJSXCommandContext,
args: string,
): Promise<React.ReactNode> {
const parts = args.trim().split(/\s+/)
const sub = parts[0] || 'list'
// 委托给 templatesMain
const { templatesMain } = await import('../../cli/handlers/templateJobs.js')
// 捕获 console.log 输出作为结果返回给 REPL
const lines: string[] = []
const origLog = console.log
const origError = console.error
console.log = (...a: unknown[]) => lines.push(a.join(' '))
console.error = (...a: unknown[]) => lines.push(a.join(' '))
try {
await templatesMain([sub, ...parts.slice(1)])
} finally {
console.log = origLog
console.error = origError
}
onDone(lines.join('\n') || 'Done.', { display: 'system' })
return null
}
```
### 4. commands.ts 注册
```typescript
const jobCmd = feature('TEMPLATES')
? require('./commands/job/index.js').default
: null
// COMMANDS 数组:
...(jobCmd ? [jobCmd] : []),
```
## 验证清单
- [ ] `claude job list` 列出模板
- [ ] `claude job new <template>` 创建任务
- [ ] `claude job reply <id> <text>` 回复任务
- [ ] `claude job status <id>` 显示任务状态
- [ ] `claude job` (无参数) 等同于 `claude job list`
- [ ] `claude new/list/reply` 输出 deprecation 警告 + 正常工作
- [ ] REPL 中 `/job` 可用
- [ ] REPL 中 `/job list` 显示模板列表
- [ ] tsc --noEmit 零错误
- [ ] bun test 通过

View File

@@ -0,0 +1,123 @@
# Task 016: 向后兼容 + 测试
> 设计文档: [daemon-restructure-design.md](../features/daemon-restructure-design.md) § 五
> 依赖: Task 014, Task 015
> 分支: `feat/integrate-5-branches`
## 目标
确保旧命令向后兼容 (deprecation 警告 + 正常代理),并为重构后的命令结构编写测试。
## 文件清单
### 新增
| 文件 | 说明 |
|------|------|
| `src/daemon/__tests__/daemonMain.test.ts` | daemonMain 子命令路由测试 |
| `src/cli/bg/__tests__/engine.test.ts` | BgEngine 选择逻辑测试 |
| `src/cli/bg/__tests__/detached.test.ts` | DetachedEngine 启动/停止测试 |
| `src/cli/bg/__tests__/tail.test.ts` | 日志 tail 功能测试 |
### 修改
| 文件 | 变更 |
|------|------|
| `src/entrypoints/cli.tsx` | 确认 deprecation 路径正确代理 |
## 实现方案
### 1. 向后兼容矩阵
| 旧命令 | 新命令 | 处理方式 |
|--------|--------|---------|
| `claude ps` | `claude daemon status` | stderr 输出 `[deprecated] Use: claude daemon status`,然后执行 |
| `claude logs <x>` | `claude daemon logs <x>` | 同上 |
| `claude attach <x>` | `claude daemon attach <x>` | 同上 |
| `claude kill <x>` | `claude daemon kill <x>` | 同上 |
| `claude --bg` | `claude daemon bg` | 保留为快捷方式,**不** deprecate (太常用) |
| `claude new <t>` | `claude job new <t>` | stderr deprecation + 执行 |
| `claude list` | `claude job list` | stderr deprecation + 执行 |
| `claude reply <id>` | `claude job reply <id>` | stderr deprecation + 执行 |
**关键**: deprecation 输出到 stderr 而非 stdout不影响脚本管道。
### 2. 测试计划
#### 2.1 daemonMain 路由测试
```typescript
describe('daemonMain', () => {
test('无参数默认 status', async () => { ... })
test('start 调用 runSupervisor', async () => { ... })
test('stop 调用 handleDaemonStop', async () => { ... })
test('bg 委托给 bg.handleBgStart', async () => { ... })
test('attach 委托给 bg.attachHandler', async () => { ... })
test('logs 委托给 bg.logsHandler', async () => { ... })
test('kill 委托给 bg.killHandler', async () => { ... })
test('未知子命令设置 exitCode=1', async () => { ... })
})
```
#### 2.2 引擎选择测试
```typescript
describe('selectEngine', () => {
test('win32 返回 DetachedEngine', async () => { ... })
test('darwin + tmux 可用返回 TmuxEngine', async () => { ... })
test('darwin + tmux 不可用返回 DetachedEngine', async () => { ... })
test('linux + tmux 可用返回 TmuxEngine', async () => { ... })
})
```
#### 2.3 DetachedEngine 测试
```typescript
describe('DetachedEngine', () => {
test('available 始终返回 true', async () => { ... })
test('start 创建 detached 子进程并写入日志', async () => { ... })
test('start 返回的 PID 文件存在', async () => { ... })
})
```
#### 2.4 Tail 测试
```typescript
describe('tailLog', () => {
test('输出已有日志内容', async () => { ... })
test('追加内容时实时输出', async () => { ... })
test('SIGINT 退出 tail', async () => { ... })
})
```
### 3. 集成验证脚本
可选: 在 `scripts/` 下添加一个手动验证脚本:
```bash
#!/bin/bash
# scripts/verify-daemon-restructure.sh
echo "=== 1. claude daemon status ==="
bun run dev -- daemon status
echo "=== 2. claude daemon bg (should start) ==="
bun run dev -- daemon bg --help
echo "=== 3. claude ps (deprecated) ==="
bun run dev -- ps 2>&1 | head -1
echo "=== 4. claude job list ==="
bun run dev -- job list
echo "=== 5. claude list (deprecated) ==="
bun run dev -- list 2>&1 | head -1
```
## 验证清单
- [ ] 旧命令全部正常工作 (仅多一行 stderr 警告)
- [ ] `--bg` 保持无警告
- [ ] 所有新增测试通过
- [ ] 现有 2695 个测试无回归
- [ ] tsc --noEmit 零错误
- [ ] 手动在 Windows + macOS/Linux 上验证关键路径

View File

@@ -0,0 +1,88 @@
# OpenClaw Autonomy Baseline Test Spec
## Purpose
This test spec locks the current behavior of the existing trigger and context layers before any formal autonomy-subsystem implementation begins.
At this stage, production code is read-only. Only test files, fixtures, and planning documents may change.
## Goal
Establish a stable baseline around the parts of `Claude-code-bast` that later autonomy work is most likely to touch:
- proactive state handling
- cron task storage semantics
- cron scheduler helper semantics
- user-context cache and `CLAUDE.md` injection behavior
## Out of Scope for This Baseline Round
- New authority behavior (`AGENTS.md` / `HEARTBEAT.md`)
- New detached-run ledger behavior
- New flow behavior
- UI redesign
## Files Under Baseline Protection
- `src/proactive/index.ts`
- `src/utils/cronTasks.ts`
- `src/utils/cronScheduler.ts`
- `src/context.ts`
## Test Files Added In This Round
- `src/proactive/__tests__/state.baseline.test.ts`
- `src/commands/__tests__/proactive.baseline.test.ts`
- `src/utils/__tests__/cronTasks.baseline.test.ts`
- `src/utils/__tests__/cronScheduler.baseline.test.ts`
- `src/__tests__/context.baseline.test.ts`
## Baseline Assertions
### Proactive state
1. Activating proactive mode sets active state and activation source.
2. Pausing proactive mode suppresses `shouldTick()` and clears `nextTickAt`.
3. Blocking context suppresses `shouldTick()` and clears `nextTickAt`.
4. Subscribers are notified on state transitions.
5. The `/proactive` command enables proactive mode and emits the expected hidden reminder.
6. The `/proactive` command disables proactive mode on the second invocation.
### Cron task storage
1. Session-only cron tasks remain in memory only.
2. Durable cron tasks are persisted to `.claude/scheduled_tasks.json`.
3. Daemon-style `dir`-scoped reads exclude session-only cron tasks.
4. `removeCronTasks()` without `dir` can remove session-only tasks.
5. `removeCronTasks()` with `dir` does not mutate session-only task storage.
### Cron scheduler helpers
1. `isRecurringTaskAged()` preserves current aging semantics.
2. `buildMissedTaskNotification()` preserves the current AskUserQuestion safety wording.
3. `buildMissedTaskNotification()` preserves code-fence hardening for prompt bodies that contain backticks.
### User context caching
1. `getUserContext()` includes `currentDate`.
2. `getUserContext()` includes mocked `claudeMd` content when memory loading is enabled.
3. `CLAUDE_CODE_DISABLE_CLAUDE_MDS` suppresses `claudeMd`.
4. `setSystemPromptInjection()` clears the memoized user-context cache.
5. `getSystemContext()` reflects the injection after cache invalidation.
## Remaining Baseline Gaps
The following areas are intentionally deferred because they require higher-cost harnessing and should still avoid production-code changes:
1. `useScheduledTasks.ts` hook-level runtime behavior
2. `src/cli/print.ts` full headless scheduler loop behavior
3. `useProactive.ts` hook timer behavior
4. end-to-end queue interaction between proactive ticks and `SleepTool`
## Acceptance
This baseline round is complete when:
1. The four new test files pass.
2. No production source files are modified.
3. The tests are stable enough to serve as a pre-implementation guardrail.

View File

@@ -22,14 +22,14 @@ Read 的 `maxResultSizeChars` 是 `Infinity`,但这并不意味着无限制输
## FileRead多模态文件读取引擎
源码路径:`src/tools/FileReadTool/FileReadTool.ts`
源码路径:`packages/builtin-tools/src/tools/FileReadTool/FileReadTool.ts`
### 读取去重机制
Read 工具有一个常被忽视但至关重要的**去重层**。当 AI 重复读取同一个文件的同一范围时,系统不会浪费 token 发送两份完整内容:
```typescript
// FileReadTool.ts:530-573 — 去重逻辑
// FileReadTool.ts — 去重逻辑
const existingState = readFileState.get(fullFilePath)
if (existingState && !existingState.isPartialView && existingState.offset !== undefined) {
const rangeMatch = existingState.offset === offset && existingState.limit === limit
@@ -83,7 +83,7 @@ Read 工具在 `validateInput()` 中设置了多层安全门:
当文件不存在时Read 不会只报一个 "file not found"
```typescript
// FileReadTool.ts:639-647
// FileReadTool.ts
const similarFilename = findSimilarFile(fullFilePath) // 相似扩展名
const cwdSuggestion = await suggestPathUnderCwd(fullFilePath) // cwd 相对路径建议
// macOS 截图特殊处理:薄空格(U+202F) vs 普通空格
@@ -94,7 +94,7 @@ const altPath = getAlternateScreenshotPath(fullFilePath)
## FileEdit精确字符串替换引擎
源码路径:`src/tools/FileEditTool/FileEditTool.ts` + `utils.ts`
源码路径:`packages/builtin-tools/src/tools/FileEditTool/FileEditTool.ts` + `utils.ts`
### 引号标准化AI 无法输出的字符怎么办
@@ -138,7 +138,7 @@ Edit 工具在 `validateInput()` 中检查两个条件:
2. **文件未被外部修改**`mtime` 未变,或全量读取时内容完全一致)
```typescript
// FileEditTool.ts:290-311 — Windows 特殊处理
// FileEditTool.ts — Windows 特殊处理
const isFullRead = readTimestamp.offset === undefined && readTimestamp.limit === undefined
if (isFullRead && fileContent === readTimestamp.content) {
// 内容不变安全继续Windows 云同步/杀毒可能改 mtime
@@ -157,7 +157,7 @@ const MAX_EDIT_FILE_SIZE = 1024 * 1024 * 1024 // 1 GiB
## FileWrite全量写入与创建
源码路径:`src/tools/FileWriteTool/FileWriteTool.ts`
源码路径:`packages/builtin-tools/src/tools/FileWriteTool/FileWriteTool.ts`
Write 工具与 Edit 共享大部分基础设施权限检查、mtime 校验、fileHistory 备份),但有两个关键差异:

View File

@@ -77,7 +77,7 @@ Glob 默认把**最近修改的文件排在前面**。这不是默认的文件
实际效果AI 优先看到"活"的代码,而不是沉寂的历史文件
```
在 `src/tools/GlobTool/` 中ripgrep 的输出在返回给 AI 前按 mtime 排序。
在 `packages/builtin-tools/src/tools/GlobTool/` 中ripgrep 的输出在返回给 AI 前按 mtime 排序。
### ripgrep 的错误处理
@@ -92,7 +92,7 @@ ripgrep 执行有专门的错误恢复链(`src/utils/ripgrep.ts`
## ToolSearch在 50+ 工具中发现目标
当可用工具超过 50 个时(含 MCP 提供的外部工具AI 可能不知道该用哪个。**ToolSearch**`src/tools/ToolSearchTool/`)提供了工具发现机制。
当可用工具超过 50 个时(含 MCP 提供的外部工具AI 可能不知道该用哪个。**ToolSearch**`packages/builtin-tools/src/tools/ToolSearchTool/`)提供了工具发现机制。
### 搜索算法
@@ -139,14 +139,14 @@ function getDeferredToolsCacheKey(deferredTools: Tools): string {
AI 的信息获取不局限于本地代码:
- **WebSearch**`src/tools/WebSearchTool/`):调用 Anthropic API 的 `web_search_20250305` server tool 搜索互联网
- **WebFetch**`src/tools/WebFetchTool/`):抓取特定 URL 内容,转换为 Markdown 供 AI 阅读
- **WebSearch**`packages/builtin-tools/src/tools/WebSearchTool/`):调用 Anthropic API 的 `web_search_20250305` server tool 搜索互联网
- **WebFetch**`packages/builtin-tools/src/tools/WebFetchTool/`):抓取特定 URL 内容,转换为 Markdown 供 AI 阅读
这让 AI 可以查阅文档、搜索 Stack Overflow、阅读 GitHub issue——和人类开发者的工作方式一致。
### WebSearch 实现机制
WebSearch 通过适配器模式支持三种搜索后端,由 `src/tools/WebSearchTool/adapters/` 中的工厂函数 `createAdapter()` 选择:
WebSearch 通过适配器模式支持三种搜索后端,由 `packages/builtin-tools/src/tools/WebSearchTool/adapters/` 中的工厂函数 `createAdapter()` 选择:
```
适配器架构:
@@ -229,7 +229,7 @@ WebSearch 通过适配器模式支持三种搜索后端,由 `src/tools/WebSear
### WebSearchTool 统一接口
`WebSearchTool``src/tools/WebSearchTool/WebSearchTool.ts`)是面向主循环的工具定义,所有 provider 均可使用(`isEnabled()` 始终返回 true。它将适配器返回的 `SearchResult[]` 转换为内部 `Output` 格式,`mapToolResultToToolResultBlockParam` 将搜索结果格式化为带 markdown 超链接的文本,并附加 "REMINDER" 要求主模型在回复中包含 Sources。
`WebSearchTool``packages/builtin-tools/src/tools/WebSearchTool/WebSearchTool.ts`)是面向主循环的工具定义,所有 provider 均可使用(`isEnabled()` 始终返回 true。它将适配器返回的 `SearchResult[]` 转换为内部 `Output` 格式,`mapToolResultToToolResultBlockParam` 将搜索结果格式化为带 markdown 超链接的文本,并附加 "REMINDER" 要求主模型在回复中包含 Sources。
### WebFetch 实现机制
@@ -264,7 +264,7 @@ WebFetch 是一个完整的 HTTP 客户端 + 内容处理管线:
| **URL 验证** | `validateURL()` | 长度、协议、用户名密码、公网域名检查 |
| **egress 检测** | `X-Proxy-Error: blocked-by-allowlist` | 检测企业代理拦截 |
预批准域名(`src/tools/WebFetchTool/preapproved.ts`
预批准域名(`packages/builtin-tools/src/tools/WebFetchTool/preapproved.ts`
用户无需手动授权即可抓取的域名列表,包含 ~90 个主流技术文档站点MDN、Python docs、React docs、AWS docs 等)。列表分为 hostname-only 和 path-prefix 两类,查找复杂度 O(1)。

View File

@@ -31,7 +31,7 @@ spawn(wrapped_command) ← 实际进程创建
## 只读命令的判定:为什么 Read 免审批而 Bash 不一定
BashTool 的 `isReadOnly()` 方法(`BashTool.tsx:437`)决定一条命令是否被视为"只读"
BashTool 的 `isReadOnly()` 方法(`packages/builtin-tools/src/tools/BashTool/BashTool.tsx:655`)决定一条命令是否被视为"只读"
```typescript
isReadOnly(input) {
@@ -41,7 +41,7 @@ isReadOnly(input) {
}
```
判定逻辑基于 4 个命令集合(`BashTool.tsx:60-78`
判定逻辑基于 4 个命令集合(`BashTool.tsx:120-166`
| 集合 | 命令 | 性质 |
|------|------|------|
@@ -53,7 +53,7 @@ isReadOnly(input) {
对于复合命令(`ls dir && echo "---" && ls dir2`),系统拆分后逐段检查——**所有非中性段都必须属于上述集合**,整条命令才被视为只读。
```typescript
// BashTool.tsx:95 — 简化的判定逻辑
// BashTool.tsx — 简化的判定逻辑
for (const part of partsWithOperators) {
if (BASH_SEMANTIC_NEUTRAL_COMMANDS.has(baseCommand)) continue // 跳过中性段
if (!isPartSearch && !isPartRead && !isPartList) {
@@ -64,7 +64,7 @@ for (const part of partsWithOperators) {
## AST 安全解析tree-sitter bash 解析
`preparePermissionMatcher()``BashTool.tsx:445`)在权限检查前用 `parseForSecurity()` 解析命令结构:
`preparePermissionMatcher()``BashTool.tsx:663`)在权限检查前用 `parseForSecurity()` 解析命令结构:
```typescript
async preparePermissionMatcher({ command }) {
@@ -92,14 +92,14 @@ getDefaultTimeoutMs()
└── 最大上限600,000ms10 分钟,用户显式设置时)
```
超时后系统不会直接杀进程——`ShellCommand``src/utils/ShellCommand.ts:129`)通过 `onTimeout` 回调通知调用方,由调用方决定是终止还是后台化。
超时后系统不会直接杀进程——`ShellCommand``src/utils/ShellCommand.ts:144`)通过 `onTimeout` 回调通知调用方,由调用方决定是终止还是后台化。
## 自动后台化
长时间运行的命令可以自动转为后台任务,不阻塞 AI 的 agentic loop
```typescript
// BashTool.tsx:880
// BashTool.tsx:1158
const shouldAutoBackground = !isBackgroundTasksDisabled
&& isAutobackgroundingAllowed(command)
```
@@ -148,7 +148,7 @@ Claude Code 为文件读写、代码搜索等操作提供了专用工具Read
| **并发安全** | `isConcurrencySafe()` 返回 `true` → 可并行执行 | Bash 命令可能有副作用,串行执行 |
| **安全审计** | 工具名精确匹配权限规则 | 需 AST 解析命令结构后匹配 |
`isConcurrencySafe()``BashTool.tsx:434`)是一个常被忽视但重要的设计——只有只读命令可以在 agentic loop 中并行执行,有副作用的命令必须串行,防止竞态条件。
`isConcurrencySafe()``BashTool.tsx:652`)是一个常被忽视但重要的设计——只有只读命令可以在 agentic loop 中并行执行,有副作用的命令必须串行,防止竞态条件。
## 进度反馈的流式设计

View File

@@ -25,7 +25,7 @@ Claude Code 的任务管理并非单一系统,而是两个并存、按运行
TodoWrite 本质是一个**全量替换**操作——每次调用传入完整的 `todos[]` 数组,完全覆盖之前的状态:
```typescript
// src/tools/TodoWriteTool/TodoWriteTool.ts — call() 核心逻辑
// packages/builtin-tools/src/tools/TodoWriteTool/TodoWriteTool.ts — call() 核心逻辑
async call({ todos }, context) {
const todoKey = context.agentId ?? getSessionId()
const oldTodos = appState.todos[todoKey] ?? []

View File

@@ -16,7 +16,7 @@ keywords: ["工具系统", "Tool 抽象", "AI 工具", "function calling", "buil
## Tool 类型35 个字段的统一接口
所有工具都实现 `src/Tool.ts:362` 的 `Tool<Input, Output, Progress>` 类型。这不是一个 class而是一个包含 35+ 字段的**结构化类型**structural typing任何满足该接口的对象就是一个工具
所有工具都实现 `src/Tool.ts:368` 的 `Tool<Input, Output, Progress>` 类型。这不是一个 class而是一个包含 35+ 字段的**结构化类型**structural typing任何满足该接口的对象就是一个工具
### 核心四要素
@@ -69,7 +69,7 @@ keywords: ["工具系统", "Tool 抽象", "AI 工具", "function calling", "buil
## 工具注册:`getTools()` 的分层组装
`src/tools.ts` 的 `getAllBaseTools()`(第 191 行)是工具注册的核心:
`src/tools.ts` 的 `getAllBaseTools()`(第 195 行)是工具注册的核心:
```
固定工具(始终可用):
@@ -96,7 +96,7 @@ Ant-only 工具:
← process.env.USER_TYPE === 'ant' ? [REPLTool, ConfigTool, TungstenTool]
```
`getTools()`(第 269 行)在 `getAllBaseTools()` 基础上应用权限过滤:
`getTools()`(第 274 行)在 `getAllBaseTools()` 基础上应用权限过滤:
```typescript
export const getTools = (permissionContext): Tools => {
@@ -110,7 +110,7 @@ export const getTools = (permissionContext): Tools => {
## `buildTool()` 工厂函数
大多数工具通过 `buildTool()` 创建(`src/Tool.ts:721`),它是一个类型安全的构造器:
大多数工具通过 `buildTool()` 创建(`src/Tool.ts:789`),它是一个类型安全的构造器:
```typescript
export const BashTool: Tool<...> = buildTool({

View File

@@ -175,7 +175,7 @@ F. getCompletedResults() → 空
---
#### #8 stream_event (input_json_delta: '{"file_path":')
#### #8 stream_event (input_json_delta: `'{"file_path":'`)
```
D. yield message ✅ → REPL 追加工具输入 JSON 碎片

View File

@@ -135,9 +135,11 @@
"group": "运行模式",
"pages": [
"docs/features/kairos",
"docs/features/channels",
"docs/features/voice-mode",
"docs/features/bridge-mode",
"docs/features/remote-control-self-hosting",
"docs/features/acp-link",
"docs/features/proactive",
"docs/features/ultraplan"
]

View File

@@ -1,6 +1,6 @@
{
"name": "claude-code-best",
"version": "1.3.5",
"version": "1.10.2",
"description": "Reverse-engineered Anthropic Claude Code CLI — interactive AI coding assistant in the terminal",
"type": "module",
"author": "claude-code-best <claude-code-best@proton.me>",
@@ -31,66 +31,80 @@
},
"workspaces": [
"packages/*",
"packages/@ant/*"
"packages/@ant/*",
"packages/@anthropic-ai/*"
],
"files": [
"dist",
"scripts/postinstall.cjs",
"scripts/run-parallel.mjs",
"scripts/setup-chrome-mcp.mjs"
],
"scripts": {
"build": "bun run build.ts",
"build:vite": "vite build && bun run scripts/post-build.ts",
"build:vite:only": "vite build",
"build:bun": "bun run build.ts",
"dev": "bun run scripts/dev.ts",
"dev:inspect": "bun run scripts/dev-debug.ts",
"prepublishOnly": "bun run build",
"prepublishOnly": "bun run build:vite",
"lint": "biome lint src/",
"lint:fix": "biome lint --fix src/",
"format": "biome format --write src/",
"prepare": "git config core.hooksPath .githooks",
"test": "bun test",
"test:production": "bun run scripts/production-test.ts",
"test:production:offline": "bun run scripts/production-test.ts --offline",
"test:production:verbose": "bun run scripts/production-test.ts --verbose",
"test:production:bun": "bun run scripts/production-test.ts --bun",
"check:bundle": "bun run scripts/check-bundle-integrity.ts",
"check:unused": "knip-bun",
"health": "bun run scripts/health-check.ts",
"postinstall": "node scripts/postinstall.cjs && node scripts/setup-chrome-mcp.mjs",
"postinstall": "node scripts/run-parallel.mjs scripts/postinstall.cjs scripts/setup-chrome-mcp.mjs",
"docs:dev": "npx mintlify dev",
"typecheck": "tsc --noEmit",
"test:all": "bun run typecheck && bun test",
"rcs": "bun run scripts/rcs.ts"
},
"dependencies": {
"@claude-code-best/mcp-chrome-bridge": "^2.0.7"
"@agentclientprotocol/sdk": "^0.19.0",
"@claude-code-best/mcp-chrome-bridge": "^3.0.1",
"highlight.js": "^11.11.1",
"ws": "^8.20.0"
},
"devDependencies": {
"@types/he": "^1.2.3",
"@langfuse/otel": "^5.1.0",
"@langfuse/tracing": "^5.1.0",
"@types/lodash-es": "^4.17.12",
"@alcalzone/ansi-tokenize": "^0.3.0",
"@ant/model-provider": "workspace:*",
"@ant/claude-for-chrome-mcp": "workspace:*",
"@ant/computer-use-input": "workspace:*",
"@ant/computer-use-mcp": "workspace:*",
"@ant/computer-use-swift": "workspace:*",
"@anthropic-ai/bedrock-sdk": "^0.26.4",
"@anthropic-ai/claude-agent-sdk": "^0.2.87",
"@anthropic-ai/claude-agent-sdk": "^0.2.114",
"@anthropic-ai/foundry-sdk": "^0.2.3",
"@anthropic-ai/mcpb": "^2.1.2",
"@anthropic-ai/sandbox-runtime": "^0.0.44",
"@anthropic-ai/sdk": "^0.80.0",
"@anthropic-ai/vertex-sdk": "^0.14.4",
"@anthropic/ink": "workspace:*",
"@claude-code-best/builtin-tools": "workspace:*",
"@claude-code-best/agent-tools": "workspace:*",
"@claude-code-best/mcp-client": "workspace:*",
"@aws-sdk/client-bedrock": "^3.1020.0",
"@aws-sdk/client-bedrock-runtime": "^3.1020.0",
"@aws-sdk/client-sts": "^3.1020.0",
"@aws-sdk/credential-provider-node": "^3.972.28",
"@aws-sdk/credential-providers": "^3.1020.0",
"@aws-sdk/client-bedrock": "^3.1032.0",
"@aws-sdk/client-bedrock-runtime": "^3.1032.0",
"@aws-sdk/client-sts": "^3.1032.0",
"@aws-sdk/credential-provider-node": "^3.972.32",
"@aws-sdk/credential-providers": "^3.1032.0",
"@azure/identity": "^4.13.1",
"@biomejs/biome": "^2.4.10",
"@biomejs/biome": "^2.4.12",
"@claude-code-best/agent-tools": "workspace:*",
"@claude-code-best/builtin-tools": "workspace:*",
"@claude-code-best/mcp-client": "workspace:*",
"@claude-code-best/weixin": "workspace:*",
"@commander-js/extra-typings": "^14.0.0",
"@growthbook/growthbook": "^1.6.5",
"@langfuse/otel": "^5.1.0",
"@langfuse/tracing": "^5.1.0",
"@modelcontextprotocol/sdk": "^1.29.0",
"@opentelemetry/api": "^1.9.1",
"@opentelemetry/api-logs": "^0.214.0",
"@opentelemetry/core": "^2.6.1",
"@opentelemetry/core": "^2.7.0",
"@opentelemetry/exporter-logs-otlp-grpc": "^0.214.0",
"@opentelemetry/exporter-logs-otlp-http": "^0.214.0",
"@opentelemetry/exporter-logs-otlp-proto": "^0.214.0",
@@ -101,16 +115,19 @@
"@opentelemetry/exporter-trace-otlp-grpc": "^0.214.0",
"@opentelemetry/exporter-trace-otlp-http": "^0.214.0",
"@opentelemetry/exporter-trace-otlp-proto": "^0.214.0",
"@opentelemetry/resources": "^2.6.1",
"@opentelemetry/resources": "^2.7.0",
"@opentelemetry/sdk-logs": "^0.214.0",
"@opentelemetry/sdk-metrics": "^2.6.1",
"@opentelemetry/sdk-trace-base": "^2.6.1",
"@opentelemetry/sdk-metrics": "^2.7.0",
"@opentelemetry/sdk-trace-base": "^2.7.0",
"@opentelemetry/semantic-conventions": "^1.40.0",
"@sentry/node": "^10.47.0",
"@smithy/core": "^3.23.13",
"@smithy/node-http-handler": "^4.5.1",
"@types/bun": "^1.3.11",
"@sentry/node": "^10.49.0",
"@smithy/core": "^3.23.15",
"@smithy/node-http-handler": "^4.5.3",
"@types/bun": "^1.3.12",
"@types/cacache": "^20.0.1",
"@types/he": "^1.2.3",
"@types/lodash-es": "^4.17.12",
"@types/node": "^25.6.0",
"@types/picomatch": "^4.0.3",
"@types/plist": "^3.0.5",
"@types/proper-lockfile": "^4.1.4",
@@ -127,7 +144,7 @@
"asciichart": "^1.5.25",
"audio-capture-napi": "workspace:*",
"auto-bind": "^5.0.1",
"axios": "^1.14.0",
"axios": "^1.15.0",
"bidi-js": "^1.0.3",
"cacache": "^20.0.4",
"chalk": "^5.6.2",
@@ -142,30 +159,30 @@
"execa": "^9.6.1",
"fflate": "^0.8.2",
"figures": "^6.1.0",
"fuse.js": "^7.1.0",
"fuse.js": "^7.3.0",
"get-east-asian-width": "^1.5.0",
"google-auth-library": "^10.6.2",
"he": "^1.2.0",
"highlight.js": "^11.11.1",
"https-proxy-agent": "^8.0.0",
"ignore": "^7.0.5",
"image-processor-napi": "workspace:*",
"indent-string": "^5.0.0",
"jsonc-parser": "^3.3.1",
"knip": "^6.1.1",
"lodash-es": "^4.17.23",
"lru-cache": "^11.2.7",
"marked": "^17.0.5",
"knip": "^6.4.1",
"lodash-es": "^4.18.1",
"lru-cache": "^11.3.5",
"marked": "^17.0.6",
"modifiers-napi": "workspace:*",
"openai": "^6.33.0",
"openai": "^6.34.0",
"p-map": "^7.0.4",
"picomatch": "^4.0.4",
"plist": "^3.1.0",
"proper-lockfile": "^4.1.2",
"qrcode": "^1.5.4",
"react": "^19.2.4",
"react": "^19.2.5",
"react-compiler-runtime": "^1.0.0",
"react-reconciler": "^0.33.0",
"rollup": "^4.60.2",
"semver": "^7.7.4",
"sharp": "^0.34.5",
"shell-quote": "^1.8.3",
@@ -174,19 +191,22 @@
"strip-ansi": "^7.2.0",
"supports-hyperlinks": "^4.4.0",
"tree-kill": "^1.2.2",
"turndown": "^7.2.2",
"type-fest": "^5.5.0",
"typescript": "^6.0.2",
"undici": "^7.24.6",
"turndown": "^7.2.4",
"type-fest": "^5.6.0",
"typescript": "^6.0.3",
"undici": "^7.25.0",
"url-handler-napi": "workspace:*",
"usehooks-ts": "^3.1.1",
"vite": "^8.0.8",
"vscode-jsonrpc": "^8.2.1",
"vscode-languageserver-protocol": "^3.17.5",
"vscode-languageserver-types": "^3.17.5",
"wrap-ansi": "^10.0.0",
"ws": "^8.20.0",
"xss": "^1.0.15",
"yaml": "^2.8.3",
"zod": "^4.3.6"
},
"optionalDependencies": {
"doubaoime-asr": "^0.1.0"
}
}

View File

@@ -0,0 +1,5 @@
{
"extends": "../../../tsconfig.base.json",
"include": ["src/**/*.ts"],
"exclude": ["node_modules", "dist"]
}

View File

@@ -5,9 +5,12 @@
* mouse and keyboard via CoreGraphics events and System Events.
*/
import { $ } from 'bun'
import { execFile, execFileSync } from 'child_process'
import { promisify } from 'util'
import type { FrontmostAppInfo, InputBackend } from '../types.js'
const execFileAsync = promisify(execFile)
const KEY_MAP: Record<string, number> = {
return: 36, enter: 36, tab: 48, space: 49, delete: 51, backspace: 51,
escape: 53, esc: 53,
@@ -25,13 +28,17 @@ const MODIFIER_MAP: Record<string, string> = {
}
async function osascript(script: string): Promise<string> {
const result = await $`osascript -e ${script}`.quiet().nothrow().text()
return result.trim()
const { stdout } = await execFileAsync('osascript', ['-e', script], {
encoding: 'utf-8',
})
return stdout.trim()
}
async function jxa(script: string): Promise<string> {
const result = await $`osascript -l JavaScript -e ${script}`.quiet().nothrow().text()
return result.trim()
const { stdout } = await execFileAsync('osascript', ['-l', 'JavaScript', '-e', script], {
encoding: 'utf-8',
})
return stdout.trim()
}
function buildMouseJxa(eventType: string, x: number, y: number, btn: number, clickState?: number): string {
@@ -115,19 +122,14 @@ export const typeText: InputBackend['typeText'] = async (text) => {
export const getFrontmostAppInfo: InputBackend['getFrontmostAppInfo'] = () => {
try {
const result = Bun.spawnSync({
cmd: ['osascript', '-e', `
tell application "System Events"
set frontApp to first application process whose frontmost is true
set appName to name of frontApp
set bundleId to bundle identifier of frontApp
return bundleId & "|" & appName
end tell
`],
stdout: 'pipe',
stderr: 'pipe',
})
const output = new TextDecoder().decode(result.stdout).trim()
const output = execFileSync('osascript', ['-e', `
tell application "System Events"
set frontApp to first application process whose frontmost is true
set appName to name of frontApp
set bundleId to bundle identifier of frontApp
return bundleId & "|" & appName
end tell
`], { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'ignore'] }).trim()
if (!output || !output.includes('|')) return null
const [bundleId, appName] = output.split('|', 2)
return { bundleId: bundleId!, appName: appName! }

View File

@@ -0,0 +1,5 @@
{
"extends": "../../../tsconfig.base.json",
"include": ["src/**/*.ts"],
"exclude": ["node_modules", "dist"]
}

View File

@@ -37,16 +37,21 @@
import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
import { randomUUID } from "node:crypto";
/** Detect actual image MIME type from base64 data using magic bytes. */
/** Detect actual image MIME type from base64 data by decoding the magic bytes. */
function detectMimeFromBase64(b64: string): string {
// First byte is enough to distinguish PNG (0x89) from JPEG (0xFF)
const c = b64.charCodeAt(0);
if (c === 0x89) return "image/png";
if (c === 0xFF) return "image/jpeg";
// RIFF = WebP
if (c === 0x52) return "image/webp";
// GIF
if (c === 0x47) return "image/gif";
// Decode first 12 raw bytes (16 base64 chars is enough) and check standard magic bytes.
// PNG: 89 50 4E 47
// JPEG: FF D8 FF
// RIFF+WEBP: "RIFF" at 0..3 + "WEBP" at 8..11
// GIF: "GIF" at 0..2
const raw = Buffer.from(b64.slice(0, 16), "base64");
if (raw[0] === 0x89 && raw[1] === 0x50 && raw[2] === 0x4e && raw[3] === 0x47) return "image/png";
if (raw[0] === 0xff && raw[1] === 0xd8 && raw[2] === 0xff) return "image/jpeg";
if (
raw[0] === 0x52 && raw[1] === 0x49 && raw[2] === 0x46 && raw[3] === 0x46 && // RIFF
raw[8] === 0x57 && raw[9] === 0x45 && raw[10] === 0x42 && raw[11] === 0x50 // WEBP
) return "image/webp";
if (raw[0] === 0x47 && raw[1] === 0x49 && raw[2] === 0x46) return "image/gif";
return "image/png";
}

View File

@@ -0,0 +1,5 @@
{
"extends": "../../../tsconfig.base.json",
"include": ["src/**/*.ts"],
"exclude": ["node_modules", "dist"]
}

View File

@@ -274,4 +274,9 @@ export const screenshot: ScreenshotAPI = {
if (displayId !== undefined) args.push('-D', String(displayId))
return captureScreenToBase64(args)
},
captureWindowTarget(_titleOrHwnd: string | number): ScreenshotResult | null {
// Window capture not supported on macOS via this backend
return null
},
}

Some files were not shown because too many files have changed in this diff Show More