@soulcraft/brainy 6.1.0 → 6.2.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 (40) hide show
  1. package/CHANGELOG.md +271 -0
  2. package/dist/augmentations/KnowledgeAugmentation.d.ts +40 -0
  3. package/dist/augmentations/KnowledgeAugmentation.js +251 -0
  4. package/dist/brainy.d.ts +17 -13
  5. package/dist/brainy.js +172 -41
  6. package/dist/coreTypes.d.ts +12 -0
  7. package/dist/graph/graphAdjacencyIndex.d.ts +23 -0
  8. package/dist/graph/graphAdjacencyIndex.js +49 -0
  9. package/dist/importManager.d.ts +78 -0
  10. package/dist/importManager.js +267 -0
  11. package/dist/query/typeInference.d.ts +158 -0
  12. package/dist/query/typeInference.js +760 -0
  13. package/dist/storage/adapters/typeAwareStorageAdapter.d.ts +252 -0
  14. package/dist/storage/adapters/typeAwareStorageAdapter.js +814 -0
  15. package/dist/storage/baseStorage.d.ts +36 -0
  16. package/dist/storage/baseStorage.js +159 -4
  17. package/dist/storage/cow/binaryDataCodec.d.ts +13 -2
  18. package/dist/storage/cow/binaryDataCodec.js +15 -2
  19. package/dist/types/brainy.types.d.ts +1 -0
  20. package/dist/types/brainyDataInterface.d.ts +52 -0
  21. package/dist/types/brainyDataInterface.js +10 -0
  22. package/dist/utils/metadataIndex.d.ts +17 -0
  23. package/dist/utils/metadataIndex.js +63 -0
  24. package/dist/vfs/ConceptSystem.d.ts +203 -0
  25. package/dist/vfs/ConceptSystem.js +545 -0
  26. package/dist/vfs/EntityManager.d.ts +75 -0
  27. package/dist/vfs/EntityManager.js +216 -0
  28. package/dist/vfs/EventRecorder.d.ts +84 -0
  29. package/dist/vfs/EventRecorder.js +269 -0
  30. package/dist/vfs/GitBridge.d.ts +167 -0
  31. package/dist/vfs/GitBridge.js +537 -0
  32. package/dist/vfs/KnowledgeLayer.d.ts +35 -0
  33. package/dist/vfs/KnowledgeLayer.js +443 -0
  34. package/dist/vfs/PersistentEntitySystem.d.ts +165 -0
  35. package/dist/vfs/PersistentEntitySystem.js +503 -0
  36. package/dist/vfs/SemanticVersioning.d.ts +105 -0
  37. package/dist/vfs/SemanticVersioning.js +309 -0
  38. package/dist/vfs/VirtualFileSystem.d.ts +37 -2
  39. package/dist/vfs/VirtualFileSystem.js +105 -68
  40. package/package.json +1 -1
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Knowledge Layer for VFS
3
+ *
4
+ * This is the REAL integration that makes VFS intelligent.
5
+ * It wraps VFS operations and adds Knowledge Layer processing.
6
+ */
7
+ import { VirtualFileSystem } from './VirtualFileSystem.js';
8
+ import { Brainy } from '../brainy.js';
9
+ export declare class KnowledgeLayer {
10
+ private vfs;
11
+ private brain;
12
+ private eventRecorder;
13
+ private semanticVersioning;
14
+ private entitySystem;
15
+ private conceptSystem;
16
+ private gitBridge;
17
+ private enabled;
18
+ constructor(vfs: VirtualFileSystem, brain: Brainy);
19
+ /**
20
+ * Enable Knowledge Layer by wrapping VFS methods
21
+ */
22
+ enable(): Promise<void>;
23
+ /**
24
+ * Add Knowledge Layer query methods to VFS
25
+ */
26
+ private addKnowledgeMethods;
27
+ /**
28
+ * Disable Knowledge Layer
29
+ */
30
+ disable(): Promise<void>;
31
+ }
32
+ /**
33
+ * Enable Knowledge Layer on a VFS instance
34
+ */
35
+ export declare function enableKnowledgeLayer(vfs: VirtualFileSystem, brain: Brainy): Promise<KnowledgeLayer>;
@@ -0,0 +1,443 @@
1
+ /**
2
+ * Knowledge Layer for VFS
3
+ *
4
+ * This is the REAL integration that makes VFS intelligent.
5
+ * It wraps VFS operations and adds Knowledge Layer processing.
6
+ */
7
+ import { EventRecorder } from './EventRecorder.js';
8
+ import { SemanticVersioning } from './SemanticVersioning.js';
9
+ import { PersistentEntitySystem } from './PersistentEntitySystem.js';
10
+ import { ConceptSystem } from './ConceptSystem.js';
11
+ import { GitBridge } from './GitBridge.js';
12
+ export class KnowledgeLayer {
13
+ constructor(vfs, brain) {
14
+ this.vfs = vfs;
15
+ this.brain = brain;
16
+ this.enabled = false;
17
+ // Initialize all Knowledge Layer components
18
+ this.eventRecorder = new EventRecorder(brain);
19
+ this.semanticVersioning = new SemanticVersioning(brain);
20
+ this.entitySystem = new PersistentEntitySystem(brain);
21
+ this.conceptSystem = new ConceptSystem(brain);
22
+ this.gitBridge = new GitBridge(vfs, brain);
23
+ }
24
+ /**
25
+ * Enable Knowledge Layer by wrapping VFS methods
26
+ */
27
+ async enable() {
28
+ if (this.enabled)
29
+ return;
30
+ this.enabled = true;
31
+ // Save original methods
32
+ const originalWriteFile = this.vfs.writeFile.bind(this.vfs);
33
+ const originalUnlink = this.vfs.unlink.bind(this.vfs);
34
+ const originalRename = this.vfs.rename.bind(this.vfs);
35
+ const originalMkdir = this.vfs.mkdir.bind(this.vfs);
36
+ const originalRmdir = this.vfs.rmdir.bind(this.vfs);
37
+ // Wrap writeFile to add intelligence
38
+ this.vfs.writeFile = async (path, data, options) => {
39
+ // Call original VFS method first
40
+ const result = await originalWriteFile(path, data, options);
41
+ // Process in background (non-blocking)
42
+ setImmediate(async () => {
43
+ try {
44
+ const buffer = Buffer.isBuffer(data) ? data : Buffer.from(data);
45
+ // 1. Record the event
46
+ await this.eventRecorder.recordEvent({
47
+ type: 'write',
48
+ path,
49
+ content: buffer,
50
+ size: buffer.length,
51
+ author: options?.author || 'system'
52
+ });
53
+ // 2. Check for semantic versioning
54
+ try {
55
+ const existingContent = await this.vfs.readFile(path).catch(() => null);
56
+ if (existingContent) {
57
+ const shouldVersion = await this.semanticVersioning.shouldVersion(existingContent, buffer);
58
+ if (shouldVersion) {
59
+ await this.semanticVersioning.createVersion(path, buffer, {
60
+ message: options?.message || 'Automatic semantic version'
61
+ });
62
+ }
63
+ }
64
+ }
65
+ catch (err) {
66
+ console.debug('Versioning check failed:', err);
67
+ }
68
+ // 3. Extract entities
69
+ if (options?.extractEntities !== false) {
70
+ await this.entitySystem.extractEntities(path, buffer);
71
+ }
72
+ // 4. Extract concepts
73
+ if (options?.extractConcepts !== false) {
74
+ await this.conceptSystem.extractAndLinkConcepts(path, buffer);
75
+ }
76
+ }
77
+ catch (error) {
78
+ console.debug('Knowledge Layer processing error:', error);
79
+ }
80
+ });
81
+ return result;
82
+ };
83
+ // Wrap unlink to record deletion
84
+ this.vfs.unlink = async (path) => {
85
+ const result = await originalUnlink(path);
86
+ setImmediate(async () => {
87
+ await this.eventRecorder.recordEvent({
88
+ type: 'delete',
89
+ path,
90
+ author: 'system'
91
+ });
92
+ });
93
+ return result;
94
+ };
95
+ // Wrap rename to track moves
96
+ this.vfs.rename = async (oldPath, newPath) => {
97
+ const result = await originalRename(oldPath, newPath);
98
+ setImmediate(async () => {
99
+ await this.eventRecorder.recordEvent({
100
+ type: 'rename',
101
+ path: oldPath,
102
+ metadata: { newPath },
103
+ author: 'system'
104
+ });
105
+ });
106
+ return result;
107
+ };
108
+ // Wrap mkdir to track directory creation
109
+ this.vfs.mkdir = async (path, options) => {
110
+ const result = await originalMkdir(path, options);
111
+ setImmediate(async () => {
112
+ await this.eventRecorder.recordEvent({
113
+ type: 'mkdir',
114
+ path,
115
+ author: 'system'
116
+ });
117
+ });
118
+ return result;
119
+ };
120
+ // Wrap rmdir to track directory deletion
121
+ this.vfs.rmdir = async (path, options) => {
122
+ const result = await originalRmdir(path, options);
123
+ setImmediate(async () => {
124
+ await this.eventRecorder.recordEvent({
125
+ type: 'rmdir',
126
+ path,
127
+ author: 'system'
128
+ });
129
+ });
130
+ return result;
131
+ };
132
+ // Add Knowledge Layer methods to VFS
133
+ this.addKnowledgeMethods();
134
+ console.log('✨ Knowledge Layer enabled on VFS');
135
+ }
136
+ /**
137
+ * Add Knowledge Layer query methods to VFS
138
+ */
139
+ addKnowledgeMethods() {
140
+ // Event history
141
+ this.vfs.getHistory = async (path, options) => {
142
+ return await this.eventRecorder.getHistory(path, options);
143
+ };
144
+ this.vfs.reconstructAtTime = async (path, timestamp) => {
145
+ return await this.eventRecorder.reconstructFileAtTime(path, timestamp);
146
+ };
147
+ // Semantic versioning
148
+ this.vfs.getVersions = async (path) => {
149
+ return await this.semanticVersioning.getVersions(path);
150
+ };
151
+ this.vfs.getVersion = async (path, versionId) => {
152
+ return await this.semanticVersioning.getVersion(path, versionId);
153
+ };
154
+ this.vfs.restoreVersion = async (path, versionId) => {
155
+ const content = await this.semanticVersioning.getVersion(path, versionId);
156
+ if (content) {
157
+ await this.vfs.writeFile(path, content);
158
+ }
159
+ };
160
+ // Entity system
161
+ this.vfs.createEntity = async (config) => {
162
+ return await this.entitySystem.createEntity(config);
163
+ };
164
+ this.vfs.findEntity = async (query) => {
165
+ return await this.entitySystem.findEntity(query);
166
+ };
167
+ this.vfs.getEntityEvolution = async (entityId) => {
168
+ return await this.entitySystem.getEvolution(entityId);
169
+ };
170
+ // Concept system
171
+ this.vfs.createConcept = async (config) => {
172
+ return await this.conceptSystem.createConcept(config);
173
+ };
174
+ this.vfs.findConcepts = async (query) => {
175
+ return await this.conceptSystem.findConcepts(query);
176
+ };
177
+ this.vfs.getConceptGraph = async (options) => {
178
+ return await this.conceptSystem.getConceptGraph(options);
179
+ };
180
+ // Git bridge
181
+ this.vfs.exportToGit = async (vfsPath, gitPath) => {
182
+ return await this.gitBridge.exportToGit(vfsPath, gitPath);
183
+ };
184
+ this.vfs.importFromGit = async (gitPath, vfsPath) => {
185
+ return await this.gitBridge.importFromGit(gitPath, vfsPath);
186
+ };
187
+ // Temporal coupling
188
+ this.vfs.findTemporalCoupling = async (path, windowMs) => {
189
+ return await this.eventRecorder.findTemporalCoupling(path, windowMs);
190
+ };
191
+ // Entity convenience methods that wrap Brainy's core API
192
+ this.vfs.linkEntities = async (fromEntity, toEntity, relationship) => {
193
+ // Handle both entity IDs and entity objects
194
+ const fromId = typeof fromEntity === 'string' ? fromEntity : fromEntity.id;
195
+ const toId = typeof toEntity === 'string' ? toEntity : toEntity.id;
196
+ // Use brain.relate to create the relationship
197
+ return await this.brain.relate({
198
+ from: fromId,
199
+ to: toId,
200
+ type: relationship // VerbType or string
201
+ });
202
+ };
203
+ // Find where an entity appears across files
204
+ this.vfs.findEntityOccurrences = async (entityId) => {
205
+ const occurrences = [];
206
+ // Search for files that contain references to this entity
207
+ // First, get all relationships where this entity is involved
208
+ const relations = await this.brain.getRelations({ from: entityId });
209
+ const toRelations = await this.brain.getRelations({ to: entityId });
210
+ // Find file entities that relate to this entity
211
+ for (const rel of [...relations, ...toRelations]) {
212
+ try {
213
+ // Check if the related entity is a file
214
+ const relatedId = rel.from === entityId ? rel.to : rel.from;
215
+ const entity = await this.brain.get(relatedId);
216
+ if (entity?.metadata?.vfsType === 'file' && entity?.metadata?.path) {
217
+ occurrences.push({
218
+ path: entity.metadata.path,
219
+ context: entity.data ? entity.data.toString().substring(0, 200) : undefined
220
+ });
221
+ }
222
+ }
223
+ catch (error) {
224
+ // Entity might not exist, continue
225
+ }
226
+ }
227
+ // Also search for files that mention the entity name in their content
228
+ const entityData = await this.brain.get(entityId);
229
+ if (entityData?.metadata?.name) {
230
+ const searchResults = await this.brain.find({
231
+ query: entityData.metadata.name,
232
+ where: { vfsType: 'file' },
233
+ limit: 20
234
+ });
235
+ for (const result of searchResults) {
236
+ if (result.entity?.metadata?.path && !occurrences.some(o => o.path === result.entity.metadata.path)) {
237
+ occurrences.push({
238
+ path: result.entity.metadata.path,
239
+ context: result.entity.data ? result.entity.data.toString().substring(0, 200) : undefined
240
+ });
241
+ }
242
+ }
243
+ }
244
+ return occurrences;
245
+ };
246
+ // Update an entity (convenience wrapper)
247
+ this.vfs.updateEntity = async (entityId, updates) => {
248
+ // Get current entity from brain
249
+ const currentEntity = await this.brain.get(entityId);
250
+ if (!currentEntity) {
251
+ throw new Error(`Entity ${entityId} not found`);
252
+ }
253
+ // Merge updates
254
+ const updatedMetadata = {
255
+ ...currentEntity.metadata,
256
+ ...updates,
257
+ lastUpdated: Date.now(),
258
+ version: (currentEntity.metadata?.version || 0) + 1
259
+ };
260
+ // Update via brain
261
+ await this.brain.update({
262
+ id: entityId,
263
+ data: JSON.stringify(updatedMetadata),
264
+ metadata: updatedMetadata
265
+ });
266
+ return entityId;
267
+ };
268
+ // Get entity graph (convenience wrapper)
269
+ this.vfs.getEntityGraph = async (entityId, options) => {
270
+ const depth = options?.depth || 2;
271
+ const graph = { nodes: new Map(), edges: [] };
272
+ const visited = new Set();
273
+ const traverse = async (id, currentDepth) => {
274
+ if (visited.has(id) || currentDepth > depth)
275
+ return;
276
+ visited.add(id);
277
+ // Add node
278
+ const entity = await this.brain.get(id);
279
+ if (entity) {
280
+ graph.nodes.set(id, entity);
281
+ }
282
+ // Get relationships
283
+ const relations = await this.brain.getRelations({ from: id });
284
+ const toRelations = await this.brain.getRelations({ to: id });
285
+ for (const rel of [...relations, ...toRelations]) {
286
+ graph.edges.push(rel);
287
+ // Traverse connected nodes
288
+ if (currentDepth < depth) {
289
+ const nextId = rel.from === id ? rel.to : rel.from;
290
+ await traverse(nextId, currentDepth + 1);
291
+ }
292
+ }
293
+ };
294
+ await traverse(entityId, 0);
295
+ return {
296
+ nodes: Array.from(graph.nodes.values()),
297
+ edges: graph.edges
298
+ };
299
+ };
300
+ // List all entities of a specific type
301
+ this.vfs.listEntities = async (query) => {
302
+ return await this.entitySystem.findEntity(query || {});
303
+ };
304
+ // Find files by concept
305
+ this.vfs.findByConcept = async (conceptName) => {
306
+ const paths = [];
307
+ // First find the concept
308
+ const concepts = await this.conceptSystem.findConcepts({ name: conceptName });
309
+ if (concepts.length === 0) {
310
+ return paths;
311
+ }
312
+ const concept = concepts[0];
313
+ // Search for files that contain concept keywords
314
+ const searchTerms = [conceptName, ...(concept.keywords || [])].join(' ');
315
+ const searchResults = await this.brain.find({
316
+ query: searchTerms,
317
+ where: { vfsType: 'file' },
318
+ limit: 50
319
+ });
320
+ // Get unique paths
321
+ const pathSet = new Set();
322
+ for (const result of searchResults) {
323
+ if (result.entity?.metadata?.path) {
324
+ pathSet.add(result.entity.metadata.path);
325
+ }
326
+ }
327
+ // Also check concept manifestations if stored
328
+ if (concept.manifestations) {
329
+ for (const manifestation of concept.manifestations) {
330
+ if (manifestation.filePath) {
331
+ pathSet.add(manifestation.filePath);
332
+ }
333
+ }
334
+ }
335
+ return Array.from(pathSet);
336
+ };
337
+ // Get timeline of events
338
+ this.vfs.getTimeline = async (options) => {
339
+ const fromTime = options?.from ? new Date(options.from).getTime() : Date.now() - 30 * 24 * 60 * 60 * 1000; // 30 days ago
340
+ const toTime = options?.to ? new Date(options.to).getTime() : Date.now();
341
+ const limit = options?.limit || 100;
342
+ // Get events from event recorder
343
+ const events = await this.eventRecorder.getEvents({
344
+ since: fromTime,
345
+ until: toTime,
346
+ types: options?.types,
347
+ limit
348
+ });
349
+ // Transform to timeline format
350
+ return events.map(event => ({
351
+ timestamp: new Date(event.timestamp),
352
+ type: event.type,
353
+ path: event.path,
354
+ user: event.author,
355
+ description: `${event.type} ${event.path}${event.oldPath ? ` (from ${event.oldPath})` : ''}`
356
+ }));
357
+ };
358
+ // Get collaboration history for a file
359
+ this.vfs.getCollaborationHistory = async (path) => {
360
+ // Get all events for this path
361
+ const history = await this.eventRecorder.getHistory(path, { limit: 100 });
362
+ return history.map(event => ({
363
+ user: event.author || 'system',
364
+ timestamp: new Date(event.timestamp),
365
+ action: event.type,
366
+ size: event.size
367
+ }));
368
+ };
369
+ // Export to markdown format
370
+ this.vfs.exportToMarkdown = async (path) => {
371
+ const markdown = [];
372
+ const traverse = async (currentPath, depth = 0) => {
373
+ const indent = ' '.repeat(depth);
374
+ try {
375
+ const stats = await this.vfs.stat(currentPath);
376
+ if (stats.isDirectory()) {
377
+ // Add directory header
378
+ const name = currentPath.split('/').pop() || currentPath;
379
+ markdown.push(`${indent}## ${name}/`);
380
+ markdown.push('');
381
+ // List and traverse children
382
+ const children = await this.vfs.readdir(currentPath);
383
+ for (const child of children.sort()) {
384
+ const childPath = currentPath === '/' ? `/${child}` : `${currentPath}/${child}`;
385
+ await traverse(childPath, depth + 1);
386
+ }
387
+ }
388
+ else {
389
+ // Add file content
390
+ const name = currentPath.split('/').pop() || currentPath;
391
+ const extension = name.split('.').pop() || 'txt';
392
+ try {
393
+ const content = await this.vfs.readFile(currentPath);
394
+ const textContent = content.toString('utf8');
395
+ markdown.push(`${indent}### ${name}`);
396
+ markdown.push('');
397
+ // Add code block for code files
398
+ if (['js', 'ts', 'jsx', 'tsx', 'py', 'java', 'cpp', 'go', 'rs', 'json'].includes(extension)) {
399
+ markdown.push(`${indent}\`\`\`${extension}`);
400
+ markdown.push(textContent.split('\n').map(line => `${indent}${line}`).join('\n'));
401
+ markdown.push(`${indent}\`\`\``);
402
+ }
403
+ else if (extension === 'md') {
404
+ // Include markdown directly
405
+ markdown.push(textContent);
406
+ }
407
+ else {
408
+ // Plain text in quotes
409
+ markdown.push(`${indent}> ${textContent.split('\n').join(`\n${indent}> `)}`);
410
+ }
411
+ markdown.push('');
412
+ }
413
+ catch (error) {
414
+ markdown.push(`${indent}*Binary or unreadable file*`);
415
+ markdown.push('');
416
+ }
417
+ }
418
+ }
419
+ catch (error) {
420
+ // Skip inaccessible paths
421
+ }
422
+ };
423
+ await traverse(path);
424
+ return markdown.join('\n');
425
+ };
426
+ }
427
+ /**
428
+ * Disable Knowledge Layer
429
+ */
430
+ async disable() {
431
+ // Would restore original methods here
432
+ this.enabled = false;
433
+ }
434
+ }
435
+ /**
436
+ * Enable Knowledge Layer on a VFS instance
437
+ */
438
+ export async function enableKnowledgeLayer(vfs, brain) {
439
+ const knowledgeLayer = new KnowledgeLayer(vfs, brain);
440
+ await knowledgeLayer.enable();
441
+ return knowledgeLayer;
442
+ }
443
+ //# sourceMappingURL=KnowledgeLayer.js.map
@@ -0,0 +1,165 @@
1
+ /**
2
+ * Persistent Entity System for VFS
3
+ *
4
+ * Manages entities that evolve across files and time
5
+ * Not just story characters - any evolving entity: APIs, customers, services, models
6
+ * PRODUCTION-READY: Real implementation using Brainy
7
+ */
8
+ import { Brainy } from '../brainy.js';
9
+ import { EntityManager, ManagedEntity } from './EntityManager.js';
10
+ /**
11
+ * Persistent entity that exists across files and evolves over time
12
+ */
13
+ export interface PersistentEntity extends ManagedEntity {
14
+ id: string;
15
+ name: string;
16
+ type: string;
17
+ description?: string;
18
+ aliases: string[];
19
+ appearances: EntityAppearance[];
20
+ attributes: Record<string, any>;
21
+ created: number;
22
+ lastUpdated: number;
23
+ version: number;
24
+ entityType?: string;
25
+ }
26
+ /**
27
+ * An appearance of an entity in a specific file/location
28
+ */
29
+ export interface EntityAppearance extends ManagedEntity {
30
+ id: string;
31
+ entityId: string;
32
+ filePath: string;
33
+ context: string;
34
+ position?: {
35
+ line?: number;
36
+ column?: number;
37
+ offset?: number;
38
+ };
39
+ timestamp: number;
40
+ version: number;
41
+ changes?: EntityChange[];
42
+ confidence: number;
43
+ eventType?: string;
44
+ }
45
+ /**
46
+ * A change/evolution to an entity
47
+ */
48
+ export interface EntityChange {
49
+ field: string;
50
+ oldValue: any;
51
+ newValue: any;
52
+ timestamp: number;
53
+ source: string;
54
+ reason?: string;
55
+ }
56
+ /**
57
+ * Configuration for persistent entities
58
+ */
59
+ export interface PersistentEntityConfig {
60
+ autoExtract?: boolean;
61
+ similarityThreshold?: number;
62
+ maxAppearances?: number;
63
+ evolutionTracking?: boolean;
64
+ }
65
+ /**
66
+ * Persistent Entity System
67
+ *
68
+ * Tracks entities that exist across multiple files and evolve over time
69
+ * Examples:
70
+ * - Story characters that appear in multiple chapters
71
+ * - API endpoints that evolve across documentation
72
+ * - Business entities that appear in multiple reports
73
+ * - Code classes/functions that span multiple files
74
+ */
75
+ export declare class PersistentEntitySystem extends EntityManager {
76
+ private config;
77
+ private entityCache;
78
+ constructor(brain: Brainy, config?: PersistentEntityConfig);
79
+ /**
80
+ * Create a new persistent entity
81
+ */
82
+ createEntity(entity: Omit<PersistentEntity, 'id' | 'created' | 'lastUpdated' | 'version' | 'appearances'>): Promise<string>;
83
+ /**
84
+ * Find an existing entity by name or attributes
85
+ */
86
+ findEntity(query: {
87
+ name?: string;
88
+ type?: string;
89
+ attributes?: Record<string, any>;
90
+ similar?: string;
91
+ }): Promise<PersistentEntity[]>;
92
+ /**
93
+ * Record an appearance of an entity in a file
94
+ */
95
+ recordAppearance(entityId: string, filePath: string, context: string, options?: {
96
+ position?: EntityAppearance['position'];
97
+ confidence?: number;
98
+ extractChanges?: boolean;
99
+ }): Promise<string>;
100
+ /**
101
+ * Get entity evolution history
102
+ */
103
+ getEvolution(entityId: string): Promise<{
104
+ entity: PersistentEntity;
105
+ timeline: Array<{
106
+ timestamp: number;
107
+ version: number;
108
+ changes: EntityChange[];
109
+ appearance?: EntityAppearance;
110
+ }>;
111
+ }>;
112
+ /**
113
+ * Find all appearances of an entity
114
+ */
115
+ findAppearances(entityId: string, options?: {
116
+ filePath?: string;
117
+ since?: number;
118
+ until?: number;
119
+ minConfidence?: number;
120
+ }): Promise<EntityAppearance[]>;
121
+ /**
122
+ * Evolve an entity with new information
123
+ */
124
+ evolveEntity(entityId: string, updates: Partial<Pick<PersistentEntity, 'name' | 'description' | 'aliases' | 'attributes'>>, source: string, reason?: string): Promise<void>;
125
+ /**
126
+ * Extract entities from content (auto-extraction)
127
+ */
128
+ extractEntities(filePath: string, content: Buffer): Promise<string[]>;
129
+ /**
130
+ * Update references when a file moves
131
+ */
132
+ updateReferences(oldPath: string, newPath: string): Promise<void>;
133
+ /**
134
+ * Get persistent entity by ID
135
+ */
136
+ getPersistentEntity(entityId: string): Promise<PersistentEntity | null>;
137
+ /**
138
+ * Update stored entity (rename to avoid parent method conflict)
139
+ */
140
+ private updatePersistentEntity;
141
+ /**
142
+ * Detect changes in entity from context
143
+ */
144
+ private detectChanges;
145
+ /**
146
+ * Generate embedding for entity
147
+ */
148
+ private generateEntityEmbedding;
149
+ /**
150
+ * Generate embedding for text
151
+ */
152
+ private generateTextEmbedding;
153
+ /**
154
+ * Detect entity type from name and context
155
+ */
156
+ private detectEntityType;
157
+ /**
158
+ * Extract context around a position
159
+ */
160
+ private extractContext;
161
+ /**
162
+ * Clear entity cache
163
+ */
164
+ clearCache(entityId?: string): void;
165
+ }