openclaw-cortex-memory 0.1.0-Alpha.1

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 (49) hide show
  1. package/README.md +198 -0
  2. package/SKILL.md +263 -0
  3. package/dist/index.d.ts +90 -0
  4. package/dist/index.d.ts.map +1 -0
  5. package/dist/index.js +1871 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/openclaw.plugin.json +295 -0
  8. package/dist/src/engine/memory_engine.d.ts +20 -0
  9. package/dist/src/engine/memory_engine.d.ts.map +1 -0
  10. package/dist/src/engine/memory_engine.js +3 -0
  11. package/dist/src/engine/memory_engine.js.map +1 -0
  12. package/dist/src/engine/ts_engine.d.ts +69 -0
  13. package/dist/src/engine/ts_engine.d.ts.map +1 -0
  14. package/dist/src/engine/ts_engine.js +390 -0
  15. package/dist/src/engine/ts_engine.js.map +1 -0
  16. package/dist/src/engine/types.d.ts +53 -0
  17. package/dist/src/engine/types.d.ts.map +1 -0
  18. package/dist/src/engine/types.js +3 -0
  19. package/dist/src/engine/types.js.map +1 -0
  20. package/dist/src/reflect/reflector.d.ts +32 -0
  21. package/dist/src/reflect/reflector.d.ts.map +1 -0
  22. package/dist/src/reflect/reflector.js +124 -0
  23. package/dist/src/reflect/reflector.js.map +1 -0
  24. package/dist/src/rules/rule_store.d.ts +22 -0
  25. package/dist/src/rules/rule_store.d.ts.map +1 -0
  26. package/dist/src/rules/rule_store.js +102 -0
  27. package/dist/src/rules/rule_store.js.map +1 -0
  28. package/dist/src/session/session_end.d.ts +30 -0
  29. package/dist/src/session/session_end.d.ts.map +1 -0
  30. package/dist/src/session/session_end.js +209 -0
  31. package/dist/src/session/session_end.js.map +1 -0
  32. package/dist/src/store/read_store.d.ts +44 -0
  33. package/dist/src/store/read_store.d.ts.map +1 -0
  34. package/dist/src/store/read_store.js +239 -0
  35. package/dist/src/store/read_store.js.map +1 -0
  36. package/dist/src/store/write_store.d.ts +31 -0
  37. package/dist/src/store/write_store.d.ts.map +1 -0
  38. package/dist/src/store/write_store.js +138 -0
  39. package/dist/src/store/write_store.js.map +1 -0
  40. package/dist/src/sync/session_sync.d.ts +28 -0
  41. package/dist/src/sync/session_sync.d.ts.map +1 -0
  42. package/dist/src/sync/session_sync.js +214 -0
  43. package/dist/src/sync/session_sync.js.map +1 -0
  44. package/index.ts +2071 -0
  45. package/openclaw.plugin.json +295 -0
  46. package/package.json +55 -0
  47. package/scripts/cli.js +262 -0
  48. package/scripts/install.js +27 -0
  49. package/scripts/uninstall.js +212 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rule_store.d.ts","sourceRoot":"","sources":["../../../src/rules/rule_store.ts"],"names":[],"mappings":"AAIA,UAAU,UAAU;IAClB,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACrD,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACpD,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;CACrD;AAMD,UAAU,gBAAgB;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,UAAU,CAAC;CACpB;AAqCD,wBAAgB,eAAe,CAAC,OAAO,EAAE,gBAAgB,GAAG;IAC1D,OAAO,CAAC,IAAI,EAAE;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAC9G,CAiCA"}
