@soulcraft/brainy 4.11.2 → 5.1.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 (44) hide show
  1. package/CHANGELOG.md +271 -0
  2. package/README.md +38 -1
  3. package/dist/augmentations/brainyAugmentation.d.ts +76 -0
  4. package/dist/augmentations/brainyAugmentation.js +126 -0
  5. package/dist/augmentations/cacheAugmentation.js +9 -4
  6. package/dist/brainy.d.ts +248 -15
  7. package/dist/brainy.js +707 -17
  8. package/dist/cli/commands/cow.d.ts +60 -0
  9. package/dist/cli/commands/cow.js +444 -0
  10. package/dist/cli/commands/import.js +1 -1
  11. package/dist/cli/commands/vfs.js +24 -40
  12. package/dist/cli/index.js +50 -0
  13. package/dist/hnsw/hnswIndex.d.ts +41 -0
  14. package/dist/hnsw/hnswIndex.js +96 -1
  15. package/dist/hnsw/typeAwareHNSWIndex.d.ts +9 -0
  16. package/dist/hnsw/typeAwareHNSWIndex.js +22 -0
  17. package/dist/import/ImportHistory.js +3 -3
  18. package/dist/importers/VFSStructureGenerator.d.ts +1 -1
  19. package/dist/importers/VFSStructureGenerator.js +3 -3
  20. package/dist/index.d.ts +6 -0
  21. package/dist/index.js +10 -0
  22. package/dist/storage/adapters/memoryStorage.d.ts +6 -0
  23. package/dist/storage/adapters/memoryStorage.js +39 -14
  24. package/dist/storage/adapters/typeAwareStorageAdapter.d.ts +31 -1
  25. package/dist/storage/adapters/typeAwareStorageAdapter.js +272 -43
  26. package/dist/storage/baseStorage.d.ts +64 -0
  27. package/dist/storage/baseStorage.js +252 -12
  28. package/dist/storage/cow/BlobStorage.d.ts +232 -0
  29. package/dist/storage/cow/BlobStorage.js +437 -0
  30. package/dist/storage/cow/CommitLog.d.ts +199 -0
  31. package/dist/storage/cow/CommitLog.js +363 -0
  32. package/dist/storage/cow/CommitObject.d.ts +276 -0
  33. package/dist/storage/cow/CommitObject.js +431 -0
  34. package/dist/storage/cow/RefManager.d.ts +213 -0
  35. package/dist/storage/cow/RefManager.js +409 -0
  36. package/dist/storage/cow/TreeObject.d.ts +177 -0
  37. package/dist/storage/cow/TreeObject.js +293 -0
  38. package/dist/storage/storageFactory.d.ts +6 -0
  39. package/dist/storage/storageFactory.js +92 -74
  40. package/dist/types/brainy.types.d.ts +1 -0
  41. package/dist/vfs/FSCompat.d.ts +1 -1
  42. package/dist/vfs/FSCompat.js +1 -1
  43. package/dist/vfs/VirtualFileSystem.js +5 -6
  44. package/package.json +1 -1
