@soulcraft/brainy 5.12.0 → 6.0.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.
- package/CHANGELOG.md +180 -5
- package/README.md +2 -6
- package/dist/api/DataAPI.d.ts +0 -40
- package/dist/api/DataAPI.js +0 -235
- package/dist/brainy.d.ts +0 -106
- package/dist/brainy.js +0 -370
- package/dist/cli/commands/cow.d.ts +1 -9
- package/dist/cli/commands/cow.js +1 -61
- package/dist/cli/commands/data.d.ts +1 -13
- package/dist/cli/commands/data.js +1 -74
- package/dist/cli/index.js +1 -16
- package/dist/neural/embeddedTypeEmbeddings.d.ts +1 -1
- package/dist/neural/embeddedTypeEmbeddings.js +2 -2
- package/dist/storage/adapters/azureBlobStorage.js +2 -1
- package/dist/storage/adapters/fileSystemStorage.js +2 -1
- package/dist/storage/adapters/gcsStorage.js +2 -1
- package/dist/storage/adapters/historicalStorageAdapter.js +2 -2
- package/dist/storage/adapters/memoryStorage.d.ts +1 -1
- package/dist/storage/adapters/memoryStorage.js +9 -11
- package/dist/storage/adapters/opfsStorage.js +2 -1
- package/dist/storage/adapters/r2Storage.js +2 -1
- package/dist/storage/adapters/s3CompatibleStorage.js +2 -1
- package/dist/storage/baseStorage.d.ts +40 -24
- package/dist/storage/baseStorage.js +490 -557
- package/dist/vfs/VirtualFileSystem.d.ts +46 -24
- package/dist/vfs/VirtualFileSystem.js +153 -146
- package/package.json +1 -1
package/dist/brainy.js
CHANGED
|
@@ -2442,368 +2442,6 @@ export class Brainy {
|
|
|
2442
2442
|
console.log(`[asOf] Snapshot ready (lazy-loading, cache size: ${options?.cacheSize || 10000})`);
|
|
2443
2443
|
return snapshotBrain;
|
|
2444
2444
|
}
|
|
2445
|
-
/**
|
|
2446
|
-
* Merge a source branch into target branch
|
|
2447
|
-
* @param sourceBranch - Branch to merge from
|
|
2448
|
-
* @param targetBranch - Branch to merge into
|
|
2449
|
-
* @param options - Merge options (strategy, author, onConflict)
|
|
2450
|
-
* @returns Merge result with statistics
|
|
2451
|
-
*
|
|
2452
|
-
* @example
|
|
2453
|
-
* ```typescript
|
|
2454
|
-
* const result = await brain.merge('experiment', 'main', {
|
|
2455
|
-
* strategy: 'last-write-wins',
|
|
2456
|
-
* author: 'dev@example.com'
|
|
2457
|
-
* })
|
|
2458
|
-
* console.log(result) // { added: 5, modified: 3, deleted: 1, conflicts: 0 }
|
|
2459
|
-
* ```
|
|
2460
|
-
*/
|
|
2461
|
-
async merge(sourceBranch, targetBranch, options) {
|
|
2462
|
-
await this.ensureInitialized();
|
|
2463
|
-
return this.augmentationRegistry.execute('merge', { sourceBranch, targetBranch, options }, async () => {
|
|
2464
|
-
if (!('refManager' in this.storage) || !('blobStorage' in this.storage)) {
|
|
2465
|
-
throw new Error('Merge requires COW-enabled storage (v5.0.0+)');
|
|
2466
|
-
}
|
|
2467
|
-
const strategy = options?.strategy || 'last-write-wins';
|
|
2468
|
-
let added = 0;
|
|
2469
|
-
let modified = 0;
|
|
2470
|
-
let deleted = 0;
|
|
2471
|
-
let conflicts = 0;
|
|
2472
|
-
// Verify both branches exist
|
|
2473
|
-
const branches = await this.listBranches();
|
|
2474
|
-
if (!branches.includes(sourceBranch)) {
|
|
2475
|
-
throw new Error(`Source branch '${sourceBranch}' does not exist`);
|
|
2476
|
-
}
|
|
2477
|
-
if (!branches.includes(targetBranch)) {
|
|
2478
|
-
throw new Error(`Target branch '${targetBranch}' does not exist`);
|
|
2479
|
-
}
|
|
2480
|
-
// 1. Create temporary fork of source branch to read from
|
|
2481
|
-
const sourceFork = await this.fork(`${sourceBranch}-merge-temp-${Date.now()}`);
|
|
2482
|
-
await sourceFork.checkout(sourceBranch);
|
|
2483
|
-
// 2. Save current branch and checkout target
|
|
2484
|
-
const currentBranch = await this.getCurrentBranch();
|
|
2485
|
-
if (currentBranch !== targetBranch) {
|
|
2486
|
-
await this.checkout(targetBranch);
|
|
2487
|
-
}
|
|
2488
|
-
try {
|
|
2489
|
-
// 3. Get all entities from source and target
|
|
2490
|
-
const sourceResults = await sourceFork.find({});
|
|
2491
|
-
const targetResults = await this.find({});
|
|
2492
|
-
// Create maps for faster lookup
|
|
2493
|
-
const targetMap = new Map(targetResults.map(r => [r.entity.id, r.entity]));
|
|
2494
|
-
// 4. Merge entities
|
|
2495
|
-
for (const sourceResult of sourceResults) {
|
|
2496
|
-
const sourceEntity = sourceResult.entity;
|
|
2497
|
-
const targetEntity = targetMap.get(sourceEntity.id);
|
|
2498
|
-
if (!targetEntity) {
|
|
2499
|
-
// NEW entity in source - ADD to target
|
|
2500
|
-
await this.add({
|
|
2501
|
-
id: sourceEntity.id,
|
|
2502
|
-
type: sourceEntity.type,
|
|
2503
|
-
data: sourceEntity.data,
|
|
2504
|
-
vector: sourceEntity.vector
|
|
2505
|
-
});
|
|
2506
|
-
added++;
|
|
2507
|
-
}
|
|
2508
|
-
else {
|
|
2509
|
-
// Entity exists in both branches - check for conflicts
|
|
2510
|
-
const sourceTime = sourceEntity.updatedAt || sourceEntity.createdAt || 0;
|
|
2511
|
-
const targetTime = targetEntity.updatedAt || targetEntity.createdAt || 0;
|
|
2512
|
-
// If timestamps are identical, no change needed
|
|
2513
|
-
if (sourceTime === targetTime) {
|
|
2514
|
-
continue;
|
|
2515
|
-
}
|
|
2516
|
-
// Apply merge strategy
|
|
2517
|
-
if (strategy === 'last-write-wins') {
|
|
2518
|
-
if (sourceTime > targetTime) {
|
|
2519
|
-
// Source is newer, update target
|
|
2520
|
-
await this.update({ id: sourceEntity.id, data: sourceEntity.data });
|
|
2521
|
-
modified++;
|
|
2522
|
-
}
|
|
2523
|
-
// else target is newer, keep target
|
|
2524
|
-
}
|
|
2525
|
-
else if (strategy === 'first-write-wins') {
|
|
2526
|
-
if (sourceTime < targetTime) {
|
|
2527
|
-
// Source is older, update target
|
|
2528
|
-
await this.update({ id: sourceEntity.id, data: sourceEntity.data });
|
|
2529
|
-
modified++;
|
|
2530
|
-
}
|
|
2531
|
-
}
|
|
2532
|
-
else if (strategy === 'custom' && options?.onConflict) {
|
|
2533
|
-
// Custom conflict resolution
|
|
2534
|
-
const resolved = await options.onConflict(targetEntity, sourceEntity);
|
|
2535
|
-
await this.update({ id: sourceEntity.id, data: resolved.data });
|
|
2536
|
-
modified++;
|
|
2537
|
-
conflicts++;
|
|
2538
|
-
}
|
|
2539
|
-
else {
|
|
2540
|
-
// Conflict detected but no resolution strategy
|
|
2541
|
-
conflicts++;
|
|
2542
|
-
}
|
|
2543
|
-
}
|
|
2544
|
-
}
|
|
2545
|
-
// 5. Merge relationships (verbs)
|
|
2546
|
-
const sourceVerbsResult = await sourceFork.storage.getVerbs({});
|
|
2547
|
-
const targetVerbsResult = await this.storage.getVerbs({});
|
|
2548
|
-
const sourceVerbs = sourceVerbsResult.items || [];
|
|
2549
|
-
const targetVerbs = targetVerbsResult.items || [];
|
|
2550
|
-
// Create set of existing target relationships for deduplication
|
|
2551
|
-
const targetRelSet = new Set(targetVerbs.map((v) => `${v.sourceId}-${v.verb}-${v.targetId}`));
|
|
2552
|
-
// Add relationships that don't exist in target
|
|
2553
|
-
for (const sourceVerb of sourceVerbs) {
|
|
2554
|
-
const key = `${sourceVerb.sourceId}-${sourceVerb.verb}-${sourceVerb.targetId}`;
|
|
2555
|
-
if (!targetRelSet.has(key)) {
|
|
2556
|
-
// Only add if both entities exist in target
|
|
2557
|
-
const hasSource = targetMap.has(sourceVerb.sourceId);
|
|
2558
|
-
const hasTarget = targetMap.has(sourceVerb.targetId);
|
|
2559
|
-
if (hasSource && hasTarget) {
|
|
2560
|
-
await this.relate({
|
|
2561
|
-
from: sourceVerb.sourceId,
|
|
2562
|
-
to: sourceVerb.targetId,
|
|
2563
|
-
type: sourceVerb.verb,
|
|
2564
|
-
weight: sourceVerb.weight,
|
|
2565
|
-
metadata: sourceVerb.metadata
|
|
2566
|
-
});
|
|
2567
|
-
}
|
|
2568
|
-
}
|
|
2569
|
-
}
|
|
2570
|
-
// 6. Create merge commit
|
|
2571
|
-
if ('commitLog' in this.storage) {
|
|
2572
|
-
await this.commit({
|
|
2573
|
-
message: `Merge ${sourceBranch} into ${targetBranch}`,
|
|
2574
|
-
author: options?.author || 'system',
|
|
2575
|
-
metadata: {
|
|
2576
|
-
mergeType: 'branch',
|
|
2577
|
-
source: sourceBranch,
|
|
2578
|
-
target: targetBranch,
|
|
2579
|
-
strategy,
|
|
2580
|
-
stats: { added, modified, deleted, conflicts }
|
|
2581
|
-
}
|
|
2582
|
-
});
|
|
2583
|
-
}
|
|
2584
|
-
}
|
|
2585
|
-
finally {
|
|
2586
|
-
// 7. Clean up temporary fork (just delete the temp branch)
|
|
2587
|
-
try {
|
|
2588
|
-
const tempBranchName = `${sourceBranch}-merge-temp-${Date.now()}`;
|
|
2589
|
-
const branches = await this.listBranches();
|
|
2590
|
-
if (branches.includes(tempBranchName)) {
|
|
2591
|
-
await this.deleteBranch(tempBranchName);
|
|
2592
|
-
}
|
|
2593
|
-
}
|
|
2594
|
-
catch (err) {
|
|
2595
|
-
// Ignore cleanup errors
|
|
2596
|
-
}
|
|
2597
|
-
// Restore original branch if needed
|
|
2598
|
-
if (currentBranch !== targetBranch) {
|
|
2599
|
-
await this.checkout(currentBranch);
|
|
2600
|
-
}
|
|
2601
|
-
}
|
|
2602
|
-
return { added, modified, deleted, conflicts };
|
|
2603
|
-
});
|
|
2604
|
-
}
|
|
2605
|
-
/**
|
|
2606
|
-
* Compare differences between two branches (like git diff)
|
|
2607
|
-
* @param sourceBranch - Branch to compare from (defaults to current branch)
|
|
2608
|
-
* @param targetBranch - Branch to compare to (defaults to 'main')
|
|
2609
|
-
* @returns Diff result showing added, modified, and deleted entities/relationships
|
|
2610
|
-
*
|
|
2611
|
-
* @example
|
|
2612
|
-
* ```typescript
|
|
2613
|
-
* // Compare current branch with main
|
|
2614
|
-
* const diff = await brain.diff()
|
|
2615
|
-
*
|
|
2616
|
-
* // Compare two specific branches
|
|
2617
|
-
* const diff = await brain.diff('experiment', 'main')
|
|
2618
|
-
* console.log(diff)
|
|
2619
|
-
* // {
|
|
2620
|
-
* // entities: { added: 5, modified: 3, deleted: 1 },
|
|
2621
|
-
* // relationships: { added: 10, modified: 2, deleted: 0 }
|
|
2622
|
-
* // }
|
|
2623
|
-
* ```
|
|
2624
|
-
*/
|
|
2625
|
-
async diff(sourceBranch, targetBranch) {
|
|
2626
|
-
await this.ensureInitialized();
|
|
2627
|
-
return this.augmentationRegistry.execute('diff', { sourceBranch, targetBranch }, async () => {
|
|
2628
|
-
// Default branches
|
|
2629
|
-
const source = sourceBranch || (await this.getCurrentBranch());
|
|
2630
|
-
const target = targetBranch || 'main';
|
|
2631
|
-
const currentBranch = await this.getCurrentBranch();
|
|
2632
|
-
// If source is current branch, use this instance directly (no fork needed)
|
|
2633
|
-
let sourceFork;
|
|
2634
|
-
let sourceForkCreated = false;
|
|
2635
|
-
if (source === currentBranch) {
|
|
2636
|
-
sourceFork = this;
|
|
2637
|
-
}
|
|
2638
|
-
else {
|
|
2639
|
-
sourceFork = await this.fork(`temp-diff-source-${Date.now()}`);
|
|
2640
|
-
sourceForkCreated = true;
|
|
2641
|
-
try {
|
|
2642
|
-
await sourceFork.checkout(source);
|
|
2643
|
-
}
|
|
2644
|
-
catch (err) {
|
|
2645
|
-
// If checkout fails, branch may not exist - just use current state
|
|
2646
|
-
}
|
|
2647
|
-
}
|
|
2648
|
-
// If target is current branch, use this instance directly (no fork needed)
|
|
2649
|
-
let targetFork;
|
|
2650
|
-
let targetForkCreated = false;
|
|
2651
|
-
if (target === currentBranch) {
|
|
2652
|
-
targetFork = this;
|
|
2653
|
-
}
|
|
2654
|
-
else {
|
|
2655
|
-
targetFork = await this.fork(`temp-diff-target-${Date.now()}`);
|
|
2656
|
-
targetForkCreated = true;
|
|
2657
|
-
try {
|
|
2658
|
-
await targetFork.checkout(target);
|
|
2659
|
-
}
|
|
2660
|
-
catch (err) {
|
|
2661
|
-
// If checkout fails, branch may not exist - just use current state
|
|
2662
|
-
}
|
|
2663
|
-
}
|
|
2664
|
-
try {
|
|
2665
|
-
// Get all entities from both branches
|
|
2666
|
-
const sourceResults = await sourceFork.find({});
|
|
2667
|
-
const targetResults = await targetFork.find({});
|
|
2668
|
-
// Create maps for lookup
|
|
2669
|
-
const sourceMap = new Map(sourceResults.map(r => [r.entity.id, r.entity]));
|
|
2670
|
-
const targetMap = new Map(targetResults.map(r => [r.entity.id, r.entity]));
|
|
2671
|
-
// Track differences
|
|
2672
|
-
const entitiesAdded = [];
|
|
2673
|
-
const entitiesModified = [];
|
|
2674
|
-
const entitiesDeleted = [];
|
|
2675
|
-
// Find added and modified entities
|
|
2676
|
-
for (const [id, sourceEntity] of sourceMap.entries()) {
|
|
2677
|
-
const targetEntity = targetMap.get(id);
|
|
2678
|
-
if (!targetEntity) {
|
|
2679
|
-
// Entity exists in source but not target = ADDED
|
|
2680
|
-
entitiesAdded.push({
|
|
2681
|
-
id: sourceEntity.id,
|
|
2682
|
-
type: sourceEntity.type,
|
|
2683
|
-
data: sourceEntity.data
|
|
2684
|
-
});
|
|
2685
|
-
}
|
|
2686
|
-
else {
|
|
2687
|
-
// Entity exists in both - check for modifications
|
|
2688
|
-
const changes = [];
|
|
2689
|
-
if (sourceEntity.data !== targetEntity.data) {
|
|
2690
|
-
changes.push('data');
|
|
2691
|
-
}
|
|
2692
|
-
if ((sourceEntity.updatedAt || 0) !== (targetEntity.updatedAt || 0)) {
|
|
2693
|
-
changes.push('updatedAt');
|
|
2694
|
-
}
|
|
2695
|
-
if (changes.length > 0) {
|
|
2696
|
-
entitiesModified.push({
|
|
2697
|
-
id: sourceEntity.id,
|
|
2698
|
-
type: sourceEntity.type,
|
|
2699
|
-
changes
|
|
2700
|
-
});
|
|
2701
|
-
}
|
|
2702
|
-
}
|
|
2703
|
-
}
|
|
2704
|
-
// Find deleted entities (in target but not in source)
|
|
2705
|
-
for (const [id, targetEntity] of targetMap.entries()) {
|
|
2706
|
-
if (!sourceMap.has(id)) {
|
|
2707
|
-
entitiesDeleted.push({
|
|
2708
|
-
id: targetEntity.id,
|
|
2709
|
-
type: targetEntity.type
|
|
2710
|
-
});
|
|
2711
|
-
}
|
|
2712
|
-
}
|
|
2713
|
-
// Compare relationships
|
|
2714
|
-
const sourceVerbsResult = await sourceFork.storage.getVerbs({});
|
|
2715
|
-
const targetVerbsResult = await targetFork.storage.getVerbs({});
|
|
2716
|
-
const sourceVerbs = sourceVerbsResult.items || [];
|
|
2717
|
-
const targetVerbs = targetVerbsResult.items || [];
|
|
2718
|
-
const sourceRelMap = new Map(sourceVerbs.map((v) => [`${v.sourceId}-${v.verb}-${v.targetId}`, v]));
|
|
2719
|
-
const targetRelMap = new Map(targetVerbs.map((v) => [`${v.sourceId}-${v.verb}-${v.targetId}`, v]));
|
|
2720
|
-
const relationshipsAdded = [];
|
|
2721
|
-
const relationshipsModified = [];
|
|
2722
|
-
const relationshipsDeleted = [];
|
|
2723
|
-
// Find added and modified relationships
|
|
2724
|
-
for (const [key, sourceVerb] of sourceRelMap.entries()) {
|
|
2725
|
-
const targetVerb = targetRelMap.get(key);
|
|
2726
|
-
if (!targetVerb) {
|
|
2727
|
-
// Relationship exists in source but not target = ADDED
|
|
2728
|
-
relationshipsAdded.push({
|
|
2729
|
-
from: sourceVerb.sourceId,
|
|
2730
|
-
to: sourceVerb.targetId,
|
|
2731
|
-
type: sourceVerb.verb
|
|
2732
|
-
});
|
|
2733
|
-
}
|
|
2734
|
-
else {
|
|
2735
|
-
// Relationship exists in both - check for modifications
|
|
2736
|
-
const changes = [];
|
|
2737
|
-
if ((sourceVerb.weight || 0) !== (targetVerb.weight || 0)) {
|
|
2738
|
-
changes.push('weight');
|
|
2739
|
-
}
|
|
2740
|
-
if (JSON.stringify(sourceVerb.metadata) !== JSON.stringify(targetVerb.metadata)) {
|
|
2741
|
-
changes.push('metadata');
|
|
2742
|
-
}
|
|
2743
|
-
if (changes.length > 0) {
|
|
2744
|
-
relationshipsModified.push({
|
|
2745
|
-
from: sourceVerb.sourceId,
|
|
2746
|
-
to: sourceVerb.targetId,
|
|
2747
|
-
type: sourceVerb.verb,
|
|
2748
|
-
changes
|
|
2749
|
-
});
|
|
2750
|
-
}
|
|
2751
|
-
}
|
|
2752
|
-
}
|
|
2753
|
-
// Find deleted relationships
|
|
2754
|
-
for (const [key, targetVerb] of targetRelMap.entries()) {
|
|
2755
|
-
if (!sourceRelMap.has(key)) {
|
|
2756
|
-
relationshipsDeleted.push({
|
|
2757
|
-
from: targetVerb.sourceId,
|
|
2758
|
-
to: targetVerb.targetId,
|
|
2759
|
-
type: targetVerb.verb
|
|
2760
|
-
});
|
|
2761
|
-
}
|
|
2762
|
-
}
|
|
2763
|
-
return {
|
|
2764
|
-
entities: {
|
|
2765
|
-
added: entitiesAdded,
|
|
2766
|
-
modified: entitiesModified,
|
|
2767
|
-
deleted: entitiesDeleted
|
|
2768
|
-
},
|
|
2769
|
-
relationships: {
|
|
2770
|
-
added: relationshipsAdded,
|
|
2771
|
-
modified: relationshipsModified,
|
|
2772
|
-
deleted: relationshipsDeleted
|
|
2773
|
-
},
|
|
2774
|
-
summary: {
|
|
2775
|
-
entitiesAdded: entitiesAdded.length,
|
|
2776
|
-
entitiesModified: entitiesModified.length,
|
|
2777
|
-
entitiesDeleted: entitiesDeleted.length,
|
|
2778
|
-
relationshipsAdded: relationshipsAdded.length,
|
|
2779
|
-
relationshipsModified: relationshipsModified.length,
|
|
2780
|
-
relationshipsDeleted: relationshipsDeleted.length
|
|
2781
|
-
}
|
|
2782
|
-
};
|
|
2783
|
-
}
|
|
2784
|
-
finally {
|
|
2785
|
-
// Clean up temporary forks (only if we created them)
|
|
2786
|
-
try {
|
|
2787
|
-
const branches = await this.listBranches();
|
|
2788
|
-
if (sourceForkCreated && sourceFork !== this) {
|
|
2789
|
-
const sourceBranchName = await sourceFork.getCurrentBranch();
|
|
2790
|
-
if (branches.includes(sourceBranchName)) {
|
|
2791
|
-
await this.deleteBranch(sourceBranchName);
|
|
2792
|
-
}
|
|
2793
|
-
}
|
|
2794
|
-
if (targetForkCreated && targetFork !== this) {
|
|
2795
|
-
const targetBranchName = await targetFork.getCurrentBranch();
|
|
2796
|
-
if (branches.includes(targetBranchName)) {
|
|
2797
|
-
await this.deleteBranch(targetBranchName);
|
|
2798
|
-
}
|
|
2799
|
-
}
|
|
2800
|
-
}
|
|
2801
|
-
catch (err) {
|
|
2802
|
-
// Ignore cleanup errors
|
|
2803
|
-
}
|
|
2804
|
-
}
|
|
2805
|
-
});
|
|
2806
|
-
}
|
|
2807
2445
|
/**
|
|
2808
2446
|
* Delete a branch/fork
|
|
2809
2447
|
* @param branch - Branch name to delete
|
|
@@ -3380,14 +3018,6 @@ export class Brainy {
|
|
|
3380
3018
|
await this.ensureInitialized();
|
|
3381
3019
|
return this.metadataIndex.getFieldsForType(nounType);
|
|
3382
3020
|
}
|
|
3383
|
-
/**
|
|
3384
|
-
* Get comprehensive type-field affinity statistics
|
|
3385
|
-
* Useful for understanding data patterns and NLP optimization
|
|
3386
|
-
*/
|
|
3387
|
-
async getTypeFieldAffinityStats() {
|
|
3388
|
-
await this.ensureInitialized();
|
|
3389
|
-
return this.metadataIndex.getTypeFieldAffinityStats();
|
|
3390
|
-
}
|
|
3391
3021
|
/**
|
|
3392
3022
|
* Create a streaming pipeline
|
|
3393
3023
|
*/
|
|
@@ -13,10 +13,6 @@ interface ForkOptions extends CoreOptions {
|
|
|
13
13
|
message?: string;
|
|
14
14
|
author?: string;
|
|
15
15
|
}
|
|
16
|
-
interface MergeOptions extends CoreOptions {
|
|
17
|
-
force?: boolean;
|
|
18
|
-
strategy?: 'last-write-wins' | 'custom';
|
|
19
|
-
}
|
|
20
16
|
interface MigrateOptions extends CoreOptions {
|
|
21
17
|
from?: string;
|
|
22
18
|
to?: string;
|
|
@@ -43,11 +39,7 @@ export declare const cowCommands: {
|
|
|
43
39
|
force?: boolean;
|
|
44
40
|
}): Promise<void>;
|
|
45
41
|
/**
|
|
46
|
-
*
|
|
47
|
-
*/
|
|
48
|
-
merge(source: string | undefined, target: string | undefined, options: MergeOptions): Promise<void>;
|
|
49
|
-
/**
|
|
50
|
-
* Get commit history
|
|
42
|
+
* View commit history
|
|
51
43
|
*/
|
|
52
44
|
history(options: CoreOptions & {
|
|
53
45
|
limit?: string;
|
package/dist/cli/commands/cow.js
CHANGED
|
@@ -215,67 +215,7 @@ ${chalk.cyan('Fork Statistics:')}
|
|
|
215
215
|
}
|
|
216
216
|
},
|
|
217
217
|
/**
|
|
218
|
-
*
|
|
219
|
-
*/
|
|
220
|
-
async merge(source, target, options) {
|
|
221
|
-
let spinner = null;
|
|
222
|
-
try {
|
|
223
|
-
const brain = getBrainy();
|
|
224
|
-
await brain.init();
|
|
225
|
-
// Interactive mode if parameters missing
|
|
226
|
-
if (!source || !target) {
|
|
227
|
-
const branches = await brain.listBranches();
|
|
228
|
-
const currentBranch = await brain.getCurrentBranch();
|
|
229
|
-
const answers = await inquirer.prompt([
|
|
230
|
-
{
|
|
231
|
-
type: 'list',
|
|
232
|
-
name: 'source',
|
|
233
|
-
message: 'Merge FROM branch:',
|
|
234
|
-
choices: branches.map(b => ({ name: b, value: b })),
|
|
235
|
-
when: !source
|
|
236
|
-
},
|
|
237
|
-
{
|
|
238
|
-
type: 'list',
|
|
239
|
-
name: 'target',
|
|
240
|
-
message: 'Merge INTO branch:',
|
|
241
|
-
choices: branches.map(b => ({
|
|
242
|
-
name: b === currentBranch ? `${b} (current)` : b,
|
|
243
|
-
value: b
|
|
244
|
-
})),
|
|
245
|
-
default: currentBranch,
|
|
246
|
-
when: !target
|
|
247
|
-
}
|
|
248
|
-
]);
|
|
249
|
-
source = source || answers.source;
|
|
250
|
-
target = target || answers.target;
|
|
251
|
-
}
|
|
252
|
-
spinner = ora(`Merging ${chalk.cyan(source)} → ${chalk.green(target)}...`).start();
|
|
253
|
-
const result = await brain.merge(source, target, {
|
|
254
|
-
strategy: options.strategy || 'last-write-wins'
|
|
255
|
-
});
|
|
256
|
-
spinner.succeed(`Merged ${chalk.cyan(source)} → ${chalk.green(target)}`);
|
|
257
|
-
console.log(`
|
|
258
|
-
${chalk.cyan('Merge Summary:')}
|
|
259
|
-
${chalk.green('Added:')} ${result.added} entities
|
|
260
|
-
${chalk.yellow('Modified:')} ${result.modified} entities
|
|
261
|
-
${chalk.red('Deleted:')} ${result.deleted} entities
|
|
262
|
-
${chalk.magenta('Conflicts:')} ${result.conflicts} (resolved)
|
|
263
|
-
`.trim());
|
|
264
|
-
if (options.json) {
|
|
265
|
-
formatOutput(result, options);
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
catch (error) {
|
|
269
|
-
if (spinner)
|
|
270
|
-
spinner.fail('Merge failed');
|
|
271
|
-
console.error(chalk.red('Error:'), error.message);
|
|
272
|
-
if (options.verbose)
|
|
273
|
-
console.error(error);
|
|
274
|
-
process.exit(1);
|
|
275
|
-
}
|
|
276
|
-
},
|
|
277
|
-
/**
|
|
278
|
-
* Get commit history
|
|
218
|
+
* View commit history
|
|
279
219
|
*/
|
|
280
220
|
async history(options) {
|
|
281
221
|
try {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Data Management Commands
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* Import, export, and statistics operations
|
|
5
5
|
*/
|
|
6
6
|
interface DataOptions {
|
|
7
7
|
verbose?: boolean;
|
|
@@ -9,18 +9,6 @@ interface DataOptions {
|
|
|
9
9
|
pretty?: boolean;
|
|
10
10
|
}
|
|
11
11
|
export declare const dataCommands: {
|
|
12
|
-
/**
|
|
13
|
-
* Backup database
|
|
14
|
-
*/
|
|
15
|
-
backup(file: string, options: DataOptions & {
|
|
16
|
-
compress?: boolean;
|
|
17
|
-
}): Promise<void>;
|
|
18
|
-
/**
|
|
19
|
-
* Restore from backup
|
|
20
|
-
*/
|
|
21
|
-
restore(file: string, options: DataOptions & {
|
|
22
|
-
merge?: boolean;
|
|
23
|
-
}): Promise<void>;
|
|
24
12
|
/**
|
|
25
13
|
* Get database statistics
|
|
26
14
|
*/
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Data Management Commands
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* Import, export, and statistics operations
|
|
5
5
|
*/
|
|
6
6
|
import chalk from 'chalk';
|
|
7
7
|
import ora from 'ora';
|
|
8
|
-
import { readFileSync, writeFileSync } from 'node:fs';
|
|
9
8
|
import { Brainy } from '../../brainy.js';
|
|
10
9
|
let brainyInstance = null;
|
|
11
10
|
const getBrainy = () => {
|
|
@@ -20,78 +19,6 @@ const formatOutput = (data, options) => {
|
|
|
20
19
|
}
|
|
21
20
|
};
|
|
22
21
|
export const dataCommands = {
|
|
23
|
-
/**
|
|
24
|
-
* Backup database
|
|
25
|
-
*/
|
|
26
|
-
async backup(file, options) {
|
|
27
|
-
const spinner = ora('Creating backup...').start();
|
|
28
|
-
try {
|
|
29
|
-
const brain = getBrainy();
|
|
30
|
-
const dataApi = await brain.data();
|
|
31
|
-
const backup = await dataApi.backup({
|
|
32
|
-
compress: options.compress
|
|
33
|
-
});
|
|
34
|
-
spinner.text = 'Writing backup file...';
|
|
35
|
-
// Write backup to file
|
|
36
|
-
const content = typeof backup === 'string'
|
|
37
|
-
? backup
|
|
38
|
-
: JSON.stringify(backup, null, options.pretty ? 2 : 0);
|
|
39
|
-
writeFileSync(file, content);
|
|
40
|
-
spinner.succeed('Backup created');
|
|
41
|
-
if (!options.json) {
|
|
42
|
-
console.log(chalk.green(`✓ Backup saved to: ${file}`));
|
|
43
|
-
if (backup.compressed) {
|
|
44
|
-
console.log(chalk.dim(` Original size: ${formatBytes(backup.originalSize)}`));
|
|
45
|
-
console.log(chalk.dim(` Compressed size: ${formatBytes(backup.compressedSize)}`));
|
|
46
|
-
console.log(chalk.dim(` Compression ratio: ${((backup.compressedSize / backup.originalSize) * 100).toFixed(1)}%`));
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
else {
|
|
50
|
-
formatOutput({ file, backup: true }, options);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
catch (error) {
|
|
54
|
-
spinner.fail('Backup failed');
|
|
55
|
-
console.error(chalk.red(error.message));
|
|
56
|
-
process.exit(1);
|
|
57
|
-
}
|
|
58
|
-
},
|
|
59
|
-
/**
|
|
60
|
-
* Restore from backup
|
|
61
|
-
*/
|
|
62
|
-
async restore(file, options) {
|
|
63
|
-
const spinner = ora('Restoring from backup...').start();
|
|
64
|
-
try {
|
|
65
|
-
const brain = getBrainy();
|
|
66
|
-
const dataApi = await brain.data();
|
|
67
|
-
// Read backup file
|
|
68
|
-
const content = readFileSync(file, 'utf-8');
|
|
69
|
-
const backup = JSON.parse(content);
|
|
70
|
-
// Restore
|
|
71
|
-
await dataApi.restore({
|
|
72
|
-
backup,
|
|
73
|
-
merge: options.merge || false
|
|
74
|
-
});
|
|
75
|
-
spinner.succeed('Restore complete');
|
|
76
|
-
if (!options.json) {
|
|
77
|
-
console.log(chalk.green(`✓ Restored from: ${file}`));
|
|
78
|
-
if (options.merge) {
|
|
79
|
-
console.log(chalk.dim(' Mode: Merged with existing data'));
|
|
80
|
-
}
|
|
81
|
-
else {
|
|
82
|
-
console.log(chalk.dim(' Mode: Replaced all data'));
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
else {
|
|
86
|
-
formatOutput({ file, restored: true }, options);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
catch (error) {
|
|
90
|
-
spinner.fail('Restore failed');
|
|
91
|
-
console.error(chalk.red(error.message));
|
|
92
|
-
process.exit(1);
|
|
93
|
-
}
|
|
94
|
-
},
|
|
95
22
|
/**
|
|
96
23
|
* Get database statistics
|
|
97
24
|
*/
|
package/dist/cli/index.js
CHANGED
|
@@ -454,16 +454,7 @@ program
|
|
|
454
454
|
storageCommands.costEstimate(options);
|
|
455
455
|
}));
|
|
456
456
|
// ===== Data Management Commands =====
|
|
457
|
-
program
|
|
458
|
-
.command('backup <file>')
|
|
459
|
-
.description('Create database backup')
|
|
460
|
-
.option('--compress', 'Compress backup')
|
|
461
|
-
.action(dataCommands.backup);
|
|
462
|
-
program
|
|
463
|
-
.command('restore <file>')
|
|
464
|
-
.description('Restore from backup')
|
|
465
|
-
.option('--merge', 'Merge with existing data (default: replace)')
|
|
466
|
-
.action(dataCommands.restore);
|
|
457
|
+
program;
|
|
467
458
|
program
|
|
468
459
|
.command('data-stats')
|
|
469
460
|
.description('Show detailed database statistics')
|
|
@@ -551,12 +542,6 @@ program
|
|
|
551
542
|
.alias('co')
|
|
552
543
|
.description('Switch to a different branch')
|
|
553
544
|
.action(cowCommands.checkout);
|
|
554
|
-
program
|
|
555
|
-
.command('merge [source] [target]')
|
|
556
|
-
.description('Merge a fork/branch into another branch')
|
|
557
|
-
.option('--strategy <type>', 'Merge strategy (last-write-wins|custom)', 'last-write-wins')
|
|
558
|
-
.option('-f, --force', 'Force merge on conflicts')
|
|
559
|
-
.action(cowCommands.merge);
|
|
560
545
|
program
|
|
561
546
|
.command('history')
|
|
562
547
|
.alias('log')
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* 🧠 BRAINY EMBEDDED TYPE EMBEDDINGS
|
|
3
3
|
*
|
|
4
4
|
* AUTO-GENERATED - DO NOT EDIT
|
|
5
|
-
* Generated: 2025-11-
|
|
5
|
+
* Generated: 2025-11-19T21:22:15.103Z
|
|
6
6
|
* Noun Types: 42
|
|
7
7
|
* Verb Types: 127
|
|
8
8
|
*
|
|
@@ -15,7 +15,7 @@ export const TYPE_METADATA = {
|
|
|
15
15
|
verbTypes: 127,
|
|
16
16
|
totalTypes: 169,
|
|
17
17
|
embeddingDimensions: 384,
|
|
18
|
-
generatedAt: "2025-11-
|
|
18
|
+
generatedAt: "2025-11-19T21:22:15.103Z",
|
|
19
19
|
sizeBytes: {
|
|
20
20
|
embeddings: 259584,
|
|
21
21
|
base64: 346112
|
|
@@ -238,7 +238,8 @@ export class AzureBlobStorage extends BaseStorage {
|
|
|
238
238
|
this.nounCacheManager.clear();
|
|
239
239
|
this.verbCacheManager.clear();
|
|
240
240
|
prodLog.info('✅ Cache cleared - starting fresh');
|
|
241
|
-
|
|
241
|
+
// v6.0.0: Initialize GraphAdjacencyIndex and type statistics
|
|
242
|
+
await super.init();
|
|
242
243
|
}
|
|
243
244
|
catch (error) {
|
|
244
245
|
this.logger.error('Failed to initialize Azure Blob Storage:', error);
|
|
@@ -174,7 +174,8 @@ export class FileSystemStorage extends BaseStorage {
|
|
|
174
174
|
}
|
|
175
175
|
// Always use fixed depth after migration/detection
|
|
176
176
|
this.cachedShardingDepth = this.SHARDING_DEPTH;
|
|
177
|
-
|
|
177
|
+
// v6.0.0: Initialize GraphAdjacencyIndex and type statistics
|
|
178
|
+
await super.init();
|
|
178
179
|
}
|
|
179
180
|
catch (error) {
|
|
180
181
|
console.error('Error initializing FileSystemStorage:', error);
|