@soulcraft/brainy 3.9.0 → 3.10.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.
- package/README.md +89 -33
- package/dist/augmentations/KnowledgeAugmentation.d.ts +40 -0
- package/dist/augmentations/KnowledgeAugmentation.js +251 -0
- package/dist/augmentations/defaultAugmentations.d.ts +1 -0
- package/dist/augmentations/defaultAugmentations.js +5 -0
- package/dist/brainy.d.ts +11 -0
- package/dist/brainy.js +87 -1
- package/dist/embeddings/EmbeddingManager.js +14 -2
- package/dist/utils/mutex.d.ts +2 -0
- package/dist/utils/mutex.js +14 -3
- package/dist/vfs/ConceptSystem.d.ts +202 -0
- package/dist/vfs/ConceptSystem.js +598 -0
- package/dist/vfs/EntityManager.d.ts +75 -0
- package/dist/vfs/EntityManager.js +216 -0
- package/dist/vfs/EventRecorder.d.ts +83 -0
- package/dist/vfs/EventRecorder.js +292 -0
- package/dist/vfs/FSCompat.d.ts +85 -0
- package/dist/vfs/FSCompat.js +257 -0
- package/dist/vfs/GitBridge.d.ts +167 -0
- package/dist/vfs/GitBridge.js +537 -0
- package/dist/vfs/KnowledgeAugmentation.d.ts +104 -0
- package/dist/vfs/KnowledgeAugmentation.js +146 -0
- package/dist/vfs/KnowledgeLayer.d.ts +35 -0
- package/dist/vfs/KnowledgeLayer.js +443 -0
- package/dist/vfs/PathResolver.d.ts +96 -0
- package/dist/vfs/PathResolver.js +362 -0
- package/dist/vfs/PersistentEntitySystem.d.ts +163 -0
- package/dist/vfs/PersistentEntitySystem.js +525 -0
- package/dist/vfs/SemanticVersioning.d.ts +105 -0
- package/dist/vfs/SemanticVersioning.js +318 -0
- package/dist/vfs/VirtualFileSystem.d.ts +246 -0
- package/dist/vfs/VirtualFileSystem.js +1927 -0
- package/dist/vfs/importers/DirectoryImporter.d.ts +86 -0
- package/dist/vfs/importers/DirectoryImporter.js +298 -0
- package/dist/vfs/index.d.ts +19 -0
- package/dist/vfs/index.js +26 -0
- package/dist/vfs/streams/VFSReadStream.d.ts +19 -0
- package/dist/vfs/streams/VFSReadStream.js +54 -0
- package/dist/vfs/streams/VFSWriteStream.d.ts +21 -0
- package/dist/vfs/streams/VFSWriteStream.js +70 -0
- package/dist/vfs/types.d.ts +330 -0
- package/dist/vfs/types.js +46 -0
- package/package.json +1 -1
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Semantic Versioning System for VFS
|
|
3
|
+
*
|
|
4
|
+
* Only creates versions when the MEANING of content changes significantly
|
|
5
|
+
* PRODUCTION-READY: Real implementation using embeddings
|
|
6
|
+
*/
|
|
7
|
+
import { NounType, VerbType } from '../types/graphTypes.js';
|
|
8
|
+
import { cosineDistance } from '../utils/distance.js';
|
|
9
|
+
import { createHash } from 'crypto';
|
|
10
|
+
import { v4 as uuidv4 } from '../universal/uuid.js';
|
|
11
|
+
/**
|
|
12
|
+
* Semantic Versioning System
|
|
13
|
+
*
|
|
14
|
+
* Creates versions only when content meaning changes significantly
|
|
15
|
+
* Uses vector embeddings to detect semantic changes
|
|
16
|
+
*/
|
|
17
|
+
export class SemanticVersioning {
|
|
18
|
+
constructor(brain, config) {
|
|
19
|
+
this.brain = brain;
|
|
20
|
+
this.versionCache = new Map();
|
|
21
|
+
this.config = {
|
|
22
|
+
threshold: config?.threshold ?? 0.3,
|
|
23
|
+
maxVersions: config?.maxVersions ?? 10,
|
|
24
|
+
minInterval: config?.minInterval ?? 60000, // 1 minute
|
|
25
|
+
sizeChangeThreshold: config?.sizeChangeThreshold ?? 0.5
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Check if content has changed enough to warrant a new version
|
|
30
|
+
*/
|
|
31
|
+
async shouldVersion(oldContent, newContent) {
|
|
32
|
+
// Quick hash check - if identical, no version needed
|
|
33
|
+
const oldHash = this.hashContent(oldContent);
|
|
34
|
+
const newHash = this.hashContent(newContent);
|
|
35
|
+
if (oldHash === newHash) {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
// Check size change
|
|
39
|
+
const sizeChange = Math.abs(oldContent.length - newContent.length) / Math.max(oldContent.length, 1);
|
|
40
|
+
if (sizeChange > this.config.sizeChangeThreshold) {
|
|
41
|
+
return true; // Large size change warrants version
|
|
42
|
+
}
|
|
43
|
+
// For small files, any change is significant
|
|
44
|
+
if (oldContent.length < 100 || newContent.length < 100) {
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
// Check semantic change using embeddings
|
|
48
|
+
try {
|
|
49
|
+
const semanticDistance = await this.calculateSemanticDistance(oldContent, newContent);
|
|
50
|
+
return semanticDistance > this.config.threshold;
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
// If embedding fails, fall back to size-based decision
|
|
54
|
+
console.warn('Failed to calculate semantic distance:', error);
|
|
55
|
+
return sizeChange > 0.2;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Create a new version
|
|
60
|
+
*/
|
|
61
|
+
async createVersion(path, content, metadata) {
|
|
62
|
+
const versionId = uuidv4();
|
|
63
|
+
const timestamp = Date.now();
|
|
64
|
+
const hash = this.hashContent(content);
|
|
65
|
+
// Get current version number
|
|
66
|
+
const versions = await this.getVersions(path);
|
|
67
|
+
const versionNumber = versions.length + 1;
|
|
68
|
+
const parentVersion = versions[0]?.id;
|
|
69
|
+
// Generate embedding for semantic comparison
|
|
70
|
+
let embedding;
|
|
71
|
+
let semanticHash;
|
|
72
|
+
try {
|
|
73
|
+
// Only generate embedding for reasonably sized content
|
|
74
|
+
if (content.length < 100000) {
|
|
75
|
+
embedding = await this.generateEmbedding(content);
|
|
76
|
+
if (embedding) {
|
|
77
|
+
semanticHash = this.hashEmbedding(embedding);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
console.warn('Failed to generate embedding for version:', error);
|
|
83
|
+
}
|
|
84
|
+
// Store version as Brainy entity
|
|
85
|
+
const entity = await this.brain.add({
|
|
86
|
+
type: NounType.State,
|
|
87
|
+
data: content, // Store actual content
|
|
88
|
+
metadata: {
|
|
89
|
+
id: versionId,
|
|
90
|
+
path,
|
|
91
|
+
version: versionNumber,
|
|
92
|
+
timestamp,
|
|
93
|
+
hash,
|
|
94
|
+
semanticHash,
|
|
95
|
+
size: content.length,
|
|
96
|
+
author: metadata?.author,
|
|
97
|
+
message: metadata?.message,
|
|
98
|
+
parentVersion,
|
|
99
|
+
system: 'vfs-version'
|
|
100
|
+
},
|
|
101
|
+
vector: embedding
|
|
102
|
+
});
|
|
103
|
+
// Create relationship to parent version if exists
|
|
104
|
+
if (parentVersion) {
|
|
105
|
+
await this.brain.relate({
|
|
106
|
+
from: entity,
|
|
107
|
+
to: parentVersion,
|
|
108
|
+
type: VerbType.Succeeds
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
// Update cache
|
|
112
|
+
if (!this.versionCache.has(path)) {
|
|
113
|
+
this.versionCache.set(path, []);
|
|
114
|
+
}
|
|
115
|
+
this.versionCache.get(path).unshift({
|
|
116
|
+
id: versionId,
|
|
117
|
+
path,
|
|
118
|
+
version: versionNumber,
|
|
119
|
+
timestamp,
|
|
120
|
+
hash,
|
|
121
|
+
size: content.length,
|
|
122
|
+
semanticHash,
|
|
123
|
+
author: metadata?.author,
|
|
124
|
+
message: metadata?.message,
|
|
125
|
+
parentVersion
|
|
126
|
+
});
|
|
127
|
+
// Prune old versions if needed
|
|
128
|
+
await this.pruneVersions(path);
|
|
129
|
+
return versionId;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Get all versions for a file
|
|
133
|
+
*/
|
|
134
|
+
async getVersions(path) {
|
|
135
|
+
// Check cache first
|
|
136
|
+
if (this.versionCache.has(path)) {
|
|
137
|
+
return this.versionCache.get(path);
|
|
138
|
+
}
|
|
139
|
+
// Query from Brainy
|
|
140
|
+
const results = await this.brain.find({
|
|
141
|
+
where: {
|
|
142
|
+
path,
|
|
143
|
+
system: 'vfs-version'
|
|
144
|
+
},
|
|
145
|
+
type: NounType.State,
|
|
146
|
+
limit: this.config.maxVersions * 2 // Get extra in case some are pruned
|
|
147
|
+
});
|
|
148
|
+
const versions = results
|
|
149
|
+
.map(r => r.entity.metadata)
|
|
150
|
+
.sort((a, b) => b.timestamp - a.timestamp); // Newest first
|
|
151
|
+
// Update cache
|
|
152
|
+
this.versionCache.set(path, versions);
|
|
153
|
+
return versions;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Get a specific version's content
|
|
157
|
+
*/
|
|
158
|
+
async getVersion(path, versionId) {
|
|
159
|
+
const results = await this.brain.find({
|
|
160
|
+
where: {
|
|
161
|
+
id: versionId,
|
|
162
|
+
path,
|
|
163
|
+
system: 'vfs-version'
|
|
164
|
+
},
|
|
165
|
+
type: NounType.State,
|
|
166
|
+
limit: 1
|
|
167
|
+
});
|
|
168
|
+
if (results.length === 0) {
|
|
169
|
+
return null;
|
|
170
|
+
}
|
|
171
|
+
return results[0].entity.data;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Restore a file to a specific version
|
|
175
|
+
*/
|
|
176
|
+
async restoreVersion(path, versionId) {
|
|
177
|
+
const content = await this.getVersion(path, versionId);
|
|
178
|
+
if (!content) {
|
|
179
|
+
throw new Error(`Version ${versionId} not found for ${path}`);
|
|
180
|
+
}
|
|
181
|
+
// Create a new version pointing to the restored one
|
|
182
|
+
await this.createVersion(path, content, {
|
|
183
|
+
message: `Restored to version ${versionId}`
|
|
184
|
+
});
|
|
185
|
+
return content;
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Get version history with diffs
|
|
189
|
+
*/
|
|
190
|
+
async getVersionHistory(path, limit = 10) {
|
|
191
|
+
const versions = await this.getVersions(path);
|
|
192
|
+
const history = [];
|
|
193
|
+
for (let i = 0; i < Math.min(versions.length, limit); i++) {
|
|
194
|
+
const version = versions[i];
|
|
195
|
+
let changes = undefined;
|
|
196
|
+
// Calculate changes from parent
|
|
197
|
+
if (version.parentVersion && i < versions.length - 1) {
|
|
198
|
+
const parentVersion = versions[i + 1];
|
|
199
|
+
if (parentVersion.id === version.parentVersion) {
|
|
200
|
+
// Simple size-based diff for now
|
|
201
|
+
changes = {
|
|
202
|
+
additions: Math.max(0, version.size - parentVersion.size),
|
|
203
|
+
deletions: Math.max(0, parentVersion.size - version.size),
|
|
204
|
+
semanticChange: version.semanticHash && parentVersion.semanticHash
|
|
205
|
+
? this.estimateSemanticChange(version.semanticHash, parentVersion.semanticHash)
|
|
206
|
+
: 0
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
history.push({ version, changes });
|
|
211
|
+
}
|
|
212
|
+
return history;
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Prune old versions beyond the limit
|
|
216
|
+
*/
|
|
217
|
+
async pruneVersions(path) {
|
|
218
|
+
const versions = await this.getVersions(path);
|
|
219
|
+
if (versions.length <= this.config.maxVersions) {
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
// Keep important versions (first, last, and evenly distributed)
|
|
223
|
+
const toKeep = new Set();
|
|
224
|
+
const toDelete = [];
|
|
225
|
+
// Always keep first and last
|
|
226
|
+
toKeep.add(versions[0].id); // Newest
|
|
227
|
+
toKeep.add(versions[versions.length - 1].id); // Oldest
|
|
228
|
+
// Keep evenly distributed versions
|
|
229
|
+
const step = Math.floor(versions.length / this.config.maxVersions);
|
|
230
|
+
for (let i = 0; i < versions.length; i += step) {
|
|
231
|
+
toKeep.add(versions[i].id);
|
|
232
|
+
}
|
|
233
|
+
// Mark others for deletion
|
|
234
|
+
for (const version of versions) {
|
|
235
|
+
if (!toKeep.has(version.id)) {
|
|
236
|
+
toDelete.push(version.id);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
// Delete excess versions
|
|
240
|
+
for (const id of toDelete.slice(0, versions.length - this.config.maxVersions)) {
|
|
241
|
+
await this.brain.delete(id);
|
|
242
|
+
}
|
|
243
|
+
// Update cache
|
|
244
|
+
this.versionCache.set(path, versions.filter(v => !toDelete.includes(v.id)));
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Calculate semantic distance between two pieces of content
|
|
248
|
+
*/
|
|
249
|
+
async calculateSemanticDistance(oldContent, newContent) {
|
|
250
|
+
// Generate embeddings
|
|
251
|
+
const [oldEmbedding, newEmbedding] = await Promise.all([
|
|
252
|
+
this.generateEmbedding(oldContent),
|
|
253
|
+
this.generateEmbedding(newContent)
|
|
254
|
+
]);
|
|
255
|
+
if (!oldEmbedding || !newEmbedding) {
|
|
256
|
+
throw new Error('Failed to generate embeddings');
|
|
257
|
+
}
|
|
258
|
+
// Calculate cosine distance
|
|
259
|
+
return cosineDistance(oldEmbedding, newEmbedding);
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Generate embedding for content
|
|
263
|
+
*/
|
|
264
|
+
async generateEmbedding(content) {
|
|
265
|
+
try {
|
|
266
|
+
// For text content, use first 10KB for embedding
|
|
267
|
+
const text = content.toString('utf8', 0, Math.min(10240, content.length));
|
|
268
|
+
// Use Brainy's embedding function
|
|
269
|
+
const vector = await this.brain.embed(text);
|
|
270
|
+
return vector;
|
|
271
|
+
}
|
|
272
|
+
catch (error) {
|
|
273
|
+
console.error('Failed to generate embedding:', error);
|
|
274
|
+
return undefined;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Hash content for quick comparison
|
|
279
|
+
*/
|
|
280
|
+
hashContent(content) {
|
|
281
|
+
return createHash('sha256').update(content).digest('hex');
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Hash embedding for quick comparison
|
|
285
|
+
*/
|
|
286
|
+
hashEmbedding(embedding) {
|
|
287
|
+
return createHash('sha256')
|
|
288
|
+
.update(Buffer.from(new Float32Array(embedding).buffer))
|
|
289
|
+
.digest('hex');
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* Estimate semantic change from hashes (rough approximation)
|
|
293
|
+
*/
|
|
294
|
+
estimateSemanticChange(hash1, hash2) {
|
|
295
|
+
if (hash1 === hash2)
|
|
296
|
+
return 0;
|
|
297
|
+
// Simple hamming distance on first few characters
|
|
298
|
+
// This is a rough approximation
|
|
299
|
+
let distance = 0;
|
|
300
|
+
for (let i = 0; i < Math.min(hash1.length, hash2.length, 8); i++) {
|
|
301
|
+
if (hash1[i] !== hash2[i])
|
|
302
|
+
distance++;
|
|
303
|
+
}
|
|
304
|
+
return distance / 8;
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Clear version cache for a file
|
|
308
|
+
*/
|
|
309
|
+
clearCache(path) {
|
|
310
|
+
if (path) {
|
|
311
|
+
this.versionCache.delete(path);
|
|
312
|
+
}
|
|
313
|
+
else {
|
|
314
|
+
this.versionCache.clear();
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
//# sourceMappingURL=SemanticVersioning.js.map
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Virtual Filesystem Implementation
|
|
3
|
+
*
|
|
4
|
+
* PRODUCTION-READY VFS built on Brainy
|
|
5
|
+
* Real code, no mocks, actual working implementation
|
|
6
|
+
*/
|
|
7
|
+
import { Brainy } from '../brainy.js';
|
|
8
|
+
import { Relation } from '../types/brainy.types.js';
|
|
9
|
+
import { IVirtualFileSystem, VFSConfig, VFSEntity, VFSMetadata, VFSStats, VFSDirent, VFSTodo, WriteOptions, ReadOptions, MkdirOptions, ReaddirOptions, CopyOptions, SearchOptions, SearchResult, SimilarOptions, RelatedOptions, ReadStreamOptions, WriteStreamOptions, WatchListener } from './types.js';
|
|
10
|
+
/**
|
|
11
|
+
* Main Virtual Filesystem Implementation
|
|
12
|
+
*
|
|
13
|
+
* This is REAL, production-ready code that:
|
|
14
|
+
* - Maps filesystem operations to Brainy entities
|
|
15
|
+
* - Uses graph relationships for directory structure
|
|
16
|
+
* - Provides semantic search and AI features
|
|
17
|
+
* - Scales to millions of files
|
|
18
|
+
*/
|
|
19
|
+
export declare class VirtualFileSystem implements IVirtualFileSystem {
|
|
20
|
+
private brain;
|
|
21
|
+
private pathResolver;
|
|
22
|
+
private config;
|
|
23
|
+
private rootEntityId?;
|
|
24
|
+
private initialized;
|
|
25
|
+
private currentUser;
|
|
26
|
+
private contentCache;
|
|
27
|
+
private statCache;
|
|
28
|
+
private watchers;
|
|
29
|
+
private backgroundTimer;
|
|
30
|
+
constructor(brain?: Brainy);
|
|
31
|
+
/**
|
|
32
|
+
* Initialize the VFS
|
|
33
|
+
*/
|
|
34
|
+
init(config?: VFSConfig): Promise<void>;
|
|
35
|
+
/**
|
|
36
|
+
* Create or find the root directory entity
|
|
37
|
+
*/
|
|
38
|
+
private initializeRoot;
|
|
39
|
+
/**
|
|
40
|
+
* Read a file's content
|
|
41
|
+
*/
|
|
42
|
+
readFile(path: string, options?: ReadOptions): Promise<Buffer>;
|
|
43
|
+
/**
|
|
44
|
+
* Write a file
|
|
45
|
+
*/
|
|
46
|
+
writeFile(path: string, data: Buffer | string, options?: WriteOptions): Promise<void>;
|
|
47
|
+
/**
|
|
48
|
+
* Append to a file
|
|
49
|
+
*/
|
|
50
|
+
appendFile(path: string, data: Buffer | string, options?: WriteOptions): Promise<void>;
|
|
51
|
+
/**
|
|
52
|
+
* Delete a file
|
|
53
|
+
*/
|
|
54
|
+
unlink(path: string): Promise<void>;
|
|
55
|
+
/**
|
|
56
|
+
* Create a directory
|
|
57
|
+
*/
|
|
58
|
+
mkdir(path: string, options?: MkdirOptions): Promise<void>;
|
|
59
|
+
/**
|
|
60
|
+
* Remove a directory
|
|
61
|
+
*/
|
|
62
|
+
rmdir(path: string, options?: {
|
|
63
|
+
recursive?: boolean;
|
|
64
|
+
}): Promise<void>;
|
|
65
|
+
/**
|
|
66
|
+
* Read directory contents
|
|
67
|
+
*/
|
|
68
|
+
readdir(path: string, options?: ReaddirOptions): Promise<string[] | VFSDirent[]>;
|
|
69
|
+
/**
|
|
70
|
+
* Get file/directory statistics
|
|
71
|
+
*/
|
|
72
|
+
stat(path: string): Promise<VFSStats>;
|
|
73
|
+
/**
|
|
74
|
+
* lstat - same as stat for now (symlinks not fully implemented)
|
|
75
|
+
*/
|
|
76
|
+
lstat(path: string): Promise<VFSStats>;
|
|
77
|
+
/**
|
|
78
|
+
* Check if path exists
|
|
79
|
+
*/
|
|
80
|
+
exists(path: string): Promise<boolean>;
|
|
81
|
+
/**
|
|
82
|
+
* Search files with natural language
|
|
83
|
+
*/
|
|
84
|
+
search(query: string, options?: SearchOptions): Promise<SearchResult[]>;
|
|
85
|
+
/**
|
|
86
|
+
* Find files similar to a given file
|
|
87
|
+
*/
|
|
88
|
+
findSimilar(path: string, options?: SimilarOptions): Promise<SearchResult[]>;
|
|
89
|
+
private ensureInitialized;
|
|
90
|
+
private ensureDirectory;
|
|
91
|
+
getEntityById(id: string): Promise<VFSEntity>;
|
|
92
|
+
private getParentPath;
|
|
93
|
+
private getBasename;
|
|
94
|
+
private getExtension;
|
|
95
|
+
private detectMimeType;
|
|
96
|
+
private isTextFile;
|
|
97
|
+
private getFileNounType;
|
|
98
|
+
private shouldCompress;
|
|
99
|
+
private readExternalContent;
|
|
100
|
+
private storeExternalContent;
|
|
101
|
+
private deleteExternalContent;
|
|
102
|
+
private readChunkedContent;
|
|
103
|
+
private storeChunkedContent;
|
|
104
|
+
private deleteChunkedContent;
|
|
105
|
+
private compress;
|
|
106
|
+
private decompress;
|
|
107
|
+
private generateEmbedding;
|
|
108
|
+
private extractMetadata;
|
|
109
|
+
private updateAccessTime;
|
|
110
|
+
private countRelationships;
|
|
111
|
+
private filterDirectoryEntries;
|
|
112
|
+
private sortDirectoryEntries;
|
|
113
|
+
private matchGlob;
|
|
114
|
+
private invalidateCaches;
|
|
115
|
+
private triggerWatchers;
|
|
116
|
+
private updateChildrenPaths;
|
|
117
|
+
private startBackgroundTasks;
|
|
118
|
+
private getDefaultConfig;
|
|
119
|
+
close(): Promise<void>;
|
|
120
|
+
chmod(path: string, mode: number): Promise<void>;
|
|
121
|
+
chown(path: string, uid: number, gid: number): Promise<void>;
|
|
122
|
+
utimes(path: string, atime: Date, mtime: Date): Promise<void>;
|
|
123
|
+
rename(oldPath: string, newPath: string): Promise<void>;
|
|
124
|
+
copy(src: string, dest: string, options?: CopyOptions): Promise<void>;
|
|
125
|
+
private copyFile;
|
|
126
|
+
private copyDirectory;
|
|
127
|
+
move(src: string, dest: string): Promise<void>;
|
|
128
|
+
symlink(target: string, path: string): Promise<void>;
|
|
129
|
+
readlink(path: string): Promise<string>;
|
|
130
|
+
realpath(path: string): Promise<string>;
|
|
131
|
+
getxattr(path: string, name: string): Promise<any>;
|
|
132
|
+
setxattr(path: string, name: string, value: any): Promise<void>;
|
|
133
|
+
listxattr(path: string): Promise<string[]>;
|
|
134
|
+
removexattr(path: string, name: string): Promise<void>;
|
|
135
|
+
getRelated(path: string, options?: RelatedOptions): Promise<Array<{
|
|
136
|
+
path: string;
|
|
137
|
+
relationship: string;
|
|
138
|
+
direction: 'from' | 'to';
|
|
139
|
+
}>>;
|
|
140
|
+
getRelationships(path: string): Promise<Relation[]>;
|
|
141
|
+
addRelationship(from: string, to: string, type: string): Promise<void>;
|
|
142
|
+
removeRelationship(from: string, to: string, type?: string): Promise<void>;
|
|
143
|
+
getTodos(path: string): Promise<VFSMetadata['todos']>;
|
|
144
|
+
setTodos(path: string, todos: VFSTodo[]): Promise<void>;
|
|
145
|
+
addTodo(path: string, todo: VFSTodo): Promise<void>;
|
|
146
|
+
/**
|
|
147
|
+
* Get metadata for a file or directory
|
|
148
|
+
*/
|
|
149
|
+
getMetadata(path: string): Promise<VFSMetadata | undefined>;
|
|
150
|
+
/**
|
|
151
|
+
* Set custom metadata for a file or directory
|
|
152
|
+
* Merges with existing metadata
|
|
153
|
+
*/
|
|
154
|
+
setMetadata(path: string, metadata: Partial<VFSMetadata>): Promise<void>;
|
|
155
|
+
/**
|
|
156
|
+
* Enable Knowledge Layer on this VFS instance
|
|
157
|
+
*/
|
|
158
|
+
enableKnowledgeLayer(): Promise<void>;
|
|
159
|
+
/**
|
|
160
|
+
* Set the current user for tracking who makes changes
|
|
161
|
+
*/
|
|
162
|
+
setUser(username: string): void;
|
|
163
|
+
/**
|
|
164
|
+
* Get the current user
|
|
165
|
+
*/
|
|
166
|
+
getCurrentUser(): string;
|
|
167
|
+
/**
|
|
168
|
+
* Get all todos recursively from a path
|
|
169
|
+
*/
|
|
170
|
+
getAllTodos(path?: string): Promise<VFSTodo[]>;
|
|
171
|
+
/**
|
|
172
|
+
* Export directory structure to JSON
|
|
173
|
+
*/
|
|
174
|
+
exportToJSON(path?: string): Promise<any>;
|
|
175
|
+
/**
|
|
176
|
+
* Search for entities with filters
|
|
177
|
+
*/
|
|
178
|
+
searchEntities(query: {
|
|
179
|
+
type?: string;
|
|
180
|
+
name?: string;
|
|
181
|
+
where?: Record<string, any>;
|
|
182
|
+
limit?: number;
|
|
183
|
+
}): Promise<Array<{
|
|
184
|
+
id: string;
|
|
185
|
+
path: string;
|
|
186
|
+
type: string;
|
|
187
|
+
metadata: any;
|
|
188
|
+
}>>;
|
|
189
|
+
/**
|
|
190
|
+
* Bulk write operations for performance
|
|
191
|
+
*/
|
|
192
|
+
bulkWrite(operations: Array<{
|
|
193
|
+
type: 'write' | 'delete' | 'mkdir' | 'update';
|
|
194
|
+
path: string;
|
|
195
|
+
data?: Buffer | string;
|
|
196
|
+
options?: any;
|
|
197
|
+
}>): Promise<{
|
|
198
|
+
successful: number;
|
|
199
|
+
failed: Array<{
|
|
200
|
+
operation: any;
|
|
201
|
+
error: string;
|
|
202
|
+
}>;
|
|
203
|
+
}>;
|
|
204
|
+
/**
|
|
205
|
+
* Get project statistics for a path
|
|
206
|
+
*/
|
|
207
|
+
getProjectStats(path?: string): Promise<{
|
|
208
|
+
fileCount: number;
|
|
209
|
+
directoryCount: number;
|
|
210
|
+
totalSize: number;
|
|
211
|
+
todoCount: number;
|
|
212
|
+
averageFileSize: number;
|
|
213
|
+
largestFile: {
|
|
214
|
+
path: string;
|
|
215
|
+
size: number;
|
|
216
|
+
} | null;
|
|
217
|
+
modifiedRange: {
|
|
218
|
+
earliest: Date;
|
|
219
|
+
latest: Date;
|
|
220
|
+
} | null;
|
|
221
|
+
}>;
|
|
222
|
+
/**
|
|
223
|
+
* Get all versions of a file (semantic versioning)
|
|
224
|
+
*/
|
|
225
|
+
createReadStream(path: string, options?: ReadStreamOptions): NodeJS.ReadableStream;
|
|
226
|
+
createWriteStream(path: string, options?: WriteStreamOptions): NodeJS.WritableStream;
|
|
227
|
+
watch(path: string, listener: WatchListener): {
|
|
228
|
+
close(): void;
|
|
229
|
+
};
|
|
230
|
+
/**
|
|
231
|
+
* Import a single file from the real filesystem into VFS
|
|
232
|
+
*/
|
|
233
|
+
importFile(sourcePath: string, targetPath: string): Promise<void>;
|
|
234
|
+
/**
|
|
235
|
+
* Import a directory from the real filesystem into VFS
|
|
236
|
+
*/
|
|
237
|
+
importDirectory(sourcePath: string, options?: any): Promise<any>;
|
|
238
|
+
/**
|
|
239
|
+
* Import a directory with progress tracking
|
|
240
|
+
*/
|
|
241
|
+
importStream(sourcePath: string, options?: any): AsyncGenerator<any>;
|
|
242
|
+
watchFile(path: string, listener: WatchListener): void;
|
|
243
|
+
unwatchFile(path: string): void;
|
|
244
|
+
getEntity(path: string): Promise<VFSEntity>;
|
|
245
|
+
resolvePath(path: string, from?: string): Promise<string>;
|
|
246
|
+
}
|