openclaw-cortex-memory 0.1.0-Alpha.3 → 0.1.0-Alpha.31

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 (110) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +296 -203
  3. package/SIGNATURE.md +7 -0
  4. package/SKILL.md +92 -268
  5. package/dist/index.d.ts +100 -22
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +1249 -1252
  8. package/dist/index.js.map +1 -1
  9. package/dist/openclaw.plugin.json +501 -16
  10. package/dist/src/dedup/three_stage_deduplicator.d.ts +25 -0
  11. package/dist/src/dedup/three_stage_deduplicator.d.ts.map +1 -0
  12. package/dist/src/dedup/three_stage_deduplicator.js +224 -0
  13. package/dist/src/dedup/three_stage_deduplicator.js.map +1 -0
  14. package/dist/src/engine/memory_engine.d.ts +6 -1
  15. package/dist/src/engine/memory_engine.d.ts.map +1 -1
  16. package/dist/src/engine/ts_engine.d.ts +242 -0
  17. package/dist/src/engine/ts_engine.d.ts.map +1 -1
  18. package/dist/src/engine/ts_engine.js +1468 -52
  19. package/dist/src/engine/ts_engine.js.map +1 -1
  20. package/dist/src/engine/types.d.ts +29 -0
  21. package/dist/src/engine/types.d.ts.map +1 -1
  22. package/dist/src/graph/ontology.d.ts +125 -0
  23. package/dist/src/graph/ontology.d.ts.map +1 -0
  24. package/dist/src/graph/ontology.js +1237 -0
  25. package/dist/src/graph/ontology.js.map +1 -0
  26. package/dist/src/net/http_post.d.ts +17 -0
  27. package/dist/src/net/http_post.d.ts.map +1 -0
  28. package/dist/src/net/http_post.js +56 -0
  29. package/dist/src/net/http_post.js.map +1 -0
  30. package/dist/src/quality/llm_output_validator.d.ts +66 -0
  31. package/dist/src/quality/llm_output_validator.d.ts.map +1 -0
  32. package/dist/src/quality/llm_output_validator.js +659 -0
  33. package/dist/src/quality/llm_output_validator.js.map +1 -0
  34. package/dist/src/reflect/reflector.d.ts +7 -0
  35. package/dist/src/reflect/reflector.d.ts.map +1 -1
  36. package/dist/src/reflect/reflector.js +352 -8
  37. package/dist/src/reflect/reflector.js.map +1 -1
  38. package/dist/src/rules/rule_store.d.ts.map +1 -1
  39. package/dist/src/rules/rule_store.js +75 -16
  40. package/dist/src/rules/rule_store.js.map +1 -1
  41. package/dist/src/session/session_end.d.ts +33 -0
  42. package/dist/src/session/session_end.d.ts.map +1 -1
  43. package/dist/src/session/session_end.js +67 -64
  44. package/dist/src/session/session_end.js.map +1 -1
  45. package/dist/src/store/archive_store.d.ts +136 -0
  46. package/dist/src/store/archive_store.d.ts.map +1 -0
  47. package/dist/src/store/archive_store.js +635 -0
  48. package/dist/src/store/archive_store.js.map +1 -0
  49. package/dist/src/store/embedding_utils.d.ts +32 -0
  50. package/dist/src/store/embedding_utils.d.ts.map +1 -0
  51. package/dist/src/store/embedding_utils.js +173 -0
  52. package/dist/src/store/embedding_utils.js.map +1 -0
  53. package/dist/src/store/graph_memory_store.d.ts +114 -0
  54. package/dist/src/store/graph_memory_store.d.ts.map +1 -0
  55. package/dist/src/store/graph_memory_store.js +841 -0
  56. package/dist/src/store/graph_memory_store.js.map +1 -0
  57. package/dist/src/store/read_store.d.ts +89 -0
  58. package/dist/src/store/read_store.d.ts.map +1 -1
  59. package/dist/src/store/read_store.js +2459 -28
  60. package/dist/src/store/read_store.js.map +1 -1
  61. package/dist/src/store/vector_store.d.ts +45 -0
  62. package/dist/src/store/vector_store.d.ts.map +1 -0
  63. package/dist/src/store/vector_store.js +202 -0
  64. package/dist/src/store/vector_store.js.map +1 -0
  65. package/dist/src/store/write_store.d.ts +54 -0
  66. package/dist/src/store/write_store.d.ts.map +1 -1
  67. package/dist/src/store/write_store.js +284 -6
  68. package/dist/src/store/write_store.js.map +1 -1
  69. package/dist/src/sync/session_sync.d.ts +119 -2
  70. package/dist/src/sync/session_sync.d.ts.map +1 -1
  71. package/dist/src/sync/session_sync.js +2377 -31
  72. package/dist/src/sync/session_sync.js.map +1 -1
  73. package/dist/src/utils/runtime_env.d.ts +4 -0
  74. package/dist/src/utils/runtime_env.d.ts.map +1 -0
  75. package/dist/src/utils/runtime_env.js +51 -0
  76. package/dist/src/utils/runtime_env.js.map +1 -0
  77. package/dist/src/wiki/wiki_linter.d.ts +25 -0
  78. package/dist/src/wiki/wiki_linter.d.ts.map +1 -0
  79. package/dist/src/wiki/wiki_linter.js +268 -0
  80. package/dist/src/wiki/wiki_linter.js.map +1 -0
  81. package/dist/src/wiki/wiki_logger.d.ts +10 -0
  82. package/dist/src/wiki/wiki_logger.d.ts.map +1 -0
  83. package/dist/src/wiki/wiki_logger.js +78 -0
  84. package/dist/src/wiki/wiki_logger.js.map +1 -0
  85. package/dist/src/wiki/wiki_maintainer.d.ts +36 -0
  86. package/dist/src/wiki/wiki_maintainer.d.ts.map +1 -0
  87. package/dist/src/wiki/wiki_maintainer.js +38 -0
  88. package/dist/src/wiki/wiki_maintainer.js.map +1 -0
  89. package/dist/src/wiki/wiki_projector.d.ts +33 -0
  90. package/dist/src/wiki/wiki_projector.d.ts.map +1 -0
  91. package/dist/src/wiki/wiki_projector.js +633 -0
  92. package/dist/src/wiki/wiki_projector.js.map +1 -0
  93. package/dist/src/wiki/wiki_queue.d.ts +29 -0
  94. package/dist/src/wiki/wiki_queue.d.ts.map +1 -0
  95. package/dist/src/wiki/wiki_queue.js +137 -0
  96. package/dist/src/wiki/wiki_queue.js.map +1 -0
  97. package/openclaw.plugin.json +501 -16
  98. package/package.json +58 -7
  99. package/schema/graph.schema.yaml +330 -0
  100. package/scripts/cli.js +19 -14
  101. package/scripts/repair-memory.js +321 -0
  102. package/scripts/uninstall.js +22 -5
  103. package/skills/cortex-memory/SKILL.md +49 -0
  104. package/skills/cortex-memory/references/agent-manual.md +115 -0
  105. package/skills/cortex-memory/references/configuration.md +92 -0
  106. package/skills/cortex-memory/references/publish-checklist.md +46 -0
  107. package/skills/cortex-memory/references/system-prompt-template.md +27 -0
  108. package/skills/cortex-memory/references/tools.md +181 -0
  109. package/skills/cortex-memory/scripts/smoke-check.ps1 +56 -0
  110. package/index.ts +0 -2142
