crbro-memory 1.0.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 (59) hide show
  1. package/README.md +122 -0
  2. package/bin/crbro.js +99 -0
  3. package/dist/engine/brain.d.ts +43 -0
  4. package/dist/engine/brain.d.ts.map +1 -0
  5. package/dist/engine/brain.js +179 -0
  6. package/dist/engine/brain.js.map +1 -0
  7. package/dist/engine/cortex.d.ts +70 -0
  8. package/dist/engine/cortex.d.ts.map +1 -0
  9. package/dist/engine/cortex.js +219 -0
  10. package/dist/engine/cortex.js.map +1 -0
  11. package/dist/engine/heat.d.ts +28 -0
  12. package/dist/engine/heat.d.ts.map +1 -0
  13. package/dist/engine/heat.js +112 -0
  14. package/dist/engine/heat.js.map +1 -0
  15. package/dist/engine/hippocampus.d.ts +26 -0
  16. package/dist/engine/hippocampus.d.ts.map +1 -0
  17. package/dist/engine/hippocampus.js +73 -0
  18. package/dist/engine/hippocampus.js.map +1 -0
  19. package/dist/engine/license.d.ts +29 -0
  20. package/dist/engine/license.d.ts.map +1 -0
  21. package/dist/engine/license.js +109 -0
  22. package/dist/engine/license.js.map +1 -0
  23. package/dist/engine/maintenance.d.ts +41 -0
  24. package/dist/engine/maintenance.d.ts.map +1 -0
  25. package/dist/engine/maintenance.js +156 -0
  26. package/dist/engine/maintenance.js.map +1 -0
  27. package/dist/engine/prefrontal.d.ts +31 -0
  28. package/dist/engine/prefrontal.d.ts.map +1 -0
  29. package/dist/engine/prefrontal.js +149 -0
  30. package/dist/engine/prefrontal.js.map +1 -0
  31. package/dist/engine/synapses.d.ts +39 -0
  32. package/dist/engine/synapses.d.ts.map +1 -0
  33. package/dist/engine/synapses.js +154 -0
  34. package/dist/engine/synapses.js.map +1 -0
  35. package/dist/index.d.ts +2 -0
  36. package/dist/index.d.ts.map +1 -0
  37. package/dist/index.js +16 -0
  38. package/dist/index.js.map +1 -0
  39. package/dist/search/index.d.ts +31 -0
  40. package/dist/search/index.d.ts.map +1 -0
  41. package/dist/search/index.js +139 -0
  42. package/dist/search/index.js.map +1 -0
  43. package/dist/server.d.ts +3 -0
  44. package/dist/server.d.ts.map +1 -0
  45. package/dist/server.js +543 -0
  46. package/dist/server.js.map +1 -0
  47. package/dist/types/index.d.ts +121 -0
  48. package/dist/types/index.d.ts.map +1 -0
  49. package/dist/types/index.js +5 -0
  50. package/dist/types/index.js.map +1 -0
  51. package/dist/utils/fs.d.ts +35 -0
  52. package/dist/utils/fs.d.ts.map +1 -0
  53. package/dist/utils/fs.js +110 -0
  54. package/dist/utils/fs.js.map +1 -0
  55. package/dist/utils/ids.d.ts +32 -0
  56. package/dist/utils/ids.d.ts.map +1 -0
  57. package/dist/utils/ids.js +92 -0
  58. package/dist/utils/ids.js.map +1 -0
  59. package/package.json +52 -0
