@yun-zero/claw-memory 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. package/.claude/settings.local.json +68 -0
  2. package/README.md +323 -0
  3. package/dist/config/llm.d.ts +13 -0
  4. package/dist/config/llm.d.ts.map +1 -0
  5. package/dist/config/llm.js +96 -0
  6. package/dist/config/llm.js.map +1 -0
  7. package/dist/config/plugin.d.ts +15 -0
  8. package/dist/config/plugin.d.ts.map +1 -0
  9. package/dist/config/plugin.js +32 -0
  10. package/dist/config/plugin.js.map +1 -0
  11. package/dist/db/entityRepository.d.ts +21 -0
  12. package/dist/db/entityRepository.d.ts.map +1 -0
  13. package/dist/db/entityRepository.js +55 -0
  14. package/dist/db/entityRepository.js.map +1 -0
  15. package/dist/db/repository.d.ts +22 -0
  16. package/dist/db/repository.d.ts.map +1 -0
  17. package/dist/db/repository.js +77 -0
  18. package/dist/db/repository.js.map +1 -0
  19. package/dist/db/schema.d.ts +5 -0
  20. package/dist/db/schema.d.ts.map +1 -0
  21. package/dist/db/schema.js +112 -0
  22. package/dist/db/schema.js.map +1 -0
  23. package/dist/db/todoRepository.d.ts +26 -0
  24. package/dist/db/todoRepository.d.ts.map +1 -0
  25. package/dist/db/todoRepository.js +54 -0
  26. package/dist/db/todoRepository.js.map +1 -0
  27. package/dist/hooks/bootstrap.d.ts +3 -0
  28. package/dist/hooks/bootstrap.d.ts.map +1 -0
  29. package/dist/hooks/bootstrap.js +28 -0
  30. package/dist/hooks/bootstrap.js.map +1 -0
  31. package/dist/hooks/message.d.ts +18 -0
  32. package/dist/hooks/message.d.ts.map +1 -0
  33. package/dist/hooks/message.js +52 -0
  34. package/dist/hooks/message.js.map +1 -0
  35. package/dist/index.d.ts +3 -0
  36. package/dist/index.d.ts.map +1 -0
  37. package/dist/index.js +46 -0
  38. package/dist/index.js.map +1 -0
  39. package/dist/mcp/tools.d.ts +26 -0
  40. package/dist/mcp/tools.d.ts.map +1 -0
  41. package/dist/mcp/tools.js +360 -0
  42. package/dist/mcp/tools.js.map +1 -0
  43. package/dist/plugin.d.ts +18 -0
  44. package/dist/plugin.d.ts.map +1 -0
  45. package/dist/plugin.js +62 -0
  46. package/dist/plugin.js.map +1 -0
  47. package/dist/services/entityGraphService.d.ts +87 -0
  48. package/dist/services/entityGraphService.d.ts.map +1 -0
  49. package/dist/services/entityGraphService.js +271 -0
  50. package/dist/services/entityGraphService.js.map +1 -0
  51. package/dist/services/memory.d.ts +26 -0
  52. package/dist/services/memory.d.ts.map +1 -0
  53. package/dist/services/memory.js +281 -0
  54. package/dist/services/memory.js.map +1 -0
  55. package/dist/services/memoryIndex.d.ts +34 -0
  56. package/dist/services/memoryIndex.d.ts.map +1 -0
  57. package/dist/services/memoryIndex.js +100 -0
  58. package/dist/services/memoryIndex.js.map +1 -0
  59. package/dist/services/metadataExtractor.d.ts +16 -0
  60. package/dist/services/metadataExtractor.d.ts.map +1 -0
  61. package/dist/services/metadataExtractor.js +75 -0
  62. package/dist/services/metadataExtractor.js.map +1 -0
  63. package/dist/services/retrieval.d.ts +24 -0
  64. package/dist/services/retrieval.d.ts.map +1 -0
  65. package/dist/services/retrieval.js +40 -0
  66. package/dist/services/retrieval.js.map +1 -0
  67. package/dist/services/scheduler.d.ts +122 -0
  68. package/dist/services/scheduler.d.ts.map +1 -0
  69. package/dist/services/scheduler.js +434 -0
  70. package/dist/services/scheduler.js.map +1 -0
  71. package/dist/services/summarizer.d.ts +43 -0
  72. package/dist/services/summarizer.d.ts.map +1 -0
  73. package/dist/services/summarizer.js +252 -0
  74. package/dist/services/summarizer.js.map +1 -0
  75. package/dist/services/tagService.d.ts +64 -0
  76. package/dist/services/tagService.d.ts.map +1 -0
  77. package/dist/services/tagService.js +281 -0
  78. package/dist/services/tagService.js.map +1 -0
  79. package/dist/tools/memory.d.ts +3 -0
  80. package/dist/tools/memory.d.ts.map +1 -0
  81. package/dist/tools/memory.js +114 -0
  82. package/dist/tools/memory.js.map +1 -0
  83. package/dist/types.d.ts +128 -0
  84. package/dist/types.d.ts.map +1 -0
  85. package/dist/types.js +6 -0
  86. package/dist/types.js.map +1 -0
  87. package/docs/plans/2026-03-02-claw-memory-design.md +445 -0
  88. package/docs/plans/2026-03-02-incremental-summary-design.md +157 -0
  89. package/docs/plans/2026-03-02-incremental-summary-implementation.md +468 -0
  90. package/docs/plans/2026-03-02-memory-index-design.md +163 -0
  91. package/docs/plans/2026-03-02-memory-index-implementation.md +836 -0
  92. package/docs/plans/2026-03-02-mvp-implementation.md +1703 -0
  93. package/docs/plans/2026-03-02-testing-implementation.md +395 -0
  94. package/docs/plans/2026-03-02-testing-plan.md +93 -0
  95. package/docs/plans/2026-03-03-claw-memory-openclaw-plugin-design.md +285 -0
  96. package/docs/plans/2026-03-03-claw-memory-plugin-implementation.md +642 -0
  97. package/docs/plans/2026-03-03-entity-graph-design.md +121 -0
  98. package/docs/plans/2026-03-03-entity-graph-implementation.md +687 -0
  99. package/docs/plans/2026-03-03-llm-generic-config-design.md +43 -0
  100. package/docs/plans/2026-03-03-llm-generic-config-implementation.md +186 -0
  101. package/docs/plans/2026-03-03-memory-e2e-stress-test-design.md +110 -0
  102. package/docs/plans/2026-03-03-memory-e2e-stress-test-implementation.md +464 -0
  103. package/docs/plans/2026-03-03-minimax-llm-fix.md +156 -0
  104. package/docs/plans/2026-03-03-scheduler-design.md +165 -0
  105. package/docs/plans/2026-03-03-scheduler-implementation.md +777 -0
  106. package/docs/plans/2026-03-03-tags-visualization-design.md +73 -0
  107. package/docs/plans/2026-03-03-tags-visualization-implementation.md +539 -0
  108. package/openclaw.plugin.json +11 -0
  109. package/package.json +41 -0
  110. package/src/config/llm.ts +129 -0
  111. package/src/config/plugin.ts +47 -0
  112. package/src/db/entityRepository.ts +80 -0
  113. package/src/db/repository.ts +106 -0
  114. package/src/db/schema.ts +121 -0
  115. package/src/db/todoRepository.ts +76 -0
  116. package/src/hooks/bootstrap.ts +36 -0
  117. package/src/hooks/message.ts +84 -0
  118. package/src/index.ts +50 -0
  119. package/src/plugin.ts +85 -0
  120. package/src/services/entityGraphService.ts +367 -0
  121. package/src/services/memory.ts +338 -0
  122. package/src/services/memoryIndex.ts +140 -0
  123. package/src/services/metadataExtractor.ts +89 -0
  124. package/src/services/retrieval.ts +71 -0
  125. package/src/services/scheduler.ts +529 -0
  126. package/src/services/summarizer.ts +318 -0
  127. package/src/services/tagService.ts +335 -0
  128. package/src/tools/memory.ts +137 -0
  129. package/src/types.ts +139 -0
  130. package/tsconfig.json +20 -0
  131. package/vitest.config.ts +16 -0