@@ -0,0 +1,321 @@
1
+ #!/usr/bin/env node
2
+
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+
6
+ const args = process.argv.slice(2);
7
+ const isDryRun = args.includes('--dry-run');
8
+ const isFix = args.includes('--fix');
9
+ const targetArg = args.find(a => a.startsWith('--target='));
10
+ const target = targetArg ? targetArg.split('=')[1] : 'all';
11
+
12
+ const PROJECT_ROOT = process.cwd();
13
+ const MEMORY_ROOT = path.join(PROJECT_ROOT, 'data', 'memory');
14
+
15
+ const VALID_TARGETS = ['all', 'archive', 'active', 'vector'];
16
+
17
+ function printUsage() {
18
+ console.log(`
19
+ Memory Data Repair Tool
20
+
21
+ Usage: node scripts/repair-memory.js [options]
22
+
23
+ Options:
24
+ --dry-run Scan and report issues without making changes
25
+ --fix Remove invalid records and create quarantine file
26
+ --target=<target> Specify target: all, archive, active, vector (default: all)
27
+
28
+ Examples:
29
+ node scripts/repair-memory.js --dry-run
30
+ node scripts/repair-memory.js --fix --target=archive
31
+ `);
32
+ }
33
+
34
+ if (!VALID_TARGETS.includes(target)) {
35
+ console.error(`Invalid target: ${target}. Valid targets: ${VALID_TARGETS.join(', ')}`);
36
+ printUsage();
37
+ process.exit(1);
38
+ }
39
+
40
+ if (!isDryRun && !isFix) {
41
+ printUsage();
42
+ process.exit(0);
43
+ }
44
+
45
+ function validateJsonlLine(line, lineNumber) {
46
+ const errors = [];
47
+ if (!line || !line.trim()) {
48
+ return { valid: true, errors: [], record: null };
49
+ }
50
+ let record;
51
+ try {
52
+ record = JSON.parse(line);
53
+ } catch (e) {
54
+ errors.push(`JSON parse error: ${e.message}`);
55
+ return { valid: false, errors, record: null };
56
+ }
57
+ if (!record || typeof record !== 'object') {
58
+ errors.push('Record is not an object');
59
+ return { valid: false, errors, record: null };
60
+ }
61
+ if (typeof record.id !== 'string' || !record.id.trim()) {
62
+ errors.push('Missing or invalid id field');
63
+ }
64
+ if (typeof record.timestamp !== 'string' || !record.timestamp.trim()) {
65
+ errors.push('Missing or invalid timestamp field');
66
+ }
67
+ if (record.layer !== 'active' && record.layer !== 'archive') {
68
+ errors.push('Missing or invalid layer field');
69
+ }
70
+ const anomalyPatterns = [
71
+ /\d+\.\d+,\s*"[^"]+"/,
72
+ /"[^"]+"\s+\d+\.\d+/,
73
+ /,\s*\d+\.\d+,/,
74
+ /"\w+\.\w+\.\w+"/,
75
+ /\d+\.\w+\.\d+/,
76
+ ];
77
+ const lineStr = JSON.stringify(record);
78
+ for (const pattern of anomalyPatterns) {
79
+ if (pattern.test(lineStr)) {
80
+ errors.push('Anomaly pattern detected in record');
81
+ break;
82
+ }
83
+ }
84
+ return { valid: errors.length === 0, errors, record };
85
+ }
86
+
87
+ function scanJsonlFile(filePath) {
88
+ const results = {
89
+ path: filePath,
90
+ exists: false,
91
+ totalLines: 0,
92
+ validLines: 0,
93
+ invalidLines: 0,
94
+ emptyLines: 0,
95
+ issues: [],
96
+ };
97
+ if (!fs.existsSync(filePath)) {
98
+ return results;
99
+ }
100
+ results.exists = true;
101
+ const content = fs.readFileSync(filePath, 'utf-8');
102
+ const lines = content.split(/\r?\n/);
103
+ for (let i = 0; i < lines.length; i++) {
104
+ const line = lines[i];
105
+ if (!line.trim()) {
106
+ results.emptyLines++;
107
+ continue;
108
+ }
109
+ results.totalLines++;
110
+ const validation = validateJsonlLine(line, i + 1);
111
+ if (validation.valid) {
112
+ results.validLines++;
113
+ } else {
114
+ results.invalidLines++;
115
+ results.issues.push({
116
+ lineNumber: i + 1,
117
+ errors: validation.errors,
118
+ preview: line.slice(0, 100) + (line.length > 100 ? '...' : ''),
119
+ });
120
+ }
121
+ }
122
+ return results;
123
+ }
124
+
125
+ function repairJsonlFile(filePath, dryRun) {
126
+ const results = {
127
+ path: filePath,
128
+ exists: false,
129
+ totalLines: 0,
130
+ validLines: 0,
131
+ removedLines: 0,
132
+ quarantineLines: [],
133
+ };
134
+ if (!fs.existsSync(filePath)) {
135
+ return results;
136
+ }
137
+ results.exists = true;
138
+ const content = fs.readFileSync(filePath, 'utf-8');
139
+ const lines = content.split(/\r?\n/);
140
+ const validRecords = [];
141
+ for (let i = 0; i < lines.length; i++) {
142
+ const line = lines[i];
143
+ if (!line.trim()) {
144
+ continue;
145
+ }
146
+ results.totalLines++;
147
+ const validation = validateJsonlLine(line, i + 1);
148
+ if (validation.valid) {
149
+ results.validLines++;
150
+ validRecords.push(line);
151
+ } else {
152
+ results.removedLines++;
153
+ results.quarantineLines.push({
154
+ lineNumber: i + 1,
155
+ content: line,
156
+ errors: validation.errors,
157
+ });
158
+ }
159
+ }
160
+ if (!dryRun && results.removedLines > 0) {
161
+ const newContent = validRecords.join('\n') + (validRecords.length > 0 ? '\n' : '');
162
+ fs.writeFileSync(filePath, newContent, 'utf-8');
163
+ const quarantinePath = filePath + '.quarantine.jsonl';
164
+ const quarantineContent = results.quarantineLines.map(q =>
165
+ JSON.stringify({ lineNumber: q.lineNumber, errors: q.errors, content: q.content })
166
+ ).join('\n');
167
+ fs.writeFileSync(quarantinePath, quarantineContent + '\n', 'utf-8');
168
+ }
169
+ return results;
170
+ }
171
+
172
+ function scanVectorFallback(filePath) {
173
+ const results = {
174
+ path: filePath,
175
+ exists: false,
176
+ totalRecords: 0,
177
+ validRecords: 0,
178
+ orphanRecords: 0,
179
+ issues: [],
180
+ };
181
+ if (!fs.existsSync(filePath)) {
182
+ return results;
183
+ }
184
+ results.exists = true;
185
+ const content = fs.readFileSync(filePath, 'utf-8');
186
+ const lines = content.split(/\r?\n/);
187
+ for (let i = 0; i < lines.length; i++) {
188
+ const line = lines[i];
189
+ if (!line.trim()) continue;
190
+ results.totalRecords++;
191
+ try {
192
+ const record = JSON.parse(line);
193
+ if (!record.id || !record.embedding) {
194
+ results.issues.push({
195
+ lineNumber: i + 1,
196
+ error: 'Missing id or embedding',
197
+ });
198
+ } else {
199
+ results.validRecords++;
200
+ }
201
+ } catch (e) {
202
+ results.issues.push({
203
+ lineNumber: i + 1,
204
+ error: `JSON parse error: ${e.message}`,
205
+ });
206
+ }
207
+ }
208
+ return results;
209
+ }
210
+
211
+ console.log('='.repeat(60));
212
+ console.log('Memory Data Repair Tool');
213
+ console.log('='.repeat(60));
214
+ console.log(`Mode: ${isDryRun ? 'DRY RUN (no changes)' : 'FIX (will modify files)'}`);
215
+ console.log(`Target: ${target}`);
216
+ console.log(`Memory Root: ${MEMORY_ROOT}`);
217
+ console.log('='.repeat(60));
218
+
219
+ const archivePath = path.join(MEMORY_ROOT, 'sessions', 'archive', 'archive.jsonl');
220
+ const activePath = path.join(MEMORY_ROOT, 'sessions', 'active', 'sessions.jsonl');
221
+ const vectorFallbackPath = path.join(MEMORY_ROOT, 'vector', 'lancedb_events.jsonl');
222
+
223
+ let totalIssues = 0;
224
+ const report = {
225
+ archive: null,
226
+ active: null,
227
+ vector: null,
228
+ };
229
+
230
+ if (target === 'all' || target === 'archive') {
231
+ console.log('\n[Archive Layer]');
232
+ if (isDryRun) {
233
+ report.archive = scanJsonlFile(archivePath);
234
+ } else {
235
+ report.archive = repairJsonlFile(archivePath, false);
236
+ }
237
+ if (!report.archive.exists) {
238
+ console.log(' File does not exist');
239
+ } else {
240
+ console.log(` Total lines: ${report.archive.totalLines}`);
241
+ console.log(` Valid lines: ${report.archive.validLines}`);
242
+ console.log(` Invalid lines: ${report.archive.invalidLines || report.archive.removedLines}`);
243
+ if (report.archive.issues && report.archive.issues.length > 0) {
244
+ console.log(' Issues found:');
245
+ report.archive.issues.slice(0, 5).forEach(issue => {
246
+ console.log(` Line ${issue.lineNumber}: ${issue.errors.join(', ')}`);
247
+ });
248
+ if (report.archive.issues.length > 5) {
249
+ console.log(` ... and ${report.archive.issues.length - 5} more`);
250
+ }
251
+ }
252
+ totalIssues += report.archive.invalidLines || report.archive.removedLines || 0;
253
+ }
254
+ }
255
+
256
+ if (target === 'all' || target === 'active') {
257
+ console.log('\n[Active Layer]');
258
+ if (isDryRun) {
259
+ report.active = scanJsonlFile(activePath);
260
+ } else {
261
+ report.active = repairJsonlFile(activePath, false);
262
+ }
263
+ if (!report.active.exists) {
264
+ console.log(' File does not exist');
265
+ } else {
266
+ console.log(` Total lines: ${report.active.totalLines}`);
267
+ console.log(` Valid lines: ${report.active.validLines}`);
268
+ console.log(` Invalid lines: ${report.active.invalidLines || report.active.removedLines}`);
269
+ if (report.active.issues && report.active.issues.length > 0) {
270
+ console.log(' Issues found:');
271
+ report.active.issues.slice(0, 5).forEach(issue => {
272
+ console.log(` Line ${issue.lineNumber}: ${issue.errors.join(', ')}`);
273
+ });
274
+ if (report.active.issues.length > 5) {
275
+ console.log(` ... and ${report.active.issues.length - 5} more`);
276
+ }
277
+ }
278
+ totalIssues += report.active.invalidLines || report.active.removedLines || 0;
279
+ }
280
+ }
281
+
282
+ if (target === 'all' || target === 'vector') {
283
+ console.log('\n[Vector Fallback]');
284
+ report.vector = scanVectorFallback(vectorFallbackPath);
285
+ if (!report.vector.exists) {
286
+ console.log(' File does not exist');
287
+ } else {
288
+ console.log(` Total records: ${report.vector.totalRecords}`);
289
+ console.log(` Valid records: ${report.vector.validRecords}`);
290
+ console.log(` Issues: ${report.vector.issues.length}`);
291
+ if (report.vector.issues.length > 0) {
292
+ console.log(' Issues found:');
293
+ report.vector.issues.slice(0, 5).forEach(issue => {
294
+ console.log(` Line ${issue.lineNumber}: ${issue.error}`);
295
+ });
296
+ }
297
+ totalIssues += report.vector.issues.length;
298
+ }
299
+ }
300
+
301
+ console.log('\n' + '='.repeat(60));
302
+ console.log('Summary');
303
+ console.log('='.repeat(60));
304
+ console.log(`Total issues found: ${totalIssues}`);
305
+
306
+ if (isDryRun) {
307
+ if (totalIssues > 0) {
308
+ console.log('\nRun with --fix to repair these issues.');
309
+ } else {
310
+ console.log('\nNo issues found. Memory data is healthy.');
311
+ }
312
+ } else {
313
+ if (totalIssues > 0) {
314
+ console.log('\nRepair completed. Invalid records have been quarantined.');
315
+ console.log('Check .quarantine.jsonl files for removed records.');
316
+ } else {
317
+ console.log('\nNo repairs needed. Memory data is healthy.');
318
+ }
319
+ }
320
+
321
+ process.exit(totalIssues > 0 && isDryRun ? 1 : 0);
@@ -17,14 +17,20 @@ function findProjectRoot() {
17
17
  }