@@ -0,0 +1,102 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.createRuleStore = createRuleStore;
37
+ const crypto = __importStar(require("crypto"));
38
+ const fs = __importStar(require("fs"));
39
+ const path = __importStar(require("path"));
40
+ function readState(filePath) {
41
+ try {
42
+ if (!fs.existsSync(filePath)) {
43
+ return { hashes: [] };
44
+ }
45
+ const content = fs.readFileSync(filePath, "utf-8").trim();
46
+ if (!content) {
47
+ return { hashes: [] };
48
+ }
49
+ const parsed = JSON.parse(content);
50
+ if (!Array.isArray(parsed.hashes)) {
51
+ return { hashes: [] };
52
+ }
53
+ return parsed;
54
+ }
55
+ catch {
56
+ return { hashes: [] };
57
+ }
58
+ }
59
+ function writeState(filePath, state) {
60
+ const dir = path.dirname(filePath);
61
+ if (!fs.existsSync(dir)) {
62
+ fs.mkdirSync(dir, { recursive: true });
63
+ }
64
+ fs.writeFileSync(filePath, JSON.stringify(state, null, 2), "utf-8");
65
+ }
66
+ function normalizeRule(content) {
67
+ return content.replace(/\s+/g, " ").trim();
68
+ }
69
+ function hashRule(content) {
70
+ return crypto.createHash("sha1").update(content).digest("hex");
71
+ }
72
+ function createRuleStore(options) {
73
+ const memoryRoot = options.dbPath ? path.resolve(options.dbPath) : path.join(options.projectRoot, "data", "memory");
74
+ const rulesPath = path.join(memoryRoot, "CORTEX_RULES.md");
75
+ const statePath = path.join(memoryRoot, ".rule_store_state.json");
76
+ function addRule(args) {
77
+ const normalized = normalizeRule(args.content);
78
+ if (!normalized) {
79
+ return { added: false, reason: "empty_rule" };
80
+ }
81
+ const contentHash = hashRule(normalized);
82
+ const state = readState(statePath);
83
+ if (state.hashes.includes(contentHash)) {
84
+ return { added: false, reason: "duplicate_rule", hash: contentHash };
85
+ }
86
+ const ruleDir = path.dirname(rulesPath);
87
+ if (!fs.existsSync(ruleDir)) {
88
+ fs.mkdirSync(ruleDir, { recursive: true });
89
+ }
90
+ if (!fs.existsSync(rulesPath)) {
91
+ fs.writeFileSync(rulesPath, "# CORTEX_RULES.md\n", "utf-8");
92
+ }
93
+ fs.appendFileSync(rulesPath, `\n## ${args.sectionTitle}\n${normalized}\n`, "utf-8");
94
+ state.hashes.push(contentHash);
95
+ writeState(statePath, state);
96
+ options.logger.info(`TS rule_store appended ${args.sectionTitle}`);
97
+ return { added: true, hash: contentHash };
98
+ }
99
+ options.logger.debug(`TS rule_store initialized at ${rulesPath}`);
100
+ return { addRule };
101
+ }
102
+ //# sourceMappingURL=rule_store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rule_store.js","sourceRoot":"","sources":["../../../src/rules/rule_store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ interface LoggerLike {
2
+ debug: (message: string, ...args: unknown[]) => void;
3
+ info: (message: string, ...args: unknown[]) => void;
4
+ warn: (message: string, ...args: unknown[]) => void;
5
+ }
6
+ interface SessionEndOptions {
7
+ projectRoot: string;
8
+ dbPath?: string;
9
+ logger: LoggerLike;
10
+ syncMemory: () => Promise<{
11
+ imported: number;
12
+ skipped: number;
13
+ filesProcessed: number;
14
+ }>;
15
+ }
16
+ export declare function createSessionEnd(options: SessionEndOptions): {
17
+ onSessionEnd(args: {
18
+ sessionId: string;
19
+ syncRecords: boolean;
20
+ }): Promise<{
21
+ events_generated: number;
22
+ sync_result?: {
23
+ imported: number;
24
+ skipped: number;
25
+ filesProcessed: number;
26
+ };
27
+ }>;
28
+ };
29
+ export {};
30
+ //# sourceMappingURL=session_end.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session_end.d.ts","sourceRoot":"","sources":["../../../src/session/session_end.ts"],"names":[],"mappings":"AAGA,UAAU,UAAU;IAClB,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACrD,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACpD,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;CACrD;AAOD,UAAU,iBAAiB;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,UAAU,CAAC;IACnB,UAAU,EAAE,MAAM,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC1F;AA+GD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,iBAAiB,GAAG;IAC5D,YAAY,CAAC,IAAI,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,gBAAgB,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE;YAAE,QAAQ,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,CAAC;YAAC,cAAc,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,CAAC,CAAC;CACrL,CAwFA"}
@@ -0,0 +1,209 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.createSessionEnd = createSessionEnd;
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ function readState(filePath) {
40
+ try {
41
+ if (!fs.existsSync(filePath)) {
42
+ return { sessions: {}, recovery: {} };
43
+ }
44
+ const content = fs.readFileSync(filePath, "utf-8").trim();
45
+ if (!content) {
46
+ return { sessions: {}, recovery: {} };
47
+ }
48
+ const parsed = JSON.parse(content);
49
+ if (!parsed.sessions || typeof parsed.sessions !== "object") {
50
+ return { sessions: {}, recovery: {} };
51
+ }
52
+ if (!parsed.recovery || typeof parsed.recovery !== "object") {
53
+ parsed.recovery = {};
54
+ }
55
+ return parsed;
56
+ }
57
+ catch {
58
+ return { sessions: {}, recovery: {} };
59
+ }
60
+ }
61
+ function writeState(filePath, state) {
62
+ const dir = path.dirname(filePath);
63
+ if (!fs.existsSync(dir)) {
64
+ fs.mkdirSync(dir, { recursive: true });
65
+ }
66
+ fs.writeFileSync(filePath, JSON.stringify(state, null, 2), "utf-8");
67
+ }
68
+ function loadActiveSessionRecords(activePath, sessionId) {
69
+ if (!fs.existsSync(activePath)) {
70
+ return [];
71
+ }
72
+ const lines = fs.readFileSync(activePath, "utf-8").split(/\r?\n/).filter(Boolean);
73
+ const records = [];
74
+ for (const line of lines) {
75
+ try {
76
+ const parsed = JSON.parse(line);
77
+ if (parsed.session_id === sessionId) {
78
+ records.push(parsed);
79
+ }
80
+ }
81
+ catch { }
82
+ }
83
+ return records;
84
+ }
85
+ function summarize(records) {
86
+ const messageCount = records.length;
87
+ const userCount = records.filter(r => r.role === "user").length;
88
+ const assistantCount = records.filter(r => r.role === "assistant").length;
89
+ const lastMessages = records.slice(Math.max(0, records.length - 3)).map(r => r.content || "").filter(Boolean);
90
+ const summary = `Session ended with ${messageCount} messages. User: ${userCount}, assistant: ${assistantCount}. Recent: ${lastMessages.join(" | ")}`.slice(0, 500);
91
+ const entities = ["session_end", "message_summary"];
92
+ const outcome = "success";
93
+ const signature = records.map(r => `${r.id || ""}:${r.timestamp || ""}:${r.content || ""}`).join("||");
94
+ return { summary, entities, outcome, signature };
95
+ }
96
+ function detectFailureToSuccess(records) {
97
+ const failurePattern = /(失败|报错|错误|异常|超时|未通过|timeout|error|failed|failure)/i;
98
+ const successPattern = /(修复|解决|成功|完成|恢复|通过|ok|fixed|resolved|success)/i;
99
+ let seenFailure = false;
100
+ let failureSample = "";
101
+ let successSample = "";
102
+ let failureIndex = -1;
103
+ let successIndex = -1;
104
+ for (let index = 0; index < records.length; index += 1) {
105
+ const record = records[index];
106
+ const content = typeof record.content === "string" ? record.content.trim() : "";
107
+ if (!content) {
108
+ continue;
109
+ }
110
+ if (!seenFailure && failurePattern.test(content)) {
111
+ seenFailure = true;
112
+ failureSample = content.slice(0, 160);
113
+ failureIndex = index;
114
+ continue;
115
+ }
116
+ if (seenFailure && successPattern.test(content)) {
117
+ successSample = content.slice(0, 160);
118
+ successIndex = index;
119
+ break;
120
+ }
121
+ }
122
+ if (!seenFailure || successIndex < 0) {
123
+ return { triggered: false, failureSample: "", successSample: "", signature: "" };
124
+ }
125
+ const signature = `${failureIndex}:${successIndex}:${failureSample}:${successSample}`;
126
+ return { triggered: true, failureSample, successSample, signature };
127
+ }
128
+ function createSessionEnd(options) {
129
+ const memoryRoot = options.dbPath ? path.resolve(options.dbPath) : path.join(options.projectRoot, "data", "memory");
130
+ const activeSessionsPath = path.join(memoryRoot, "sessions", "active", "sessions.jsonl");
131
+ const archiveSessionsPath = path.join(memoryRoot, "sessions", "archive", "sessions.jsonl");
132
+ const statePath = path.join(memoryRoot, ".session_end_state.json");
133
+ async function onSessionEnd(args) {
134
+ const sessionId = args.sessionId;
135
+ if (!sessionId) {
136
+ return { events_generated: 0 };
137
+ }
138
+ const records = loadActiveSessionRecords(activeSessionsPath, sessionId);
139
+ if (records.length === 0) {
140
+ const syncResult = args.syncRecords ? await options.syncMemory() : undefined;
141
+ return { events_generated: 0, sync_result: syncResult };
142
+ }
143
+ const state = readState(statePath);
144
+ const { summary, entities, outcome, signature } = summarize(records);
145
+ const recoveryDetection = detectFailureToSuccess(records);
146
+ const previous = state.sessions[sessionId];
147
+ let generated = 0;
148
+ if (!previous || previous.signature !== signature) {
149
+ const event = {
150
+ id: `evt_${Date.now().toString(36)}`,
151
+ timestamp: new Date().toISOString(),
152
+ summary,
153
+ entities,
154
+ outcome,
155
+ source_file: `session_end:${sessionId}`,
156
+ session_id: sessionId,
157
+ };
158
+ const archiveDir = path.dirname(archiveSessionsPath);
159
+ if (!fs.existsSync(archiveDir)) {
160
+ fs.mkdirSync(archiveDir, { recursive: true });
161
+ }
162
+ fs.appendFileSync(archiveSessionsPath, `${JSON.stringify(event)}\n`, "utf-8");
163
+ state.sessions[sessionId] = { signature, endedAt: new Date().toISOString() };
164
+ writeState(statePath, state);
165
+ generated = 1;
166
+ options.logger.info(`TS session_end generated event for session ${sessionId}`);
167
+ }
168
+ else {
169
+ options.logger.debug(`TS session_end skipped duplicate event for session ${sessionId}`);
170
+ }
171
+ if (recoveryDetection.triggered) {
172
+ const previousRecovery = state.recovery[sessionId];
173
+ if (!previousRecovery || previousRecovery.signature !== recoveryDetection.signature) {
174
+ const recoveryEvent = {
175
+ id: `evt_${Date.now().toString(36)}_recovery`,
176
+ timestamp: new Date().toISOString(),
177
+ summary: `Recovered from failure to success in session ${sessionId}`,
178
+ entities: ["failure_recovery", "session_learning"],
179
+ outcome: "success_after_failure",
180
+ details: {
181
+ failure: recoveryDetection.failureSample,
182
+ success: recoveryDetection.successSample,
183
+ },
184
+ source_file: `session_end:recovery:${sessionId}`,
185
+ session_id: sessionId,
186
+ };
187
+ const archiveDir = path.dirname(archiveSessionsPath);
188
+ if (!fs.existsSync(archiveDir)) {
189
+ fs.mkdirSync(archiveDir, { recursive: true });
190
+ }
191
+ fs.appendFileSync(archiveSessionsPath, `${JSON.stringify(recoveryEvent)}\n`, "utf-8");
192
+ state.recovery[sessionId] = {
193
+ signature: recoveryDetection.signature,
194
+ detectedAt: new Date().toISOString(),
195
+ };
196
+ writeState(statePath, state);
197
+ generated += 1;
198
+ options.logger.info(`TS session_end generated recovery event for session ${sessionId}`);
199
+ }
200
+ else {
201
+ options.logger.debug(`TS session_end skipped duplicate recovery event for session ${sessionId}`);
202
+ }
203
+ }
204
+ const syncResult = args.syncRecords ? await options.syncMemory() : undefined;
205
+ return { events_generated: generated, sync_result: syncResult };
206
+ }
207
+ return { onSessionEnd };
208
+ }
209
+ //# sourceMappingURL=session_end.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session_end.js","sourceRoot":"","sources":["../../../src/session/session_end.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ interface LoggerLike {
2
+ debug: (message: string, ...args: unknown[]) => void;
3
+ warn: (message: string, ...args: unknown[]) => void;
4
+ }
5
+ export interface ReadStoreSearchArgs {
6
+ query: string;
7
+ topK: number;
8
+ }
9
+ export interface ReadStoreHotArgs {
10
+ limit: number;
11
+ }
12
+ export interface ReadStoreAutoArgs {
13
+ includeHot: boolean;
14
+ sessionId: string;
15
+ cachedAutoSearch?: {
16
+ query: string;
17
+ results: unknown[];
18
+ ageSeconds: number;
19
+ };
20
+ }
21
+ interface ReadStoreOptions {
22
+ projectRoot: string;
23
+ dbPath?: string;
24
+ logger: LoggerLike;
25
+ }
26
+ export interface ReadStore {
27
+ searchMemory(args: ReadStoreSearchArgs): Promise<{
28
+ results: unknown[];
29
+ }>;
30
+ getHotContext(args: ReadStoreHotArgs): Promise<{
31
+ context: unknown[];
32
+ }>;
33
+ getAutoContext(args: ReadStoreAutoArgs): Promise<{
34
+ auto_search?: {
35
+ query: string;
36
+ results: unknown[];
37
+ age_seconds: number;
38
+ };
39
+ hot_context?: unknown[];
40
+ }>;
41
+ }
42
+ export declare function createReadStore(options: ReadStoreOptions): ReadStore;
43
+ export {};
44
+ //# sourceMappingURL=read_store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read_store.d.ts","sourceRoot":"","sources":["../../../src/store/read_store.ts"],"names":[],"mappings":"AAGA,UAAU,UAAU;IAClB,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACrD,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;CACrD;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,CAAC,EAAE;QACjB,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,OAAO,EAAE,CAAC;QACnB,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;CACH;AASD,UAAU,gBAAgB;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,UAAU,CAAC;CACpB;AAED,MAAM,WAAW,SAAS;IACxB,YAAY,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,EAAE,CAAA;KAAE,CAAC,CAAC;IACzE,aAAa,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,EAAE,CAAA;KAAE,CAAC,CAAC;IACvE,cAAc,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC;QAC/C,WAAW,CAAC,EAAE;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,OAAO,EAAE,CAAC;YAAC,WAAW,EAAE,MAAM,CAAA;SAAE,CAAC;QACzE,WAAW,CAAC,EAAE,OAAO,EAAE,CAAC;KACzB,CAAC,CAAC;CACJ;AAiID,wBAAgB,eAAe,CAAC,OAAO,EAAE,gBAAgB,GAAG,SAAS,CAwFpE"}
@@ -0,0 +1,239 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.createReadStore = createReadStore;
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ function safeReadFile(filePath) {
40
+ try {
41
+ if (!fs.existsSync(filePath)) {
42
+ return "";
43
+ }
44
+ return fs.readFileSync(filePath, "utf-8");
45
+ }
46
+ catch {
47
+ return "";
48
+ }
49
+ }
50
+ function scoreText(query, text) {
51
+ const q = query.trim().toLowerCase();
52
+ const t = text.toLowerCase();
53
+ if (!q || !t) {
54
+ return 0;
55
+ }
56
+ let score = 0;
57
+ if (t.includes(q)) {
58
+ score += 5;
59
+ }
60
+ const tokens = q.split(/\s+/).filter(Boolean);
61
+ for (const token of tokens) {
62
+ if (t.includes(token)) {
63
+ score += 1;
64
+ }
65
+ }
66
+ return score;
67
+ }
68
+ function normalizeRecordText(record) {
69
+ const direct = [record.content, record.summary, record.text, record.message]
70
+ .find(v => typeof v === "string" && v.trim());
71
+ if (direct) {
72
+ return direct.trim();
73
+ }
74
+ if (Array.isArray(record.messages)) {
75
+ const merged = record.messages
76
+ .map(item => {
77
+ if (typeof item === "string")
78
+ return item;
79
+ if (typeof item === "object" && item !== null) {
80
+ const obj = item;
81
+ const role = typeof obj.role === "string" ? obj.role : "unknown";
82
+ const content = [obj.content, obj.text, obj.body].find(v => typeof v === "string" && v.trim());
83
+ if (content) {
84
+ return `${role}: ${content}`;
85
+ }
86
+ }
87
+ return "";
88
+ })
89
+ .filter(Boolean)
90
+ .join("\n")
91
+ .trim();
92
+ if (merged) {
93
+ return merged;
94
+ }
95
+ }
96
+ return JSON.stringify(record);
97
+ }
98
+ function parseJsonlFile(filePath, sourceLabel, logger) {
99
+ const content = safeReadFile(filePath);
100
+ if (!content) {
101
+ return [];
102
+ }
103
+ const docs = [];
104
+ for (const line of content.split(/\r?\n/)) {
105
+ const trimmed = line.trim();
106
+ if (!trimmed) {
107
+ continue;
108
+ }
109
+ try {
110
+ const parsed = JSON.parse(trimmed);
111
+ const text = normalizeRecordText(parsed);
112
+ if (!text.trim()) {
113
+ continue;
114
+ }
115
+ const id = typeof parsed.id === "string" ? parsed.id : `${sourceLabel}:${docs.length + 1}`;
116
+ const timestampValue = typeof parsed.timestamp === "string" ? Date.parse(parsed.timestamp) : NaN;
117
+ docs.push({
118
+ id,
119
+ text,
120
+ source: sourceLabel,
121
+ timestamp: Number.isFinite(timestampValue) ? timestampValue : undefined,
122
+ });
123
+ }
124
+ catch (error) {
125
+ logger.debug(`Skipping invalid JSONL line in ${filePath}: ${error}`);
126
+ }
127
+ }
128
+ return docs;
129
+ }
130
+ function parseMarkdownFile(filePath, sourceLabel) {
131
+ const content = safeReadFile(filePath);
132
+ if (!content.trim()) {
133
+ return [];
134
+ }
135
+ const lines = content
136
+ .split(/\r?\n/)
137
+ .map(line => line.trim())
138
+ .filter(line => line && !line.startsWith("#"));
139
+ if (lines.length === 0) {
140
+ return [];
141
+ }
142
+ return [
143
+ {
144
+ id: sourceLabel,
145
+ text: lines.join("\n"),
146
+ source: sourceLabel,
147
+ },
148
+ ];
149
+ }
150
+ function withRecencyBoost(score, timestamp) {
151
+ if (!timestamp) {
152
+ return score;
153
+ }
154
+ const ageHours = (Date.now() - timestamp) / (1000 * 60 * 60);
155
+ if (ageHours < 24) {
156
+ return score + 0.6;
157
+ }
158
+ if (ageHours < 168) {
159
+ return score + 0.3;
160
+ }
161
+ return score;
162
+ }
163
+ function createReadStore(options) {
164
+ const memoryRoot = options.dbPath ? path.resolve(options.dbPath) : path.join(options.projectRoot, "data", "memory");
165
+ function loadAllDocuments() {
166
+ const cortexRulesPath = path.join(memoryRoot, "CORTEX_RULES.md");
167
+ const memoryMdPath = path.join(memoryRoot, "MEMORY.md");
168
+ const activeSessionsPath = path.join(memoryRoot, "sessions", "active", "sessions.jsonl");
169
+ const archiveSessionsPath = path.join(memoryRoot, "sessions", "archive", "sessions.jsonl");
170
+ return [
171
+ ...parseMarkdownFile(cortexRulesPath, "CORTEX_RULES.md"),
172
+ ...parseMarkdownFile(memoryMdPath, "MEMORY.md"),
173
+ ...parseJsonlFile(activeSessionsPath, "sessions_active", options.logger),
174
+ ...parseJsonlFile(archiveSessionsPath, "sessions_archive", options.logger),
175
+ ];
176
+ }
177
+ async function searchMemory(args) {
178
+ const query = args.query?.trim();
179
+ if (!query) {
180
+ return { results: [] };
181
+ }
182
+ const docs = loadAllDocuments();
183
+ const ranked = docs
184
+ .map(doc => {
185
+ const base = scoreText(query, doc.text);
186
+ const total = withRecencyBoost(base, doc.timestamp);
187
+ return { doc, score: total };
188
+ })
189
+ .filter(item => item.score > 0)
190
+ .sort((a, b) => b.score - a.score)
191
+ .slice(0, Math.max(1, args.topK))
192
+ .map(item => ({
193
+ id: item.doc.id,
194
+ text: item.doc.text,
195
+ source: item.doc.source,
196
+ score: Number(item.score.toFixed(4)),
197
+ }));
198
+ return { results: ranked };
199
+ }
200
+ async function getHotContext(args) {
201
+ const limit = Math.max(1, args.limit);
202
+ const docs = loadAllDocuments();
203
+ const coreRules = docs.find(doc => doc.source === "CORTEX_RULES.md");
204
+ const sessionDocs = docs
205
+ .filter(doc => doc.source.startsWith("sessions_"))
206
+ .sort((a, b) => (b.timestamp ?? 0) - (a.timestamp ?? 0))
207
+ .slice(0, limit);
208
+ const result = [];
209
+ if (coreRules) {
210
+ result.push({ id: coreRules.id, text: coreRules.text, source: coreRules.source });
211
+ }
212
+ for (const doc of sessionDocs) {
213
+ result.push({ id: doc.id, text: doc.text, source: doc.source });
214
+ }
215
+ return { context: result.slice(0, limit) };
216
+ }
217
+ async function getAutoContext(args) {
218
+ const result = {};
219
+ if (args.cachedAutoSearch) {
220
+ result.auto_search = {
221
+ query: args.cachedAutoSearch.query,
222
+ results: args.cachedAutoSearch.results,
223
+ age_seconds: args.cachedAutoSearch.ageSeconds,
224
+ };
225
+ }
226
+ if (args.includeHot) {
227
+ const hot = await getHotContext({ limit: 20 });
228
+ result.hot_context = hot.context;
229
+ }
230
+ return result;
231
+ }
232
+ options.logger.debug(`TS read store initialized at ${memoryRoot}`);
233
+ return {
234
+ searchMemory,
235
+ getHotContext,
236
+ getAutoContext,
237
+ };
238
+ }
239
+ //# sourceMappingURL=read_store.js.map