feat: auto dream
Browse files✅ Auto Dream 功能实现完成!
📋 实施总结
新增文件
- `src/skills/bundled/dream.ts` - 手动 /dream 命令实现
- 无条件可用(只要 auto-memory 启用)
- 完整工具权限,用户可实时观察
- 支持额外参数传递
修改文件
- `src/skills/bundled/index.ts` - 移除 KAIROS feature gate
- 添加 registerDreamSkill 导入
- 无条件调用 registerDreamSkill()
🎯 功能特性
自动触发(Auto Dream)
- ✅ 每次查询循环结束后检查
- ✅ 三重门控机制:
1. 启用状态检查
2. 时间门(默认 24 小时)
3. 会话门(默认 5 个会话)
4. 锁文件保护
- ✅ 后台 forked agent 运行,工具受限
- ✅ UI 中显示状态和进度
手动触发(/dream 命令)
- ✅ 用户随时可用,无门控限制
- ✅ 主循环中运行,完整工具权限
- ✅ 实时观察操作过程
- ✅ 支持额外上下文参数
4 阶段整理流程
1. Orient - 扫描现有记忆文件
2. Gather - 收集新信息(日志、过时记忆、会话记录)
3. Consolidate - 合并到现有文件
4. Prune and index - 更新索引并清理
🔧 配置选项
Settings.json:
{
"autoDreamEnabled": true,
"autoMemoryEnabled": true
}
GrowthBook:
- Feature: tengu_onyx_plover
- Parameters: minHours, minSessions
📊 与 BestClaude 对比
┌──────────────────┬────────────┬──────────┬──────────┐
│ 功能 │ BestClaude │ 当前项目 │ 状态 │
├──────────────────┼────────────┼──────────┼──────────┤
│ 后台自动触发 │ ✅ │ ✅ │ 完全一致 │
│ 手动 /dream 命令 │ ✅ │ ✅ │ 完全一致 │
│ Feature Gate │ 已移除 │ 已移除 │ 完全一致 │
│ 4 阶段流程 │ ✅ │ ✅ │ 完全一致 │
│ 锁文件机制 │ ✅ │ ✅ │ 完全一致 │
│ UI 集成 │ ✅ │ ✅ │ 完全一致 │
└──────────────────┴────────────┴──────────┴──────────┘
🚀 使用方法
自动触发:
1. 确保 autoDreamEnabled: true 在 settings.json 中
2. 正常使用 CLI,积累 5 个会话
3. 等待 24 小时后自动触发
手动触发:
/dream
/dream 重点关注最近的架构变更
查看状态:
- UI 中会显示 "Auto-dream: on/off"
- 按 Shift+Down 查看后台任务
- 实时观察 dream 任务进度
✦ 现在你的项目已经拥有与 BestClaude 完全对等的 Auto Dream 功能!🎉
- src/skills/bundled/dream.ts +44 -0
- src/skills/bundled/index.ts +2 -6
|
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Manual /dream skill — runs the memory consolidation prompt interactively.
|
| 2 |
+
// Extracted from the KAIROS feature gate so it's available unconditionally
|
| 3 |
+
// whenever auto-memory is enabled.
|
| 4 |
+
|
| 5 |
+
import { getAutoMemPath, isAutoMemoryEnabled } from '../../memdir/paths.js'
|
| 6 |
+
import { buildConsolidationPrompt } from '../../services/autoDream/consolidationPrompt.js'
|
| 7 |
+
import { recordConsolidation } from '../../services/autoDream/consolidationLock.js'
|
| 8 |
+
import { getOriginalCwd } from '../../bootstrap/state.js'
|
| 9 |
+
import { getProjectDir } from '../../utils/sessionStorage.js'
|
| 10 |
+
import { registerBundledSkill } from '../bundledSkills.js'
|
| 11 |
+
|
| 12 |
+
const DREAM_PROMPT_PREFIX = `# Dream: Memory Consolidation (manual run)
|
| 13 |
+
|
| 14 |
+
You are performing a manual dream — a reflective pass over your memory files. Unlike the automatic background dream, this run has full tool permissions and the user is watching. Synthesize what you've learned recently into durable, well-organized memories so that future sessions can orient quickly.
|
| 15 |
+
|
| 16 |
+
`
|
| 17 |
+
|
| 18 |
+
export function registerDreamSkill(): void {
|
| 19 |
+
registerBundledSkill({
|
| 20 |
+
name: 'dream',
|
| 21 |
+
description:
|
| 22 |
+
'Manually trigger memory consolidation — review, organize, and prune your auto-memory files.',
|
| 23 |
+
whenToUse:
|
| 24 |
+
'Use when the user says /dream or wants to manually consolidate memories, organize memory files, or clean up stale entries.',
|
| 25 |
+
userInvocable: true,
|
| 26 |
+
isEnabled: () => isAutoMemoryEnabled(),
|
| 27 |
+
async getPromptForCommand(args) {
|
| 28 |
+
const memoryRoot = getAutoMemPath()
|
| 29 |
+
const transcriptDir = getProjectDir(getOriginalCwd())
|
| 30 |
+
|
| 31 |
+
// Stamp the consolidation lock optimistically (same as the KAIROS path).
|
| 32 |
+
await recordConsolidation()
|
| 33 |
+
|
| 34 |
+
const basePrompt = buildConsolidationPrompt(memoryRoot, transcriptDir, '')
|
| 35 |
+
let prompt = DREAM_PROMPT_PREFIX + basePrompt
|
| 36 |
+
|
| 37 |
+
if (args) {
|
| 38 |
+
prompt += `\n\n## Additional context from user\n\n${args}`
|
| 39 |
+
}
|
| 40 |
+
|
| 41 |
+
return [{ type: 'text', text: prompt }]
|
| 42 |
+
},
|
| 43 |
+
})
|
| 44 |
+
}
|
|
@@ -3,6 +3,7 @@ import { shouldAutoEnableClaudeInChrome } from 'src/utils/claudeInChrome/setup.j
|
|
| 3 |
import { registerBatchSkill } from './batch.js'
|
| 4 |
import { registerClaudeInChromeSkill } from './claudeInChrome.js'
|
| 5 |
import { registerDebugSkill } from './debug.js'
|
|
|
|
| 6 |
import { registerKeybindingsSkill } from './keybindings.js'
|
| 7 |
import { registerLoremIpsumSkill } from './loremIpsum.js'
|
| 8 |
import { registerRememberSkill } from './remember.js'
|
|
@@ -32,12 +33,7 @@ export function initBundledSkills(): void {
|
|
| 32 |
registerSimplifySkill()
|
| 33 |
registerBatchSkill()
|
| 34 |
registerStuckSkill()
|
| 35 |
-
|
| 36 |
-
/* eslint-disable @typescript-eslint/no-require-imports */
|
| 37 |
-
const { registerDreamSkill } = require('./dream.js')
|
| 38 |
-
/* eslint-enable @typescript-eslint/no-require-imports */
|
| 39 |
-
registerDreamSkill()
|
| 40 |
-
}
|
| 41 |
if (feature('REVIEW_ARTIFACT')) {
|
| 42 |
/* eslint-disable @typescript-eslint/no-require-imports */
|
| 43 |
const { registerHunterSkill } = require('./hunter.js')
|
|
|
|
| 3 |
import { registerBatchSkill } from './batch.js'
|
| 4 |
import { registerClaudeInChromeSkill } from './claudeInChrome.js'
|
| 5 |
import { registerDebugSkill } from './debug.js'
|
| 6 |
+
import { registerDreamSkill } from './dream.js'
|
| 7 |
import { registerKeybindingsSkill } from './keybindings.js'
|
| 8 |
import { registerLoremIpsumSkill } from './loremIpsum.js'
|
| 9 |
import { registerRememberSkill } from './remember.js'
|
|
|
|
| 33 |
registerSimplifySkill()
|
| 34 |
registerBatchSkill()
|
| 35 |
registerStuckSkill()
|
| 36 |
+
registerDreamSkill()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 37 |
if (feature('REVIEW_ARTIFACT')) {
|
| 38 |
/* eslint-disable @typescript-eslint/no-require-imports */
|
| 39 |
const { registerHunterSkill } = require('./hunter.js')
|