cortex-mcp 2.4.0 → 2.6.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 (47) hide show
  1. package/CHANGELOG.md +49 -1
  2. package/README.md +35 -39
  3. package/dist/memory/access-pattern-tracker.d.ts +51 -0
  4. package/dist/memory/access-pattern-tracker.d.ts.map +1 -0
  5. package/dist/memory/access-pattern-tracker.js +92 -0
  6. package/dist/memory/access-pattern-tracker.js.map +1 -0
  7. package/dist/memory/auto-learner.d.ts.map +1 -1
  8. package/dist/memory/auto-learner.js +33 -2
  9. package/dist/memory/auto-learner.js.map +1 -1
  10. package/dist/memory/cross-memory-linker.d.ts +18 -0
  11. package/dist/memory/cross-memory-linker.d.ts.map +1 -0
  12. package/dist/memory/cross-memory-linker.js +115 -0
  13. package/dist/memory/cross-memory-linker.js.map +1 -0
  14. package/dist/memory/daily-diary.d.ts +30 -0
  15. package/dist/memory/daily-diary.d.ts.map +1 -0
  16. package/dist/memory/daily-diary.js +159 -0
  17. package/dist/memory/daily-diary.js.map +1 -0
  18. package/dist/memory/embedding-cache.d.ts +32 -0
  19. package/dist/memory/embedding-cache.d.ts.map +1 -0
  20. package/dist/memory/embedding-cache.js +76 -0
  21. package/dist/memory/embedding-cache.js.map +1 -0
  22. package/dist/memory/memory-decay.d.ts.map +1 -1
  23. package/dist/memory/memory-decay.js +23 -6
  24. package/dist/memory/memory-decay.js.map +1 -1
  25. package/dist/memory/memory-export-md.d.ts +12 -0
  26. package/dist/memory/memory-export-md.d.ts.map +1 -0
  27. package/dist/memory/memory-export-md.js +188 -0
  28. package/dist/memory/memory-export-md.js.map +1 -0
  29. package/dist/memory/memory-ranker.d.ts.map +1 -1
  30. package/dist/memory/memory-ranker.js +7 -2
  31. package/dist/memory/memory-ranker.js.map +1 -1
  32. package/dist/memory/mmr-reranker.d.ts +39 -0
  33. package/dist/memory/mmr-reranker.d.ts.map +1 -0
  34. package/dist/memory/mmr-reranker.js +115 -0
  35. package/dist/memory/mmr-reranker.js.map +1 -0
  36. package/dist/memory/query-expansion.d.ts +28 -0
  37. package/dist/memory/query-expansion.d.ts.map +1 -0
  38. package/dist/memory/query-expansion.js +140 -0
  39. package/dist/memory/query-expansion.js.map +1 -0
  40. package/dist/memory/soul-manager.d.ts +30 -0
  41. package/dist/memory/soul-manager.d.ts.map +1 -0
  42. package/dist/memory/soul-manager.js +171 -0
  43. package/dist/memory/soul-manager.js.map +1 -0
  44. package/dist/server/mcp-handler.d.ts.map +1 -1
  45. package/dist/server/mcp-handler.js +119 -48
  46. package/dist/server/mcp-handler.js.map +1 -1
  47. package/package.json +1 -1