@@ -0,0 +1,363 @@
1
+ /**
2
+ * CommitLog: Commit history traversal and querying for COW (Copy-on-Write)
3
+ *
4
+ * Provides efficient commit history operations:
5
+ * - Walk commit graph (DAG traversal)
6
+ * - Find commits by time, author, operation
7
+ * - Time-travel queries (asOf)
8
+ * - Commit statistics and analytics
9
+ *
10
+ * Optimizations:
11
+ * - Commit index for fast timestamp lookups
12
+ * - Parent cache for efficient traversal
13
+ * - Lazy loading (only read commits when needed)
14
+ *
15
+ * @module storage/cow/CommitLog
16
+ */
17
+ import { CommitObject } from './CommitObject.js';
18
+ /**
19
+ * CommitLog: Efficient commit history traversal and querying
20
+ *
21
+ * Pure v5.0.0 implementation - modern, clean, fast
22
+ */
23
+ export class CommitLog {
24
+ constructor(blobStorage, refManager) {
25
+ this.blobStorage = blobStorage;
26
+ this.refManager = refManager;
27
+ this.index = new Map();
28
+ this.indexValid = false;
29
+ }
30
+ /**
31
+ * Walk commit history from a starting point
32
+ *
33
+ * Yields commits in reverse chronological order (newest first)
34
+ *
35
+ * @param startRef - Starting ref/commit (e.g., 'main', commit hash)
36
+ * @param options - Walk options
37
+ */
38
+ async *walk(startRef = 'main', options) {
39
+ // Resolve ref to commit hash
40
+ let startHash;
41
+ if (/^[a-f0-9]{64}$/.test(startRef)) {
42
+ // Already a commit hash
43
+ startHash = startRef;
44
+ }
45
+ else {
46
+ // Resolve ref
47
+ const commitHash = await this.refManager.resolveRef(startRef);
48
+ if (!commitHash) {
49
+ throw new Error(`Ref not found: ${startRef}`);
50
+ }
51
+ startHash = commitHash;
52
+ }
53
+ // Walk using CommitObject (delegates to it)
54
+ yield* CommitObject.walk(this.blobStorage, startHash, options);
55
+ }
56
+ /**
57
+ * Find commit at or before a specific timestamp
58
+ *
59
+ * Uses index for fast O(log n) lookup
60
+ *
61
+ * @param ref - Starting ref (e.g., 'main')
62
+ * @param timestamp - Target timestamp
63
+ * @returns Commit at or before timestamp, or null
64
+ */
65
+ async findAtTime(ref, timestamp) {
66
+ // Build index if needed
67
+ await this.buildIndex(ref);
68
+ // Binary search in index
69
+ const entries = Array.from(this.index.values()).sort((a, b) => b.timestamp - a.timestamp // Newest first
70
+ );
71
+ let left = 0;
72
+ let right = entries.length - 1;
73
+ let result = null;
74
+ while (left <= right) {
75
+ const mid = Math.floor((left + right) / 2);
76
+ const entry = entries[mid];
77
+ if (entry.timestamp <= timestamp) {
78
+ result = entry;
79
+ right = mid - 1; // Look for newer commit
80
+ }
81
+ else {
82
+ left = mid + 1; // Look for older commit
83
+ }
84
+ }
85
+ if (!result) {
86
+ return null;
87
+ }
88
+ // Read full commit
89
+ return CommitObject.read(this.blobStorage, result.hash);
90
+ }
91
+ /**
92
+ * Get commit by hash
93
+ *
94
+ * @param hash - Commit hash
95
+ * @returns Commit object
96
+ */
97
+ async getCommit(hash) {
98
+ return CommitObject.read(this.blobStorage, hash);
99
+ }
100
+ /**
101
+ * Get commits in time range
102
+ *
103
+ * @param ref - Starting ref
104
+ * @param startTime - Start of time range
105
+ * @param endTime - End of time range
106
+ * @returns Array of commits in range (newest first)
107
+ */
108
+ async getInTimeRange(ref, startTime, endTime) {
109
+ const commits = [];
110
+ for await (const commit of this.walk(ref, { until: startTime })) {
111
+ if (commit.timestamp >= startTime && commit.timestamp <= endTime) {
112
+ commits.push(commit);
113
+ }
114
+ }
115
+ return commits;
116
+ }
117
+ /**
118
+ * Get commits by author
119
+ *
120
+ * @param ref - Starting ref
121
+ * @param author - Author name
122
+ * @param options - Additional options
123
+ * @returns Array of commits by author
124
+ */
125
+ async getByAuthor(ref, author, options) {
126
+ const commits = [];
127
+ let count = 0;
128
+ for await (const commit of this.walk(ref, { until: options?.since })) {
129
+ if (commit.author === author) {
130
+ commits.push(commit);
131
+ count++;
132
+ if (options?.maxCount && count >= options.maxCount) {
133
+ break;
134
+ }
135
+ }
136
+ }
137
+ return commits;
138
+ }
139
+ /**
140
+ * Get commits by operation type
141
+ *
142
+ * @param ref - Starting ref
143
+ * @param operation - Operation type (e.g., 'add', 'update', 'delete')
144
+ * @param options - Additional options
145
+ * @returns Array of commits by operation
146
+ */
147
+ async getByOperation(ref, operation, options) {
148
+ const commits = [];
149
+ let count = 0;
150
+ for await (const commit of this.walk(ref, { until: options?.since })) {
151
+ if (commit.metadata?.operation === operation) {
152
+ commits.push(commit);
153
+ count++;
154
+ if (options?.maxCount && count >= options.maxCount) {
155
+ break;
156
+ }
157
+ }
158
+ }
159
+ return commits;
160
+ }
161
+ /**
162
+ * Get commit history as array
163
+ *
164
+ * @param ref - Starting ref
165
+ * @param options - Walk options
166
+ * @returns Array of commits (newest first)
167
+ */
168
+ async getHistory(ref, options) {
169
+ const commits = [];
170
+ let count = 0;
171
+ for await (const commit of this.walk(ref, {
172
+ maxDepth: options?.maxCount,
173
+ until: options?.until
174
+ })) {
175
+ if (options?.since && commit.timestamp < options.since) {
176
+ continue;
177
+ }
178
+ commits.push(commit);
179
+ count++;
180
+ if (options?.maxCount && count >= options.maxCount) {
181
+ break;
182
+ }
183
+ }
184
+ return commits;
185
+ }
186
+ /**
187
+ * Count commits between two commits
188
+ *
189
+ * @param fromRef - Starting ref/commit
190
+ * @param toRef - Ending ref/commit (optional, defaults to fromRef's parent)
191
+ * @returns Number of commits between
192
+ */
193
+ async countBetween(fromRef, toRef) {
194
+ const fromHash = await this.resolveToHash(fromRef);
195
+ const toHash = toRef ? await this.resolveToHash(toRef) : null;
196
+ return CommitObject.countBetween(this.blobStorage, fromHash, toHash);
197
+ }
198
+ /**
199
+ * Find common ancestor of two commits (merge base)
200
+ *
201
+ * @param ref1 - First ref/commit
202
+ * @param ref2 - Second ref/commit
203
+ * @returns Common ancestor commit or null
204
+ */
205
+ async findCommonAncestor(ref1, ref2) {
206
+ const hash1 = await this.resolveToHash(ref1);
207
+ const hash2 = await this.resolveToHash(ref2);
208
+ return CommitObject.findCommonAncestor(this.blobStorage, hash1, hash2);
209
+ }
210
+ /**
211
+ * Get commit log statistics
212
+ *
213
+ * @param ref - Starting ref
214
+ * @param options - Options
215
+ * @returns Commit log statistics
216
+ */
217
+ async getStats(ref = 'main', options) {
218
+ const authors = new Set();
219
+ const operations = new Set();
220
+ const timestamps = [];
221
+ let totalCommits = 0;
222
+ for await (const commit of this.walk(ref, options)) {
223
+ totalCommits++;
224
+ authors.add(commit.author);
225
+ timestamps.push(commit.timestamp);
226
+ if (commit.metadata?.operation) {
227
+ operations.add(commit.metadata.operation);
228
+ }
229
+ }
230
+ // Calculate average interval
231
+ let avgInterval = 0;
232
+ if (timestamps.length > 1) {
233
+ const intervals = [];
234
+ for (let i = 0; i < timestamps.length - 1; i++) {
235
+ intervals.push(timestamps[i] - timestamps[i + 1]);
236
+ }
237
+ avgInterval = intervals.reduce((a, b) => a + b, 0) / intervals.length;
238
+ }
239
+ return {
240
+ totalCommits,
241
+ oldestCommit: timestamps[timestamps.length - 1] ?? 0,
242
+ newestCommit: timestamps[0] ?? 0,
243
+ authors,
244
+ operations,
245
+ avgCommitInterval: avgInterval
246
+ };
247
+ }
248
+ /**
249
+ * Check if commit is ancestor of another commit
250
+ *
251
+ * @param ancestorRef - Potential ancestor ref/commit
252
+ * @param descendantRef - Descendant ref/commit
253
+ * @returns True if ancestor is in descendant's history
254
+ */
255
+ async isAncestor(ancestorRef, descendantRef) {
256
+ const ancestorHash = await this.resolveToHash(ancestorRef);
257
+ const descendantHash = await this.resolveToHash(descendantRef);
258
+ // Walk from descendant, check if we encounter ancestor
259
+ for await (const commit of this.walk(descendantHash)) {
260
+ const commitHash = CommitObject.hash(commit);
261
+ if (commitHash === ancestorHash) {
262
+ return true;
263
+ }
264
+ }
265
+ return false;
266
+ }
267
+ /**
268
+ * Get recent commits (last N)
269
+ *
270
+ * @param ref - Starting ref
271
+ * @param count - Number of commits to retrieve
272
+ * @returns Array of recent commits
273
+ */
274
+ async getRecent(ref, count = 10) {
275
+ return this.getHistory(ref, { maxCount: count });
276
+ }
277
+ /**
278
+ * Find commits with tag
279
+ *
280
+ * @param ref - Starting ref
281
+ * @param tag - Tag to search for
282
+ * @returns Array of commits with tag
283
+ */
284
+ async findWithTag(ref, tag) {
285
+ const commits = [];
286
+ for await (const commit of this.walk(ref)) {
287
+ if (CommitObject.hasTag(commit, tag)) {
288
+ commits.push(commit);
289
+ }
290
+ }
291
+ return commits;
292
+ }
293
+ /**
294
+ * Get first (oldest) commit
295
+ *
296
+ * @param ref - Starting ref
297
+ * @returns Oldest commit
298
+ */
299
+ async getFirstCommit(ref) {
300
+ let oldest = null;
301
+ for await (const commit of this.walk(ref)) {
302
+ oldest = commit;
303
+ }
304
+ return oldest;
305
+ }
306
+ /**
307
+ * Get latest commit
308
+ *
309
+ * @param ref - Starting ref
310
+ * @returns Latest commit
311
+ */
312
+ async getLatestCommit(ref) {
313
+ for await (const commit of this.walk(ref, { maxDepth: 1 })) {
314
+ return commit;
315
+ }
316
+ return null;
317
+ }
318
+ /**
319
+ * Clear index (useful for testing, after new commits)
320
+ */
321
+ clearIndex() {
322
+ this.index.clear();
323
+ this.indexValid = false;
324
+ }
325
+ // ========== PRIVATE METHODS ==========
326
+ /**
327
+ * Build commit index for fast lookups
328
+ *
329
+ * @param ref - Starting ref
330
+ */
331
+ async buildIndex(ref) {
332
+ if (this.indexValid) {
333
+ return; // Already built
334
+ }
335
+ this.index.clear();
336
+ for await (const commit of this.walk(ref)) {
337
+ const hash = CommitObject.hash(commit);
338
+ this.index.set(hash, {
339
+ hash,
340
+ timestamp: commit.timestamp,
341
+ parentHash: commit.parent
342
+ });
343
+ }
344
+ this.indexValid = true;
345
+ }
346
+ /**
347
+ * Resolve ref or hash to commit hash
348
+ *
349
+ * @param refOrHash - Ref name or commit hash
350
+ * @returns Commit hash
351
+ */
352
+ async resolveToHash(refOrHash) {
353
+ if (/^[a-f0-9]{64}$/.test(refOrHash)) {
354
+ return refOrHash; // Already a hash
355
+ }
356
+ const hash = await this.refManager.resolveRef(refOrHash);
357
+ if (!hash) {
358
+ throw new Error(`Ref not found: ${refOrHash}`);
359
+ }
360
+ return hash;
361
+ }
362
+ }
363
+ //# sourceMappingURL=CommitLog.js.map
@@ -0,0 +1,276 @@
1
+ /**
2
+ * CommitObject: Snapshot metadata for COW (Copy-on-Write)
3
+ *
4
+ * Similar to Git commits, represents a point-in-time snapshot of a Brainy instance.
5
+ * Commits reference tree objects and parent commits, forming a directed acyclic graph (DAG).
6
+ *
7
+ * Structure:
8
+ * - tree: hash of root tree object (contains all data)
9
+ * - parent: hash of parent commit (null for initial commit)
10
+ * - message: human-readable commit message
11
+ * - author: who/what created this commit
12
+ * - timestamp: when this commit was created
13
+ * - metadata: additional commit metadata (tags, etc.)
14
+ *
15
+ * @module storage/cow/CommitObject
16
+ */
17
+ import { BlobStorage } from './BlobStorage.js';
18
+ /**
19
+ * Commit object structure
20
+ */
21
+ export interface CommitObject {
22
+ tree: string;
23
+ parent: string | null;
24
+ message: string;
25
+ author: string;
26
+ timestamp: number;
27
+ metadata?: {
28
+ tags?: string[];
29
+ branch?: string;
30
+ operation?: string;
31
+ entityCount?: number;
32
+ relationshipCount?: number;
33
+ [key: string]: any;
34
+ };
35
+ }
36
+ /**
37
+ * CommitBuilder: Fluent API for building commit objects
38
+ *
39
+ * Example:
40
+ * ```typescript
41
+ * const commit = await CommitBuilder.create(blobStorage)
42
+ * .tree(treeHash)
43
+ * .parent(parentHash)
44
+ * .message('Add user entities')
45
+ * .author('system')
46
+ * .tag('v1.0.0')
47
+ * .build()
48
+ * ```
49
+ */
50
+ export declare class CommitBuilder {
51
+ private _tree?;
52
+ private _parent?;
53
+ private _message;
54
+ private _author;
55
+ private _timestamp;
56
+ private _metadata;
57
+ private blobStorage;
58
+ constructor(blobStorage: BlobStorage);
59
+ static create(blobStorage: BlobStorage): CommitBuilder;
60
+ /**
61
+ * Set tree hash
62
+ */
63
+ tree(hash: string): this;
64
+ /**
65
+ * Set parent commit hash (null for initial commit)
66
+ */
67
+ parent(hash: string | null): this;
68
+ /**
69
+ * Set commit message
70
+ */
71
+ message(message: string): this;
72
+ /**
73
+ * Set commit author
74
+ */
75
+ author(author: string): this;
76
+ /**
77
+ * Set commit timestamp (defaults to now)
78
+ */
79
+ timestamp(timestamp: number | Date): this;
80
+ /**
81
+ * Add tag to commit
82
+ */
83
+ tag(tag: string): this;
84
+ /**
85
+ * Set branch name
86
+ */
87
+ branch(branch: string): this;
88
+ /**
89
+ * Set operation type
90
+ */
91
+ operation(operation: string): this;
92
+ /**
93
+ * Set entity count
94
+ */
95
+ entityCount(count: number): this;
96
+ /**
97
+ * Set relationship count
98
+ */
99
+ relationshipCount(count: number): this;
100
+ /**
101
+ * Set custom metadata
102
+ */
103
+ meta(key: string, value: any): this;
104
+ /**
105
+ * Build and persist the commit object
106
+ *
107
+ * @returns Commit hash
108
+ */
109
+ build(): Promise<string>;
110
+ }
111
+ /**
112
+ * CommitObject: Represents a point-in-time snapshot in COW storage
113
+ */
114
+ export declare class CommitObject {
115
+ /**
116
+ * Serialize commit object to Buffer
117
+ *
118
+ * Format: JSON (simple, debuggable)
119
+ * Future: Could use protobuf for efficiency
120
+ *
121
+ * @param commit - Commit object
122
+ * @returns Serialized commit
123
+ */
124
+ static serialize(commit: CommitObject): Buffer;
125
+ /**
126
+ * Deserialize commit object from Buffer
127
+ *
128
+ * @param data - Serialized commit
129
+ * @returns Commit object
130
+ */
131
+ static deserialize(data: Buffer): CommitObject;
132
+ /**
133
+ * Compute hash of commit object
134
+ *
135
+ * @param commit - Commit object
136
+ * @returns SHA-256 hash
137
+ */
138
+ static hash(commit: CommitObject): string;
139
+ /**
140
+ * Write commit object to blob storage
141
+ *
142
+ * @param blobStorage - Blob storage instance
143
+ * @param commit - Commit object
144
+ * @returns Commit hash
145
+ */
146
+ static write(blobStorage: BlobStorage, commit: CommitObject): Promise<string>;
147
+ /**
148
+ * Read commit object from blob storage
149
+ *
150
+ * @param blobStorage - Blob storage instance
151
+ * @param hash - Commit hash
152
+ * @returns Commit object
153
+ */
154
+ static read(blobStorage: BlobStorage, hash: string): Promise<CommitObject>;
155
+ /**
156
+ * Check if commit is initial commit (has no parent)
157
+ *
158
+ * @param commit - Commit object
159
+ * @returns True if initial commit
160
+ */
161
+ static isInitial(commit: CommitObject): boolean;
162
+ /**
163
+ * Check if commit is merge commit (has multiple parents)
164
+ * (Future enhancement: support merge commits with multiple parents)
165
+ *
166
+ * @param commit - Commit object
167
+ * @returns True if merge commit
168
+ */
169
+ static isMerge(commit: CommitObject): boolean;
170
+ /**
171
+ * Check if commit has a specific tag
172
+ *
173
+ * @param commit - Commit object
174
+ * @param tag - Tag to check
175
+ * @returns True if commit has tag
176
+ */
177
+ static hasTag(commit: CommitObject, tag: string): boolean;
178
+ /**
179
+ * Get all tags from commit
180
+ *
181
+ * @param commit - Commit object
182
+ * @returns Array of tags
183
+ */
184
+ static getTags(commit: CommitObject): string[];
185
+ /**
186
+ * Walk commit history (traverse DAG)
187
+ *
188
+ * Yields commits in reverse chronological order (newest first)
189
+ *
190
+ * @param blobStorage - Blob storage instance
191
+ * @param startHash - Starting commit hash
192
+ * @param options - Walk options
193
+ */
194
+ static walk(blobStorage: BlobStorage, startHash: string, options?: {
195
+ maxDepth?: number;
196
+ until?: number;
197
+ stopAt?: string;
198
+ filter?: (commit: CommitObject) => boolean;
199
+ }): AsyncIterableIterator<CommitObject>;
200
+ /**
201
+ * Find commit at or before a specific timestamp
202
+ *
203
+ * @param blobStorage - Blob storage instance
204
+ * @param startHash - Starting commit hash (e.g., 'main' ref)
205
+ * @param timestamp - Target timestamp
206
+ * @returns Commit at or before timestamp, or null if not found
207
+ */
208
+ static findAtTime(blobStorage: BlobStorage, startHash: string, timestamp: number): Promise<CommitObject | null>;
209
+ /**
210
+ * Get commit history as array (newest first)
211
+ *
212
+ * @param blobStorage - Blob storage instance
213
+ * @param startHash - Starting commit hash
214
+ * @param options - Walk options
215
+ * @returns Array of commits
216
+ */
217
+ static getHistory(blobStorage: BlobStorage, startHash: string, options?: {
218
+ maxDepth?: number;
219
+ until?: number;
220
+ stopAt?: string;
221
+ }): Promise<CommitObject[]>;
222
+ /**
223
+ * Find common ancestor of two commits (merge base)
224
+ *
225
+ * Useful for diff/merge operations
226
+ *
227
+ * @param blobStorage - Blob storage instance
228
+ * @param hash1 - First commit hash
229
+ * @param hash2 - Second commit hash
230
+ * @returns Common ancestor commit, or null if not found
231
+ */
232
+ static findCommonAncestor(blobStorage: BlobStorage, hash1: string, hash2: string): Promise<CommitObject | null>;
233
+ /**
234
+ * Count commits between two commits
235
+ *
236
+ * @param blobStorage - Blob storage instance
237
+ * @param fromHash - Starting commit hash
238
+ * @param toHash - Ending commit hash
239
+ * @returns Number of commits between (inclusive)
240
+ */
241
+ static countBetween(blobStorage: BlobStorage, fromHash: string, toHash: string): Promise<number>;
242
+ /**
243
+ * Get commits in time range
244
+ *
245
+ * @param blobStorage - Blob storage instance
246
+ * @param startHash - Starting commit hash
247
+ * @param startTime - Start of time range
248
+ * @param endTime - End of time range
249
+ * @returns Array of commits in range
250
+ */
251
+ static getInTimeRange(blobStorage: BlobStorage, startHash: string, startTime: number, endTime: number): Promise<CommitObject[]>;
252
+ /**
253
+ * Get commits by author
254
+ *
255
+ * @param blobStorage - Blob storage instance
256
+ * @param startHash - Starting commit hash
257
+ * @param author - Author name
258
+ * @param options - Walk options
259
+ * @returns Array of commits by author
260
+ */
261
+ static getByAuthor(blobStorage: BlobStorage, startHash: string, author: string, options?: {
262
+ maxDepth?: number;
263
+ }): Promise<CommitObject[]>;
264
+ /**
265
+ * Get commits by operation type
266
+ *
267
+ * @param blobStorage - Blob storage instance
268
+ * @param startHash - Starting commit hash
269
+ * @param operation - Operation type (e.g., 'add', 'update', 'delete')
270
+ * @param options - Walk options
271
+ * @returns Array of commits by operation
272
+ */
273
+ static getByOperation(blobStorage: BlobStorage, startHash: string, operation: string, options?: {
274
+ maxDepth?: number;
275
+ }): Promise<CommitObject[]>;
276
+ }