mirror of
https://github.com/claude-code-best/claude-code.git
synced 2026-06-15 12:55:51 +00:00
docs: 添加一大堆 feature 的描述
This commit is contained in:
107
docs/features/bash-classifier.md
Normal file
107
docs/features/bash-classifier.md
Normal file
@@ -0,0 +1,107 @@
|
||||
# BASH_CLASSIFIER — Bash 命令分类器
|
||||
|
||||
> Feature Flag: `FEATURE_BASH_CLASSIFIER=1`
|
||||
> 实现状态:bashClassifier.ts 全部 Stub,yoloClassifier.ts 完整实现可参考
|
||||
> 引用数:45
|
||||
|
||||
## 一、功能概述
|
||||
|
||||
BASH_CLASSIFIER 使用 LLM 对 bash 命令进行意图分类(允许/拒绝/询问),实现自动权限决策。用户不需要逐个审批 bash 命令,分类器根据命令内容和上下文自动判断安全性。
|
||||
|
||||
### 核心特性
|
||||
|
||||
- **LLM 驱动分类**:使用 Opus 模型评估命令安全性
|
||||
- **两阶段分类**:快速阻止/允许 → 深度思考链
|
||||
- **自动审批**:分类器判定安全的命令自动通过
|
||||
- **UI 集成**:权限对话框显示分类器状态和审核选项
|
||||
|
||||
## 二、实现架构
|
||||
|
||||
### 2.1 模块状态
|
||||
|
||||
| 模块 | 文件 | 状态 | 说明 |
|
||||
|------|------|------|------|
|
||||
| Bash 分类器 | `src/utils/permissions/bashClassifier.ts` | **Stub** | 所有函数返回空操作。注释:"ANT-ONLY" |
|
||||
| YOLO 分类器 | `src/utils/permissions/yoloClassifier.ts` | **完整** | 1496 行,两阶段 XML 分类器 |
|
||||
| 审批信号 | `src/utils/classifierApprovals.ts` | **完整** | Map + 信号管理分类器决策 |
|
||||
| 权限 UI | `src/components/permissions/BashPermissionRequest.tsx` | **布线** | 分类器状态显示、审核选项 |
|
||||
| 权限管道 | `src/hooks/toolPermission/handlers/*.ts` | **布线** | 分类器结果路由到决策 |
|
||||
| API beta 标头 | `src/services/api/withRetry.ts` | **布线** | 启用时发送 `bash_classifier` beta |
|
||||
|
||||
### 2.2 参考实现:yoloClassifier.ts
|
||||
|
||||
文件:`src/utils/permissions/yoloClassifier.ts`(1496 行)
|
||||
|
||||
这是已实现的完整分类器,可作为 bashClassifier.ts 的参考:
|
||||
|
||||
```
|
||||
两阶段分类:
|
||||
1. 快速阶段:构建对话记录 → 调用 sideQuery(Opus)→ 快速阻止/允许
|
||||
2. 深度阶段:思考链分析 → 最终决策
|
||||
```
|
||||
|
||||
特性:
|
||||
- 构建完整对话记录上下文
|
||||
- 调用安全系统提示的 sideQuery
|
||||
- GrowthBook 配置和指标
|
||||
- 错误处理和降级
|
||||
|
||||
### 2.3 分类器在权限管道中的位置
|
||||
|
||||
```
|
||||
bash 命令到达
|
||||
│
|
||||
▼
|
||||
bashPermissions.ts 权限检查
|
||||
│
|
||||
├── 传统规则匹配(字符串级别)
|
||||
│
|
||||
└── [BASH_CLASSIFIER] LLM 分类
|
||||
│
|
||||
├── allow → 自动通过
|
||||
├── deny → 自动拒绝
|
||||
└── ask → 显示权限对话框
|
||||
│
|
||||
├── 分类器自动审批标记
|
||||
└── 审核选项(用户可覆盖)
|
||||
```
|
||||
|
||||
## 三、需要补全的内容
|
||||
|
||||
| 函数 | 需要实现 | 说明 |
|
||||
|------|---------|------|
|
||||
| `classifyBashCommand()` | LLM 调用评估安全性 | 参考 yoloClassifier.ts 的两阶段模式 |
|
||||
| `isClassifierPermissionsEnabled()` | GrowthBook/配置检查 | 控制分类器是否激活 |
|
||||
| `getBashPromptDenyDescriptions()` | 返回基于提示的拒绝规则 | 权限设置描述 |
|
||||
| `getBashPromptAskDescriptions()` | 返回询问规则 | 需要用户确认的命令 |
|
||||
| `getBashPromptAllowDescriptions()` | 返回允许规则 | 自动通过的命令 |
|
||||
| `generateGenericDescription()` | LLM 生成命令描述 | 为权限对话框提供说明 |
|
||||
| `extractPromptDescription()` | 解析规则内容 | 从规则中提取描述 |
|
||||
|
||||
## 四、关键设计决策
|
||||
|
||||
1. **ANT-ONLY 标记**:bashClassifier.ts 标注为 "ANT-ONLY",可能是 Anthropic 内部服务端分类器的客户端适配
|
||||
2. **两阶段分类**:快速阶段处理明确情况(减少延迟),深度阶段处理模糊情况
|
||||
3. **分类器结果可审核**:权限 UI 显示分类器决策,用户可覆盖
|
||||
4. **YOLO 分类器参考**:yoloClassifier.ts 提供完整的分类器实现模式,可直接参考
|
||||
|
||||
## 五、使用方式
|
||||
|
||||
```bash
|
||||
# 启用 feature
|
||||
FEATURE_BASH_CLASSIFIER=1 bun run dev
|
||||
|
||||
# 配合 TREE_SITTER_BASH 使用(AST + LLM 双重安全)
|
||||
FEATURE_BASH_CLASSIFIER=1 FEATURE_TREE_SITTER_BASH=1 bun run dev
|
||||
```
|
||||
|
||||
## 六、文件索引
|
||||
|
||||
| 文件 | 行数 | 职责 |
|
||||
|------|------|------|
|
||||
| `src/utils/permissions/bashClassifier.ts` | — | Bash 分类器(stub,ANT-ONLY) |
|
||||
| `src/utils/permissions/yoloClassifier.ts` | 1496 | YOLO 分类器(完整参考实现) |
|
||||
| `src/utils/classifierApprovals.ts` | — | 分类器审批信号管理 |
|
||||
| `src/components/permissions/BashPermissionRequest.tsx:261-469` | — | 分类器 UI |
|
||||
| `src/hooks/toolPermission/handlers/interactiveHandler.ts` | — | 交互式权限处理 |
|
||||
| `src/services/api/withRetry.ts:81` | — | API beta 标头 |
|
||||
158
docs/features/bridge-mode.md
Normal file
158
docs/features/bridge-mode.md
Normal file
@@ -0,0 +1,158 @@
|
||||
# BRIDGE_MODE — 远程控制
|
||||
|
||||
> Feature Flag: `FEATURE_BRIDGE_MODE=1`
|
||||
> 实现状态:完整可用(v1 + v2 实现)
|
||||
> 引用数:28
|
||||
|
||||
## 一、功能概述
|
||||
|
||||
BRIDGE_MODE 将本地 CLI 注册为"bridge 环境",可从 claude.ai 或其他控制面远程驱动。本地终端变为一个"执行者",接受远程指令并执行。
|
||||
|
||||
### 核心特性
|
||||
|
||||
- **环境注册**:本地 CLI 向 Anthropic 服务器注册为可用的 bridge 环境
|
||||
- **工作轮询**:长轮询(long-poll)等待远程任务分配
|
||||
- **会话管理**:创建、恢复、归档远程会话
|
||||
- **权限透传**:远程权限请求发送到控制面,用户在 claude.ai 上批准/拒绝
|
||||
- **心跳保活**:定期发送 heartbeat 延长任务租约
|
||||
- **可信设备**:v2 支持可信设备令牌增强安全性
|
||||
|
||||
## 二、实现架构
|
||||
|
||||
### 2.1 版本演进
|
||||
|
||||
| 版本 | 实现 | 特点 |
|
||||
|------|------|------|
|
||||
| v1(env-based) | `src/bridge/replBridge.ts` | 基于环境变量的传统 bridge |
|
||||
| v2(env-less) | `src/bridge/remoteBridgeCore.ts` | 无需环境变量,更安全的 bridge |
|
||||
|
||||
### 2.2 API 协议
|
||||
|
||||
文件:`src/bridge/bridgeApi.ts`
|
||||
|
||||
Bridge API Client 提供 7 个核心操作:
|
||||
|
||||
| 操作 | HTTP | 说明 |
|
||||
|------|------|------|
|
||||
| `registerBridgeEnvironment` | POST `/v1/environments/bridge` | 注册本地环境,获取 `environment_id` + `environment_secret` |
|
||||
| `pollForWork` | GET `/v1/environments/{id}/work/poll` | 长轮询等待任务(10s 超时) |
|
||||
| `acknowledgeWork` | POST `/v1/environments/{id}/work/{workId}/ack` | 确认接收任务 |
|
||||
| `stopWork` | POST `/v1/environments/{id}/work/{workId}/stop` | 停止任务 |
|
||||
| `heartbeatWork` | POST `/v1/environments/{id}/work/{workId}/heartbeat` | 续约任务租约 |
|
||||
| `deregisterEnvironment` | DELETE `/v1/environments/bridge/{id}` | 注销环境 |
|
||||
| `archiveSession` | POST `/v1/sessions/{id}/archive` | 归档会话(409 = 已归档,幂等) |
|
||||
| `sendPermissionResponseEvent` | POST `/v1/sessions/{id}/events` | 发送权限审批结果 |
|
||||
| `reconnectSession` | POST `/v1/environments/{id}/bridge/reconnect` | 重连已存在的会话 |
|
||||
|
||||
### 2.3 认证流程
|
||||
|
||||
```
|
||||
注册: OAuth Bearer Token → 获取 environment_secret
|
||||
轮询: environment_secret 作为 Authorization
|
||||
├── 401 → 尝试 OAuth token 刷新(onAuth401)
|
||||
└── 刷新成功 → 重试一次
|
||||
```
|
||||
|
||||
**OAuth 刷新**:API client 内置 `withOAuthRetry` 机制。401 时调用 `handleOAuth401Error`(同 withRetry.ts 的 v1/messages 模式),刷新后重试一次。
|
||||
|
||||
### 2.4 安全设计
|
||||
|
||||
- **路径穿越防护**:`validateBridgeId()` 使用 `/^[a-zA-Z0-9_-]+$/` 白名单验证所有服务端 ID
|
||||
- **BridgeFatalError**:不可重试的错误(401/403/404/410)直接抛出,阻止重试循环
|
||||
- **可信设备令牌**:v2 通过 `X-Trusted-Device-Token` header 增强安全层级
|
||||
- **幂关注册**:支持 `reuseEnvironmentId` 实现会话恢复,避免重复创建环境
|
||||
|
||||
### 2.5 数据流
|
||||
|
||||
```
|
||||
claude.ai 用户选择远程环境
|
||||
│
|
||||
▼
|
||||
POST /v1/environments/bridge (注册)
|
||||
│
|
||||
◀── environment_id + environment_secret
|
||||
│
|
||||
▼
|
||||
GET .../work/poll (长轮询)
|
||||
│
|
||||
◀── WorkResponse { id, data: { type, sessionId } }
|
||||
│
|
||||
▼
|
||||
POST .../work/{id}/ack (确认)
|
||||
│
|
||||
▼
|
||||
sessionRunner 创建 REPL session
|
||||
│
|
||||
├── 权限请求 → sendPermissionResponseEvent
|
||||
├── 心跳 → heartbeatWork (续约)
|
||||
└── 任务完成 → 自动归档
|
||||
```
|
||||
|
||||
### 2.6 模块结构
|
||||
|
||||
| 模块 | 文件 | 职责 |
|
||||
|------|------|------|
|
||||
| API Client | `bridgeApi.ts` | HTTP 通信(注册/轮询/确认/心跳/注销) |
|
||||
| Session Runner | `sessionRunner.ts` | 创建/恢复 REPL 会话 |
|
||||
| Bridge Config | `bridgeConfig.ts` | 配置管理(machine name、max sessions 等) |
|
||||
| Transport | `replBridgeTransport.ts` | Bridge 传输层 |
|
||||
| Permission Callbacks | `bridgePermissionCallbacks.ts` | 权限请求处理 |
|
||||
| Pointer | `bridgePointer.ts` | 当前活跃 bridge 状态指针 |
|
||||
| Flush Gate | `flushGate.ts` | 刷新控制 |
|
||||
| JWT Utils | `jwtUtils.ts` | JWT 令牌工具 |
|
||||
| Trusted Device | `trustedDevice.ts` | 可信设备管理 |
|
||||
| Debug Utils | `debugUtils.ts` | 调试日志 |
|
||||
| Types | `types.ts` | 类型定义 |
|
||||
|
||||
## 三、关键设计决策
|
||||
|
||||
1. **长轮询而非 WebSocket**:`pollForWork` 使用 HTTP GET + 10s 超时。简单可靠,无需维护 WebSocket 连接
|
||||
2. **OAuth 刷新内嵌**:API client 自带 `withOAuthRetry`,无需外层重试逻辑
|
||||
3. **ETag 条件请求**:注册时支持 `reuseEnvironmentId` 实现幂等会话恢复
|
||||
4. **v1/v2 共存**:代码中同时存在两套实现,v2 是更安全的升级版
|
||||
5. **权限双向流动**:本地权限请求发送到 claude.ai,用户在 web 上审批
|
||||
|
||||
## 四、使用方式
|
||||
|
||||
```bash
|
||||
# 启用 bridge mode
|
||||
FEATURE_BRIDGE_MODE=1 bun run dev
|
||||
|
||||
# 从 claude.ai/code 远程连接
|
||||
# 在 web 界面选择已注册的环境
|
||||
|
||||
# 配合 DAEMON 使用(后台守护)
|
||||
FEATURE_BRIDGE_MODE=1 FEATURE_DAEMON=1 bun run dev
|
||||
```
|
||||
|
||||
## 五、外部依赖
|
||||
|
||||
| 依赖 | 说明 |
|
||||
|------|------|
|
||||
| Anthropic OAuth | claude.ai 订阅登录 |
|
||||
| GrowthBook | `tengu_ccr_bridge` 门控 |
|
||||
| Bridge API | `/v1/environments/bridge` 系列端点 |
|
||||
|
||||
## 六、文件索引
|
||||
|
||||
| 文件 | 行数 | 职责 |
|
||||
|------|------|------|
|
||||
| `src/bridge/bridgeApi.ts` | 540 | API Client(核心) |
|
||||
| `src/bridge/sessionRunner.ts` | — | 会话运行器 |
|
||||
| `src/bridge/bridgeConfig.ts` | — | 配置管理 |
|
||||
| `src/bridge/replBridgeTransport.ts` | — | 传输层 |
|
||||
| `src/bridge/bridgePermissionCallbacks.ts` | — | 权限回调 |
|
||||
| `src/bridge/bridgePointer.ts` | — | 状态指针 |
|
||||
| `src/bridge/flushGate.ts` | — | 刷新控制 |
|
||||
| `src/bridge/jwtUtils.ts` | — | JWT 工具 |
|
||||
| `src/bridge/trustedDevice.ts` | — | 可信设备 |
|
||||
| `src/bridge/remoteBridgeCore.ts` | — | v2 核心实现 |
|
||||
| `src/bridge/types.ts` | — | 类型定义 |
|
||||
| `src/bridge/debugUtils.ts` | — | 调试工具 |
|
||||
| `src/bridge/pollConfigDefaults.ts` | — | 轮询配置默认值 |
|
||||
| `src/bridge/bridgeUI.ts` | — | UI 组件 |
|
||||
| `src/bridge/codeSessionApi.ts` | — | 代码会话 API |
|
||||
| `src/bridge/peerSessions.ts` | — | 对等会话管理 |
|
||||
| `src/bridge/sessionIdCompat.ts` | — | Session ID 兼容层 |
|
||||
| `src/bridge/createSession.ts` | — | 会话创建 |
|
||||
| `src/bridge/replBridgeHandle.ts` | — | Bridge 句柄 |
|
||||
140
docs/features/context-collapse.md
Normal file
140
docs/features/context-collapse.md
Normal file
@@ -0,0 +1,140 @@
|
||||
# CONTEXT_COLLAPSE — 上下文折叠
|
||||
|
||||
> Feature Flag: `FEATURE_CONTEXT_COLLAPSE=1`
|
||||
> 子 Feature: `FEATURE_HISTORY_SNIP=1`
|
||||
> 实现状态:核心逻辑全部 Stub,布线完整
|
||||
> 引用数:CONTEXT_COLLAPSE 20 + HISTORY_SNIP 16 = 36
|
||||
|
||||
## 一、功能概述
|
||||
|
||||
CONTEXT_COLLAPSE 让模型内省上下文窗口使用情况,并智能压缩旧消息。当对话接近上下文限制时,自动将旧消息折叠为压缩摘要,保留关键信息的同时释放 token 空间。
|
||||
|
||||
### 子 Feature
|
||||
|
||||
| Feature | 功能 |
|
||||
|---------|------|
|
||||
| `CONTEXT_COLLAPSE` | 上下文折叠引擎(后台 LLM 调用压缩旧消息) |
|
||||
| `HISTORY_SNIP` | SnipTool — 标记消息进行折叠/修剪 |
|
||||
|
||||
## 二、实现架构
|
||||
|
||||
### 2.1 模块状态
|
||||
|
||||
| 模块 | 文件 | 状态 |
|
||||
|------|------|------|
|
||||
| 折叠核心 | `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/` | **缺失** — 目录不存在 |
|
||||
| SnipTool 提示 | `src/tools/SnipTool/prompt.ts` | **Stub** — 空工具名 |
|
||||
| SnipTool 实现 | `src/tools/SnipTool/SnipTool.ts` | **缺失** |
|
||||
| force-snip 命令 | `src/commands/force-snip.js` | **缺失** |
|
||||
| 折叠读取搜索 | `src/utils/collapseReadSearch.ts` | **完整** — Snip 作为静默吸收操作 |
|
||||
| QueryEngine 集成 | `src/QueryEngine.ts` | **布线** — 导入并使用 snip 投影 |
|
||||
| Token 警告 UI | `src/components/TokenWarning.tsx` | **布线** — 折叠进度标签 |
|
||||
|
||||
### 2.2 核心接口(已定义,待实现)
|
||||
|
||||
```ts
|
||||
// contextCollapse/index.ts
|
||||
interface ContextCollapseStats {
|
||||
// 上下文使用统计
|
||||
}
|
||||
interface CollapseResult {
|
||||
// 折叠操作结果
|
||||
}
|
||||
interface DrainResult {
|
||||
// 紧急释放结果
|
||||
}
|
||||
|
||||
// 关键函数(全部 stub):
|
||||
isContextCollapseEnabled() // → false
|
||||
applyCollapsesIfNeeded(messages) // 透传
|
||||
recoverFromOverflow(messages) // 透传(413 恢复)
|
||||
initContextCollapse() // 空操作
|
||||
```
|
||||
|
||||
### 2.3 预期数据流
|
||||
|
||||
```
|
||||
对话持续增长
|
||||
│
|
||||
▼
|
||||
上下文接近限制(由 query.ts 检测)
|
||||
│
|
||||
├── 溢出检测 (query.ts:440,616,802)
|
||||
│
|
||||
▼
|
||||
applyCollapsesIfNeeded(messages) [需要实现]
|
||||
│
|
||||
├── 后台 LLM 调用压缩旧消息
|
||||
├── 保留关键信息(决策、文件路径、错误)
|
||||
└── 替换旧消息为压缩摘要
|
||||
│
|
||||
├── 413 恢复 (query.ts:1093,1179)
|
||||
│ └── recoverFromOverflow() 紧急折叠
|
||||
│
|
||||
▼
|
||||
projectView() 过滤折叠后的消息视图
|
||||
│
|
||||
▼
|
||||
模型继续工作(在压缩后的上下文中)
|
||||
```
|
||||
|
||||
### 2.4 HISTORY_SNIP 子功能
|
||||
|
||||
SnipTool 提供手动折叠能力:
|
||||
|
||||
- `/force-snip` 命令 — 强制执行折叠
|
||||
- SnipTool — 标记特定消息进行折叠/修剪
|
||||
- `collapseReadSearch.ts` 已完整实现,将 Snip 作为静默吸收操作处理
|
||||
|
||||
### 2.5 集成点
|
||||
|
||||
| 文件 | 位置 | 说明 |
|
||||
|------|------|------|
|
||||
| `src/query.ts` | 18,440,616,802,1093,1179 | 溢出检测、413 恢复、折叠应用 |
|
||||
| `src/QueryEngine.ts` | 124,127,1301 | Snip 投影使用 |
|
||||
| `src/utils/analyzeContext.ts` | 1122 | 跳过保留缓冲区显示 |
|
||||
| `src/utils/sessionRestore.ts` | 127,494 | 恢复折叠状态 |
|
||||
| `src/services/compact/autoCompact.ts` | 179,215 | 自动压缩时考虑折叠 |
|
||||
|
||||
## 三、需要补全的内容
|
||||
|
||||
| 优先级 | 模块 | 工作量 | 说明 |
|
||||
|--------|------|--------|------|
|
||||
| 1 | `services/contextCollapse/index.ts` | 大 | 折叠状态机、LLM 调用、消息压缩 |
|
||||
| 2 | `services/contextCollapse/operations.ts` | 中 | `projectView()` 消息过滤 |
|
||||
| 3 | `services/contextCollapse/persist.ts` | 小 | `restoreFromEntries()` 磁盘持久化 |
|
||||
| 4 | `tools/CtxInspectTool/` | 中 | 上下文内省工具(token 计数、已折叠范围) |
|
||||
| 5 | `tools/SnipTool/SnipTool.ts` | 中 | Snip 工具实现 |
|
||||
| 6 | `commands/force-snip.js` | 小 | `/force-snip` 命令 |
|
||||
|
||||
## 四、关键设计决策
|
||||
|
||||
1. **后台 LLM 压缩**:折叠不是简单截断,而是用 LLM 生成压缩摘要保留关键信息
|
||||
2. **413 恢复**:当 API 返回 413(请求过大)时,紧急折叠是最重要的恢复手段
|
||||
3. **与 autoCompact 协作**:折叠和自动压缩(compact)是不同的机制,折叠在消息级别,压缩在对话级别
|
||||
4. **持久化**:折叠状态持久化到磁盘,会话恢复时重载
|
||||
|
||||
## 五、使用方式
|
||||
|
||||
```bash
|
||||
# 启用 context collapse
|
||||
FEATURE_CONTEXT_COLLAPSE=1 bun run dev
|
||||
|
||||
# 启用 snip 子功能
|
||||
FEATURE_CONTEXT_COLLAPSE=1 FEATURE_HISTORY_SNIP=1 bun run dev
|
||||
```
|
||||
|
||||
## 六、文件索引
|
||||
|
||||
| 文件 | 职责 |
|
||||
|------|------|
|
||||
| `src/services/contextCollapse/index.ts` | 折叠核心(stub,接口已定义) |
|
||||
| `src/services/contextCollapse/operations.ts` | 投影操作(stub) |
|
||||
| `src/services/contextCollapse/persist.ts` | 持久化(stub) |
|
||||
| `src/utils/collapseReadSearch.ts` | Snip 吸收操作(完整) |
|
||||
| `src/query.ts` | 溢出检测和 413 恢复集成 |
|
||||
| `src/QueryEngine.ts` | Snip 投影使用 |
|
||||
| `src/components/TokenWarning.tsx` | 折叠进度 UI |
|
||||
151
docs/features/coordinator-mode.md
Normal file
151
docs/features/coordinator-mode.md
Normal file
@@ -0,0 +1,151 @@
|
||||
# COORDINATOR_MODE — 多 Agent 编排
|
||||
|
||||
> Feature Flag: `FEATURE_COORDINATOR_MODE=1` + 环境变量 `CLAUDE_CODE_COORDINATOR_MODE=1`
|
||||
> 实现状态:编排者完整可用,worker agent 为通用 AgentTool worker
|
||||
> 引用数:32
|
||||
|
||||
## 一、功能概述
|
||||
|
||||
COORDINATOR_MODE 将 CLI 变为"编排者"角色。编排者不直接操作文件,而是通过 AgentTool 派发任务给多个 worker 并行执行。适用于大型任务拆分、并行研究、实现+验证分离等场景。
|
||||
|
||||
### 核心约束
|
||||
|
||||
- 编排者只能使用:`Agent`(派发 worker)、`SendMessage`(继续 worker)、`TaskStop`(停止 worker)
|
||||
- Worker 可以使用所有标准工具(Bash、Read、Edit 等)+ MCP 工具 + Skill 工具
|
||||
- 编排者的每条消息都是给用户看的;worker 结果以 `<task-notification>` XML 形式到达
|
||||
|
||||
## 二、用户交互
|
||||
|
||||
### 启用方式
|
||||
|
||||
```bash
|
||||
FEATURE_COORDINATOR_MODE=1 CLAUDE_CODE_COORDINATOR_MODE=1 bun run dev
|
||||
```
|
||||
|
||||
需要同时设置 feature flag 和环境变量。`CLAUDE_CODE_COORDINATOR_MODE` 可在会话恢复时自动切换(`matchSessionMode`)。
|
||||
|
||||
### 典型工作流
|
||||
|
||||
```
|
||||
用户: "修复 auth 模块的 null pointer"
|
||||
|
||||
编排者:
|
||||
1. 并行派发两个 worker:
|
||||
- Agent({ description: "调查 auth bug", prompt: "..." })
|
||||
- Agent({ description: "研究 auth 测试", prompt: "..." })
|
||||
|
||||
2. 收到 <task-notification>:
|
||||
- Worker A: "在 validate.ts:42 发现 null pointer"
|
||||
- Worker B: "测试覆盖情况..."
|
||||
|
||||
3. 综合发现,继续 Worker A:
|
||||
- SendMessage({ to: "agent-a1b", message: "修复 validate.ts:42..." })
|
||||
|
||||
4. 收到修复结果,派发验证:
|
||||
- Agent({ description: "验证修复", prompt: "..." })
|
||||
```
|
||||
|
||||
## 三、实现架构
|
||||
|
||||
### 3.1 模式检测
|
||||
|
||||
文件:`src/coordinator/coordinatorMode.ts:36-41`
|
||||
|
||||
```ts
|
||||
export function isCoordinatorMode(): boolean {
|
||||
return feature('COORDINATOR_MODE') &&
|
||||
isEnvTruthy(process.env.CLAUDE_CODE_COORDINATOR_MODE)
|
||||
}
|
||||
```
|
||||
|
||||
### 3.2 会话模式恢复
|
||||
|
||||
`matchSessionMode(sessionMode)` 在恢复旧会话时检查存储的模式,如果当前环境变量与存储不一致,自动翻转环境变量。防止在普通模式下恢复编排会话(或反之)。
|
||||
|
||||
### 3.3 Worker 工具集
|
||||
|
||||
`getCoordinatorUserContext()` 告知编排者 worker 可用的工具列表:
|
||||
|
||||
- **标准模式**:`ASYNC_AGENT_ALLOWED_TOOLS` 排除内部工具(TeamCreate、TeamDelete、SendMessage、SyntheticOutput)
|
||||
- **Simple 模式**(`CLAUDE_CODE_SIMPLE=1`):仅 Bash、Read、Edit
|
||||
- **MCP 工具**:列出已连接的 MCP 服务器名称
|
||||
- **Scratchpad**:如果 GrowthBook `tengu_scratch` 启用,提供跨 worker 共享的 scratchpad 目录
|
||||
|
||||
### 3.4 系统提示
|
||||
|
||||
文件:`src/coordinator/coordinatorMode.ts:111-369`
|
||||
|
||||
编排者系统提示(`getCoordinatorSystemPrompt()`)约 370 行,包含:
|
||||
|
||||
| 章节 | 内容 |
|
||||
|------|------|
|
||||
| 1. Your Role | 编排者职责定义 |
|
||||
| 2. Your Tools | Agent/SendMessage/TaskStop 使用说明 |
|
||||
| 3. Workers | Worker 能力和限制 |
|
||||
| 4. Task Workflow | Research → Synthesis → Implementation → Verification 流程 |
|
||||
| 5. Writing Worker Prompts | 自包含 prompt 编写指南 + 好坏示例对比 |
|
||||
| 6. Example Session | 完整示例对话 |
|
||||
|
||||
### 3.5 Worker Agent
|
||||
|
||||
文件:`src/coordinator/workerAgent.ts`
|
||||
|
||||
当前为 stub。Worker 实际使用通用 AgentTool 的 `worker` subagent_type。
|
||||
|
||||
### 3.6 数据流
|
||||
|
||||
```
|
||||
用户消息
|
||||
│
|
||||
▼
|
||||
编排者 REPL(受限工具集)
|
||||
│
|
||||
├──→ Agent({ subagent_type: "worker", prompt: "..." })
|
||||
│ │
|
||||
│ ▼
|
||||
│ Worker Agent(完整工具集)
|
||||
│ ├── 执行任务(Bash/Read/Edit/...)
|
||||
│ └── 返回 <task-notification>
|
||||
│
|
||||
├──→ SendMessage({ to: "agent-id", message: "..." })
|
||||
│ │
|
||||
│ ▼
|
||||
│ 继续已存在的 Worker
|
||||
│
|
||||
└──→ TaskStop({ task_id: "agent-id" })
|
||||
│
|
||||
▼
|
||||
停止运行中的 Worker
|
||||
```
|
||||
|
||||
## 四、关键设计决策
|
||||
|
||||
1. **双开关设计**:feature flag 控制代码可用性,环境变量控制实际激活。允许编译时包含但不默认启用
|
||||
2. **编排者受限**:只能用 Agent/SendMessage/TaskStop,确保编排者专注于派发而非执行
|
||||
3. **Worker 不可见编排者对话**:每个 worker 的 prompt 必须自包含(所有必要上下文)
|
||||
4. **并行优先**:系统提示强调"Parallelism is your superpower",鼓励并行派发独立任务
|
||||
5. **综合而非转发**:编排者必须理解 worker 发现,再写出具体的实现指令。禁止 "based on your findings" 类懒惰委托
|
||||
6. **Scratchpad 可选共享**:通过 GrowthBook 门控的共享目录,让 worker 之间持久化共享知识
|
||||
|
||||
## 五、使用方式
|
||||
|
||||
```bash
|
||||
# 基本启用
|
||||
FEATURE_COORDINATOR_MODE=1 CLAUDE_CODE_COORDINATOR_MODE=1 bun run dev
|
||||
|
||||
# 配合 Fork Subagent
|
||||
FEATURE_COORDINATOR_MODE=1 FEATURE_FORK_SUBAGENT=1 \
|
||||
CLAUDE_CODE_COORDINATOR_MODE=1 bun run dev
|
||||
|
||||
# Simple 模式(worker 只有 Bash/Read/Edit)
|
||||
FEATURE_COORDINATOR_MODE=1 CLAUDE_CODE_COORDINATOR_MODE=1 \
|
||||
CLAUDE_CODE_SIMPLE=1 bun run dev
|
||||
```
|
||||
|
||||
## 六、文件索引
|
||||
|
||||
| 文件 | 行数 | 职责 |
|
||||
|------|------|------|
|
||||
| `src/coordinator/coordinatorMode.ts` | 370 | 模式检测 + 系统提示 + 用户上下文 |
|
||||
| `src/coordinator/workerAgent.ts` | — | Worker agent 定义(stub) |
|
||||
| `src/constants/tools.ts` | — | `ASYNC_AGENT_ALLOWED_TOOLS` 工具白名单 |
|
||||
102
docs/features/daemon.md
Normal file
102
docs/features/daemon.md
Normal file
@@ -0,0 +1,102 @@
|
||||
# DAEMON — 后台守护进程
|
||||
|
||||
> Feature Flag: `FEATURE_DAEMON=1`
|
||||
> 实现状态:主进程和 worker 注册为 Stub,CLI 路由完整
|
||||
> 引用数:3
|
||||
|
||||
## 一、功能概述
|
||||
|
||||
DAEMON 将 Claude Code 变为后台守护进程。主进程(supervisor)管理多个 worker 进程的生命周期,通过 Unix 域套接字进行 IPC。适用于持续运行的后台服务场景(如配合 BRIDGE_MODE 提供远程控制服务)。
|
||||
|
||||
## 二、实现架构
|
||||
|
||||
### 2.1 模块状态
|
||||
|
||||
| 模块 | 文件 | 状态 |
|
||||
|------|------|------|
|
||||
| 守护主进程 | `src/daemon/main.ts` | **Stub** — `daemonMain: () => Promise.resolve()` |
|
||||
| Worker 注册 | `src/daemon/workerRegistry.ts` | **Stub** — `runDaemonWorker: () => Promise.resolve()` |
|
||||
| CLI 路由 | `src/entrypoints/cli.tsx` | **布线** — `--daemon-worker` 和 `daemon` 子命令 |
|
||||
| 命令注册 | `src/commands.ts` | **布线** — DAEMON + BRIDGE_MODE 门控 |
|
||||
|
||||
### 2.2 CLI 入口
|
||||
|
||||
```
|
||||
# 启动守护进程
|
||||
claude daemon
|
||||
|
||||
# 以 worker 身份启动
|
||||
claude --daemon-worker=<kind>
|
||||
```
|
||||
|
||||
### 2.3 预期架构
|
||||
|
||||
```
|
||||
Supervisor (daemonMain)
|
||||
│
|
||||
├── Worker 1: assistant-mode
|
||||
│ └── 接收和处理 assistant 会话
|
||||
│
|
||||
├── Worker 2: bridge-sync
|
||||
│ └── bridge 消息同步
|
||||
│
|
||||
└── Worker 3: proactive
|
||||
└── 主动任务执行
|
||||
│
|
||||
▼
|
||||
IPC via Unix Domain Sockets
|
||||
- 生命周期管理(启动、停止、重启)
|
||||
- 工作分发
|
||||
- 状态报告
|
||||
```
|
||||
|
||||
### 2.4 与 BRIDGE_MODE 的关系
|
||||
|
||||
DAEMON 和 BRIDGE_MODE 常组合使用:
|
||||
|
||||
```ts
|
||||
// src/commands.ts
|
||||
if (feature('DAEMON') && feature('BRIDGE_MODE')) {
|
||||
// 加载 remoteControlServer 命令
|
||||
}
|
||||
```
|
||||
|
||||
双重门控:两个 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**:本地进程间通信,低延迟
|
||||
3. **与 BRIDGE_MODE 强绑定**:守护进程最常见的用途是提供远程控制服务
|
||||
4. **CLI 子命令路由**:`daemon` 子命令和 `--daemon-worker` 参数在 `cli.tsx` 中路由
|
||||
|
||||
## 五、使用方式
|
||||
|
||||
```bash
|
||||
# 启用守护进程模式
|
||||
FEATURE_DAEMON=1 FEATURE_BRIDGE_MODE=1 bun run dev
|
||||
|
||||
# 启动守护进程
|
||||
claude daemon
|
||||
|
||||
# 以特定 worker 启动
|
||||
claude --daemon-worker=assistant
|
||||
```
|
||||
|
||||
## 六、文件索引
|
||||
|
||||
| 文件 | 职责 |
|
||||
|------|------|
|
||||
| `src/daemon/main.ts` | Supervisor 主进程(stub) |
|
||||
| `src/daemon/workerRegistry.ts` | Worker 注册(stub) |
|
||||
| `src/entrypoints/cli.tsx:95,149` | CLI 路由 |
|
||||
| `src/commands.ts:77` | 命令注册(双重门控) |
|
||||
99
docs/features/experimental-skill-search.md
Normal file
99
docs/features/experimental-skill-search.md
Normal file
@@ -0,0 +1,99 @@
|
||||
# EXPERIMENTAL_SKILL_SEARCH — 技能语义搜索
|
||||
|
||||
> Feature Flag: `FEATURE_EXPERIMENTAL_SKILL_SEARCH=1`
|
||||
> 实现状态:全部 Stub(8 个文件),布线完整
|
||||
> 引用数:21
|
||||
|
||||
## 一、功能概述
|
||||
|
||||
EXPERIMENTAL_SKILL_SEARCH 提供 DiscoverSkills 工具,根据当前任务语义搜索可用技能。目标是让模型在执行任务时自动发现和推荐相关的技能(包括本地和远程),无需用户手动查找。
|
||||
|
||||
## 二、实现架构
|
||||
|
||||
### 2.1 模块状态
|
||||
|
||||
| 模块 | 文件 | 状态 | 说明 |
|
||||
|------|------|------|------|
|
||||
| DiscoverSkillsTool | `src/tools/DiscoverSkillsTool/prompt.ts` | **Stub** | 空工具名 |
|
||||
| 预取 | `src/services/skillSearch/prefetch.ts` | **Stub** | 3 个函数全部空操作 |
|
||||
| 远程加载 | `src/services/skillSearch/remoteSkillLoader.ts` | **Stub** | 返回空结果 |
|
||||
| 远程状态 | `src/services/skillSearch/remoteSkillState.ts` | **Stub** | 返回 null/undefined |
|
||||
| 信号 | `src/services/skillSearch/signals.ts` | **Stub** | `DiscoverySignal = any` |
|
||||
| 遥测 | `src/services/skillSearch/telemetry.ts` | **Stub** | 空操作日志 |
|
||||
| 本地搜索 | `src/services/skillSearch/localSearch.ts` | **Stub** | 空操作缓存 |
|
||||
| 功能检查 | `src/services/skillSearch/featureCheck.ts` | **Stub** | `isSkillSearchEnabled => false` |
|
||||
| SkillTool 集成 | `src/tools/SkillTool/SkillTool.ts` | **布线** | 动态加载所有远程技能模块 |
|
||||
| 提示集成 | `src/constants/prompts.ts` | **布线** | DiscoverSkills schema 注入 |
|
||||
|
||||
### 2.2 预期数据流
|
||||
|
||||
```
|
||||
模型处理用户任务
|
||||
│
|
||||
▼
|
||||
DiscoverSkills 工具触发 [需要实现]
|
||||
│
|
||||
├── 本地搜索:索引已安装技能元数据
|
||||
│ └── localSearch.ts → 技能名称/描述/关键字匹配
|
||||
│
|
||||
└── 远程搜索:查询技能市场/注册表
|
||||
└── remoteSkillLoader.ts → fetch + 解析
|
||||
│
|
||||
▼
|
||||
结果排序和过滤
|
||||
│
|
||||
▼
|
||||
返回推荐技能列表
|
||||
│
|
||||
▼
|
||||
模型使用 SkillTool 调用推荐技能
|
||||
```
|
||||
|
||||
### 2.3 预取机制
|
||||
|
||||
`prefetch.ts` 预期在用户提交输入前分析消息内容,提前搜索相关技能:
|
||||
|
||||
- `startSkillDiscoveryPrefetch()` — 开始预取
|
||||
- `collectSkillDiscoveryPrefetch()` — 收集预取结果
|
||||
- `getTurnZeroSkillDiscovery()` — 获取 turn 0 的技能发现结果
|
||||
|
||||
## 三、需要补全的内容
|
||||
|
||||
| 优先级 | 模块 | 工作量 | 说明 |
|
||||
|--------|------|--------|------|
|
||||
| 1 | `DiscoverSkillsTool` | 大 | 语义搜索工具 schema + 执行 |
|
||||
| 2 | `skillSearch/prefetch.ts` | 中 | 用户输入分析和预取逻辑 |
|
||||
| 3 | `skillSearch/remoteSkillLoader.ts` | 大 | 远程市场/注册表获取 |
|
||||
| 4 | `skillSearch/remoteSkillState.ts` | 小 | 已发现技能状态管理 |
|
||||
| 5 | `skillSearch/localSearch.ts` | 中 | 本地索引构建/查询 |
|
||||
| 6 | `skillSearch/featureCheck.ts` | 小 | GrowthBook/配置门控 |
|
||||
| 7 | `skillSearch/signals.ts` | 小 | `DiscoverySignal` 类型定义 |
|
||||
|
||||
## 四、关键设计决策
|
||||
|
||||
1. **预取优化**:在用户提交前就开始搜索,减少首次响应延迟
|
||||
2. **本地+远程双搜索**:本地索引快速匹配 + 远程市场深度搜索
|
||||
3. **SkillTool 集成**:发现的技能通过 SkillTool 调用,不需要新的调用机制
|
||||
4. **独立于 MCP_SKILLS**:MCP_SKILLS 从 MCP 服务器发现,EXPERIMENTAL_SKILL_SEARCH 从技能市场发现
|
||||
|
||||
## 五、使用方式
|
||||
|
||||
```bash
|
||||
# 启用 feature(需要补全后才能真正使用)
|
||||
FEATURE_EXPERIMENTAL_SKILL_SEARCH=1 bun run dev
|
||||
```
|
||||
|
||||
## 六、文件索引
|
||||
|
||||
| 文件 | 职责 |
|
||||
|------|------|
|
||||
| `src/tools/DiscoverSkillsTool/prompt.ts` | 工具 schema(stub) |
|
||||
| `src/services/skillSearch/prefetch.ts` | 预取逻辑(stub) |
|
||||
| `src/services/skillSearch/remoteSkillLoader.ts` | 远程加载(stub) |
|
||||
| `src/services/skillSearch/remoteSkillState.ts` | 远程状态(stub) |
|
||||
| `src/services/skillSearch/signals.ts` | 信号类型(stub) |
|
||||
| `src/services/skillSearch/telemetry.ts` | 遥测(stub) |
|
||||
| `src/services/skillSearch/localSearch.ts` | 本地搜索(stub) |
|
||||
| `src/services/skillSearch/featureCheck.ts` | 功能检查(stub) |
|
||||
| `src/tools/SkillTool/SkillTool.ts` | SkillTool 集成点 |
|
||||
| `src/constants/prompts.ts:95,335,778` | 提示增强 |
|
||||
195
docs/features/fork-subagent.md
Normal file
195
docs/features/fork-subagent.md
Normal file
@@ -0,0 +1,195 @@
|
||||
# FORK_SUBAGENT — 上下文继承子 Agent
|
||||
|
||||
> Feature Flag: `FEATURE_FORK_SUBAGENT=1`
|
||||
> 实现状态:完整可用
|
||||
> 引用数:4
|
||||
|
||||
## 一、功能概述
|
||||
|
||||
FORK_SUBAGENT 让 AgentTool 生成"fork 子 agent",继承父级完整对话上下文。子 agent 看到父级的所有历史消息、工具集和系统提示,并且与父级共享 API 请求前缀以最大化 prompt cache 命中率。
|
||||
|
||||
### 核心优势
|
||||
|
||||
- **Prompt Cache 最大化**:多个并行 fork 共享相同的 API 请求前缀,只有最后的 directive 文本块不同
|
||||
- **上下文完整性**:子 agent 继承父级的完整对话历史(包括 thinking config)
|
||||
- **权限冒泡**:子 agent 的权限提示上浮到父级终端显示
|
||||
- **Worktree 隔离**:支持 git worktree 隔离,子 agent 在独立分支工作
|
||||
|
||||
## 二、用户交互
|
||||
|
||||
### 触发方式
|
||||
|
||||
当 `FORK_SUBAGENT` 启用时,AgentTool 调用不指定 `subagent_type` 时自动走 fork 路径:
|
||||
|
||||
```
|
||||
// Fork 路径(继承上下文)
|
||||
Agent({ prompt: "修复这个 bug" }) // 无 subagent_type
|
||||
|
||||
// 普通 agent 路径(全新上下文)
|
||||
Agent({ subagent_type: "general-purpose", prompt: "..." })
|
||||
```
|
||||
|
||||
### /fork 命令
|
||||
|
||||
注册了 `/fork` 斜杠命令(当前为 stub)。当 FORK_SUBAGENT 开启时,`/branch` 命令失去 `fork` 别名,避免冲突。
|
||||
|
||||
## 三、实现架构
|
||||
|
||||
### 3.1 门控与互斥
|
||||
|
||||
文件:`src/tools/AgentTool/forkSubagent.ts:32-39`
|
||||
|
||||
```ts
|
||||
export function isForkSubagentEnabled(): boolean {
|
||||
if (feature('FORK_SUBAGENT')) {
|
||||
if (isCoordinatorMode()) return false // Coordinator 有自己的委派模型
|
||||
if (getIsNonInteractiveSession()) return false // pipe/SDK 模式禁用
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
```
|
||||
|
||||
### 3.2 FORK_AGENT 定义
|
||||
|
||||
```ts
|
||||
export const FORK_AGENT = {
|
||||
agentType: 'fork',
|
||||
tools: ['*'], // 通配符:使用父级完整工具集
|
||||
maxTurns: 200,
|
||||
model: 'inherit', // 继承父级模型
|
||||
permissionMode: 'bubble', // 权限冒泡到父级终端
|
||||
getSystemPrompt: () => '', // 不使用:直接传递父级已渲染 prompt
|
||||
}
|
||||
```
|
||||
|
||||
### 3.3 核心调用流程
|
||||
|
||||
```
|
||||
AgentTool.call({ prompt, name })
|
||||
│
|
||||
▼
|
||||
isForkSubagentEnabled() && !subagent_type?
|
||||
│
|
||||
├── No → 普通 agent 路径
|
||||
│
|
||||
└── Yes → Fork 路径
|
||||
│
|
||||
▼
|
||||
递归防护检查
|
||||
├── querySource === 'agent:builtin:fork' → 拒绝
|
||||
└── isInForkChild(messages) → 拒绝
|
||||
│
|
||||
▼
|
||||
获取父级 system prompt
|
||||
├── toolUseContext.renderedSystemPrompt(首选)
|
||||
└── buildEffectiveSystemPrompt(回退)
|
||||
│
|
||||
▼
|
||||
buildForkedMessages(prompt, assistantMessage)
|
||||
├── 克隆父级 assistant 消息
|
||||
├── 生成占位符 tool_result
|
||||
└── 附加 directive 文本块
|
||||
│
|
||||
▼
|
||||
[可选] buildWorktreeNotice()
|
||||
│
|
||||
▼
|
||||
runAgent({
|
||||
useExactTools: true,
|
||||
override.systemPrompt: 父级,
|
||||
forkContextMessages: 父级消息,
|
||||
availableTools: 父级工具,
|
||||
})
|
||||
```
|
||||
|
||||
### 3.4 消息构建:buildForkedMessages
|
||||
|
||||
文件:`src/tools/AgentTool/forkSubagent.ts:107-169`
|
||||
|
||||
构建的消息结构:
|
||||
|
||||
```
|
||||
[
|
||||
...history (filterIncompleteToolCalls), // 父级完整历史
|
||||
assistant(所有 tool_use 块), // 父级当前 turn 的 assistant 消息
|
||||
user(
|
||||
占位符 tool_result × N + // 相同占位符文本
|
||||
<fork-boilerplate> directive // 每个 fork 不同
|
||||
)
|
||||
]
|
||||
```
|
||||
|
||||
**所有 fork 使用相同的占位符文本**:`"Fork started — processing in background"`。这确保多个并行 fork 的 API 请求前缀完全一致,最大化 prompt cache 命中。
|
||||
|
||||
### 3.5 递归防护
|
||||
|
||||
两层检查防止 fork 嵌套:
|
||||
|
||||
1. **querySource 检查**:`toolUseContext.options.querySource === 'agent:builtin:fork'`。在 `context.options` 上设置,抗自动压缩(autocompact 只重写消息不改 options)
|
||||
2. **消息扫描**:`isInForkChild()` 扫描消息历史中的 `<fork-boilerplate>` 标签
|
||||
|
||||
### 3.6 Worktree 隔离通知
|
||||
|
||||
当 fork + worktree 组合时,追加通知告知子 agent:
|
||||
|
||||
> "你继承了父 agent 在 `{parentCwd}` 的对话上下文,但你在独立的 git worktree `{worktreeCwd}` 中操作。路径需要转换,编辑前重新读取。"
|
||||
|
||||
### 3.7 强制异步
|
||||
|
||||
当 `isForkSubagentEnabled()` 为 true 时,所有 agent 启动都强制异步。`run_in_background` 参数从 schema 中移除。统一通过 `<task-notification>` XML 消息交互。
|
||||
|
||||
## 四、Prompt Cache 优化
|
||||
|
||||
这是整个 fork 设计的核心优化目标:
|
||||
|
||||
| 优化点 | 实现 |
|
||||
|--------|------|
|
||||
| **相同 system prompt** | 直传 `renderedSystemPrompt`,避免重新渲染(GrowthBook 状态可能不一致) |
|
||||
| **相同工具集** | `useExactTools: true` 直接使用父级工具,不经过 `resolveAgentTools` 过滤 |
|
||||
| **相同 thinking config** | 继承父级 thinking 配置(非 fork agent 默认禁用 thinking) |
|
||||
| **相同占位符结果** | 所有 fork 使用 `FORK_PLACEHOLDER_RESULT` 相同文本 |
|
||||
| **ContentReplacementState 克隆** | 默认克隆父级替换状态,保持 wire prefix 一致 |
|
||||
|
||||
## 五、子 Agent 指令
|
||||
|
||||
`buildChildMessage()` 生成 `<fork-boilerplate>` 包裹的指令:
|
||||
|
||||
- 你是 fork worker,不是主 agent
|
||||
- 禁止再次 spawn sub-agent(直接执行)
|
||||
- 不要闲聊、不要元评论
|
||||
- 直接使用工具
|
||||
- 修改文件后要 commit,报告 commit hash
|
||||
- 报告格式:`Scope:` / `Result:` / `Key files:` / `Files changed:` / `Issues:`
|
||||
|
||||
## 六、关键设计决策
|
||||
|
||||
1. **Fork ≠ 普通 agent**:fork 继承完整上下文,普通 agent 从零开始。选择依据是 `subagent_type` 是否存在
|
||||
2. **renderedSystemPrompt 直传**:避免 fork 时重新调用 `getSystemPrompt()`。父级在 turn 开始时冻结 prompt 字节
|
||||
3. **占位符结果共享**:多个并行 fork 使用完全相同的占位符,只有 directive 不同
|
||||
4. **Coordinator 互斥**:Coordinator 模式下禁用 fork,两者有不兼容的委派模型
|
||||
5. **非交互式禁用**:pipe 模式和 SDK 模式下禁用,避免不可见的 fork 嵌套
|
||||
|
||||
## 七、使用方式
|
||||
|
||||
```bash
|
||||
# 启用 feature
|
||||
FEATURE_FORK_SUBAGENT=1 bun run dev
|
||||
|
||||
# 在 REPL 中使用(不指定 subagent_type 即走 fork)
|
||||
# Agent({ prompt: "研究这个模块的结构" })
|
||||
# Agent({ prompt: "实现这个功能" })
|
||||
```
|
||||
|
||||
## 八、文件索引
|
||||
|
||||
| 文件 | 行数 | 职责 |
|
||||
|------|------|------|
|
||||
| `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 恢复 |
|
||||
| `src/constants/xml.ts` | — | XML 标签常量 |
|
||||
| `src/utils/forkedAgent.ts` | — | CacheSafeParams + ContentReplacementState 克隆 |
|
||||
| `src/commands/fork/index.ts` | — | /fork 命令(stub) |
|
||||
179
docs/features/kairos.md
Normal file
179
docs/features/kairos.md
Normal file
@@ -0,0 +1,179 @@
|
||||
# KAIROS — 常驻助手模式
|
||||
|
||||
> Feature Flag: `FEATURE_KAIROS=1`(及子 Feature)
|
||||
> 实现状态:核心框架完整,部分子模块为 stub
|
||||
> 引用数:154(全库最大)
|
||||
|
||||
## 一、功能概述
|
||||
|
||||
KAIROS 将 Claude Code CLI 从"问答工具"转变为"常驻助手"。开启后,CLI 持续运行在后台,支持:
|
||||
|
||||
- **持久化 bridge 会话**:跨终端重启复用 session,通过 Anthropic OAuth 连接 claude.ai
|
||||
- **后台执行任务**:用户离开终端时继续工作(配合 PROACTIVE feature)
|
||||
- **推送通知到移动端**:任务完成或需要输入时推送(配合 `KAIROS_PUSH_NOTIFICATION`)
|
||||
- **每日记忆日志**:自动记录和回顾工作内容(配合 `KAIROS_DREAM`)
|
||||
- **外部频道消息接入**:Slack/Discord/Telegram 消息转发到 CLI(配合 `KAIROS_CHANNELS`)
|
||||
- **结构化 Brief 输出**:通过 BriefTool 输出结构化消息(配合 `KAIROS_BRIEF`)
|
||||
|
||||
### 子 Feature 依赖关系
|
||||
|
||||
```
|
||||
KAIROS (主开关)
|
||||
├── KAIROS_BRIEF (BriefTool, 结构化输出)
|
||||
├── KAIROS_CHANNELS (外部频道消息)
|
||||
├── KAIROS_PUSH_NOTIFICATION (移动端推送)
|
||||
├── KAIROS_GITHUB_WEBHOOKS (GitHub PR webhook)
|
||||
└── KAIROS_DREAM (记忆蒸馏)
|
||||
```
|
||||
|
||||
**注意**:PROACTIVE 与 KAIROS 强绑定。所有代码检查都是 `feature('PROACTIVE') || feature('KAIROS')`,即 KAIROS 开启时自动获得 proactive 能力。
|
||||
|
||||
## 二、系统提示
|
||||
|
||||
KAIROS 在系统提示中注入两大段落:
|
||||
|
||||
### 2.1 Brief 段落 (`getBriefSection`)
|
||||
|
||||
文件:`src/constants/prompts.ts:843-858`
|
||||
|
||||
当 `feature('KAIROS') || feature('KAIROS_BRIEF')` 时注入。Brief 工具(`SendUserMessage`)的结构化消息输出指令。`/brief` toggle 和 `--brief` flag 只控制显示过滤,不影响模型行为。
|
||||
|
||||
### 2.2 Proactive/Autonomous Work 段落 (`getProactiveSection`)
|
||||
|
||||
文件:`src/constants/prompts.ts:860-914`
|
||||
|
||||
当 `feature('PROACTIVE') || feature('KAIROS')` 且 `isProactiveActive()` 时注入。核心行为指令:
|
||||
|
||||
- **Tick 驱动**:通过 `<tick_tag>` prompt 保持存活,每个 tick 包含用户当前本地时间
|
||||
- **节奏控制**:使用 `SleepTool` 控制等待间隔(prompt cache 5 分钟过期)
|
||||
- **空操作时必须 Sleep**:禁止输出 "still waiting" 类文本(浪费 turn 和 token)
|
||||
- **偏向行动**:读文件、搜索代码、修改文件、commit — 都不需询问
|
||||
- **终端焦点感知**:`terminalFocus` 字段指示用户是否在看终端
|
||||
- Unfocused → 高度自主行动
|
||||
- Focused → 更协作,展示选择
|
||||
|
||||
## 三、实现架构
|
||||
|
||||
### 3.1 核心模块
|
||||
|
||||
| 模块 | 文件 | 状态 | 职责 |
|
||||
|------|------|------|------|
|
||||
| Assistant 入口 | `src/assistant/index.ts` | Stub | `isAssistantMode()`、`initializeAssistantTeam()` |
|
||||
| Session 发现 | `src/assistant/sessionDiscovery.ts` | Stub | 发现可用 bridge session |
|
||||
| Session 历史 | `src/assistant/sessionHistory.ts` | Stub | 持久化 session 历史 |
|
||||
| Gate 控制 | `src/assistant/gate.ts` | Stub | GrowthBook 门控检查 |
|
||||
| Session 选择器 | `src/assistant/AssistantSessionChooser.ts` | Stub | UI 选择 session |
|
||||
| BriefTool | `src/tools/BriefTool/` | Stub | 结构化消息输出工具 |
|
||||
| Channel Notification | `src/services/mcp/channelNotification.ts` | Stub | 外部频道消息接入 |
|
||||
| Dream Task | `src/components/tasks/src/tasks/DreamTask/` | Stub | 记忆蒸馏任务 |
|
||||
| Memory Directory | `src/memdir/memdir.ts` | Stub | 记忆目录管理 |
|
||||
|
||||
### 3.2 SleepTool(与 Proactive 共享)
|
||||
|
||||
文件:`src/tools/SleepTool/prompt.ts`
|
||||
|
||||
SleepTool 是 KAIROS/Proactive 的节奏控制核心。工具描述让模型理解"休眠"概念:
|
||||
- 工具名:`Sleep`
|
||||
- 功能:等待指定时间后响应 tick prompt
|
||||
- 与 `<tick_tag>` 配合实现心跳式自主工作
|
||||
|
||||
### 3.3 Bridge 集成
|
||||
|
||||
KAIROS 通过 Bridge Mode(`src/bridge/`)连接到 claude.ai 服务器:
|
||||
|
||||
```
|
||||
claude.ai web/app
|
||||
│
|
||||
▼ (HTTPS long-poll)
|
||||
┌──────────────────────┐
|
||||
│ Bridge API Client │ src/bridge/bridgeApi.ts
|
||||
│ (register/poll/ │
|
||||
│ acknowledge) │
|
||||
└──────────┬───────────┘
|
||||
│
|
||||
▼
|
||||
┌──────────────────────┐
|
||||
│ Session Runner │ src/bridge/sessionRunner.ts
|
||||
│ (创建/恢复 REPL) │
|
||||
└──────────┬───────────┘
|
||||
│
|
||||
▼
|
||||
┌──────────────────────┐
|
||||
│ REPL + Proactive │ Tick 驱动自主工作
|
||||
│ Tick Loop │
|
||||
└──────────────────────┘
|
||||
```
|
||||
|
||||
### 3.4 数据流
|
||||
|
||||
```
|
||||
用户从 claude.ai 发送消息
|
||||
│
|
||||
▼
|
||||
Bridge pollForWork() 收到 WorkResponse
|
||||
│
|
||||
▼
|
||||
acknowledgeWork() 确认接收
|
||||
│
|
||||
▼
|
||||
sessionRunner 创建/恢复 REPL session
|
||||
│
|
||||
▼
|
||||
用户消息注入到 REPL 对话
|
||||
│
|
||||
▼
|
||||
模型处理 → 工具调用 → BriefTool 结构化输出
|
||||
│
|
||||
▼
|
||||
结果通过 Bridge API 回传到 claude.ai
|
||||
```
|
||||
|
||||
## 四、关键设计决策
|
||||
|
||||
1. **Tick 驱动而非事件驱动**:模型通过 SleepTool 自行控制唤醒频率,而非外部事件推送。简化架构但增加 API 调用开销
|
||||
2. **KAIROS ⊃ PROACTIVE**:所有 proactive 检查都包含 KAIROS,无需同时开启两个 flag
|
||||
3. **Brief 显示/行为分离**:`/brief` toggle 只控制 UI 过滤,模型始终可以使用 BriefTool
|
||||
4. **Terminal Focus 感知**:模型根据用户是否在看终端自动调节自主程度
|
||||
5. **GrowthBook 门控**:部分功能(如推送通知)即使 feature flag 开启还需要服务端 GrowthBook 开关
|
||||
|
||||
## 五、使用方式
|
||||
|
||||
```bash
|
||||
# 最小启用(常驻助手 + Brief)
|
||||
FEATURE_KAIROS=1 FEATURE_KAIROS_BRIEF=1 bun run dev
|
||||
|
||||
# 全功能启用
|
||||
FEATURE_KAIROS=1 \
|
||||
FEATURE_KAIROS_BRIEF=1 \
|
||||
FEATURE_KAIROS_CHANNELS=1 \
|
||||
FEATURE_KAIROS_PUSH_NOTIFICATION=1 \
|
||||
FEATURE_KAIROS_GITHUB_WEBHOOKS=1 \
|
||||
FEATURE_PROACTIVE=1 \
|
||||
bun run dev
|
||||
|
||||
# 配合 Token Budget 使用
|
||||
FEATURE_KAIROS=1 FEATURE_TOKEN_BUDGET=1 bun run dev
|
||||
```
|
||||
|
||||
## 六、外部依赖
|
||||
|
||||
- **Anthropic OAuth**:必须使用 claude.ai 订阅登录(非 API key)
|
||||
- **GrowthBook**:服务端特性门控(`tengu_ccr_bridge` 等)
|
||||
- **Bridge API**:`/v1/environments/bridge` 系列端点
|
||||
|
||||
## 七、文件索引
|
||||
|
||||
| 文件 | 行数 | 职责 |
|
||||
|------|------|------|
|
||||
| `src/assistant/index.ts` | 9 | Assistant 模块入口(stub) |
|
||||
| `src/assistant/gate.ts` | — | GrowthBook 门控(stub) |
|
||||
| `src/assistant/sessionDiscovery.ts` | — | Session 发现(stub) |
|
||||
| `src/assistant/sessionHistory.ts` | — | Session 历史(stub) |
|
||||
| `src/assistant/AssistantSessionChooser.ts` | — | Session 选择 UI(stub) |
|
||||
| `src/tools/BriefTool/` | — | BriefTool 实现(stub) |
|
||||
| `src/tools/SleepTool/prompt.ts` | ~30 | SleepTool 工具提示 |
|
||||
| `src/services/mcp/channelNotification.ts` | 5 | 频道消息接入(stub) |
|
||||
| `src/memdir/memdir.ts` | — | 记忆目录管理(stub) |
|
||||
| `src/constants/prompts.ts:552-554,843-914` | 72 | 系统提示注入 |
|
||||
| `src/components/tasks/src/tasks/DreamTask/` | 3 | Dream 任务(stub) |
|
||||
| `src/proactive/index.ts` | — | Proactive 核心(stub,KAIROS 共享) |
|
||||
118
docs/features/mcp-skills.md
Normal file
118
docs/features/mcp-skills.md
Normal file
@@ -0,0 +1,118 @@
|
||||
# MCP_SKILLS — MCP 技能发现
|
||||
|
||||
> Feature Flag: `FEATURE_MCP_SKILLS=1`
|
||||
> 实现状态:功能性实现(config 门控筛选器完整,核心 fetcher 为 stub)
|
||||
> 引用数:9
|
||||
|
||||
## 一、功能概述
|
||||
|
||||
MCP_SKILLS 将 MCP 服务器暴露的资源(`skill://` URI 方案)发现并转换为可调用的技能命令。MCP 服务器可以同时提供 tools、prompts 和 resources;启用此 feature 后,带有 `skill://` URI 的资源被识别为技能。
|
||||
|
||||
### 核心特性
|
||||
|
||||
- **自动发现**:MCP 服务器连接时自动获取 `skill://` 资源
|
||||
- **命令转换**:将 MCP 资源转换为 `prompt` 类型的 Command 对象
|
||||
- **实时刷新**:prompts/resources 列表变化时重新获取技能
|
||||
- **缓存一致性**:连接关闭时清除技能缓存
|
||||
|
||||
## 二、实现架构
|
||||
|
||||
### 2.1 数据流
|
||||
|
||||
```
|
||||
MCP Server 连接
|
||||
│
|
||||
▼
|
||||
client.ts: connectToServer / setupMcpClientConnections
|
||||
├── fetchToolsForClient (MCP tools)
|
||||
├── fetchCommandsForClient (MCP prompts → Command 对象)
|
||||
├── fetchMcpSkillsForClient (MCP skill:// 资源 → Command 对象) [MCP_SKILLS]
|
||||
└── fetchResourcesForClient (MCP resources)
|
||||
│
|
||||
▼
|
||||
commands = [...mcpPrompts, ...mcpSkills]
|
||||
│
|
||||
▼
|
||||
AppState.mcp.commands 更新
|
||||
│
|
||||
▼
|
||||
getMcpSkillCommands() 过滤 → SkillTool 调用
|
||||
```
|
||||
|
||||
### 2.2 技能筛选
|
||||
|
||||
文件:`src/commands.ts:547-558`
|
||||
|
||||
`getMcpSkillCommands(mcpCommands)` 过滤条件:
|
||||
|
||||
```ts
|
||||
cmd.type === 'prompt' // 必须是 prompt 类型
|
||||
cmd.loadedFrom === 'mcp' // 必须来自 MCP 服务器
|
||||
!cmd.disableModelInvocation // 必须可由模型调用
|
||||
feature('MCP_SKILLS') // feature flag 必须开启
|
||||
```
|
||||
|
||||
### 2.3 条件加载
|
||||
|
||||
文件:`src/services/mcp/client.ts:117-121`
|
||||
|
||||
`fetchMcpSkillsForClient` 通过 `require()` 条件加载,feature flag 关闭时不加载任何模块:
|
||||
|
||||
```ts
|
||||
const fetchMcpSkillsForClient = feature('MCP_SKILLS')
|
||||
? require('../../skills/mcpSkills.js').fetchMcpSkillsForClient
|
||||
: null
|
||||
```
|
||||
|
||||
### 2.4 缓存管理
|
||||
|
||||
技能获取函数维护 `.cache`(Map),在以下时机清除:
|
||||
|
||||
| 事件 | 行为 |
|
||||
|------|------|
|
||||
| 连接关闭 | 清除该 client 的技能缓存 |
|
||||
| `disconnectMcpServer()` | 清除技能缓存 |
|
||||
| `prompts/list_changed` 通知 | 刷新 prompts + 并行获取技能 |
|
||||
| `resources/list_changed` 通知 | 刷新 resources + prompts + 技能 |
|
||||
|
||||
### 2.5 集成点
|
||||
|
||||
| 文件 | 行 | 说明 |
|
||||
|------|------|------|
|
||||
| `src/commands.ts` | 547-558, 561-608 | 命令过滤和 SkillTool 命令收集 |
|
||||
| `src/services/mcp/client.ts` | 117-121, 1394, 1672, 2173-2181, 2346-2358 | 技能获取、缓存清除、连接时获取 |
|
||||
| `src/services/mcp/useManageMCPConnections.ts` | 22-26, 682-740 | 实时刷新(prompts/resources 变化) |
|
||||
|
||||
## 三、关键设计决策
|
||||
|
||||
1. **Feature gate 隔离**:`feature('MCP_SKILLS')` 守护条件 `require()` 和所有调用点。关闭时无模块加载、无获取操作
|
||||
2. **资源到技能映射**:技能从 MCP 服务器的 `skill://` URI 资源中发现。`fetchMcpSkillsForClient` 负责转换(当前为 stub)
|
||||
3. **循环依赖避免**:`mcpSkillBuilders.ts` 作为依赖图叶节点,避免 `client.ts ↔ mcpSkills.ts ↔ loadSkillsDir.ts` 循环
|
||||
4. **服务器能力检查**:技能获取还需要 MCP 服务器支持 resources (`!!client.capabilities?.resources`)
|
||||
|
||||
## 四、使用方式
|
||||
|
||||
```bash
|
||||
# 启用 feature
|
||||
FEATURE_MCP_SKILLS=1 bun run dev
|
||||
|
||||
# 前提条件:
|
||||
# 1. 配置了支持 skill:// 资源的 MCP 服务器
|
||||
# 2. MCP 服务器声明了 resources 能力
|
||||
```
|
||||
|
||||
## 五、需要补全的内容
|
||||
|
||||
| 文件 | 状态 | 需要实现 |
|
||||
|------|------|---------|
|
||||
| `src/skills/mcpSkills.ts` | Stub | `fetchMcpSkillsForClient()` — 从 MCP 资源列表中筛选 `skill://` URI 并转换为 Command 对象 |
|
||||
| `src/skills/mcpSkillBuilders.ts` | Stub | 技能构建器注册(避免循环依赖) |
|
||||
|
||||
## 六、文件索引
|
||||
|
||||
| 文件 | 职责 |
|
||||
|------|------|
|
||||
| `src/commands.ts:547-608` | 技能命令过滤 |
|
||||
| `src/services/mcp/client.ts:117-2358` | 技能获取 + 缓存管理 |
|
||||
| `src/services/mcp/useManageMCPConnections.ts` | 实时刷新 |
|
||||
| `src/skills/mcpSkills.ts` | 核心转换逻辑(stub) |
|
||||
109
docs/features/proactive.md
Normal file
109
docs/features/proactive.md
Normal file
@@ -0,0 +1,109 @@
|
||||
# PROACTIVE — 主动模式
|
||||
|
||||
> Feature Flag: `FEATURE_PROACTIVE=1`(与 `FEATURE_KAIROS=1` 共享功能)
|
||||
> 实现状态:核心模块全部 Stub,布线完整
|
||||
> 引用数:37
|
||||
|
||||
## 一、功能概述
|
||||
|
||||
PROACTIVE 实现 Tick 驱动的自主代理。CLI 在用户不输入时也能持续工作:定时唤醒执行任务,配合 SleepTool 控制节奏。适用于长时间运行的后台任务(等待 CI、监控文件变化、定时检查等)。
|
||||
|
||||
### 与 KAIROS 的关系
|
||||
|
||||
所有代码检查都是 `feature('PROACTIVE') || feature('KAIROS')`,即:
|
||||
- 单独开 `FEATURE_PROACTIVE=1` → 获得 proactive 能力
|
||||
- 单独开 `FEATURE_KAIROS=1` → 自动获得 proactive 能力
|
||||
- 两者都开 → 相同效果(不重复)
|
||||
|
||||
## 二、实现架构
|
||||
|
||||
### 2.1 模块状态
|
||||
|
||||
| 模块 | 文件 | 状态 | 说明 |
|
||||
|------|------|------|------|
|
||||
| 核心逻辑 | `src/proactive/index.ts` | **Stub** | `activateProactive()`、`deactivateProactive()`、`isProactiveActive() => false` |
|
||||
| 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 消息注入对话流 |
|
||||
|
||||
### 2.2 系统提示内容
|
||||
|
||||
`getProactiveSection()` 注入的自主工作指令包含:
|
||||
|
||||
| 章节 | 内容 |
|
||||
|------|------|
|
||||
| Tick 驱动 | `<tick_tag>` prompt 保持存活,包含用户本地时间 |
|
||||
| 节奏控制 | SleepTool 控制等待间隔,prompt cache 5 分钟过期 |
|
||||
| 空操作规则 | 无事可做时**必须**调用 Sleep,禁止输出 "still waiting" |
|
||||
| 首次唤醒 | 简短问候,等待方向(不主动探索) |
|
||||
| 后续唤醒 | 寻找有用工作:调查、验证、检查(不 spam 用户) |
|
||||
| 偏向行动 | 读文件、搜索代码、commit — 不需询问 |
|
||||
| 终端焦点 | `terminalFocus` 字段调节自主程度 |
|
||||
|
||||
### 2.3 数据流
|
||||
|
||||
```
|
||||
activateProactive() [需要实现]
|
||||
│
|
||||
▼
|
||||
Tick 调度器启动
|
||||
│
|
||||
├── 定时生成 <tick_tag> 消息
|
||||
│ ├── 包含用户当前本地时间
|
||||
│ └── 注入到对话流(sessionStorage)
|
||||
│
|
||||
▼
|
||||
模型处理 tick
|
||||
│
|
||||
├── 有事可做 → 使用工具执行 → 可能再次 Sleep
|
||||
└── 无事可做 → 必须调用 SleepTool
|
||||
│
|
||||
▼
|
||||
SleepTool 等待 [需要实现]
|
||||
│
|
||||
▼
|
||||
下一个 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 hook(REPL 引用但不存在) |
|
||||
|
||||
## 四、关键设计决策
|
||||
|
||||
1. **Tick 驱动**:模型通过 SleepTool 自行控制唤醒频率,不是外部事件推送
|
||||
2. **空操作必须 Sleep**:防止 "still waiting" 类空消息浪费 turn 和 token
|
||||
3. **Prompt cache 考量**:SleepTool 提示中提到 cache 5 分钟过期,建议平衡等待时间
|
||||
4. **Terminal Focus 感知**:模型根据用户是否在看终端调整自主程度
|
||||
|
||||
## 五、使用方式
|
||||
|
||||
```bash
|
||||
# 单独启用 proactive
|
||||
FEATURE_PROACTIVE=1 bun run dev
|
||||
|
||||
# 通过 KAIROS 间接启用
|
||||
FEATURE_KAIROS=1 bun run dev
|
||||
|
||||
# 组合使用
|
||||
FEATURE_PROACTIVE=1 FEATURE_KAIROS=1 FEATURE_KAIROS_BRIEF=1 bun run dev
|
||||
```
|
||||
|
||||
## 六、文件索引
|
||||
|
||||
| 文件 | 职责 |
|
||||
|------|------|
|
||||
| `src/proactive/index.ts` | 核心逻辑(stub) |
|
||||
| `src/tools/SleepTool/prompt.ts` | SleepTool 工具提示 |
|
||||
| `src/constants/prompts.ts:860-914` | 自主工作系统提示 |
|
||||
| `src/screens/REPL.tsx` | REPL tick 集成 |
|
||||
| `src/utils/sessionStorage.ts:4892-4912` | Tick 消息注入 |
|
||||
| `src/components/PromptInput/PromptInputFooterLeftSide.tsx` | 页脚 UI 状态 |
|
||||
167
docs/features/teammem.md
Normal file
167
docs/features/teammem.md
Normal file
@@ -0,0 +1,167 @@
|
||||
# TEAMMEM — 团队共享记忆
|
||||
|
||||
> Feature Flag: `FEATURE_TEAMMEM=1`
|
||||
> 实现状态:完整可用(需要 Anthropic OAuth + GitHub remote)
|
||||
> 引用数:51
|
||||
|
||||
## 一、功能概述
|
||||
|
||||
TEAMMEM 实现基于 GitHub 仓库的团队共享记忆系统。`memory/team/` 目录中的文件双向同步到 Anthropic 服务器,团队所有认证成员可共享项目知识。
|
||||
|
||||
### 核心特性
|
||||
|
||||
- **增量同步**:只上传内容哈希变化的文件(delta upload)
|
||||
- **冲突解决**:基于 ETag 的乐观锁 + 412 冲突重试
|
||||
- **密钥扫描**:上传前检测并跳过包含密钥的文件(PSR M22174)
|
||||
- **路径穿越防护**:所有写入路径验证在 `memory/team/` 边界内
|
||||
- **分批上传**:自动拆分超过 200KB 的 PUT 请求避免网关拒绝
|
||||
|
||||
## 二、用户交互
|
||||
|
||||
### 同步行为
|
||||
|
||||
| 事件 | 行为 |
|
||||
|------|------|
|
||||
| 项目启动 | 自动 pull 团队记忆到 `memory/team/` |
|
||||
| 本地文件编辑 | watcher 检测变更,自动 push |
|
||||
| 服务端更新 | 下次 pull 时覆盖本地(server-wins) |
|
||||
| 密钥检测 | 跳过该文件,记录警告,不阻止其他文件同步 |
|
||||
|
||||
### API 端点
|
||||
|
||||
```
|
||||
GET /api/claude_code/team_memory?repo={owner/repo} → 完整数据 + entryChecksums
|
||||
GET /api/claude_code/team_memory?repo={owner/repo}&view=hashes → 仅 checksums(冲突解决用)
|
||||
PUT /api/claude_code/team_memory?repo={owner/repo} → 上传 entries(upsert 语义)
|
||||
```
|
||||
|
||||
## 三、实现架构
|
||||
|
||||
### 3.1 同步状态
|
||||
|
||||
```ts
|
||||
type SyncState = {
|
||||
lastKnownChecksum: string | null // ETag 条件请求
|
||||
serverChecksums: Map<string, string> // sha256:<hex> 逐文件哈希
|
||||
serverMaxEntries: number | null // 从 413 学习的服务端容量
|
||||
}
|
||||
```
|
||||
|
||||
### 3.2 Pull 流程(Server → Local)
|
||||
|
||||
文件:`src/services/teamMemorySync/index.ts:770-867`
|
||||
|
||||
```
|
||||
pullTeamMemory(state)
|
||||
│
|
||||
▼
|
||||
检查 OAuth + GitHub remote
|
||||
│
|
||||
▼
|
||||
fetchTeamMemory(state, repo, etag)
|
||||
├── 304 Not Modified → 返回(无变化)
|
||||
├── 404 → 返回(服务端无数据)
|
||||
└── 200 → 解析 TeamMemoryData
|
||||
│
|
||||
▼
|
||||
刷新 serverChecksums(per-key hashes)
|
||||
│
|
||||
▼
|
||||
writeRemoteEntriesToLocal(entries)
|
||||
├── 路径穿越验证(validateTeamMemKey)
|
||||
├── 文件大小检查(> 250KB 跳过)
|
||||
├── 内容比较(相同则跳过写入)
|
||||
└── 并行写入(Promise.all)
|
||||
```
|
||||
|
||||
### 3.3 Push 流程(Local → Server)
|
||||
|
||||
文件:`src/services/teamMemorySync/index.ts:889-1146`
|
||||
|
||||
```
|
||||
pushTeamMemory(state)
|
||||
│
|
||||
▼
|
||||
readLocalTeamMemory(maxEntries)
|
||||
├── 递归扫描 memory/team/ 目录
|
||||
├── 跳过超大文件(> 250KB)
|
||||
├── 密钥扫描(scanForSecrets,gitleaks 规则)
|
||||
└── 按 serverMaxEntries 截断(如果已知)
|
||||
│
|
||||
▼
|
||||
计算 delta = 本地文件 - serverChecksums
|
||||
(只包含哈希不同的文件)
|
||||
│
|
||||
▼
|
||||
batchDeltaByBytes(delta)
|
||||
(拆分为 ≤200KB 的批次)
|
||||
│
|
||||
▼
|
||||
逐批 uploadTeamMemory(state, repo, batch, etag)
|
||||
├── 200 成功 → 更新 serverChecksums
|
||||
├── 412 冲突 → fetchTeamMemoryHashes() 刷新 checksums
|
||||
│ → 重试 delta 计算(最多 2 次)
|
||||
└── 413 超容量 → 学习 serverMaxEntries
|
||||
```
|
||||
|
||||
### 3.4 密钥扫描
|
||||
|
||||
文件:`src/services/teamMemorySync/secretScanner.ts`
|
||||
|
||||
使用 gitleaks 规则模式扫描文件内容。检测到密钥时:
|
||||
- 跳过该文件(不上传)
|
||||
- 记录 `tengu_team_mem_secret_skipped` 事件(仅记录规则 ID,不记录值)
|
||||
- 不阻止其他文件同步
|
||||
|
||||
### 3.5 文件监视
|
||||
|
||||
文件:`src/services/teamMemorySync/watcher.ts`
|
||||
|
||||
监视 `memory/team/` 目录变更,触发自动 push。抑制由 pull 写入引起的假变更。
|
||||
|
||||
### 3.6 路径安全
|
||||
|
||||
文件:`src/memdir/teamMemPaths.ts`
|
||||
|
||||
- `validateTeamMemKey(relPath)` — 验证相对路径不超出 `memory/team/` 边界
|
||||
- `getTeamMemPath()` — 返回 team memory 根目录路径
|
||||
|
||||
## 四、关键设计决策
|
||||
|
||||
1. **Server-wins on pull, Local-wins on push**:pull 时服务端内容覆盖本地;push 时本地编辑覆盖服务端。本地用户正在编辑,不应被静默丢弃
|
||||
2. **Delta upload**:只上传哈希变化的条目,节省带宽。首次 push 为全量,后续增量
|
||||
3. **分批 PUT**:单次 PUT ≤200KB,避免 API 网关(~256-512KB)拒绝。每批独立 upsert,部分失败不影响已提交批次
|
||||
4. **密钥扫描在上传前**:PSR M22174 要求密钥永不离开本机。扫描在 `readLocalTeamMemory` 中执行,密钥文件不进入上传集
|
||||
5. **ETag 乐观锁**:push 使用 `If-Match` header。412 时 probe `?view=hashes`(只获取 checksums,不下载内容),刷新后重试
|
||||
6. **服务端容量动态学习**:不假设客户端容量上限,从 413 的 `extra_details.max_entries` 学习
|
||||
|
||||
## 五、使用方式
|
||||
|
||||
```bash
|
||||
# 启用 feature
|
||||
FEATURE_TEAMMEM=1 bun run dev
|
||||
|
||||
# 前提条件:
|
||||
# 1. 已通过 Anthropic OAuth 登录
|
||||
# 2. 项目有 GitHub remote(git remote -v 显示 origin)
|
||||
# 3. memory/team/ 目录自动创建
|
||||
```
|
||||
|
||||
## 六、外部依赖
|
||||
|
||||
| 依赖 | 说明 |
|
||||
|------|------|
|
||||
| Anthropic OAuth | first-party 认证 |
|
||||
| GitHub Remote | `getGithubRepo()` 获取 `owner/repo` 作为同步 scope |
|
||||
| Team Memory API | `/api/claude_code/team_memory` 端点 |
|
||||
|
||||
## 七、文件索引
|
||||
|
||||
| 文件 | 行数 | 职责 |
|
||||
|------|------|------|
|
||||
| `src/services/teamMemorySync/index.ts` | 1257 | 核心同步逻辑(pull/push/sync) |
|
||||
| `src/services/teamMemorySync/watcher.ts` | — | 文件监视 + 自动同步触发 |
|
||||
| `src/services/teamMemorySync/secretScanner.ts` | — | gitleaks 密钥扫描 |
|
||||
| `src/services/teamMemorySync/types.ts` | — | Zod schema + 类型定义 |
|
||||
| `src/services/teamMemorySync/teamMemSecretGuard.ts` | — | 密钥防护辅助 |
|
||||
| `src/memdir/teamMemPaths.ts` | — | 路径验证 + 目录管理 |
|
||||
76
docs/features/tier3-stubs.md
Normal file
76
docs/features/tier3-stubs.md
Normal file
@@ -0,0 +1,76 @@
|
||||
# Tier 3 — 纯 Stub / N/A 低优先级 Feature 概览
|
||||
|
||||
> 本文档汇总所有 Tier 3 feature。这些功能要么是纯 Stub(所有函数返回空值),
|
||||
> 要么是 Anthropic 内部基础设施(N/A),要么是引用量极低的辅助功能。
|
||||
|
||||
## 概览
|
||||
|
||||
| Feature | 引用 | 状态 | 类别 | 简要说明 |
|
||||
|---------|------|------|------|---------|
|
||||
| CHICAGO_MCP | 16 | N/A | 内部基础设施 | Anthropic 内部 MCP 基础设施,非外部可用 |
|
||||
| UDS_INBOX | 17 | Stub | 消息通信 | Unix 域套接字对等消息,进程间消息传递 |
|
||||
| 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 状态 |
|
||||
|
||||
## 单引用 Feature(40+ 个)
|
||||
|
||||
以下 feature 各只有 1 处引用,多为内部标记或实验性功能:
|
||||
|
||||
UNATTENDED_RETRY, ULTRATHINK, TORCH, SLOW_OPERATION_LOGGING, SKILL_IMPROVEMENT,
|
||||
SELF_HOSTED_RUNNER, RUN_SKILL_GENERATOR, PERFETTO_TRACING, NATIVE_CLIENT_ATTESTATION,
|
||||
KAIROS_DREAM(见 kairos.md), IS_LIBC_MUSL, IS_LIBC_GLIBC, DUMP_SYSTEM_PROMPT,
|
||||
COMPACTION_REMINDERS, CCR_REMOTE_SETUP, BYOC_ENVIRONMENT_RUNNER, BUILTIN_EXPLORE_PLAN_AGENTS,
|
||||
BUILDING_CLAUDE_APPS, ANTI_DISTILLATION_CC, AGENT_TRIGGERS, ABLATION_BASELINE
|
||||
|
||||
## 优先级说明
|
||||
|
||||
这些 feature 被列为 Tier 3 的原因:
|
||||
|
||||
1. **内部基础设施**(CHICAGO_MCP, LODESTONE):Anthropic 内部使用,外部无法运行
|
||||
2. **纯 Stub 且引用低**(UDS_INBOX, MONITOR_TOOL, BG_SESSIONS):需要大量工作才能实现
|
||||
3. **实验性功能**(SHOT_STATS, EXTRACT_MEMORIES):尚在概念阶段
|
||||
4. **辅助功能**(STREAMLINED_OUTPUT, HOOK_PROMPTS):影响范围小
|
||||
5. **CCR 系列**:依赖远程控制基础设施,需要 BRIDGE_MODE 先完善
|
||||
|
||||
如需深入了解某个 Tier 3 feature,可以在代码库中搜索 `feature('FEATURE_NAME')` 查看具体使用场景。
|
||||
198
docs/features/token-budget.md
Normal file
198
docs/features/token-budget.md
Normal file
@@ -0,0 +1,198 @@
|
||||
# TOKEN_BUDGET — Token 预算自动持续模式
|
||||
|
||||
> Feature Flag: `FEATURE_TOKEN_BUDGET=1`
|
||||
> 实现状态:完整可用
|
||||
|
||||
## 一、功能概述
|
||||
|
||||
TOKEN_BUDGET 让用户在 prompt 中指定一个 output token 预算目标(如 `+500k`、`spend 2M tokens`),Claude 会**自动持续工作**直到达到目标,无需用户反复按回车催促继续。
|
||||
|
||||
适用于大型重构、批量修改、大规模代码生成等需要多轮工具调用的长任务。
|
||||
|
||||
## 二、用户交互
|
||||
|
||||
### 语法
|
||||
|
||||
| 格式 | 示例 | 说明 |
|
||||
|------|------|------|
|
||||
| 简写(开头) | `+500k` | 输入开头直接写 |
|
||||
| 简写(结尾) | `帮我重构这个模块 +2m` | 输入末尾追加 |
|
||||
| 完整语法 | `spend 2M tokens` 或 `use 1B tokens` | 自然语言嵌入 |
|
||||
|
||||
单位支持:`k`(千)、`m`(百万)、`b`(十亿),大小写不敏感。
|
||||
|
||||
### UI 反馈
|
||||
|
||||
- **输入框高亮**:输入包含预算语法时,对应文字会被高亮标记(`PromptInput.tsx` 通过 `findTokenBudgetPositions` 计算)
|
||||
- **Spinner 进度**:底部 spinner 显示实时进度,格式如:
|
||||
- 未完成:`Target: 125,000 / 500,000 (25%) · ~2m 30s`
|
||||
- 已完成:`Target: 510,000 used (500,000 min ✓)`
|
||||
- 包含 ETA(基于当前 token 产出速率计算)
|
||||
|
||||
## 三、实现架构
|
||||
|
||||
### 数据流
|
||||
|
||||
```
|
||||
用户输入 "+500k"
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────┐
|
||||
│ parseTokenBudget() │ src/utils/tokenBudget.ts
|
||||
│ 正则解析 → 500,000 │
|
||||
└────────┬────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────┐
|
||||
│ REPL.tsx │ 提交时调用
|
||||
│ snapshotOutputTokens │ snapshotOutputTokensForTurn(500000)
|
||||
│ ForTurn(500000) │ 记录 turn 起始 token 数 + 预算
|
||||
└────────┬────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────┐
|
||||
│ query.ts 主循环 │ 每轮结束后检查
|
||||
│ checkTokenBudget() │ 当前 output tokens vs 预算
|
||||
└────────┬────────────────┘
|
||||
│
|
||||
┌────┴─────┐
|
||||
│ │
|
||||
▼ ▼
|
||||
continue stop
|
||||
(未达 90%) (已达 90% 或收益递减)
|
||||
│ │
|
||||
▼ ▼
|
||||
注入 nudge 正常结束
|
||||
消息继续 发送完成事件
|
||||
```
|
||||
|
||||
### 核心模块
|
||||
|
||||
#### 1. 解析层 — `src/utils/tokenBudget.ts`
|
||||
|
||||
三个正则表达式解析用户输入:
|
||||
|
||||
```
|
||||
SHORTHAND_START_RE = /^\s*\+(\d+(?:\.\d+)?)\s*(k|m|b)\b/i // "+500k" 在开头
|
||||
SHORTHAND_END_RE = /\s\+(\d+(?:\.\d+)?)\s*(k|m|b)\s*[.!?]?\s*$/i // "+2m" 在结尾
|
||||
VERBOSE_RE = /\b(?:use|spend)\s+(\d+(?:\.\d+)?)\s*(k|m|b)\s*tokens?\b/i // "spend 2M tokens"
|
||||
```
|
||||
|
||||
- `parseTokenBudget(text)` — 提取预算数值,返回 `number | null`
|
||||
- `findTokenBudgetPositions(text)` — 返回匹配位置数组,用于输入框高亮
|
||||
- `getBudgetContinuationMessage(pct, turnTokens, budget)` — 生成继续消息
|
||||
|
||||
#### 2. 状态层 — `src/bootstrap/state.ts`
|
||||
|
||||
模块级单例变量追踪当前 turn 的预算状态:
|
||||
|
||||
```
|
||||
outputTokensAtTurnStart — 本 turn 开始时的累计 output token 数
|
||||
currentTurnTokenBudget — 本 turn 的预算目标(null 表示无预算)
|
||||
budgetContinuationCount — 本 turn 已自动续接的次数
|
||||
```
|
||||
|
||||
关键函数:
|
||||
- `getTotalOutputTokens()` — 从 `STATE.modelUsage` 汇总所有模型的 output tokens
|
||||
- `getTurnOutputTokens()` — `getTotalOutputTokens() - outputTokensAtTurnStart`
|
||||
- `snapshotOutputTokensForTurn(budget)` — 重置 turn 起点,设置新预算
|
||||
- `getCurrentTurnTokenBudget()` — 返回当前预算
|
||||
|
||||
#### 3. 决策层 — `src/query/tokenBudget.ts`
|
||||
|
||||
`checkTokenBudget(tracker, agentId, budget, globalTurnTokens)` 做出 continue/stop 决策:
|
||||
|
||||
**继续条件**:
|
||||
- 不在子 agent 中(`agentId` 为空)
|
||||
- 预算存在且 > 0
|
||||
- 当前 token 未达预算的 **90%**
|
||||
- 非收益递减(连续 3 轮 nudge 后,每轮新增 < 500 tokens)
|
||||
|
||||
**停止条件**:
|
||||
- 达到预算 90%
|
||||
- 收益递减(模型已经"做不动了")
|
||||
- 子 agent 模式下直接跳过
|
||||
|
||||
**收益递减检测**:`continuationCount >= 3` 且最近两次 nudge 的 delta 都 < 500 tokens。
|
||||
|
||||
#### 4. 主循环集成 — `src/query.ts`
|
||||
|
||||
```
|
||||
query() 函数内:
|
||||
1. 创建 budgetTracker = createBudgetTracker()
|
||||
2. 进入 while 循环
|
||||
3. 每轮结束后调用 checkTokenBudget()
|
||||
4. decision.action === 'continue' 时:
|
||||
- 注入 meta user message(nudge)
|
||||
- continue 回到循环顶部
|
||||
5. decision.action === 'stop' 时:
|
||||
- 记录完成事件(含 diminishingReturns 标记)
|
||||
- 正常返回
|
||||
```
|
||||
|
||||
#### 5. UI 层
|
||||
|
||||
| 文件 | 职责 |
|
||||
|------|------|
|
||||
| `components/PromptInput/PromptInput.tsx:534` | 输入框中高亮预算语法 |
|
||||
| `components/Spinner.tsx:319-338` | spinner 显示进度百分比 + ETA |
|
||||
| `screens/REPL.tsx:2897` | 提交时解析预算并快照 |
|
||||
| `screens/REPL.tsx:2138` | 用户取消时清除预算 |
|
||||
| `screens/REPL.tsx:2963` | turn 结束时捕获预算信息用于显示 |
|
||||
|
||||
#### 6. 系统提示 — `src/constants/prompts.ts:538-551`
|
||||
|
||||
注入 `token_budget` section:
|
||||
|
||||
> "When the user specifies a token target (e.g., '+500k', 'spend 2M tokens', 'use 1B tokens'), your output token count will be shown each turn. Keep working until you approach the target — plan your work to fill it productively. The target is a hard minimum, not a suggestion. If you stop early, the system will automatically continue you."
|
||||
|
||||
注意:这段 prompt **无条件缓存**(不随预算开关变化),因为 "When the user specifies..." 的措辞在没有预算时是空操作。
|
||||
|
||||
#### 7. API 附件 — `src/utils/attachments.ts:3830-3845`
|
||||
|
||||
每轮 API 调用附带 `output_token_usage` attachment:
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "output_token_usage",
|
||||
"turn": 125000, // 本 turn 产出
|
||||
"session": 350000, // 会话总产出
|
||||
"budget": 500000 // 预算目标
|
||||
}
|
||||
```
|
||||
|
||||
让模型能看到自己的进度。
|
||||
|
||||
## 四、关键设计决策
|
||||
|
||||
1. **90% 阈值而非 100%**:在 `COMPLETION_THRESHOLD = 0.9` 处停止,避免最后一轮 nudge 产生远超预算的 token
|
||||
2. **收益递减保护**:连续 3 轮 nudge 后如果每轮产出 < 500 tokens,判定模型已无实质进展,提前终止
|
||||
3. **子 agent 豁免**:AgentTool 内部的子任务不做预算检查,避免子任务重复触发续接
|
||||
4. **无条件缓存系统提示**:预算 prompt 始终注入(不随预算变化 toggle),避免每次切换预算导致 ~20K token 的 cache miss
|
||||
5. **用户取消清预算**:按 Escape 取消时调用 `snapshotOutputTokensForTurn(null)`,防止残留预算触发续接
|
||||
|
||||
## 五、使用方式
|
||||
|
||||
```bash
|
||||
# 启用 feature
|
||||
FEATURE_TOKEN_BUDGET=1 bun run dev
|
||||
|
||||
# 在 prompt 中使用
|
||||
> +500k 重构所有测试文件
|
||||
> spend 2M tokens 把这个项目从 JS 迁移到 TS
|
||||
> 帮我写完整的 CRUD 模块 +1m
|
||||
```
|
||||
|
||||
## 六、文件索引
|
||||
|
||||
| 文件 | 行数 | 职责 |
|
||||
|------|------|------|
|
||||
| `src/utils/tokenBudget.ts` | 73 | 正则解析 + 位置查找 + 续接消息生成 |
|
||||
| `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/query.ts:280,1311-1358` | 48 | 主循环集成 |
|
||||
| `src/screens/REPL.tsx:2897,2963,2138` | 20 | REPL 提交/完成/取消处理 |
|
||||
| `src/components/Spinner.tsx:319-338` | 20 | 进度条 UI |
|
||||
| `src/components/PromptInput/PromptInput.tsx:534` | 1 | 输入高亮 |
|
||||
161
docs/features/tree-sitter-bash.md
Normal file
161
docs/features/tree-sitter-bash.md
Normal file
@@ -0,0 +1,161 @@
|
||||
# TREE_SITTER_BASH — Bash AST 解析
|
||||
|
||||
> Feature Flag: `FEATURE_TREE_SITTER_BASH=1`
|
||||
> 实现状态:完整可用(纯 TypeScript 实现,~7000+ 行)
|
||||
> 引用数:3
|
||||
|
||||
## 一、功能概述
|
||||
|
||||
TREE_SITTER_BASH 启用一个完整的 Bash AST 解析器,用于安全验证 Bash 命令。它用完整的树遍历安全分析器取代了旧的基于正则表达式的 shell-quote 解析器。关键属性是 **fail-closed**:任何无法识别的内容都被归类为 `too-complex` 并需要用户批准。
|
||||
|
||||
### 关联 Feature
|
||||
|
||||
| Feature | 说明 |
|
||||
|---------|------|
|
||||
| `TREE_SITTER_BASH` | 激活用于权限检查的 AST 解析器 |
|
||||
| `TREE_SITTER_BASH_SHADOW` | Shadow/观测模式:运行解析器但丢弃结果,仅记录遥测 |
|
||||
|
||||
## 二、安全架构
|
||||
|
||||
### 2.1 Fail-Closed 设计
|
||||
|
||||
核心设计使用 **allowlist** 遍历模式:
|
||||
|
||||
- `walkArgument()` 只处理已知安全的节点类型(`word`、`number`、`raw_string`、`string`、`concatenation`、`arithmetic_expansion`、`simple_expansion`)
|
||||
- 任何未知节点类型 → `tooComplex()` → 需要用户批准
|
||||
- 解析器加载但失败(超时/节点预算/panic)→ 返回 `PARSE_ABORTED` 符号(区别于"模块未加载")
|
||||
|
||||
### 2.2 解析结果
|
||||
|
||||
```ts
|
||||
parseForSecurity(cmd) 返回:
|
||||
{ kind: 'simple', commands: SimpleCommand[] } // 可静态分析
|
||||
{ kind: 'too-complex', reason, nodeType } // 需要用户批准
|
||||
{ kind: 'parse-unavailable' } // 解析器未加载
|
||||
```
|
||||
|
||||
### 2.3 安全检查层次
|
||||
|
||||
```
|
||||
parseForSecurity(cmd)
|
||||
│
|
||||
▼
|
||||
parseCommandRaw(cmd) → AST root node
|
||||
│
|
||||
▼
|
||||
预检查:控制字符、Unicode 空白、反斜杠+空白、
|
||||
zsh ~[ ] 语法、zsh =cmd 展开、大括号+引号混淆
|
||||
│
|
||||
▼
|
||||
walkProgram(root) → collectCommands(root, commands, varScope)
|
||||
│
|
||||
├── 'command' → walkCommand()
|
||||
├── 'pipeline'/'list' → 结构性,递归子节点
|
||||
├── 'for_statement' → 跟踪循环变量为 VAR_PLACEHOLDER
|
||||
├── 'if/while' → 作用域隔离的分支
|
||||
├── 'subshell' → 作用域复制
|
||||
├── 'variable_assignment' → walkVariableAssignment()
|
||||
├── 'declaration_command' → 验证 declare/export flags
|
||||
├── 'test_command' → walk test expressions
|
||||
└── 其他 → tooComplex()
|
||||
│
|
||||
▼
|
||||
checkSemantics(commands)
|
||||
├── EVAL_LIKE_BUILTINS(eval, source, exec, trap...)
|
||||
├── ZSH_DANGEROUS_BUILTINS(zmodload, emulate...)
|
||||
├── SUBSCRIPT_EVAL_FLAGS(test -v, printf -v, read -a)
|
||||
├── Shell keywords as argv[0](误解析检测)
|
||||
├── /proc/*/environ 访问
|
||||
├── jq system() 和危险 flags
|
||||
└── 包装器剥离(time, nohup, timeout, nice, env, stdbuf)
|
||||
```
|
||||
|
||||
## 三、实现架构
|
||||
|
||||
### 3.1 核心模块
|
||||
|
||||
| 模块 | 文件 | 行数 | 职责 |
|
||||
|------|------|------|------|
|
||||
| 门控入口 | `src/utils/bash/parser.ts` | ~110 | `parseCommand()`、`parseCommandRaw()`、`ensureInitialized()` |
|
||||
| Bash 解析器 | `src/utils/bash/bashParser.ts` | 4437 | 纯 TS 词法分析 + 递归下降解析器 |
|
||||
| 安全分析器 | `src/utils/bash/ast.ts` | 2680 | 树遍历安全分析 + `parseForSecurity()` |
|
||||
| AST 分析辅助 | `src/utils/bash/treeSitterAnalysis.ts` | 507 | 引号上下文、复合结构、危险模式提取 |
|
||||
| 权限检查入口 | `src/tools/BashTool/bashPermissions.ts` | — | 集成 AST 结果到权限决策 |
|
||||
|
||||
### 3.2 Bash 解析器
|
||||
|
||||
文件:`src/utils/bash/bashParser.ts`(4437 行)
|
||||
|
||||
- 纯 TypeScript 实现(无原生依赖)
|
||||
- 生成与 tree-sitter-bash 兼容的 AST
|
||||
- 关键类型:`TsNode`(type、text、startIndex、endIndex、children)
|
||||
- 安全限制:`PARSE_TIMEOUT_MS = 50`、`MAX_NODES = 50_000` — 防止对抗性输入导致 OOM
|
||||
|
||||
### 3.3 安全分析器
|
||||
|
||||
文件:`src/utils/bash/ast.ts`(2680 行)
|
||||
|
||||
核心函数:
|
||||
|
||||
| 函数 | 职责 |
|
||||
|------|------|
|
||||
| `parseForSecurity(cmd)` | 顶层入口,返回 `simple/too-complex/parse-unavailable` |
|
||||
| `parseForSecurityFromAst(cmd, root)` | 接受预解析 AST |
|
||||
| `checkSemantics(commands)` | 后解析语义检查 |
|
||||
| `walkCommand()` | 提取 argv、envVars、redirects |
|
||||
| `walkArgument()` | Allowlist 参数遍历 |
|
||||
| `collectCommands()` | 递归收集所有命令 |
|
||||
|
||||
### 3.4 AST 分析辅助
|
||||
|
||||
文件:`src/utils/bash/treeSitterAnalysis.ts`(507 行)
|
||||
|
||||
| 函数 | 职责 |
|
||||
|------|------|
|
||||
| `extractQuoteContext()` | 识别单引号、双引号、ANSI-C 字符串、heredoc |
|
||||
| `extractCompoundStructure()` | 检测管道、子 shell、命令组 |
|
||||
| `hasActualOperatorNodes()` | 区分真实 `;`/`&&`/`||` 与转义形式 |
|
||||
| `extractDangerousPatterns()` | 检测命令替换、参数展开、heredocs |
|
||||
| `analyzeCommand()` | 单次遍历提取 |
|
||||
|
||||
### 3.5 Shadow 模式
|
||||
|
||||
`TREE_SITTER_BASH_SHADOW` 运行解析器但**从不影响权限决策**:
|
||||
|
||||
```ts
|
||||
// Shadow 模式:记录遥测,然后强制使用旧版路径
|
||||
astResult = { kind: 'parse-unavailable' }
|
||||
astRoot = null
|
||||
// 记录: available, astTooComplex, astSemanticFail, subsDiffer, ...
|
||||
```
|
||||
|
||||
记录 `tengu_tree_sitter_shadow` 事件,包含与旧版 `splitCommand()` 的对比数据。用于在不影响行为的情况下收集遥测。
|
||||
|
||||
## 四、关键设计决策
|
||||
|
||||
1. **Allowlist 遍历**:只处理已知安全的节点类型,未知类型直接 `tooComplex()`
|
||||
2. **PARSE_ABORTED 符号**:区分"解析器未加载"和"解析器加载但失败"。后者阻止回退旧版(旧版缺少 `EVAL_LIKE_BUILTINS` 检查)
|
||||
3. **变量作用域跟踪**:`VAR=value && cmd $VAR` 模式。静态值解析为真实字符串,`$()` 输出使用 `VAR_PLACEHOLDER`
|
||||
4. **PS4/IFS Allowlist**:PS4 赋值使用严格字符白名单 `[A-Za-z0-9 _+:.\/=\[\]-]`,只允许 `${VAR}` 引用
|
||||
5. **包装器剥离**:从 argv 前面剥离 `time/nohup/timeout/nice/env/stdbuf`,未知标志 → fail-closed
|
||||
6. **Shadow 安全性**:Shadow 模式**总是**强制 `astResult = { kind: 'parse-unavailable' }`,绝不影响权限
|
||||
|
||||
## 五、使用方式
|
||||
|
||||
```bash
|
||||
# 激活 AST 解析用于权限检查
|
||||
FEATURE_TREE_SITTER_BASH=1 bun run dev
|
||||
|
||||
# Shadow 模式(仅遥测,不影响行为)
|
||||
FEATURE_TREE_SITTER_BASH_SHADOW=1 bun run dev
|
||||
```
|
||||
|
||||
## 六、文件索引
|
||||
|
||||
| 文件 | 行数 | 职责 |
|
||||
|------|------|------|
|
||||
| `src/utils/bash/parser.ts` | ~110 | 门控入口点 |
|
||||
| `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 遥测 |
|
||||
107
docs/features/ultraplan.md
Normal file
107
docs/features/ultraplan.md
Normal file
@@ -0,0 +1,107 @@
|
||||
# ULTRAPLAN — 增强规划
|
||||
|
||||
> Feature Flag: `FEATURE_ULTRAPLAN=1`
|
||||
> 实现状态:关键字检测完整,命令处理完整,CCR 远程会话完整
|
||||
> 引用数:10
|
||||
|
||||
## 一、功能概述
|
||||
|
||||
ULTRAPLAN 在用户输入中检测 "ultraplan" 关键字时,自动进入增强计划模式。相比普通 plan mode,ultraplan 提供更深入的规划能力,支持本地和远程(CCR)执行。
|
||||
|
||||
### 触发方式
|
||||
|
||||
| 方式 | 行为 |
|
||||
|------|------|
|
||||
| 输入含 "ultraplan" 的文本 | 自动重定向到 `/ultraplan` 命令 |
|
||||
| `/ultraplan` 斜杠命令 | 直接执行 |
|
||||
| 彩虹高亮 | 输入框中 "ultraplan" 关键字彩虹动画 |
|
||||
|
||||
## 二、实现架构
|
||||
|
||||
### 2.1 模块状态
|
||||
|
||||
| 模块 | 文件 | 行数 | 状态 |
|
||||
|------|------|------|------|
|
||||
| 命令处理器 | `src/commands/ultraplan.tsx` | 472 | **完整** |
|
||||
| CCR 会话 | `src/utils/ultraplan/ccrSession.ts` | 350 | **完整** |
|
||||
| 关键字检测 | `src/utils/ultraplan/keyword.ts` | 128 | **完整** |
|
||||
| 嵌入式提示 | `src/utils/ultraplan/prompt.txt` | 1 | **完整** |
|
||||
| REPL 对话框 | `src/screens/REPL.tsx` | — | **布线** |
|
||||
| 关键字高亮 | `src/components/PromptInput/PromptInput.tsx` | — | **布线** |
|
||||
|
||||
### 2.2 关键字检测
|
||||
|
||||
文件:`src/utils/ultraplan/keyword.ts`(128 行)
|
||||
|
||||
`findUltraplanTriggerPositions(text)` 智能过滤:
|
||||
- 排除引号内的 "ultraplan"
|
||||
- 排除路径中的 "ultraplan"(如 `/path/to/ultraplan/`)
|
||||
- 排除斜杠命令以外的上下文
|
||||
- `replaceUltraplanKeyword(text)` 清理关键字
|
||||
|
||||
### 2.3 CCR 远程会话
|
||||
|
||||
文件:`src/utils/ultraplan/ccrSession.ts`(350 行)
|
||||
|
||||
`ExitPlanModeScanner` 类实现完整的事件状态机:
|
||||
- `pollForApprovedExitPlanMode()` — 3 秒轮询间隔
|
||||
- 超时处理和重试
|
||||
- 支持远程(teleport)和本地执行
|
||||
|
||||
### 2.4 数据流
|
||||
|
||||
```
|
||||
用户输入 "帮我 ultraplan 重构这个模块"
|
||||
│
|
||||
▼
|
||||
processUserInput 检测 "ultraplan"
|
||||
│
|
||||
▼
|
||||
重定向到 /ultraplan 命令
|
||||
│
|
||||
├── 本地执行 → EnterPlanMode
|
||||
│
|
||||
└── 远程执行 → teleportToRemote → CCR 会话
|
||||
│
|
||||
▼
|
||||
ExitPlanModeScanner 轮询
|
||||
│
|
||||
▼
|
||||
用户在远程审批 → 本地收到结果
|
||||
```
|
||||
|
||||
## 三、需要补全的内容
|
||||
|
||||
| 模块 | 说明 |
|
||||
|------|------|
|
||||
| `src/screens/REPL.tsx` 中的 UltraplanChoiceDialog / UltraplanLaunchDialog | 用户选择本地/远程执行的对话框组件 |
|
||||
| `src/commands/ultraplan/` | 空目录,可能是未合并的子命令结构 |
|
||||
|
||||
## 四、关键设计决策
|
||||
|
||||
1. **智能关键字过滤**:排除引号和路径中的 "ultraplan",避免误触发
|
||||
2. **本地/远程双模式**:支持本地 plan mode 和 CCR 远程会话
|
||||
3. **彩虹高亮反馈**:输入框中 "ultraplan" 关键字使用彩虹动画,暗示这是特殊功能
|
||||
4. **processUserInput 集成**:在用户输入处理管道中拦截,无缝重定向
|
||||
|
||||
## 五、使用方式
|
||||
|
||||
```bash
|
||||
# 启用 feature
|
||||
FEATURE_ULTRAPLAN=1 bun run dev
|
||||
|
||||
# 在 REPL 中使用
|
||||
# > ultraplan 重构认证模块
|
||||
# > /ultraplan
|
||||
```
|
||||
|
||||
## 六、文件索引
|
||||
|
||||
| 文件 | 行数 | 职责 |
|
||||
|------|------|------|
|
||||
| `src/commands/ultraplan.tsx` | 472 | 斜杠命令处理器 |
|
||||
| `src/utils/ultraplan/ccrSession.ts` | 350 | CCR 远程会话管理 |
|
||||
| `src/utils/ultraplan/keyword.ts` | 128 | 关键字检测和替换 |
|
||||
| `src/utils/ultraplan/prompt.txt` | 1 | 嵌入式提示 |
|
||||
| `src/utils/processUserInput/processUserInput.ts:468` | — | 关键字重定向 |
|
||||
| `src/components/PromptInput/PromptInput.tsx` | — | 彩虹高亮 |
|
||||
125
docs/features/voice-mode.md
Normal file
125
docs/features/voice-mode.md
Normal file
@@ -0,0 +1,125 @@
|
||||
# VOICE_MODE — 语音输入
|
||||
|
||||
> Feature Flag: `FEATURE_VOICE_MODE=1`
|
||||
> 实现状态:完整可用(需要 Anthropic OAuth)
|
||||
> 引用数:46
|
||||
|
||||
## 一、功能概述
|
||||
|
||||
VOICE_MODE 实现"按键说话"(Push-to-Talk)语音输入。用户按住空格键录音,音频通过 WebSocket 流式传输到 Anthropic STT 端点(Nova 3),实时转录显示在终端中。
|
||||
|
||||
### 核心特性
|
||||
|
||||
- **Push-to-Talk**:长按空格键录音,释放后自动发送
|
||||
- **流式转录**:录音过程中实时显示中间转录结果
|
||||
- **无缝集成**:转录文本直接作为用户消息提交到对话
|
||||
|
||||
## 二、用户交互
|
||||
|
||||
| 操作 | 行为 |
|
||||
|------|------|
|
||||
| 长按空格 | 开始录音,显示录音状态 |
|
||||
| 释放空格 | 停止录音,等待最终转录 |
|
||||
| 转录完成 | 自动插入到输入框并提交 |
|
||||
| `/voice` 命令 | 切换语音模式开关 |
|
||||
|
||||
### UI 反馈
|
||||
|
||||
- **录音指示器**:录音时显示红色/脉冲动画
|
||||
- **中间转录**:录音过程中显示 STT 实时识别文本
|
||||
- **最终转录**:完成后替换中间结果
|
||||
|
||||
## 三、实现架构
|
||||
|
||||
### 3.1 门控逻辑
|
||||
|
||||
文件:`src/voice/voiceModeEnabled.ts`
|
||||
|
||||
三层检查:
|
||||
|
||||
```ts
|
||||
isVoiceModeEnabled() = hasVoiceAuth() && 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.2 核心模块
|
||||
|
||||
| 模块 | 职责 |
|
||||
|------|------|
|
||||
| `src/voice/voiceModeEnabled.ts` | Feature flag + GrowthBook + Auth 三层门控 |
|
||||
| `src/hooks/useVoice.ts` | React hook 管理录音状态和 WebSocket 连接 |
|
||||
| `src/services/voiceStreamSTT.ts` | WebSocket 流式传输到 Anthropic STT |
|
||||
|
||||
### 3.3 数据流
|
||||
|
||||
```
|
||||
用户按下空格键
|
||||
│
|
||||
▼
|
||||
useVoice hook 激活
|
||||
│
|
||||
▼
|
||||
macOS 原生音频 / SoX 开始录音
|
||||
│
|
||||
▼
|
||||
WebSocket 连接到 Anthropic STT 端点
|
||||
│
|
||||
├──→ 中间转录结果 → 实时显示
|
||||
│
|
||||
▼
|
||||
用户释放空格键
|
||||
│
|
||||
▼
|
||||
停止录音,等待最终转录
|
||||
│
|
||||
▼
|
||||
转录文本 → 插入输入框 → 自动提交
|
||||
```
|
||||
|
||||
### 3.4 音频录制
|
||||
|
||||
支持两种音频后端:
|
||||
- **macOS 原生音频**:优先使用,低延迟
|
||||
- **SoX(Sound eXchange)**:回退方案,跨平台
|
||||
|
||||
音频流通过 WebSocket 发送到 Anthropic 的 Nova 3 STT 模型。
|
||||
|
||||
## 四、关键设计决策
|
||||
|
||||
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`,不触发任何模块加载
|
||||
|
||||
## 五、使用方式
|
||||
|
||||
```bash
|
||||
# 启用 feature
|
||||
FEATURE_VOICE_MODE=1 bun run dev
|
||||
|
||||
# 在 REPL 中使用
|
||||
# 1. 确保已通过 OAuth 登录(claude.ai 订阅)
|
||||
# 2. 按住空格键说话
|
||||
# 3. 释放空格键等待转录
|
||||
# 4. 或使用 /voice 命令切换开关
|
||||
```
|
||||
|
||||
## 六、外部依赖
|
||||
|
||||
| 依赖 | 说明 |
|
||||
|------|------|
|
||||
| Anthropic OAuth | claude.ai 订阅登录,非 API key |
|
||||
| GrowthBook | `tengu_amber_quartz_disabled` 紧急关闭 |
|
||||
| macOS 原生音频 或 SoX | 音频录制 |
|
||||
| Nova 3 STT | 语音转文本模型 |
|
||||
|
||||
## 七、文件索引
|
||||
|
||||
| 文件 | 行数 | 职责 |
|
||||
|------|------|------|
|
||||
| `src/voice/voiceModeEnabled.ts` | 55 | 三层门控逻辑 |
|
||||
| `src/hooks/useVoice.ts` | — | React hook(录音状态 + WebSocket) |
|
||||
| `src/services/voiceStreamSTT.ts` | — | STT WebSocket 流式传输 |
|
||||
69
docs/features/web-browser-tool.md
Normal file
69
docs/features/web-browser-tool.md
Normal file
@@ -0,0 +1,69 @@
|
||||
# WEB_BROWSER_TOOL — 浏览器工具
|
||||
|
||||
> Feature Flag: `FEATURE_WEB_BROWSER_TOOL=1`
|
||||
> 实现状态:核心实现缺失,面板为 Stub,布线完整
|
||||
> 引用数:4
|
||||
|
||||
## 一、功能概述
|
||||
|
||||
WEB_BROWSER_TOOL 让模型可以启动浏览器实例、导航网页、与页面元素交互。使用 Bun 的内置 WebView API 提供无头/有头浏览器能力。
|
||||
|
||||
## 二、实现架构
|
||||
|
||||
### 2.1 模块状态
|
||||
|
||||
| 模块 | 文件 | 状态 |
|
||||
|------|------|------|
|
||||
| 浏览器面板 | `src/tools/WebBrowserTool/WebBrowserPanel.ts` | **Stub** — 返回 null |
|
||||
| 浏览器工具 | `src/tools/WebBrowserTool/WebBrowserTool.ts` | **缺失** |
|
||||
| REPL 集成 | `src/screens/REPL.tsx` | **布线** — 渲染 WebBrowserPanel |
|
||||
| 工具注册 | `src/tools.ts` | **布线** — 动态加载 |
|
||||
| WebView 检测 | `src/main.tsx` | **布线** — `'WebView' in Bun` 检测 |
|
||||
|
||||
### 2.2 预期数据流
|
||||
|
||||
```
|
||||
模型调用 WebBrowserTool
|
||||
│
|
||||
▼
|
||||
Bun WebView 创建浏览器实例
|
||||
│
|
||||
├── navigate(url) — 导航到 URL
|
||||
├── click(selector) — 点击元素
|
||||
├── screenshot() — 截取页面截图
|
||||
└── extract(selector) — 提取页面内容
|
||||
│
|
||||
▼
|
||||
结果返回给模型
|
||||
│
|
||||
▼
|
||||
WebBrowserPanel 在 REPL 侧边显示浏览器状态
|
||||
```
|
||||
|
||||
## 三、需要补全的内容
|
||||
|
||||
| 模块 | 工作量 | 说明 |
|
||||
|------|--------|------|
|
||||
| `WebBrowserTool.ts` | 大 | 工具 schema + Bun WebView API 执行 |
|
||||
| `WebBrowserPanel.tsx` | 中 | REPL 侧边栏浏览器状态面板 |
|
||||
|
||||
## 四、关键设计决策
|
||||
|
||||
1. **Bun WebView API**:使用 Bun 内置的 WebView 而非外部浏览器驱动(Puppeteer/Playwright)
|
||||
2. **REPL 侧边面板**:浏览器状态在 REPL 布局中独立渲染
|
||||
3. **Bun 特性检测**:`'WebView' in Bun` 检查运行时是否支持
|
||||
|
||||
## 五、使用方式
|
||||
|
||||
```bash
|
||||
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` | 面板渲染 |
|
||||
| `src/tools.ts:115-116` | 工具注册 |
|
||||
105
docs/features/workflow-scripts.md
Normal file
105
docs/features/workflow-scripts.md
Normal file
@@ -0,0 +1,105 @@
|
||||
# WORKFLOW_SCRIPTS — 工作流自动化
|
||||
|
||||
> Feature Flag: `FEATURE_WORKFLOW_SCRIPTS=1`
|
||||
> 实现状态:全部 Stub(7 个文件),布线完整
|
||||
> 引用数:10
|
||||
|
||||
## 一、功能概述
|
||||
|
||||
WORKFLOW_SCRIPTS 实现基于文件的多步自动化工作流。用户可以定义 YAML/JSON 格式的工作流描述文件,系统将其解析为可执行的多 agent 步骤序列。提供 `/workflows` 命令管理和触发工作流。
|
||||
|
||||
## 二、实现架构
|
||||
|
||||
### 2.1 模块状态
|
||||
|
||||
| 模块 | 文件 | 状态 |
|
||||
|------|------|------|
|
||||
| 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/` | **缺失** — 目录不存在 |
|
||||
| 本地工作流任务 | `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` 命令 |
|
||||
|
||||
### 2.2 预期数据流
|
||||
|
||||
```
|
||||
用户定义工作流(YAML/JSON 文件)
|
||||
│
|
||||
▼
|
||||
/workflows 命令发现工作流文件
|
||||
│
|
||||
▼
|
||||
createWorkflowCommand() 解析为 Command 对象 [需要实现]
|
||||
│
|
||||
▼
|
||||
WorkflowTool 执行工作流 [需要实现]
|
||||
│
|
||||
├── 步骤 1: Agent({ task: "..." })
|
||||
├── 步骤 2: Agent({ task: "..." })
|
||||
└── 步骤 N: Agent({ task: "..." })
|
||||
│
|
||||
▼
|
||||
LocalWorkflowTask 协调步骤执行 [需要实现]
|
||||
│
|
||||
▼
|
||||
WorkflowDetailDialog 显示进度 [需要实现]
|
||||
```
|
||||
|
||||
### 2.3 预期工作流 DSL
|
||||
|
||||
```
|
||||
# workflow.yaml(预期格式,需要设计)
|
||||
name: "代码审查工作流"
|
||||
steps:
|
||||
- name: "静态分析"
|
||||
agent: { type: "general-purpose", prompt: "运行 lint 和类型检查" }
|
||||
- name: "测试"
|
||||
agent: { type: "general-purpose", prompt: "运行测试套件" }
|
||||
- name: "综合报告"
|
||||
agent: { type: "general-purpose", prompt: "综合分析结果写报告" }
|
||||
```
|
||||
|
||||
## 三、需要补全的内容
|
||||
|
||||
| 优先级 | 模块 | 工作量 | 说明 |
|
||||
|--------|------|--------|------|
|
||||
| 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. **基于文件的 DSL**:工作流定义为文件(YAML/JSON),版本控制友好
|
||||
2. **多 Agent 步骤**:每个步骤是独立的 agent 任务,支持并行/串行
|
||||
3. **内置工作流**:`bundled/` 目录提供开箱即用的常用工作流
|
||||
4. **/workflows 命令**:统一的发现和触发入口
|
||||
|
||||
## 五、使用方式
|
||||
|
||||
```bash
|
||||
# 启用 feature(需要补全后才能真正使用)
|
||||
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) |
|
||||
| `src/tasks/LocalWorkflowTask/LocalWorkflowTask.ts` | 任务协调(stub) |
|
||||
| `src/components/tasks/WorkflowDetailDialog.ts` | 详情对话框(stub) |
|
||||
| `src/tools.ts:127-132` | 工具注册 |
|
||||
| `src/commands.ts:86-89` | 命令注册 |
|
||||
Reference in New Issue
Block a user