@@ -0,0 +1,39 @@
1
+ /**
2
+ * MMR Re-ranking — Maximal Marginal Relevance.
3
+ *
4
+ * Extracted from OpenClaw's mmr.ts architecture.
5
+ *
6
+ * Problem: Without MMR, recall might return 5 memories all saying
7
+ * "use TypeScript strict mode." That's redundant.
8
+ *
9
+ * Solution: MMR balances RELEVANCE (how well it matches the query)
10
+ * with DIVERSITY (how different it is from already-selected results).
11
+ *
12
+ * Formula: MMR(d) = λ * relevance(d) - (1-λ) * max_similarity(d, selected)
13
+ * Where λ = 0.7 means "70% relevance, 30% diversity"
14
+ */
15
+ export interface MMRConfig {
16
+ enabled: boolean;
17
+ lambda: number;
18
+ diversityWeight: number;
19
+ }
20
+ export declare const DEFAULT_MMR_CONFIG: MMRConfig;
21
+ export interface ScoredItem {
22
+ score: number;
23
+ memory: {
24
+ id: string;
25
+ intent: string;
26
+ type: string;
27
+ tags?: string[];
28
+ files?: string[];
29
+ };
30
+ matchMethod: string;
31
+ }
32
+ /**
33
+ * Apply MMR re-ranking to search results.
34
+ * Keeps the top result unchanged, then iteratively picks
35
+ * the next result that maximizes relevance while being
36
+ * different from already-selected results.
37
+ */
38
+ export declare function applyMMR<T extends ScoredItem>(results: T[], config?: Partial<MMRConfig>): T[];
39
+ //# sourceMappingURL=mmr-reranker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mmr-reranker.d.ts","sourceRoot":"","sources":["../../src/memory/mmr-reranker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,MAAM,WAAW,SAAS;IACtB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,MAAM,CAAC;CAC3B;AAED,eAAO,MAAM,kBAAkB,EAAE,SAIhC,CAAC;AAEF,MAAM,WAAW,UAAU;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE;QACJ,EAAE,EAAE,MAAM,CAAC;QACX,MAAM,EAAE,MAAM,CAAC;QACf,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;QAChB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;KACpB,CAAC;IACF,WAAW,EAAE,MAAM,CAAC;CACvB;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,CAAC,SAAS,UAAU,EACzC,OAAO,EAAE,CAAC,EAAE,EACZ,MAAM,GAAE,OAAO,CAAC,SAAS,CAAM,GAChC,CAAC,EAAE,CAuCL"}
@@ -0,0 +1,115 @@
1
+ "use strict";
2
+ /**
3
+ * MMR Re-ranking — Maximal Marginal Relevance.
4
+ *
5
+ * Extracted from OpenClaw's mmr.ts architecture.
6
+ *
7
+ * Problem: Without MMR, recall might return 5 memories all saying
8
+ * "use TypeScript strict mode." That's redundant.
9
+ *
10
+ * Solution: MMR balances RELEVANCE (how well it matches the query)
11
+ * with DIVERSITY (how different it is from already-selected results).
12
+ *
13
+ * Formula: MMR(d) = λ * relevance(d) - (1-λ) * max_similarity(d, selected)
14
+ * Where λ = 0.7 means "70% relevance, 30% diversity"
15
+ */
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.DEFAULT_MMR_CONFIG = void 0;
18
+ exports.applyMMR = applyMMR;
19
+ exports.DEFAULT_MMR_CONFIG = {
20
+ enabled: true,
21
+ lambda: 0.7, // OpenClaw default: 70% relevance, 30% diversity
22
+ diversityWeight: 0.3,
23
+ };
24
+ /**
25
+ * Apply MMR re-ranking to search results.
26
+ * Keeps the top result unchanged, then iteratively picks
27
+ * the next result that maximizes relevance while being
28
+ * different from already-selected results.
29
+ */
30
+ function applyMMR(results, config = {}) {
31
+ const cfg = { ...exports.DEFAULT_MMR_CONFIG, ...config };
32
+ if (!cfg.enabled || results.length <= 2)
33
+ return results;
34
+ const lambda = cfg.lambda;
35
+ const selected = [];
36
+ const remaining = [...results];
37
+ // Always pick the top result first
38
+ selected.push(remaining.shift());
39
+ while (remaining.length > 0 && selected.length < results.length) {
40
+ let bestIdx = 0;
41
+ let bestMMR = -Infinity;
42
+ for (let i = 0; i < remaining.length; i++) {
43
+ const candidate = remaining[i];
44
+ // Relevance score (normalized)
45
+ const relevance = candidate.score;
46
+ // Max similarity to any already-selected result
47
+ const maxSim = Math.max(...selected.map(s => computeSimilarity(candidate, s)));
48
+ // MMR formula
49
+ const mmrScore = lambda * relevance - (1 - lambda) * maxSim;
50
+ if (mmrScore > bestMMR) {
51
+ bestMMR = mmrScore;
52
+ bestIdx = i;
53
+ }
54
+ }
55
+ selected.push(remaining.splice(bestIdx, 1)[0]);
56
+ }
57
+ return selected;
58
+ }
59
+ /**
60
+ * Compute similarity between two memories.
61
+ * Uses a combination of:
62
+ * 1. Word overlap (Jaccard similarity on intent words)
63
+ * 2. Type match (same type = more similar)
64
+ * 3. File overlap (shared files = more similar)
65
+ */
66
+ function computeSimilarity(a, b) {
67
+ let sim = 0;
68
+ // 1. Word overlap (Jaccard) — main signal
69
+ const wordsA = new Set(extractWords(a.memory.intent));
70
+ const wordsB = new Set(extractWords(b.memory.intent));
71
+ if (wordsA.size > 0 && wordsB.size > 0) {
72
+ let intersection = 0;
73
+ for (const w of wordsA) {
74
+ if (wordsB.has(w))
75
+ intersection++;
76
+ }
77
+ const union = wordsA.size + wordsB.size - intersection;
78
+ sim += (intersection / union) * 0.6; // 60% weight on word overlap
79
+ }
80
+ // 2. Same type = similar
81
+ if (a.memory.type === b.memory.type) {
82
+ sim += 0.2;
83
+ }
84
+ // 3. File overlap
85
+ const filesA = new Set(a.memory.files || []);
86
+ const filesB = new Set(b.memory.files || []);
87
+ if (filesA.size > 0 && filesB.size > 0) {
88
+ let fileOverlap = 0;
89
+ for (const f of filesA) {
90
+ if (filesB.has(f))
91
+ fileOverlap++;
92
+ }
93
+ if (fileOverlap > 0) {
94
+ sim += 0.2 * (fileOverlap / Math.max(filesA.size, filesB.size));
95
+ }
96
+ }
97
+ return Math.min(sim, 1.0);
98
+ }
99
+ // Stop words to ignore in similarity computation
100
+ const STOP_WORDS = new Set([
101
+ 'the', 'a', 'an', 'is', 'are', 'was', 'were', 'be', 'been', 'being',
102
+ 'have', 'has', 'had', 'do', 'does', 'did', 'will', 'would', 'could',
103
+ 'should', 'may', 'might', 'can', 'shall', 'to', 'of', 'in', 'for',
104
+ 'on', 'with', 'at', 'by', 'from', 'as', 'into', 'through', 'during',
105
+ 'use', 'used', 'using', 'this', 'that', 'these', 'those', 'it', 'its',
106
+ 'not', 'no', 'nor', 'but', 'or', 'and', 'if', 'then', 'else', 'when',
107
+ 'up', 'out', 'about', 'so', 'all', 'each', 'every', 'both', 'few',
108
+ ]);
109
+ function extractWords(text) {
110
+ return text.toLowerCase()
111
+ .replace(/[^a-z0-9\s]/g, ' ')
112
+ .split(/\s+/)
113
+ .filter(w => w.length > 2 && !STOP_WORDS.has(w));
114
+ }
115
+ //# sourceMappingURL=mmr-reranker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mmr-reranker.js","sourceRoot":"","sources":["../../src/memory/mmr-reranker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Query Expansion — Smarter search like OpenClaw's query-expansion.ts.
3
+ *
4
+ * Problem: User searches for "authentication bug" but the memory
5
+ * says "login issue with JWT tokens." Raw search misses it.
6
+ *
7
+ * Solution: Expand the query with synonyms and related terms:
8
+ * "authentication bug" → "authentication auth login bug error issue fix"
9
+ *
10
+ * This is OpenClaw's approach — extract keywords and add related terms
11
+ * so both FTS and vector search find more relevant results.
12
+ */
13
+ /**
14
+ * Expand a query with synonyms and related programming terms.
15
+ * Returns the original query plus expanded terms.
16
+ */
17
+ export declare function expandQuery(query: string): string;
18
+ /**
19
+ * Extract key technical terms from a query for targeted search.
20
+ * Filters out stop words and generic terms, keeping only meaningful tokens.
21
+ */
22
+ export declare function extractKeyTerms(query: string): string[];
23
+ /**
24
+ * Generate alternative search queries for better recall.
25
+ * Returns the original plus 1-2 reformulated queries.
26
+ */
27
+ export declare function generateAlternativeQueries(query: string): string[];
28
+ //# sourceMappingURL=query-expansion.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query-expansion.d.ts","sourceRoot":"","sources":["../../src/memory/query-expansion.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH;;;GAGG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAcjD;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAKvD;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAsBlE"}
@@ -0,0 +1,140 @@
1
+ "use strict";
2
+ /**
3
+ * Query Expansion — Smarter search like OpenClaw's query-expansion.ts.
4
+ *
5
+ * Problem: User searches for "authentication bug" but the memory
6
+ * says "login issue with JWT tokens." Raw search misses it.
7
+ *
8
+ * Solution: Expand the query with synonyms and related terms:
9
+ * "authentication bug" → "authentication auth login bug error issue fix"
10
+ *
11
+ * This is OpenClaw's approach — extract keywords and add related terms
12
+ * so both FTS and vector search find more relevant results.
13
+ */
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.expandQuery = expandQuery;
16
+ exports.extractKeyTerms = extractKeyTerms;
17
+ exports.generateAlternativeQueries = generateAlternativeQueries;
18
+ /**
19
+ * Expand a query with synonyms and related programming terms.
20
+ * Returns the original query plus expanded terms.
21
+ */
22
+ function expandQuery(query) {
23
+ const words = query.toLowerCase().split(/\s+/).filter(w => w.length > 1);
24
+ const expanded = new Set(words);
25
+ for (const word of words) {
26
+ const synonyms = SYNONYM_MAP[word];
27
+ if (synonyms) {
28
+ for (const syn of synonyms) {
29
+ expanded.add(syn);
30
+ }
31
+ }
32
+ }
33
+ return Array.from(expanded).join(' ');
34
+ }
35
+ /**
36
+ * Extract key technical terms from a query for targeted search.
37
+ * Filters out stop words and generic terms, keeping only meaningful tokens.
38
+ */
39
+ function extractKeyTerms(query) {
40
+ return query.toLowerCase()
41
+ .replace(/[^a-z0-9\s_-]/g, ' ')
42
+ .split(/\s+/)
43
+ .filter(w => w.length > 2 && !STOP_WORDS.has(w));
44
+ }
45
+ /**
46
+ * Generate alternative search queries for better recall.
47
+ * Returns the original plus 1-2 reformulated queries.
48
+ */
49
+ function generateAlternativeQueries(query) {
50
+ const queries = [query];
51
+ const lower = query.toLowerCase();
52
+ // If asking "how to X" → also search for "X implementation"
53
+ const howToMatch = lower.match(/how\s+to\s+(.+)/);
54
+ if (howToMatch) {
55
+ queries.push(`${howToMatch[1]} implementation`);
56
+ queries.push(`${howToMatch[1]} pattern`);
57
+ }
58
+ // If asking about "error" → also search for "bug fix"
59
+ if (lower.includes('error') || lower.includes('bug')) {
60
+ queries.push(lower.replace(/error|bug/g, 'fix correction'));
61
+ }
62
+ // If asking about "why" → search for decisions
63
+ if (lower.startsWith('why')) {
64
+ queries.push(lower.replace('why', 'decision reason'));
65
+ }
66
+ return queries.slice(0, 3); // Max 3 alternatives
67
+ }
68
+ // ─── Synonym Map for Programming Terms ──────────────────────────────────────
69
+ const SYNONYM_MAP = {
70
+ // Authentication
71
+ 'auth': ['authentication', 'login', 'signin', 'jwt', 'token', 'session'],
72
+ 'authentication': ['auth', 'login', 'signin', 'jwt'],
73
+ 'login': ['auth', 'authentication', 'signin'],
74
+ 'logout': ['signout', 'session'],
75
+ // Database
76
+ 'database': ['db', 'sql', 'query', 'schema', 'migration'],
77
+ 'db': ['database', 'sql', 'query'],
78
+ 'sql': ['database', 'query', 'schema'],
79
+ 'migration': ['database', 'schema', 'alter'],
80
+ 'schema': ['database', 'model', 'table'],
81
+ // API
82
+ 'api': ['endpoint', 'route', 'rest', 'request', 'response'],
83
+ 'endpoint': ['api', 'route', 'handler'],
84
+ 'route': ['api', 'endpoint', 'path', 'handler'],
85
+ 'request': ['req', 'http', 'fetch'],
86
+ 'response': ['res', 'http', 'reply'],
87
+ // Errors & Debugging
88
+ 'error': ['bug', 'issue', 'exception', 'crash', 'failure', 'fix'],
89
+ 'bug': ['error', 'issue', 'defect', 'fix', 'correction'],
90
+ 'fix': ['repair', 'correction', 'patch', 'resolve'],
91
+ 'crash': ['error', 'exception', 'failure', 'abort'],
92
+ 'debug': ['troubleshoot', 'diagnose', 'inspect', 'trace'],
93
+ // Testing
94
+ 'test': ['testing', 'spec', 'unit', 'jest', 'mocha', 'vitest'],
95
+ 'testing': ['test', 'spec', 'assertion', 'mock'],
96
+ 'mock': ['stub', 'fake', 'spy', 'test'],
97
+ // Architecture
98
+ 'component': ['module', 'widget', 'element'],
99
+ 'module': ['component', 'package', 'library'],
100
+ 'pattern': ['architecture', 'design', 'structure'],
101
+ 'refactor': ['restructure', 'cleanup', 'reorganize'],
102
+ // Frontend
103
+ 'style': ['css', 'styling', 'theme', 'design'],
104
+ 'css': ['style', 'stylesheet', 'tailwind'],
105
+ 'ui': ['interface', 'frontend', 'view', 'component'],
106
+ 'layout': ['grid', 'flex', 'responsive', 'design'],
107
+ // State
108
+ 'state': ['store', 'context', 'redux', 'zustand'],
109
+ 'cache': ['memo', 'memoize', 'store', 'buffer'],
110
+ // Config
111
+ 'config': ['configuration', 'settings', 'options', 'env'],
112
+ 'env': ['environment', 'config', 'dotenv', 'variable'],
113
+ // Performance
114
+ 'performance': ['speed', 'optimize', 'fast', 'slow', 'latency'],
115
+ 'optimize': ['performance', 'improve', 'speed', 'efficient'],
116
+ 'slow': ['performance', 'latency', 'bottleneck', 'optimize'],
117
+ // Security
118
+ 'security': ['auth', 'encryption', 'vulnerability', 'xss', 'csrf'],
119
+ 'encrypt': ['hash', 'security', 'cipher', 'bcrypt'],
120
+ // TypeScript
121
+ 'type': ['interface', 'typescript', 'generic', 'typing'],
122
+ 'interface': ['type', 'contract', 'shape', 'typescript'],
123
+ 'generic': ['type', 'template', 'parameterized'],
124
+ // Deployment
125
+ 'deploy': ['deployment', 'release', 'publish', 'ship'],
126
+ 'ci': ['pipeline', 'github-actions', 'workflow', 'build'],
127
+ };
128
+ const STOP_WORDS = new Set([
129
+ 'the', 'a', 'an', 'is', 'are', 'was', 'were', 'be', 'been', 'being',
130
+ 'have', 'has', 'had', 'do', 'does', 'did', 'will', 'would', 'could',
131
+ 'should', 'may', 'might', 'can', 'shall', 'to', 'of', 'in', 'for',
132
+ 'on', 'with', 'at', 'by', 'from', 'as', 'into', 'through', 'during',
133
+ 'this', 'that', 'these', 'those', 'it', 'its', 'not', 'no', 'but',
134
+ 'or', 'and', 'if', 'then', 'else', 'when', 'up', 'out', 'about',
135
+ 'so', 'all', 'each', 'every', 'both', 'few', 'more', 'most', 'other',
136
+ 'some', 'such', 'only', 'own', 'same', 'than', 'too', 'very',
137
+ 'just', 'because', 'before', 'after', 'above', 'below', 'between',
138
+ 'what', 'which', 'who', 'whom', 'how', 'where', 'there', 'here',
139
+ ]);
140
+ //# sourceMappingURL=query-expansion.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query-expansion.js","sourceRoot":"","sources":["../../src/memory/query-expansion.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ export interface SoulEntry {
2
+ category: string;
3
+ content: string;
4
+ }
5
+ /**
6
+ * Load SOUL.md from workspace. Returns content or null.
7
+ */
8
+ export declare function loadSoul(workspaceRoot: string): string | null;
9
+ /**
10
+ * Initialize SOUL.md with default template if it doesn't exist.
11
+ */
12
+ export declare function initSoul(workspaceRoot: string): string;
13
+ /**
14
+ * Update soul by appending a new entry under the right category.
15
+ */
16
+ export declare function updateSoul(workspaceRoot: string, entry: SoulEntry): void;
17
+ /**
18
+ * Format soul content for injection into force_recall (Layer 0).
19
+ */
20
+ export declare function formatSoul(workspaceRoot: string): string;
21
+ /**
22
+ * Auto-learn from memories to build soul entries.
23
+ * Called periodically — extracts strong conventions and rules.
24
+ */
25
+ export declare function autoLearnSoul(workspaceRoot: string, memories: Array<{
26
+ type: string;
27
+ intent: string;
28
+ accessCount?: number;
29
+ }>): void;
30
+ //# sourceMappingURL=soul-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"soul-manager.d.ts","sourceRoot":"","sources":["../../src/memory/soul-manager.ts"],"names":[],"mappings":"AAgBA,MAAM,WAAW,SAAS;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACnB;AAuBD;;GAEG;AACH,wBAAgB,QAAQ,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAQ7D;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAWtD;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,aAAa,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,GAAG,IAAI,CAoBxE;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CASxD;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,aAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG,IAAI,CAelI"}
@@ -0,0 +1,171 @@
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.loadSoul = loadSoul;
37
+ exports.initSoul = initSoul;
38
+ exports.updateSoul = updateSoul;
39
+ exports.formatSoul = formatSoul;
40
+ exports.autoLearnSoul = autoLearnSoul;
41
+ /**
42
+ * Soul Manager — OpenClaw-style persistent identity layer.
43
+ *
44
+ * Creates and maintains a SOUL.md file in the workspace that stores:
45
+ * - User's coding preferences ("always use TypeScript strict mode")
46
+ * - Project conventions ("we use PostgreSQL, never MongoDB")
47
+ * - Identity ("Senior Backend Engineer working on e-commerce platform")
48
+ *
49
+ * This is injected as Layer 0 in force_recall — the very first thing the AI sees.
50
+ * Unlike transient memories, the Soul NEVER decays.
51
+ *
52
+ * Inspired by OpenClaw's SOUL.md / IDENTITY.md architecture.
53
+ */
54
+ const fs = __importStar(require("fs"));
55
+ const path = __importStar(require("path"));
56
+ const DEFAULT_SOUL = `# 🧠 Cortex Soul — Who I Am
57
+
58
+ > This file is your AI's persistent identity. Edit it freely.
59
+ > Cortex reads this at the start of every session.
60
+
61
+ ## Identity
62
+ - (Add your role: e.g., "Senior TypeScript developer")
63
+ - (Add your project: e.g., "Building an e-commerce platform")
64
+
65
+ ## Conventions
66
+ - (Add team rules: e.g., "Always use strict TypeScript, never \`any\`")
67
+ - (Add stack: e.g., "PostgreSQL, Redis, Next.js 14")
68
+
69
+ ## Preferences
70
+ - (Add style: e.g., "Prefer functional over OOP")
71
+ - (Add tools: e.g., "Use pnpm, not npm")
72
+
73
+ ## Rules (Never Break)
74
+ - (Add hard rules: e.g., "Never delete user data without confirmation")
75
+ `;
76
+ /**
77
+ * Load SOUL.md from workspace. Returns content or null.
78
+ */
79
+ function loadSoul(workspaceRoot) {
80
+ const soulPath = getSoulPath(workspaceRoot);
81
+ try {
82
+ if (fs.existsSync(soulPath)) {
83
+ return fs.readFileSync(soulPath, 'utf-8').trim();
84
+ }
85
+ }
86
+ catch { /* file not readable */ }
87
+ return null;
88
+ }
89
+ /**
90
+ * Initialize SOUL.md with default template if it doesn't exist.
91
+ */
92
+ function initSoul(workspaceRoot) {
93
+ const soulPath = getSoulPath(workspaceRoot);
94
+ try {
95
+ const dir = path.dirname(soulPath);
96
+ if (!fs.existsSync(dir))
97
+ fs.mkdirSync(dir, { recursive: true });
98
+ if (!fs.existsSync(soulPath)) {
99
+ fs.writeFileSync(soulPath, DEFAULT_SOUL, 'utf-8');
100
+ return DEFAULT_SOUL;
101
+ }
102
+ return fs.readFileSync(soulPath, 'utf-8').trim();
103
+ }
104
+ catch {
105
+ return '';
106
+ }
107
+ }
108
+ /**
109
+ * Update soul by appending a new entry under the right category.
110
+ */
111
+ function updateSoul(workspaceRoot, entry) {
112
+ const soulPath = getSoulPath(workspaceRoot);
113
+ try {
114
+ let content = loadSoul(workspaceRoot) || DEFAULT_SOUL;
115
+ const sectionMap = {
116
+ 'identity': '## Identity',
117
+ 'convention': '## Conventions',
118
+ 'preference': '## Preferences',
119
+ 'rule': '## Rules (Never Break)',
120
+ };
121
+ const header = sectionMap[entry.category] || '## Preferences';
122
+ const idx = content.indexOf(header);
123
+ if (idx >= 0) {
124
+ const insertAt = content.indexOf('\n', idx) + 1;
125
+ content = content.slice(0, insertAt) + `- ${entry.content}\n` + content.slice(insertAt);
126
+ }
127
+ else {
128
+ content += `\n${header}\n- ${entry.content}\n`;
129
+ }
130
+ fs.writeFileSync(soulPath, content, 'utf-8');
131
+ }
132
+ catch { /* non-fatal */ }
133
+ }
134
+ /**
135
+ * Format soul content for injection into force_recall (Layer 0).
136
+ */
137
+ function formatSoul(workspaceRoot) {
138
+ const soul = loadSoul(workspaceRoot);
139
+ if (!soul || soul.includes('(Add your role'))
140
+ return ''; // Still default template
141
+ // Strip the header explanation, keep only the actual content
142
+ const lines = soul.split('\n').filter(l => l.trim() && !l.startsWith('>') && !l.includes('(Add your'));
143
+ if (lines.length <= 1)
144
+ return '';
145
+ return `\n## 🧬 Soul (Persistent Identity)\n${lines.join('\n')}`;
146
+ }
147
+ /**
148
+ * Auto-learn from memories to build soul entries.
149
+ * Called periodically — extracts strong conventions and rules.
150
+ */
151
+ function autoLearnSoul(workspaceRoot, memories) {
152
+ try {
153
+ const soul = loadSoul(workspaceRoot) || '';
154
+ const strongConventions = memories.filter(m => (m.type === 'CONVENTION' || m.type === 'DECISION') &&
155
+ (m.accessCount || 0) >= 3 && // Accessed multiple times = important
156
+ !soul.includes(m.intent.slice(0, 40)) // Not already in soul
157
+ );
158
+ for (const m of strongConventions.slice(0, 3)) {
159
+ updateSoul(workspaceRoot, {
160
+ category: m.type === 'CONVENTION' ? 'convention' : 'preference',
161
+ content: m.intent.slice(0, 150),
162
+ });
163
+ }
164
+ }
165
+ catch { /* non-fatal */ }
166
+ }
167
+ // ─── Helpers ──────────────────────────────────────────────────────────────────
168
+ function getSoulPath(workspaceRoot) {
169
+ return path.join(workspaceRoot, '.cortex', 'SOUL.md');
170
+ }
171
+ //# sourceMappingURL=soul-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"soul-manager.js","sourceRoot":"","sources":["../../src/memory/soul-manager.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-handler.d.ts","sourceRoot":"","sources":["../../src/server/mcp-handler.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAyT3C,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,CAAC,EAAE,MAAM;4BAC5D,GAAG,KAAG,OAAO,CAAC,GAAG,CAAC;EAm4D1D"}
1
+ {"version":3,"file":"mcp-handler.d.ts","sourceRoot":"","sources":["../../src/server/mcp-handler.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAsS3C,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,CAAC,EAAE,MAAM;4BAC5D,GAAG,KAAG,OAAO,CAAC,GAAG,CAAC;EA88D1D"}