@@ -0,0 +1,642 @@
1
+ # Claw-Memory OpenClaw 插件实现计划
2
+
3
+ > **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
4
+
5
+ **Goal:** 开发 OpenClaw 插件,实现自动保存对话到记忆,会话开始时注入摘要
6
+
7
+ **Architecture:** 完全集成到 OpenClaw 插件系统,复用 claw-memory 现有服务(schema, summarizer, scheduler),使用 OpenClaw 内置 LLM
8
+
9
+ **Tech Stack:** TypeScript, OpenClaw Plugin SDK, better-sqlite3, node-cron
10
+
11
+ ---
12
+
13
+ ## 准备工作
14
+
15
+ ### Task 1: 创建开发分支
16
+
17
+ **Step 1: 创建并切换到新分支**
18
+
19
+ ```bash
20
+ cd /home/ubuntu/openclaw/claw-memory
21
+ git checkout -b feature/claw-memory-plugin
22
+ ```
23
+
24
+ **Step 2: 验证分支**
25
+
26
+ ```bash
27
+ git branch --show-current
28
+ ```
29
+
30
+ Expected: `feature/claw-memory-plugin`
31
+
32
+ ---
33
+
34
+ ## Task 2: 创建插件项目结构
35
+
36
+ **Files:**
37
+ - Create: `plugin/openclaw.plugin.json`
38
+ - Create: `plugin/package.json`
39
+ - Create: `plugin/tsconfig.json`
40
+
41
+ **Step 1: 创建 openclaw.plugin.json**
42
+
43
+ ```json
44
+ {
45
+ "id": "claw-memory",
46
+ "name": "ClawMemory",
47
+ "version": "0.1.0",
48
+ "description": "AI memory system - auto-save conversations and inject memory summary",
49
+ "main": "./dist/index.js",
50
+ "dependencies": {},
51
+ "scripts": {
52
+ "build": "tsc"
53
+ }
54
+ }
55
+ ```
56
+
57
+ **Step 2: 创建 package.json**
58
+
59
+ ```json
60
+ {
61
+ "name": "@openclaw/claw-memory",
62
+ "version": "0.1.0",
63
+ "description": "AI memory system for OpenClaw",
64
+ "main": "dist/index.js",
65
+ "type": "module",
66
+ "scripts": {
67
+ "build": "tsc"
68
+ },
69
+ "dependencies": {
70
+ "better-sqlite3": "^11.0.0",
71
+ "node-cron": "^4.2.1",
72
+ "uuid": "^10.0.0"
73
+ },
74
+ "devDependencies": {
75
+ "@types/better-sqlite3": "^7.6.0",
76
+ "@types/node": "^20.0.0",
77
+ "@types/node-cron": "^3.0.11",
78
+ "@types/uuid": "^10.0.0",
79
+ "typescript": "^5.0.0"
80
+ }
81
+ }
82
+ ```
83
+
84
+ **Step 3: 创建 tsconfig.json**
85
+
86
+ ```json
87
+ {
88
+ "compilerOptions": {
89
+ "target": "ES2022",
90
+ "module": "ESNext",
91
+ "moduleResolution": "bundler",
92
+ "esModuleInterop": true,
93
+ "strict": true,
94
+ "outDir": "./dist",
95
+ "rootDir": "./src"
96
+ },
97
+ "include": ["src/**/*"]
98
+ }
99
+ ```
100
+
101
+ **Step 4: 提交**
102
+
103
+ ```bash
104
+ git add plugin/
105
+ git commit -m "feat: add OpenClaw plugin project structure"
106
+ ```
107
+
108
+ ---
109
+
110
+ ## Task 3: 创建插件入口文件
111
+
112
+ **Files:**
113
+ - Create: `plugin/src/index.ts`
114
+
115
+ **Step 1: 创建插件入口**
116
+
117
+ ```typescript
118
+ // plugin/src/index.ts
119
+ import type { OpenClawPlugin } from '@openclaw/plugin-sdk';
120
+
121
+ export default {
122
+ name: 'claw-memory',
123
+ version: '0.1.0',
124
+
125
+ async register(context: any) {
126
+ // 注册 Hooks
127
+ await context.hooks.register('message:sent', async (event: any) => {
128
+ const { message, session } = event;
129
+ // TODO: 实现保存逻辑
130
+ });
131
+
132
+ await context.hooks.register('agent:bootstrap', async (context: any) => {
133
+ // TODO: 实现注入摘要逻辑
134
+ });
135
+
136
+ // 注册 Agent Tools
137
+ context.tools.register({
138
+ name: 'memory_save',
139
+ description: 'Save conversation to memory',
140
+ schema: { /* ... */ },
141
+ handler: async (params: any) => {
142
+ // TODO: 实现保存工具
143
+ }
144
+ });
145
+
146
+ // 初始化数据库
147
+ // TODO: 初始化 SQLite
148
+
149
+ // 启动定时任务
150
+ // TODO: 启动 scheduler
151
+ }
152
+ } satisfies OpenClawPlugin;
153
+ ```
154
+
155
+ **Step 2: 提交**
156
+
157
+ ```bash
158
+ git add plugin/src/index.ts
159
+ git commit -m "feat: add plugin entry point"
160
+ ```
161
+
162
+ ---
163
+
164
+ ## Task 4: 实现配置管理
165
+
166
+ **Files:**
167
+ - Create: `plugin/src/config.ts`
168
+
169
+ **Step 1: 创建配置管理**
170
+
171
+ ```typescript
172
+ // plugin/src/config.ts
173
+ export interface PluginConfig {
174
+ enabled: boolean;
175
+ autoSave: boolean;
176
+ saveMode: 'qa' | 'full';
177
+ dataDir: string;
178
+ scheduler: {
179
+ enabled: boolean;
180
+ deduplicateTime: string;
181
+ dailyTime: string;
182
+ weeklyTime: string;
183
+ monthlyTime: string;
184
+ };
185
+ }
186
+
187
+ export function getConfig(context: any): PluginConfig {
188
+ const defaultConfig: PluginConfig = {
189
+ enabled: true,
190
+ autoSave: true,
191
+ saveMode: 'qa',
192
+ dataDir: '~/.openclaw/claw-memory',
193
+ scheduler: {
194
+ enabled: true,
195
+ deduplicateTime: '01:00',
196
+ dailyTime: '02:00',
197
+ weeklyTime: '03:00',
198
+ monthlyTime: '04:00'
199
+ }
200
+ };
201
+
202
+ const userConfig = context.config.get('plugins.claw-memory') || {};
203
+ return { ...defaultConfig, ...userConfig };
204
+ }
205
+ ```
206
+
207
+ **Step 2: 提交**
208
+
209
+ ```bash
210
+ git add plugin/src/config.ts
211
+ git commit -m "feat: add config management"
212
+ ```
213
+
214
+ ---
215
+
216
+ ## Task 5: 复用数据库 Schema
217
+
218
+ 由于现有 `claw-memory/src/db/schema.ts` 已有完整的数据库 Schema,需要将其复制到插件中。
219
+
220
+ **Files:**
221
+ - Create: `plugin/src/db/schema.ts`
222
+
223
+ **Step 1: 复制 schema**
224
+
225
+ 从 `src/db/schema.ts` 复制以下内容到 `plugin/src/db/schema.ts`:
226
+ - `initializeDatabase()` 函数
227
+ - `getDatabase()` 函数
228
+
229
+ **Step 2: 修改 getDatabase 路径**
230
+
231
+ ```typescript
232
+ // plugin/src/db/schema.ts
233
+ import Database from 'better-sqlite3';
234
+ import * as path from 'path';
235
+ import * as fs from 'fs';
236
+ import { homedir } from 'os';
237
+
238
+ export function getDatabase(): Database.Database {
239
+ const dataDir = process.env.CLAW_MEMORY_DATA_DIR || path.join(homedir(), '.openclaw', 'claw-memory');
240
+
241
+ // 确保目录存在
242
+ if (!fs.existsSync(dataDir)) {
243
+ fs.mkdirSync(dataDir, { recursive: true });
244
+ }
245
+
246
+ const dbPath = path.join(dataDir, 'memory.db');
247
+ const db = new Database(dbPath);
248
+
249
+ initializeDatabase(db);
250
+ return db;
251
+ }
252
+ ```
253
+
254
+ **Step 3: 提交**
255
+
256
+ ```bash
257
+ git add plugin/src/db/
258
+ git commit -m "feat: add database schema"
259
+ ```
260
+
261
+ ---
262
+
263
+ ## Task 6: 实现 message:sent Hook
264
+
265
+ **Files:**
266
+ - Create: `plugin/src/hooks/message.ts`
267
+
268
+ **Step 1: 创建 Hook 处理逻辑**
269
+
270
+ ```typescript
271
+ // plugin/src/hooks/message.ts
272
+ import type { Database } from 'better-sqlite3';
273
+ import { v4 as uuidv4 } from 'uuid';
274
+
275
+ interface MessageEvent {
276
+ message: {
277
+ role: 'user' | 'assistant';
278
+ content: string;
279
+ };
280
+ session: {
281
+ id: string;
282
+ key: string;
283
+ };
284
+ }
285
+
286
+ export async function handleMessageSent(
287
+ event: MessageEvent,
288
+ db: Database,
289
+ config: any
290
+ ): Promise<void> {
291
+ // 只处理 assistant 消息(AI 回复后保存)
292
+ if (event.message.role !== 'assistant') {
293
+ return;
294
+ }
295
+
296
+ // 获取对应的 user 消息(需要从 session 上下文中获取)
297
+ // TODO: 从 session JSONL 中获取最后一条 user 消息
298
+
299
+ const userMessage = event.message.content; // 临时:需要从上下文获取
300
+ const assistantMessage = event.message.content;
301
+
302
+ // 构建 Q&A
303
+ const qaContent = `Q: ${userMessage}\nA: ${assistantMessage}`;
304
+
305
+ // 保存到数据库
306
+ const memoryId = uuidv4();
307
+ const dataDir = process.env.CLAW_MEMORY_DATA_DIR || '~/.openclaw/claw-memory';
308
+ const contentPath = `${dataDir}/memories/${memoryId}.md`;
309
+
310
+ // 写入文件
311
+ const fs = await import('fs/promises');
312
+ await fs.writeFile(contentPath, qaContent);
313
+
314
+ // 插入数据库
315
+ db.prepare(`
316
+ INSERT INTO memories (id, content_path, summary, created_at)
317
+ VALUES (?, ?, ?, datetime('now'))
318
+ `).run(memoryId, contentPath, assistantMessage.substring(0, 200));
319
+
320
+ console.log(`[ClawMemory] Saved memory: ${memoryId}`);
321
+ }
322
+ ```
323
+
324
+ **Step 2: 提交**
325
+
326
+ ```bash
327
+ git add plugin/src/hooks/message.ts
328
+ git commit -m "feat: implement message:sent hook"
329
+ ```
330
+
331
+ ---
332
+
333
+ ## Task 7: 实现 agent:bootstrap Hook
334
+
335
+ **Files:**
336
+ - Create: `plugin/src/hooks/bootstrap.ts`
337
+
338
+ **Step 1: 创建 Bootstrap Hook**
339
+
340
+ ```typescript
341
+ // plugin/src/hooks/bootstrap.ts
342
+ import type { Database } from 'better-sqlite3';
343
+
344
+ export async function handleAgentBootstrap(
345
+ context: any,
346
+ db: Database
347
+ ): Promise<string> {
348
+ // 获取本周记忆摘要
349
+ const today = new Date();
350
+ const weekStart = new Date(today);
351
+ weekStart.setDate(today.getDate() - today.getDay());
352
+ const weekStartStr = weekStart.toISOString().split('T')[0];
353
+
354
+ const weekMemories = db.prepare(`
355
+ SELECT summary, importance
356
+ FROM memories
357
+ WHERE date(created_at) >= date(?)
358
+ ORDER BY importance DESC
359
+ LIMIT 10
360
+ `).all(weekStartStr) as { summary: string; importance: number }[];
361
+
362
+ if (weekMemories.length === 0) {
363
+ return '';
364
+ }
365
+
366
+ // 构建摘要文本
367
+ const lines = ['## 记忆摘要\n'];
368
+ lines.push(`本周共有 ${weekMemories.length} 条记忆记录。\n`);
369
+ lines.push('### 重点内容:\n');
370
+
371
+ for (const m of weekMemories.slice(0, 5)) {
372
+ if (m.summary) {
373
+ lines.push(`- ${m.summary}`);
374
+ }
375
+ }
376
+
377
+ return lines.join('\n');
378
+ }
379
+ ```
380
+
381
+ **Step 2: 提交**
382
+
383
+ ```bash
384
+ git add plugin/src/hooks/bootstrap.ts
385
+ git commit -m "feat: implement agent:bootstrap hook"
386
+ ```
387
+
388
+ ---
389
+
390
+ ## Task 8: 实现 Agent Tools
391
+
392
+ **Files:**
393
+ - Create: `plugin/src/tools/memory.ts`
394
+
395
+ **Step 1: 创建 memory_save 工具**
396
+
397
+ ```typescript
398
+ // plugin/src/tools/memory.ts
399
+ import type { Database } from 'better-sqlite3';
400
+ import { v4 as uuidv4 } from 'uuid';
401
+
402
+ export function registerMemoryTools(context: any, db: Database) {
403
+ context.tools.register({
404
+ name: 'memory_save',
405
+ description: 'Save conversation to memory with metadata',
406
+ schema: {
407
+ type: 'object',
408
+ properties: {
409
+ content: { type: 'string', description: 'Conversation content' },
410
+ metadata: {
411
+ type: 'object',
412
+ properties: {
413
+ tags: { type: 'array', items: { type: 'string' } },
414
+ keywords: { type: 'array', items: { type: 'string' } },
415
+ importance: { type: 'number', minimum: 0, maximum: 1 }
416
+ }
417
+ }
418
+ },
419
+ required: ['content']
420
+ },
421
+ handler: async (params: any) => {
422
+ const { content, metadata = {} } = params;
423
+ const memoryId = uuidv4();
424
+
425
+ const dataDir = process.env.CLAW_MEMORY_DATA_DIR || '~/.openclaw/claw-memory';
426
+ const contentPath = `${dataDir}/memories/${memoryId}.md`;
427
+
428
+ const fs = await import('fs/promises');
429
+ await fs.writeFile(contentPath, content);
430
+
431
+ db.prepare(`
432
+ INSERT INTO memories (id, content_path, summary, importance, created_at)
433
+ VALUES (?, ?, ?, ?, datetime('now'))
434
+ `).run(memoryId, contentPath, metadata.summary || content.substring(0, 200), metadata.importance || 0.5);
435
+
436
+ return { success: true, memory_id: memoryId };
437
+ }
438
+ });
439
+
440
+ context.tools.register({
441
+ name: 'memory_search',
442
+ description: 'Search memories by query',
443
+ schema: {
444
+ type: 'object',
445
+ properties: {
446
+ query: { type: 'string' },
447
+ limit: { type: 'number', default: 10 }
448
+ },
449
+ required: ['query']
450
+ },
451
+ handler: async (params: any) => {
452
+ const { query, limit = 10 } = params;
453
+ const memories = db.prepare(`
454
+ SELECT id, summary, importance, created_at
455
+ FROM memories
456
+ WHERE summary LIKE ?
457
+ ORDER BY importance DESC
458
+ LIMIT ?
459
+ ).all(`%${query}%`, limit);
460
+
461
+ return { memories };
462
+ }
463
+ });
464
+
465
+ context.tools.register({
466
+ name: 'memory_summary',
467
+ description: 'Get memory summary for time period',
468
+ schema: {
469
+ type: 'object',
470
+ properties: {
471
+ period: { type: 'string', enum: ['day', 'week', 'month'] },
472
+ date: { type: 'string' }
473
+ },
474
+ required: ['period']
475
+ },
476
+ handler: async (params: any) => {
477
+ const { period, date } = params;
478
+ // 复用现有 summarizer 逻辑
479
+ // TODO: 实现摘要获取
480
+ return { summary: 'TODO' };
481
+ }
482
+ });
483
+ }
484
+ ```
485
+
486
+ **Step 2: 提交**
487
+
488
+ ```bash
489
+ git add plugin/src/tools/memory.ts
490
+ git commit -m "feat: register memory tools"
491
+ ```
492
+
493
+ ---
494
+
495
+ ## Task 9: 复用 Scheduler 服务
496
+
497
+ 由于现有 `claw-memory/src/services/scheduler.ts` 已有完整的 Scheduler,需要适配到插件中。
498
+
499
+ **Files:**
500
+ - Create: `plugin/src/services/scheduler.ts`
501
+
502
+ **Step 1: 复制并修改 Scheduler**
503
+
504
+ 从 `src/services/scheduler.ts` 复制主要内容,并修改:
505
+ - 移除外部依赖(直接从插件上下文获取 db)
506
+ - 适配插件配置
507
+
508
+ **Step 2: 提交**
509
+
510
+ ```bash
511
+ git add plugin/src/services/scheduler.ts
512
+ git commit -m "feat: add scheduler service"
513
+ ```
514
+
515
+ ---
516
+
517
+ ## Task 10: 集成所有组件
518
+
519
+ **Files:**
520
+ - Modify: `plugin/src/index.ts`
521
+
522
+ **Step 1: 更新插件入口**
523
+
524
+ ```typescript
525
+ // plugin/src/index.ts
526
+ import type { OpenClawPlugin } from '@openclaw/plugin-sdk';
527
+ import { getConfig, PluginConfig } from './config.js';
528
+ import { getDatabase } from './db/schema.js';
529
+ import { handleMessageSent } from './hooks/message.js';
530
+ import { handleAgentBootstrap } from './hooks/bootstrap.js';
531
+ import { registerMemoryTools } from './tools/memory.js';
532
+
533
+ export default {
534
+ name: 'claw-memory',
535
+ version: '0.1.0',
536
+
537
+ async register(context: any) {
538
+ const config = getConfig(context);
539
+ if (!config.enabled) {
540
+ console.log('[ClawMemory] Plugin disabled');
541
+ return;
542
+ }
543
+
544
+ console.log('[ClawMemory] Starting...');
545
+
546
+ // 初始化数据库
547
+ const db = getDatabase();
548
+
549
+ // 注册 Hooks
550
+ await context.hooks.register('message:sent', async (event: any) => {
551
+ if (config.autoSave) {
552
+ try {
553
+ await handleMessageSent(event, db, config);
554
+ } catch (error) {
555
+ console.error('[ClawMemory] Failed to save memory:', error);
556
+ }
557
+ }
558
+ });
559
+
560
+ await context.hooks.register('agent:bootstrap', async (bootstrapContext: any) => {
561
+ try {
562
+ const summary = await handleAgentBootstrap(bootstrapContext, db);
563
+ if (summary) {
564
+ bootstrapContext.context = bootstrapContext.context || '';
565
+ bootstrapContext.context += '\n\n' + summary;
566
+ }
567
+ } catch (error) {
568
+ console.error('[ClawMemory] Failed to inject summary:', error);
569
+ }
570
+ });
571
+
572
+ // 注册 Tools
573
+ registerMemoryTools(context, db);
574
+
575
+ // 启动 Scheduler
576
+ if (config.scheduler.enabled) {
577
+ // TODO: 启动定时任务
578
+ }
579
+
580
+ console.log('[ClawMemory] Started successfully');
581
+ }
582
+ } satisfies OpenClawPlugin;
583
+ ```
584
+
585
+ **Step 2: 测试编译**
586
+
587
+ ```bash
588
+ cd plugin
589
+ npm install
590
+ npm run build
591
+ ```
592
+
593
+ **Step 3: 提交**
594
+
595
+ ```bash
596
+ git add plugin/src/index.ts
597
+ git commit -m "feat: integrate all components"
598
+ ```
599
+
600
+ ---
601
+
602
+ ## Task 11: 最终测试
603
+
604
+ **Step 1: 模拟安装测试**
605
+
606
+ 由于需要 OpenClaw 环境,这里先验证代码能编译通过。
607
+
608
+ ```bash
609
+ cd plugin
610
+ npm run build
611
+ ls -la dist/
612
+ ```
613
+
614
+ Expected: 生成 dist/index.js 等文件
615
+
616
+ ---
617
+
618
+ ## Task 12: 合并到主分支
619
+
620
+ **Step 1: 切换到主分支**
621
+
622
+ ```bash
623
+ git checkout main
624
+ ```
625
+
626
+ **Step 2: 合并功能分支**
627
+
628
+ ```bash
629
+ git merge feature/claw-memory-plugin
630
+ ```
631
+
632
+ **Step 3: 推送到远程**
633
+
634
+ ```bash
635
+ git push origin main
636
+ ```
637
+
638
+ **Step 4: 删除功能分支(可选)**
639
+
640
+ ```bash
641
+ git branch -d feature/claw-memory-plugin
642
+ ```