18
18
 
19
19
  function findOpenClawConfig() {
20
+ const explicitConfigPath = process.env.OPENCLAW_CONFIG_PATH || '';
21
+ const stateDir = process.env.OPENCLAW_STATE_DIR || '';
22
+ const basePath = process.env.OPENCLAW_BASE_PATH || '';
23
+ const homePath = process.env.USERPROFILE || process.env.HOME || '';
20
24
  const possiblePaths = [
25
+ explicitConfigPath,
26
+ stateDir ? path.join(stateDir, 'openclaw.json') : '',
27
+ basePath ? path.join(basePath, 'openclaw.json') : '',
21
28
  path.join(process.cwd(), 'openclaw.json'),
22
- path.join(process.env.USERPROFILE || process.env.HOME || '', '.openclaw', 'openclaw.json'),
23
- path.join(process.env.OPENCLAW_BASE_PATH || '', 'openclaw.json'),
29
+ homePath ? path.join(homePath, '.openclaw', 'openclaw.json') : '',
24
30
  ];
25
31
 
26
32
  for (const p of possiblePaths) {
27
- if (fs.existsSync(p)) {
33
+ if (p && fs.existsSync(p)) {
28
34
  return p;
29
35
  }
30
36
  }
@@ -114,15 +120,20 @@ function removeFromConfig() {
114
120
  const content = fs.readFileSync(configPath, 'utf-8');
115
121
  const config = JSON.parse(content);
116
122
 
123
+ if (Array.isArray(config.plugins?.allow)) {
124
+ config.plugins.allow = config.plugins.allow.filter((item) => item !== PLUGIN_NAME);
125
+ }
117
126
  if (config.plugins?.entries?.[PLUGIN_NAME]) {
118
127
  delete config.plugins.entries[PLUGIN_NAME];
119
-
120
128
  if (config.plugins.slots?.memory === PLUGIN_NAME) {
121
129
  delete config.plugins.slots.memory;
122
130
  }
123
131
 
124
132
  fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
125
133
  console.log(`Removed plugin from config: ${configPath}`);
134
+ } else if (Array.isArray(config.plugins?.allow)) {
135
+ fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
136
+ console.log(`Removed plugin allowlist entry from config: ${configPath}`);
126
137
  } else {
127
138
  console.log('Plugin not found in config.');
128
139
  }
@@ -209,4 +220,10 @@ function main() {
209
220
  }
210
221
  }
211
222
 
212
- main();
223
+ module.exports = {
224
+ uninstall,
225
+ };
226
+
227
+ if (require.main === module) {
228
+ main();
229
+ }
@@ -0,0 +1,49 @@
1
+ ---
2
+ name: cortex-memory
3
+ description: Independent skill for Cortex Memory operations in OpenClaw. Use when users ask for cross-session memory continuity, prior decisions, preferences, relationship tracing, or memory maintenance. If the memory plugin is not installed, guide users to install and enable openclaw-cortex-memory first, then continue with normal memory workflows.
4
+ homepage: https://github.com/deki18/openclaw-cortex-memory
5
+ metadata: { "openclaw": { "os": ["darwin", "linux", "win32"], "primaryEnv": "EMBEDDING_API_KEY" } }
6
+ ---
7
+
8
+ # Cortex Memory
9
+
10
+ This is an independent skill, not a plugin-embedded skill.
11
+
12
+ Use this runtime flow:
13
+
14
+ 1. Check whether plugin `openclaw-cortex-memory` is available.
15
+ 2. If missing or disabled, run the install bootstrap guide in `{baseDir}/references/agent-manual.md` with README-consistent install order.
16
+ 3. After plugin is enabled, run memory retrieval or write operations.
17
+
18
+ After plugin is ready, use this default workflow:
19
+
20
+ 1. Retrieve candidate memory with `search_memory`.
21
+ 2. If the user asks about entity links or dependency paths, use `query_graph`.
22
+ 3. If `query_graph` returns `conflict_hint`, use `list_graph_conflicts` and ask user confirmation before `resolve_graph_conflict`.
23
+ 4. For graph status snapshots or projection consistency checks, use `export_graph_view` and `lint_memory_wiki`.
24
+ 5. Answer with retrieved evidence first, then add reasoning.
25
+ 6. If the turn introduces durable new information, persist it with `store_event`.
26
+ 7. For maintenance windows or session wrap-up, run `sync_memory` and optionally `reflect_memory`.
27
+
28
+ If tool calls fail:
29
+
30
+ 1. Run `diagnostics`.
31
+ 2. Tell the user the plugin is unavailable or misconfigured.
32
+ 3. Continue with a normal answer without fabricating memory hits.
33
+
34
+ Do not use this skill for:
35
+
36
+ - Real-time web facts (weather, stock, breaking news).
37
+ - One-off temporary context that should not be persisted.
38
+
39
+ Use these local references when needed:
40
+
41
+ - Install and bootstrap playbook: `{baseDir}/references/agent-manual.md`
42
+ - System prompt template: `{baseDir}/references/system-prompt-template.md`
43
+ - Tool details: `{baseDir}/references/tools.md`
44
+ - Config and dependency setup: `{baseDir}/references/configuration.md`
45
+ - Publish and validation checklist: `{baseDir}/references/publish-checklist.md`
46
+
47
+ Use this script for a quick environment preflight:
48
+
49
+ - `{baseDir}/scripts/smoke-check.ps1 -Json`
@@ -0,0 +1,115 @@
1
+ # Cortex Memory Agent Manual
2
+
3
+ ## Goal
4
+
5
+ Use Cortex Memory as a long-term memory layer in OpenClaw. This manual is for agents operating from the independent `cortex-memory` skill folder.
6
+
7
+ ## Phase 1: Plugin Availability Check
8
+
9
+ Run:
10
+
11
+ ```bash
12
+ openclaw plugins list
13
+ openclaw plugins inspect openclaw-cortex-memory
14
+ ```
15
+
16
+ If plugin exists and is enabled, continue to Phase 3.
17
+
18
+ If plugin is missing or disabled, go to Phase 2.
19
+
20
+ ## Phase 2: Install and Enable Plugin
21
+
22
+ Preferred install path (README default):
23
+
24
+ ```bash
25
+ openclaw plugins install clawhub:openclaw-cortex-memory
26
+ openclaw plugins enable openclaw-cortex-memory
27
+ ```
28
+
29
+ Fallback install path:
30
+
31
+ ```bash
32
+ npm pack openclaw-cortex-memory@0.1.0-Alpha.30
33
+ openclaw plugins install ./openclaw-cortex-memory-0.1.0-Alpha.30.tgz
34
+ openclaw plugins enable openclaw-cortex-memory
35
+ rm ./openclaw-cortex-memory-0.1.0-Alpha.30.tgz
36
+ ```
37
+
38
+ Then verify:
39
+
40
+ ```bash
41
+ openclaw plugins list
42
+ openclaw plugins inspect openclaw-cortex-memory
43
+ ```
44
+
45
+ If config is not ready, apply the baseline from `configuration.md`.
46
+
47
+ If the user asks for "system prompt rules", use `{baseDir}/references/system-prompt-template.md`.
48
+
49
+ ## Phase 3: Runtime Workflow
50
+
51
+ ### Retrieval-first answers
52
+
53
+ 1. `search_memory` with the user query.
54
+ 2. `query_graph` when relationship/path reasoning is needed.
55
+ 3. If `query_graph` returns `conflict_hint`, run `list_graph_conflicts` and confirm with user before `resolve_graph_conflict`.
56
+ 4. Respond with evidence first, reasoning second.
57
+
58
+ ### Persistence
59
+
60
+ Use `store_event` only for durable information:
61
+
62
+ - stable preferences
63
+ - project decisions
64
+ - long-lived constraints
65
+
66
+ Avoid persisting ephemeral chatter.
67
+
68
+ ### Maintenance
69
+
70
+ - `sync_memory` for historical import
71
+ - `reflect_memory` for rule extraction
72
+ - `backfill_embeddings` for vector repair
73
+ - `export_graph_view` for status-aware graph snapshots
74
+ - `lint_memory_wiki` for projection consistency checks
75
+ - `diagnostics` when anything looks inconsistent
76
+
77
+ ## Failure Handling
78
+
79
+ If plugin tools are unavailable:
80
+
81
+ 1. Run `diagnostics`.
82
+ 2. Explain the issue clearly (plugin disabled, config incomplete, endpoint unavailable, or API key missing).
83
+ 3. Provide immediate next action with exact command.
84
+
85
+ If install or enable flow reports a `memory-lancedb` config requirement, add this block under `plugins.entries` in `openclaw.json`:
86
+
87
+ ```json
88
+ "memory-lancedb": {
89
+ "enabled": false,
90
+ "config": {
91
+ "embedding": {
92
+ "apiKey": "${MEMORY_LANCEDB_API_KEY}",
93
+ "model": "text-embedding-3-small"
94
+ },
95
+ "dbPath": "~/.openclaw/memory/lancedb",
96
+ "autoRecall": true,
97
+ "autoCapture": false,
98
+ "captureMaxChars": 500
99
+ }
100
+ }
101
+ ```
102
+
103
+ ## Operator Commands Cheat Sheet
104
+
105
+ ```bash
106
+ openclaw plugins install clawhub:openclaw-cortex-memory
107
+ openclaw plugins enable openclaw-cortex-memory
108
+ openclaw plugins inspect openclaw-cortex-memory
109
+ npm pack openclaw-cortex-memory@0.1.0-Alpha.30
110
+ openclaw plugins install ./openclaw-cortex-memory-0.1.0-Alpha.30.tgz
111
+ openclaw plugins enable openclaw-cortex-memory
112
+ rm ./openclaw-cortex-memory-0.1.0-Alpha.30.tgz
113
+ openclaw skills info cortex-memory
114
+ openclaw skills check
115
+ ```
@@ -0,0 +1,92 @@
1
+ # Configuration Reference
2
+
3
+ ## Minimum OpenClaw Config
4
+
5
+ Use this as the baseline in `openclaw.json`.
6
+
7
+ ```json
8
+ {
9
+ "plugins": {
10
+ "allow": ["openclaw-cortex-memory"],
11
+ "slots": {
12
+ "memory": "none"
13
+ },
14
+ "entries": {
15
+ "openclaw-cortex-memory": {
16
+ "enabled": true,
17
+ "config": {
18
+ "autoSync": true,
19
+ "autoReflect": false,
20
+ "graphQualityMode": "warn",
21
+ "wikiProjection": {
22
+ "enabled": true,
23
+ "mode": "incremental",
24
+ "maxBatch": 100
25
+ },
26
+ "embedding": {
27
+ "provider": "api",
28
+ "model": "text-embedding-3-large",
29
+ "apiKey": "${EMBEDDING_API_KEY}",
30
+ "baseURL": "https://your-embedding-endpoint/v1",
31
+ "dimensions": 3072
32
+ },
33
+ "llm": {
34
+ "provider": "api",
35
+ "model": "gpt-4",
36
+ "apiKey": "${LLM_API_KEY}",
37
+ "baseURL": "https://your-llm-endpoint/v1"
38
+ },
39
+ "reranker": {
40
+ "provider": "api",
41
+ "model": "BAAI/bge-reranker-v2-m3",
42
+ "apiKey": "${RERANKER_API_KEY}",
43
+ "baseURL": "https://your-reranker-endpoint/v1/rerank"
44
+ }
45
+ }
46
+ }
47
+ }
48
+ }
49
+ }
50
+ ```
51
+
52
+ ## Required Environment Variables
53
+
54
+ - `EMBEDDING_API_KEY`
55
+ - `LLM_API_KEY`
56
+ - `RERANKER_API_KEY`
57
+
58
+ ## Required Endpoints
59
+
60
+ - Embedding: OpenAI-compatible `/embeddings`
61
+ - LLM: OpenAI-compatible `/chat/completions`
62
+ - Reranker: `/rerank`
63
+
64
+ ## Troubleshooting: memory-lancedb Requirement
65
+
66
+ If `openclaw plugins install/enable` reports a `memory-lancedb` config requirement, add this entry under `plugins.entries`:
67
+
68
+ ```json
69
+ "memory-lancedb": {
70
+ "enabled": false,
71
+ "config": {
72
+ "embedding": {
73
+ "apiKey": "${MEMORY_LANCEDB_API_KEY}",
74
+ "model": "text-embedding-3-small"
75
+ },
76
+ "dbPath": "~/.openclaw/memory/lancedb",
77
+ "autoRecall": true,
78
+ "autoCapture": false,
79
+ "captureMaxChars": 500
80
+ }
81
+ }
82
+ ```
83
+
84
+ ## Recommended Validation Commands
85
+
86
+ ```bash
87
+ openclaw plugins list
88
+ openclaw plugins inspect openclaw-cortex-memory
89
+ openclaw skills list
90
+ openclaw skills info cortex-memory
91
+ openclaw skills check
92
+ ```
@@ -0,0 +1,46 @@
1
+ # ClawHub Publish Checklist
2
+
3
+ ## Preflight
4
+
5
+ 1. Confirm skill root contains `SKILL.md`.
6
+ 2. Confirm frontmatter includes:
7
+ - `name`
8
+ - `description`
9
+ 3. Confirm no secret values are hardcoded in skill files.
10
+
11
+ ## Local Validation
12
+
13
+ ```bash
14
+ openclaw skills list
15
+ openclaw skills info cortex-memory
16
+ openclaw skills check
17
+ ```
18
+
19
+ Optional plugin validation:
20
+
21
+ ```bash
22
+ openclaw plugins list
23
+ openclaw plugins inspect openclaw-cortex-memory
24
+ ```
25
+
26
+ ## Publish
27
+
28
+ ```bash
29
+ clawhub login
30
+ clawhub whoami
31
+ clawhub skill publish ./skills/cortex-memory --slug cortex-memory --name "Cortex Memory" --version 0.1.0 --changelog "Initial ClawHub release" --tags latest
32
+ ```
33
+
34
+ ## Install Test (Clean Workspace)
35
+
36
+ ```bash
37
+ openclaw skills install cortex-memory
38
+ openclaw skills info cortex-memory
39
+ ```
40
+
41
+ ## Post Publish
42
+
43
+ 1. Start a new session.
44
+ 2. Trigger retrieval workflow with a memory-related prompt.
45
+ 3. Verify skill appears and is eligible in `openclaw skills list --eligible`.
46
+