@@ -0,0 +1,219 @@
1
+ "use strict";
2
+ // ─── CRBRO Cortex Engine ─────────────────────────────────────────
3
+ // Neuron CRUD — create, read, update, list neurons
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ exports.Cortex = void 0;
6
+ const fs_js_1 = require("../utils/fs.js");
7
+ const ids_js_1 = require("../utils/ids.js");
8
+ class Cortex {
9
+ brain;
10
+ constructor(brain) {
11
+ this.brain = brain;
12
+ }
13
+ /**
14
+ * Get a neuron by ID.
15
+ */
16
+ async get(id) {
17
+ const neuron = await (0, fs_js_1.readJSON)(this.brain.paths.neuron(id));
18
+ if (neuron) {
19
+ // Touch — update access time and count
20
+ neuron.last_accessed = (0, fs_js_1.now)();
21
+ neuron.access_count += 1;
22
+ await (0, fs_js_1.writeJSON)(this.brain.paths.neuron(id), neuron);
23
+ }
24
+ return neuron;
25
+ }
26
+ /**
27
+ * Get a neuron by ID without updating access stats.
28
+ */
29
+ async peek(id) {
30
+ return (0, fs_js_1.readJSON)(this.brain.paths.neuron(id));
31
+ }
32
+ /**
33
+ * Find a neuron by name (fuzzy match against existing neurons).
34
+ * Returns the best match or null.
35
+ */
36
+ async findByName(name) {
37
+ const ids = await (0, fs_js_1.listJSONFiles)(this.brain.paths.cortex);
38
+ const slug = (0, ids_js_1.toSnakeCase)(name);
39
+ // Exact match first
40
+ for (const id of ids) {
41
+ if (id.endsWith(`_${slug}`) || id === slug) {
42
+ return this.peek(id);
43
+ }
44
+ }
45
+ // Partial match
46
+ for (const id of ids) {
47
+ if (id.includes(slug) || slug.includes(id.replace(/^(project_|tech_|lang_|person_|domain_|process_)/, ''))) {
48
+ return this.peek(id);
49
+ }
50
+ }
51
+ return null;
52
+ }
53
+ /**
54
+ * Create a new neuron.
55
+ */
56
+ async create(name, type, domain, summary) {
57
+ const id = (0, ids_js_1.neuronId)(name, type);
58
+ const neuron = {
59
+ id,
60
+ name,
61
+ domain,
62
+ type,
63
+ created: (0, fs_js_1.now)(),
64
+ last_accessed: (0, fs_js_1.now)(),
65
+ access_count: 1,
66
+ heat: 0.5, // Initial heat
67
+ summary: summary || '',
68
+ facts: [],
69
+ decisions: [],
70
+ patterns: [],
71
+ preferences: [],
72
+ connections: [],
73
+ tags: [],
74
+ };
75
+ await (0, fs_js_1.writeJSON)(this.brain.paths.neuron(id), neuron);
76
+ // Update manifest count
77
+ const manifest = await this.brain.getManifest();
78
+ await this.brain.updateManifest({ total_neurons: manifest.total_neurons + 1 });
79
+ return neuron;
80
+ }
81
+ /**
82
+ * Learn — add a fact, decision, or pattern to a neuron.
83
+ * If the neuron doesn't exist, creates it first.
84
+ */
85
+ async learn(topic, type, content, options) {
86
+ // Try to find existing neuron
87
+ let neuron = await this.findByName(topic);
88
+ let action = 'updated';
89
+ if (!neuron) {
90
+ // Create new neuron
91
+ const nType = options?.neuronType || (0, ids_js_1.inferNeuronType)(topic);
92
+ const domain = options?.domain || 'general';
93
+ neuron = await this.create(topic, nType, domain);
94
+ action = 'created';
95
+ }
96
+ // Add content based on type
97
+ switch (type) {
98
+ case 'fact': {
99
+ // Check for duplicate
100
+ const isDuplicate = neuron.facts.some(f => f.text.toLowerCase() === content.toLowerCase());
101
+ if (!isDuplicate) {
102
+ const fact = {
103
+ text: content,
104
+ confidence: options?.confidence ?? 1.0,
105
+ added: (0, fs_js_1.now)(),
106
+ source: 'session',
107
+ };
108
+ neuron.facts.push(fact);
109
+ }
110
+ break;
111
+ }
112
+ case 'decision': {
113
+ const decision = {
114
+ text: content,
115
+ date: (0, fs_js_1.now)(),
116
+ rationale: options?.rationale || '',
117
+ };
118
+ neuron.decisions.push(decision);
119
+ break;
120
+ }
121
+ case 'pattern': {
122
+ if (!neuron.patterns.includes(content)) {
123
+ neuron.patterns.push(content);
124
+ }
125
+ break;
126
+ }
127
+ case 'preference': {
128
+ if (!neuron.preferences.includes(content)) {
129
+ neuron.preferences.push(content);
130
+ }
131
+ break;
132
+ }
133
+ }
134
+ // Update access
135
+ neuron.last_accessed = (0, fs_js_1.now)();
136
+ neuron.access_count += 1;
137
+ // Update domain if provided and neuron was just using default
138
+ if (options?.domain && neuron.domain === 'general') {
139
+ neuron.domain = options.domain;
140
+ }
141
+ await (0, fs_js_1.writeJSON)(this.brain.paths.neuron(neuron.id), neuron);
142
+ return { neuron, action };
143
+ }
144
+ /**
145
+ * List all neurons with optional filters.
146
+ */
147
+ async list(options) {
148
+ const ids = await (0, fs_js_1.listJSONFiles)(this.brain.paths.cortex);
149
+ const neurons = [];
150
+ for (const id of ids) {
151
+ const neuron = await (0, fs_js_1.readJSON)(this.brain.paths.neuron(id));
152
+ if (!neuron)
153
+ continue;
154
+ // Apply filters
155
+ if (options?.domain && neuron.domain !== options.domain)
156
+ continue;
157
+ if (options?.type && neuron.type !== options.type)
158
+ continue;
159
+ if (options?.min_heat && neuron.heat < options.min_heat)
160
+ continue;
161
+ neurons.push({
162
+ id: neuron.id,
163
+ name: neuron.name,
164
+ domain: neuron.domain,
165
+ type: neuron.type,
166
+ heat: neuron.heat,
167
+ last_accessed: neuron.last_accessed,
168
+ facts_count: neuron.facts.length,
169
+ });
170
+ }
171
+ // Sort by heat (descending)
172
+ neurons.sort((a, b) => b.heat - a.heat);
173
+ // Apply limit
174
+ const limit = options?.limit || 50;
175
+ return neurons.slice(0, limit);
176
+ }
177
+ /**
178
+ * Update a neuron's summary.
179
+ */
180
+ async updateSummary(id, summary) {
181
+ const neuron = await this.peek(id);
182
+ if (!neuron)
183
+ return null;
184
+ neuron.summary = summary;
185
+ neuron.last_accessed = (0, fs_js_1.now)();
186
+ await (0, fs_js_1.writeJSON)(this.brain.paths.neuron(id), neuron);
187
+ return neuron;
188
+ }
189
+ /**
190
+ * Add tags to a neuron.
191
+ */
192
+ async addTags(id, tags) {
193
+ const neuron = await this.peek(id);
194
+ if (!neuron)
195
+ return null;
196
+ for (const tag of tags) {
197
+ if (!neuron.tags.includes(tag)) {
198
+ neuron.tags.push(tag);
199
+ }
200
+ }
201
+ await (0, fs_js_1.writeJSON)(this.brain.paths.neuron(id), neuron);
202
+ return neuron;
203
+ }
204
+ /**
205
+ * Get all neuron IDs.
206
+ */
207
+ async allIds() {
208
+ return (0, fs_js_1.listJSONFiles)(this.brain.paths.cortex);
209
+ }
210
+ /**
211
+ * Count total neurons.
212
+ */
213
+ async count() {
214
+ const ids = await (0, fs_js_1.listJSONFiles)(this.brain.paths.cortex);
215
+ return ids.length;
216
+ }
217
+ }
218
+ exports.Cortex = Cortex;
219
+ //# sourceMappingURL=cortex.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cortex.js","sourceRoot":"","sources":["../../src/engine/cortex.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import type { HotTopics } from '../types/index.js';
2
+ import type { Brain } from './brain.js';
3
+ /**
4
+ * Calculate recency score (0.0 - 1.0) based on last access date.
5
+ */
6
+ export declare function recencyScore(lastAccessed: string): number;
7
+ /**
8
+ * Calculate frequency score (0.0 - 1.0) normalized against max access count.
9
+ */
10
+ export declare function frequencyScore(accessCount: number, maxAccessCount: number): number;
11
+ /**
12
+ * Calculate connectivity score (0.0 - 1.0) based on number of connections.
13
+ */
14
+ export declare function connectivityScore(connectionCount: number, maxConnections: number): number;
15
+ /**
16
+ * Calculate the heat score for a neuron.
17
+ */
18
+ export declare function calculateHeat(accessCount: number, lastAccessed: string, connectionCount: number, maxAccessCount: number, maxConnections: number): number;
19
+ export declare class HeatEngine {
20
+ private brain;
21
+ constructor(brain: Brain);
22
+ /**
23
+ * Recalculate heat scores for all neurons.
24
+ * Returns updated hot topics list.
25
+ */
26
+ recalculate(): Promise<HotTopics>;
27
+ }
28
+ //# sourceMappingURL=heat.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"heat.d.ts","sourceRoot":"","sources":["../../src/engine/heat.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAoB,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAErE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAOxC;;GAEG;AACH,wBAAgB,YAAY,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAUzD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,MAAM,CAGlF;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,eAAe,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,MAAM,CAGzF;AAED;;GAEG;AACH,wBAAgB,aAAa,CAC3B,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,EACpB,eAAe,EAAE,MAAM,EACvB,cAAc,EAAE,MAAM,EACtB,cAAc,EAAE,MAAM,GACrB,MAAM,CASR;AAID,qBAAa,UAAU;IACT,OAAO,CAAC,KAAK;gBAAL,KAAK,EAAE,KAAK;IAEhC;;;OAGG;IACG,WAAW,IAAI,OAAO,CAAC,SAAS,CAAC;CAqDxC"}
@@ -0,0 +1,112 @@
1
+ "use strict";
2
+ // ─── CRBRO Heat Score Engine ─────────────────────────────────────
3
+ // Calculates relevance score based on frequency, recency, and connectivity
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ exports.HeatEngine = void 0;
6
+ exports.recencyScore = recencyScore;
7
+ exports.frequencyScore = frequencyScore;
8
+ exports.connectivityScore = connectivityScore;
9
+ exports.calculateHeat = calculateHeat;
10
+ const fs_js_1 = require("../utils/fs.js");
11
+ // Weight constants
12
+ const WEIGHT_FREQUENCY = 0.35;
13
+ const WEIGHT_RECENCY = 0.40;
14
+ const WEIGHT_CONNECTIVITY = 0.25;
15
+ /**
16
+ * Calculate recency score (0.0 - 1.0) based on last access date.
17
+ */
18
+ function recencyScore(lastAccessed) {
19
+ const lastDate = new Date(lastAccessed).getTime();
20
+ const nowMs = Date.now();
21
+ const diffDays = (nowMs - lastDate) / (1000 * 60 * 60 * 24);
22
+ if (diffDays < 1)
23
+ return 1.0; // Today
24
+ if (diffDays < 7)
25
+ return 0.8; // This week
26
+ if (diffDays < 30)
27
+ return 0.5; // This month
28
+ if (diffDays < 90)
29
+ return 0.2; // Last 3 months
30
+ return 0.05; // Older
31
+ }
32
+ /**
33
+ * Calculate frequency score (0.0 - 1.0) normalized against max access count.
34
+ */
35
+ function frequencyScore(accessCount, maxAccessCount) {
36
+ if (maxAccessCount === 0)
37
+ return 0;
38
+ return Math.min(1.0, accessCount / maxAccessCount);
39
+ }
40
+ /**
41
+ * Calculate connectivity score (0.0 - 1.0) based on number of connections.
42
+ */
43
+ function connectivityScore(connectionCount, maxConnections) {
44
+ if (maxConnections === 0)
45
+ return 0;
46
+ return Math.min(1.0, connectionCount / maxConnections);
47
+ }
48
+ /**
49
+ * Calculate the heat score for a neuron.
50
+ */
51
+ function calculateHeat(accessCount, lastAccessed, connectionCount, maxAccessCount, maxConnections) {
52
+ const freq = frequencyScore(accessCount, maxAccessCount);
53
+ const rec = recencyScore(lastAccessed);
54
+ const conn = connectivityScore(connectionCount, maxConnections);
55
+ const heat = (freq * WEIGHT_FREQUENCY) + (rec * WEIGHT_RECENCY) + (conn * WEIGHT_CONNECTIVITY);
56
+ // Round to 3 decimal places
57
+ return Math.round(heat * 1000) / 1000;
58
+ }
59
+ // ─── Heat Manager ────────────────────────────────────────────────
60
+ class HeatEngine {
61
+ brain;
62
+ constructor(brain) {
63
+ this.brain = brain;
64
+ }
65
+ /**
66
+ * Recalculate heat scores for all neurons.
67
+ * Returns updated hot topics list.
68
+ */
69
+ async recalculate() {
70
+ const ids = await (0, fs_js_1.listJSONFiles)(this.brain.paths.cortex);
71
+ // First pass — find maximums for normalization
72
+ let maxAccess = 1;
73
+ let maxConnections = 1;
74
+ const neurons = [];
75
+ for (const id of ids) {
76
+ const neuron = await (0, fs_js_1.readJSON)(this.brain.paths.neuron(id));
77
+ if (!neuron)
78
+ continue;
79
+ neurons.push(neuron);
80
+ if (neuron.access_count > maxAccess)
81
+ maxAccess = neuron.access_count;
82
+ if (neuron.connections.length > maxConnections)
83
+ maxConnections = neuron.connections.length;
84
+ }
85
+ // Second pass — calculate and update heat
86
+ const hotTopics = [];
87
+ for (const neuron of neurons) {
88
+ const heat = calculateHeat(neuron.access_count, neuron.last_accessed, neuron.connections.length, maxAccess, maxConnections);
89
+ // Update neuron's heat
90
+ neuron.heat = heat;
91
+ await (0, fs_js_1.writeJSON)(this.brain.paths.neuron(neuron.id), neuron);
92
+ hotTopics.push({
93
+ id: neuron.id,
94
+ name: neuron.name,
95
+ heat,
96
+ last_access: neuron.last_accessed,
97
+ domain: neuron.domain,
98
+ });
99
+ }
100
+ // Sort by heat descending
101
+ hotTopics.sort((a, b) => b.heat - a.heat);
102
+ // Save hot topics (top 20)
103
+ const result = {
104
+ topics: hotTopics.slice(0, 20),
105
+ last_recalculated: (0, fs_js_1.now)(),
106
+ };
107
+ await (0, fs_js_1.writeJSON)(this.brain.paths.hotTopics(), result);
108
+ return result;
109
+ }
110
+ }
111
+ exports.HeatEngine = HeatEngine;
112
+ //# sourceMappingURL=heat.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"heat.js","sourceRoot":"","sources":["../../src/engine/heat.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import type { Brain } from './brain.js';
2
+ import type { SessionLog } from '../types/index.js';
3
+ export declare class Hippocampus {
4
+ private brain;
5
+ constructor(brain: Brain);
6
+ /**
7
+ * Log a session.
8
+ */
9
+ logSession(data: {
10
+ summary: string;
11
+ topics_touched: string[];
12
+ key_facts_added?: number;
13
+ decisions_made?: number;
14
+ new_neurons_created?: number;
15
+ synapses_updated?: number;
16
+ }): Promise<SessionLog>;
17
+ /**
18
+ * List recent sessions.
19
+ */
20
+ listSessions(limit?: number): Promise<SessionLog[]>;
21
+ /**
22
+ * Get today's session log.
23
+ */
24
+ getToday(): Promise<SessionLog | null>;
25
+ }
26
+ //# sourceMappingURL=hippocampus.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hippocampus.d.ts","sourceRoot":"","sources":["../../src/engine/hippocampus.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEpD,qBAAa,WAAW;IACV,OAAO,CAAC,KAAK;gBAAL,KAAK,EAAE,KAAK;IAEhC;;OAEG;IACG,UAAU,CAAC,IAAI,EAAE;QACrB,OAAO,EAAE,MAAM,CAAC;QAChB,cAAc,EAAE,MAAM,EAAE,CAAC;QACzB,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,mBAAmB,CAAC,EAAE,MAAM,CAAC;QAC7B,gBAAgB,CAAC,EAAE,MAAM,CAAC;KAC3B,GAAG,OAAO,CAAC,UAAU,CAAC;IAwCvB;;OAEG;IACG,YAAY,CAAC,KAAK,GAAE,MAAW,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAe7D;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;CAI7C"}
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ // ─── CRBRO Hippocampus Engine ────────────────────────────────────
3
+ // Session logging and memory formation
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ exports.Hippocampus = void 0;
6
+ const fs_js_1 = require("../utils/fs.js");
7
+ const ids_js_1 = require("../utils/ids.js");
8
+ class Hippocampus {
9
+ brain;
10
+ constructor(brain) {
11
+ this.brain = brain;
12
+ }
13
+ /**
14
+ * Log a session.
15
+ */
16
+ async logSession(data) {
17
+ const id = (0, ids_js_1.sessionId)();
18
+ // Check if session for today already exists — append to it
19
+ let existing = await (0, fs_js_1.readJSON)(this.brain.paths.session(id));
20
+ if (existing) {
21
+ // Append to existing session
22
+ existing.summary += `\n---\n${data.summary}`;
23
+ existing.topics_touched = [...new Set([...existing.topics_touched, ...data.topics_touched])];
24
+ existing.key_facts_added += data.key_facts_added || 0;
25
+ existing.decisions_made += data.decisions_made || 0;
26
+ existing.new_neurons_created += data.new_neurons_created || 0;
27
+ existing.synapses_updated += data.synapses_updated || 0;
28
+ await (0, fs_js_1.writeJSON)(this.brain.paths.session(id), existing);
29
+ return existing;
30
+ }
31
+ // Create new session log
32
+ const session = {
33
+ session_id: id,
34
+ date: (0, fs_js_1.today)(),
35
+ duration_estimate: 'unknown',
36
+ topics_touched: data.topics_touched,
37
+ summary: data.summary,
38
+ key_facts_added: data.key_facts_added || 0,
39
+ decisions_made: data.decisions_made || 0,
40
+ new_neurons_created: data.new_neurons_created || 0,
41
+ synapses_updated: data.synapses_updated || 0,
42
+ };
43
+ await (0, fs_js_1.writeJSON)(this.brain.paths.session(id), session);
44
+ // Update manifest
45
+ const manifest = await this.brain.getManifest();
46
+ await this.brain.updateManifest({ total_sessions: manifest.total_sessions + 1 });
47
+ return session;
48
+ }
49
+ /**
50
+ * List recent sessions.
51
+ */
52
+ async listSessions(limit = 10) {
53
+ const ids = await (0, fs_js_1.listJSONFiles)(this.brain.paths.hippocampus);
54
+ const sessions = [];
55
+ for (const id of ids) {
56
+ const session = await (0, fs_js_1.readJSON)(this.brain.paths.session(id));
57
+ if (session)
58
+ sessions.push(session);
59
+ }
60
+ // Sort by date descending (newest first)
61
+ sessions.sort((a, b) => b.date.localeCompare(a.date));
62
+ return sessions.slice(0, limit);
63
+ }
64
+ /**
65
+ * Get today's session log.
66
+ */
67
+ async getToday() {
68
+ const id = (0, ids_js_1.sessionId)();
69
+ return (0, fs_js_1.readJSON)(this.brain.paths.session(id));
70
+ }
71
+ }
72
+ exports.Hippocampus = Hippocampus;
73
+ //# sourceMappingURL=hippocampus.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hippocampus.js","sourceRoot":"","sources":["../../src/engine/hippocampus.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import type { Brain } from './brain.js';
2
+ import type { LicenseInfo } from '../types/index.js';
3
+ export declare class LicenseEngine {
4
+ private brain;
5
+ constructor(brain: Brain);
6
+ /**
7
+ * Validate and set a license key.
8
+ */
9
+ setLicense(key: string): Promise<LicenseInfo>;
10
+ /**
11
+ * Check if a specific tool is available.
12
+ */
13
+ canUse(toolName: string): Promise<boolean>;
14
+ /**
15
+ * Get current license info.
16
+ */
17
+ getLicenseInfo(): Promise<LicenseInfo>;
18
+ /**
19
+ * Check if premium features are available.
20
+ */
21
+ isPremium(): Promise<boolean>;
22
+ /**
23
+ * Resolve the license key — env var takes priority over manifest.
24
+ */
25
+ private resolveKey;
26
+ private validateKey;
27
+ private getInfo;
28
+ }
29
+ //# sourceMappingURL=license.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"license.d.ts","sourceRoot":"","sources":["../../src/engine/license.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,KAAK,EAAE,WAAW,EAAkB,MAAM,mBAAmB,CAAC;AA4BrE,qBAAa,aAAa;IACZ,OAAO,CAAC,KAAK;gBAAL,KAAK,EAAE,KAAK;IAEhC;;OAEG;IACG,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAUnD;;OAEG;IACG,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAQhD;;OAEG;IACG,cAAc,IAAI,OAAO,CAAC,WAAW,CAAC;IAK5C;;OAEG;IACG,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC;IAOnC;;OAEG;YACW,UAAU;IAUxB,OAAO,CAAC,WAAW;IAenB,OAAO,CAAC,OAAO;CAUhB"}
@@ -0,0 +1,109 @@
1
+ "use strict";
2
+ // ─── CRBRO License Engine ────────────────────────────────────────
3
+ // Premium feature gating with license key validation
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ exports.LicenseEngine = void 0;
6
+ // Free features available without license
7
+ const FREE_FEATURES = new Set([
8
+ 'crbro_boot',
9
+ 'crbro_status',
10
+ 'crbro_learn',
11
+ 'crbro_neuron',
12
+ 'crbro_neurons',
13
+ 'crbro_recall',
14
+ 'crbro_connect',
15
+ 'crbro_connections',
16
+ 'crbro_session_log',
17
+ 'crbro_sessions',
18
+ 'crbro_context',
19
+ 'crbro_hot_topics',
20
+ 'crbro_consolidate',
21
+ ]);
22
+ // Premium features requiring license
23
+ const PREMIUM_FEATURES = new Set([
24
+ 'crbro_global_map',
25
+ 'crbro_maintenance',
26
+ ]);
27
+ // Valid license key prefix — Synthetica Zero Deck keys
28
+ const LICENSE_PREFIX = 'SYNTH-ZERO-';
29
+ class LicenseEngine {
30
+ brain;
31
+ constructor(brain) {
32
+ this.brain = brain;
33
+ }
34
+ /**
35
+ * Validate and set a license key.
36
+ */
37
+ async setLicense(key) {
38
+ const isValid = this.validateKey(key);
39
+ if (isValid) {
40
+ await this.brain.updateManifest({ license_key: key });
41
+ }
42
+ return this.getInfo(isValid ? key : null);
43
+ }
44
+ /**
45
+ * Check if a specific tool is available.
46
+ */
47
+ async canUse(toolName) {
48
+ if (FREE_FEATURES.has(toolName))
49
+ return true;
50
+ if (!PREMIUM_FEATURES.has(toolName))
51
+ return true; // Unknown tools default to allowed
52
+ const key = await this.resolveKey();
53
+ return this.validateKey(key);
54
+ }
55
+ /**
56
+ * Get current license info.
57
+ */
58
+ async getLicenseInfo() {
59
+ const key = await this.resolveKey();
60
+ return this.getInfo(key);
61
+ }
62
+ /**
63
+ * Check if premium features are available.
64
+ */
65
+ async isPremium() {
66
+ const key = await this.resolveKey();
67
+ return this.validateKey(key);
68
+ }
69
+ // ─── Private ─────────────────────────────────────────────────
70
+ /**
71
+ * Resolve the license key — env var takes priority over manifest.
72
+ */
73
+ async resolveKey() {
74
+ // 1. Check environment variable first (set in mcp_config.json env block)
75
+ const envKey = process.env.CRBRO_LICENSE_KEY || null;
76
+ if (envKey && this.validateKey(envKey))
77
+ return envKey;
78
+ // 2. Fall back to manifest (set via CLI activate)
79
+ const manifest = await this.brain.getManifest();
80
+ return manifest.license_key || null;
81
+ }
82
+ validateKey(key) {
83
+ if (!key)
84
+ return false;
85
+ // Basic validation — prefix check + length
86
+ if (!key.startsWith(LICENSE_PREFIX))
87
+ return false;
88
+ if (key.length < 20)
89
+ return false;
90
+ // Checksum validation (simple)
91
+ const payload = key.substring(LICENSE_PREFIX.length);
92
+ // Must be alphanumeric + hyphens
93
+ if (!/^[A-Z0-9-]+$/.test(payload))
94
+ return false;
95
+ return true;
96
+ }
97
+ getInfo(key) {
98
+ const valid = this.validateKey(key);
99
+ return {
100
+ valid,
101
+ tier: valid ? 'premium' : 'free',
102
+ features: valid
103
+ ? ['global_map', 'maintenance', 'export', 'import', 'advanced_search']
104
+ : [],
105
+ };
106
+ }
107
+ }
108
+ exports.LicenseEngine = LicenseEngine;
109
+ //# sourceMappingURL=license.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"license.js","sourceRoot":"","sources":["../../src/engine/license.ts"],"names":[],"mappings":"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"}