diff --git a/.gitignore b/.gitignore index f03bc66b5..2a4224105 100644 --- a/.gitignore +++ b/.gitignore @@ -15,7 +15,7 @@ src/utils/vendor/ .claude/ .codex/ .omx/ - +.docs/task/ # Binary / screenshot files (root only) /*.png *.bmp diff --git a/02-kairos (1).md b/02-kairos (1).md new file mode 100644 index 000000000..ce022bac1 --- /dev/null +++ b/02-kairos (1).md @@ -0,0 +1,204 @@ +# KAIROS — 永不关机的 Claude + +> 源码位置:`src/assistant/`、`src/proactive/`、`src/services/autoDream/` +> 编译开关:`feature('KAIROS')`、`feature('KAIROS_BRIEF')`、`feature('KAIROS_CHANNELS')` +> 远程开关:GrowthBook `tengu_kairos` + +关掉终端 Claude 还在运行的持久助手模式。KAIROS 是 Claude Code 中最复杂的隐藏功能之一。 + +--- + +## 核心概念 + +KAIROS 让 Claude 从"一次性对话工具"变成"持久运行的 AI 助手": + +- 关闭终端后 Claude 仍在后台运行 +- 每天自动写日志 +- 晚上自动"做梦"整理记忆 +- 没人说话时自己找活干 +- 命令超 15 秒自动丢后台 + +--- + +## 激活流程 + +定义在 `src/main.tsx`(约第 1054-1092 行),需要通过五层检查: + +``` +1. feature('KAIROS') ← 编译时 flag +2. settings.assistant: true ← .claude/settings.json +3. 目录信任状态检查 ← 防恶意仓库劫持 +4. tengu_kairos ← GrowthBook 远程开关 +5. setKairosActive(true) ← 全局状态激活 +``` + +`--assistant` CLI 参数可跳过远程开关检查(用于 Agent SDK daemon 模式)。 + +全局状态存储在 `src/bootstrap/state.ts`: +- `kairosActive: boolean`(默认 `false`) +- `getKairosActive()` / `setKairosActive(true)` + +--- + +## 跨会话持久运行 + +### 会话恢复 + +`src/utils/conversationRecovery.ts` 中使用 `feature('KAIROS')` 条件导入 `BriefTool` 和 `SendUserFileTool`。在反序列化会话时识别这些工具的结果为"终端工具结果",判断 turn 是正常完成还是被中断。 + +### 持久 Cron 任务 + +关键在 `.claude/scheduled_tasks.json`。标记为 `permanent: true` 的任务不受 7 天自动过期限制: + +- `catch-up`:恢复中断的工作 +- `morning-checkin`:每日早间签到 +- `dream`:记忆整合 + +### 会话历史 API + +`src/assistant/sessionHistory.ts` 通过 OAuth API 加载远程会话历史,使用 `v1/sessions/{sessionId}/events` 端点,支持分页拉取。 + +--- + +## 做梦机制(Dream) + +KAIROS 最精巧的子系统——后台运行的子代理,将分散的会话记忆整合为持久的结构化知识。 + +### 触发条件(三层门控,由廉到贵) + +定义在 `src/services/autoDream/autoDream.ts`: + +``` +1. 时间门控:距上次整合超过 24 小时(minHours) +2. 会话门控:至少 5 个新会话(minSessions) +3. 锁门控:没有其他进程正在整合 +``` + +阈值通过 GrowthBook `tengu_onyx_plover` 远程配置动态控制。 + +### 四阶段整合流程 + +定义在 `src/services/autoDream/consolidationPrompt.ts`: + +| 阶段 | 动作 | +|------|------| +| **Orient** | 列出记忆目录、读取 `MEMORY.md` 索引、浏览已有主题文件 | +| **Gather** | 从每日日志、已有记忆、JSONL transcript 中搜集新信号 | +| **Consolidate** | 合并新信号到主题文件,转换相对日期为绝对日期,删除过时事实 | +| **Prune** | 更新 `MEMORY.md` 索引,保持在行数和大小限制内 | + +### 锁机制 + +`src/services/autoDream/consolidationLock.ts`: + +- 使用 `.consolidate-lock` 文件 +- 文件 mtime = `lastConsolidatedAt` +- 文件内容 = 持有者 PID +- 支持 PID 存活检查(1 小时超时) +- double-write 后 re-read 验证防竞争 + +### 每日日志 + +路径由 `src/memdir/paths.ts` 的 `getAutoMemDailyLogPath()` 计算: + +``` +/logs/YYYY/MM/YYYY-MM-DD.md +``` + +### UI 呈现 + +- Footer pill 标签显示 **"dreaming"** +- `src/components/tasks/DreamDetailDialog.tsx` 提供专门的详情对话框 +- 支持查看实时进度和手动中止 +- `Shift+Down` 打开后台任务对话框 + +--- + +## 主动模式(Proactive Mode) + +没人说话时 Claude 自己找活干。 + +### 核心状态 + +`src/proactive/index.ts` 维护三个状态: + +| 状态 | 说明 | +|------|------| +| `active` | 是否激活 | +| `paused` | 是否暂停(用户按 Esc 取消时暂停,下次输入恢复) | +| `contextBlocked` | API 错误时阻塞 tick,防止 tick-error-tick 死循环 | + +### 激活方式 + +- `--proactive` CLI 参数 +- `CLAUDE_CODE_PROACTIVE` 环境变量 +- 受 `feature('PROACTIVE') || feature('KAIROS')` 保护 + +### 系统提示 + +激活后追加: + +``` +# Proactive Mode + +You are in proactive mode. Take initiative -- explore, act, and make progress +without waiting for instructions. + +Start by briefly greeting the user. + +You will receive periodic prompts. These are check-ins. Do whatever +seems most useful, or call Sleep if there's nothing to do. +``` + +### SleepTool 集成 + +设置中的 `minSleepDurationMs` 和 `maxSleepDurationMs` 控制 Sleep 持续时间范围,节流 proactive tick 频率。没活干就 Sleep 等着。 + +--- + +## 后台任务管理 + +### Cron 调度器 + +`src/utils/cronScheduler.ts`: + +- 每 1 秒 tick 一次(`CHECK_INTERVAL_MS = 1000`) +- 使用 chokidar 监视 `.claude/scheduled_tasks.json` +- 支持调度器锁(`src/utils/cronTasksLock.ts`),防止多实例重复触发 +- 锁探测间隔 5 秒,持有者崩溃时自动接管 + +### 任务类型 + +| 类型 | 说明 | +|------|------| +| 一次性(`recurring: false`) | 触发后自动删除,支持错过任务检测 | +| 循环(`recurring: true`) | 触发后重新调度,默认 7 天过期 | +| 永久(`permanent: true`) | 不受过期限制(KAIROS 专用) | +| 会话级(`durable: false`) | 仅内存中,进程退出即消失 | + +### Jitter 防雷群机制 + +`src/utils/cronJitterConfig.ts`: + +- 循环任务:基于 taskId 的确定性延迟(interval 的 10%,上限 15 分钟) +- 一次性任务:在 :00 和 :30 施加最多 90 秒提前量 +- 运维可在事故期间推送配置变更,60 秒内全客户端生效 + +--- + +## 关键源码文件 + +| 文件 | 职责 | +|------|------| +| `src/bootstrap/state.ts` | KAIROS 全局状态 | +| `src/assistant/index.ts` | 助手模式入口 | +| `src/assistant/sessionHistory.ts` | 远程会话历史 API | +| `src/proactive/index.ts` | 主动模式状态管理 | +| `src/services/autoDream/autoDream.ts` | Auto-Dream 引擎 | +| `src/services/autoDream/consolidationPrompt.ts` | 整合提示(四阶段) | +| `src/services/autoDream/consolidationLock.ts` | 整合锁 | +| `src/services/autoDream/config.ts` | Dream 配置 | +| `src/tasks/DreamTask/DreamTask.ts` | Dream 任务定义 | +| `src/utils/cronScheduler.ts` | Cron 调度器 | +| `src/utils/cronTasks.ts` | Cron 任务持久化 | +| `src/skills/bundled/dream.ts` | `/dream` Skill(存根) | diff --git a/build.ts b/build.ts index 349a21e7e..3600515ab 100644 --- a/build.ts +++ b/build.ts @@ -40,6 +40,8 @@ const DEFAULT_BUILD_FEATURES = [ 'KAIROS', 'COORDINATOR_MODE', 'LAN_PIPES', + 'BG_SESSIONS', + 'TEMPLATES', // 'REVIEW_ARTIFACT', // API 请求无响应,需进一步排查 schema 兼容性 // P3: poor mode (disable extract_memories + prompt_suggestion) 'POOR', diff --git a/docs/features/stub-recovery-design-1-4.md b/docs/features/stub-recovery-design-1-4.md new file mode 100644 index 000000000..e25afddc3 --- /dev/null +++ b/docs/features/stub-recovery-design-1-4.md @@ -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 2A:MVP + +- 实现 `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 ` 能输出对应日志 +3. `kill ` 能结束目标 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