@vishal_20/basetree 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (149) hide show
  1. package/.env.example +10 -0
  2. package/README.md +369 -0
  3. package/dist/agents/alignmentAgent.js +68 -0
  4. package/dist/agents/governanceOrchestrator.js +152 -0
  5. package/dist/agents/planet/climateAgent.js +39 -0
  6. package/dist/agents/planet/diplomacyAgent.js +52 -0
  7. package/dist/agents/planet/discoveryAgent.js +41 -0
  8. package/dist/agents/planet/economicAgent.js +64 -0
  9. package/dist/agents/planet/educationAgent.js +41 -0
  10. package/dist/agents/planet/governanceCouncilAgent.js +76 -0
  11. package/dist/agents/planet/healthcareAgent.js +42 -0
  12. package/dist/agents/planet/infrastructureAgent.js +49 -0
  13. package/dist/agents/planet/planetAgent.js +5 -0
  14. package/dist/agents/planet/riskStabilityAgent.js +84 -0
  15. package/dist/agents/planet/urbanSystemsAgent.js +42 -0
  16. package/dist/agents/policyAgent.js +31 -0
  17. package/dist/agents/promptGenomeAgent.js +120 -0
  18. package/dist/agents/reasoningOptimizerAgent.js +72 -0
  19. package/dist/agents/regressionAgent.js +162 -0
  20. package/dist/agents/reinforcementLearnerAgent.js +108 -0
  21. package/dist/agents/riskEvaluationAgent.js +131 -0
  22. package/dist/agents/rollbackAgent.js +53 -0
  23. package/dist/agents/stabilityAgent.js +90 -0
  24. package/dist/agents/strategyMutationAgent.js +74 -0
  25. package/dist/agents/systemIntrospectionAgent.js +274 -0
  26. package/dist/agents/upgradeExecutorAgent.js +146 -0
  27. package/dist/agents/upgradePlannerAgent.js +80 -0
  28. package/dist/agents/venture/businessModelAgent.js +81 -0
  29. package/dist/agents/venture/growthAgent.js +82 -0
  30. package/dist/agents/venture/ideationAgent.js +89 -0
  31. package/dist/agents/venture/investorAgent.js +90 -0
  32. package/dist/agents/venture/legalAgent.js +112 -0
  33. package/dist/agents/venture/marketResearchAgent.js +80 -0
  34. package/dist/agents/venture/productAgent.js +96 -0
  35. package/dist/agents/venture/revenueAgent.js +63 -0
  36. package/dist/agents/venture/validationAgent.js +189 -0
  37. package/dist/bootstrap.js +200 -0
  38. package/dist/cli.js +453 -0
  39. package/dist/cognitiveGraph/cognitiveGraphEngine.js +180 -0
  40. package/dist/cognitiveGraph/graphStore.js +81 -0
  41. package/dist/cognitiveGraph/reasoningStreamBus.js +190 -0
  42. package/dist/config/config.js +76 -0
  43. package/dist/core/agent/AdaptivePlanner.js +49 -0
  44. package/dist/core/agent/AutoFixEngine.js +37 -0
  45. package/dist/core/agent/ExecutorAgent.js +79 -0
  46. package/dist/core/agent/LearningMemoryAgent.js +67 -0
  47. package/dist/core/agent/MemoryAgent.js +35 -0
  48. package/dist/core/agent/MetaCognitionAgent.js +38 -0
  49. package/dist/core/agent/PlannerAgent.js +59 -0
  50. package/dist/core/agent/ReflectionLoop.js +34 -0
  51. package/dist/core/agent/ReviewerAgent.js +34 -0
  52. package/dist/core/agent/VerificationAgent.js +20 -0
  53. package/dist/core/agent/specialists/SpecializedAgents.js +43 -0
  54. package/dist/core/ai/GeminiProvider.js +113 -0
  55. package/dist/core/ai/listModels.js +73 -0
  56. package/dist/core/monitor/PerformanceMonitor.js +18 -0
  57. package/dist/core/swarm/AgentSwarm.js +56 -0
  58. package/dist/core/swarm/ReasoningBus.js +26 -0
  59. package/dist/core/swarm/SwarmOrchestrator.js +36 -0
  60. package/dist/discovery/experimentOrchestrator.js +75 -0
  61. package/dist/discovery/hypothesisEngine.js +79 -0
  62. package/dist/discovery/knowledgeSynthesizer.js +83 -0
  63. package/dist/discovery/simulationPipeline.js +57 -0
  64. package/dist/experiments/experimentationEngine.js +174 -0
  65. package/dist/index.js +67 -0
  66. package/dist/kernel/eventBus.js +89 -0
  67. package/dist/kernel/kernel.js +146 -0
  68. package/dist/llm/tokenEfficiencyOptimizer.js +91 -0
  69. package/dist/memory/civilizationMemory.js +147 -0
  70. package/dist/memory/globalVectorMemory.js +87 -0
  71. package/dist/mesh/crossOrgProtocol.js +110 -0
  72. package/dist/mesh/globalReasoningBus.js +99 -0
  73. package/dist/observability/businessDashboard.js +103 -0
  74. package/dist/observability/businessMetrics.js +105 -0
  75. package/dist/observability/cognitiveMetrics.js +119 -0
  76. package/dist/observability/failureSurfaceMapper.js +135 -0
  77. package/dist/observability/metricsCollector.js +94 -0
  78. package/dist/observability/planetaryDashboard.js +97 -0
  79. package/dist/observability/planetaryMetrics.js +127 -0
  80. package/dist/observability/reportRenderer.js +100 -0
  81. package/dist/performance/memoryProfiler.js +107 -0
  82. package/dist/performance/profiler.js +130 -0
  83. package/dist/pipelines/evolvePipeline.js +150 -0
  84. package/dist/pipelines/governanceReviewPipeline.js +68 -0
  85. package/dist/pipelines/introspectPipeline.js +73 -0
  86. package/dist/pipelines/venture/growPipeline.js +51 -0
  87. package/dist/pipelines/venture/launchPipeline.js +55 -0
  88. package/dist/pipelines/venture/monetizePipeline.js +46 -0
  89. package/dist/pipelines/venture/shutdownPipeline.js +40 -0
  90. package/dist/pipelines/venture/startupPipeline.js +145 -0
  91. package/dist/pipelines/venture/validatePipeline.js +40 -0
  92. package/dist/planet/controlPlane.js +131 -0
  93. package/dist/planet/executionEngine.js +142 -0
  94. package/dist/planet/globalTypes.js +5 -0
  95. package/dist/planet/regionManager.js +114 -0
  96. package/dist/quality/codeQualityAuditor.js +161 -0
  97. package/dist/safety/containmentProtocols.js +87 -0
  98. package/dist/safety/integrityChecker.js +110 -0
  99. package/dist/safety/kernelGuard.js +57 -0
  100. package/dist/safety/killSwitch.js +100 -0
  101. package/dist/safety/planetaryKernel.js +92 -0
  102. package/dist/safety/policyEngine.js +129 -0
  103. package/dist/safety/rollbackManager.js +141 -0
  104. package/dist/safety/sandbox.js +143 -0
  105. package/dist/server/mindmapServer.js +102 -0
  106. package/dist/state/distributedState.js +241 -0
  107. package/dist/state/fileStateStore.js +264 -0
  108. package/dist/state/snapshotter.js +96 -0
  109. package/dist/state/stateStore.js +5 -0
  110. package/dist/tools/FileTools.js +25 -0
  111. package/dist/tools/GitTools.js +16 -0
  112. package/dist/tools/ShellTools.js +24 -0
  113. package/dist/types/architecture.js +5 -0
  114. package/dist/types/core.js +35 -0
  115. package/dist/types/governance.js +5 -0
  116. package/dist/types/venture.js +5 -0
  117. package/dist/ui/App.js +32 -0
  118. package/dist/ui/animation/AnimationEngine.js +117 -0
  119. package/dist/ui/animation/Easing.js +61 -0
  120. package/dist/ui/cli.js +50 -0
  121. package/dist/ui/command/ActionPreview.js +47 -0
  122. package/dist/ui/command/CommandPalette.js +55 -0
  123. package/dist/ui/command/NaturalLanguageBar.js +77 -0
  124. package/dist/ui/emotion/AnimationSequences.js +59 -0
  125. package/dist/ui/emotion/EmotionalUXEngine.js +86 -0
  126. package/dist/ui/integration/BackendAdapter.js +50 -0
  127. package/dist/ui/integration/WebSocketAdapter.js +90 -0
  128. package/dist/ui/intelligence/AdaptiveUIEngine.js +75 -0
  129. package/dist/ui/intelligence/UserBehaviorTracker.js +88 -0
  130. package/dist/ui/layout/LayoutEngine.js +115 -0
  131. package/dist/ui/mindmap/CognitiveMindmapRenderer.js +53 -0
  132. package/dist/ui/mindmap/EdgeRenderer.js +35 -0
  133. package/dist/ui/mindmap/GraphLayout.js +137 -0
  134. package/dist/ui/mindmap/MindmapControls.js +53 -0
  135. package/dist/ui/mindmap/NodeRenderer.js +53 -0
  136. package/dist/ui/modes/CognitiveMode.js +31 -0
  137. package/dist/ui/modes/CommandMode.js +6 -0
  138. package/dist/ui/modes/GovernanceMode.js +6 -0
  139. package/dist/ui/modes/MissionControlMode.js +6 -0
  140. package/dist/ui/modes/ModeManager.js +67 -0
  141. package/dist/ui/modes/ObservatoryMode.js +10 -0
  142. package/dist/ui/modes/TimelineMode.js +27 -0
  143. package/dist/ui/terminalOS.js +180 -0
  144. package/dist/ui/theme/ThemeEngine.js +164 -0
  145. package/dist/ui/visual/ColorGradient.js +91 -0
  146. package/dist/ui/visual/Typography.js +128 -0
  147. package/dist/ui/visual/UnicodeRenderer.js +86 -0
  148. package/dist/venture/ventureMemory.js +62 -0
  149. package/package.json +70 -0
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Planetary Safety Kernel for BASETREE V7
3
+ * Defines hard safety invariants for planetary-scale operations
4
+ */
5
+ import { getKernel } from '../kernel/kernel.js';
6
+ export class PlanetaryKernel {
7
+ kernel = getKernel();
8
+ invariants = [];
9
+ constructor() {
10
+ this.setupInvariants();
11
+ }
12
+ /**
13
+ * Setup hard safety invariants
14
+ */
15
+ setupInvariants() {
16
+ // Invariant 1: Protected zones cannot be edited
17
+ this.invariants.push({
18
+ id: 'protected-zones',
19
+ description: 'Protected zones cannot be modified',
20
+ check: () => {
21
+ // Check kernel protected paths
22
+ const protectedPaths = [
23
+ 'src/kernel/',
24
+ 'src/safety/',
25
+ 'src/planet/controlPlane.ts',
26
+ ];
27
+ // This is a simplified check - in production would verify no changes to protected paths
28
+ return true;
29
+ },
30
+ });
31
+ // Invariant 2: Maximum blast radius across regions
32
+ this.invariants.push({
33
+ id: 'max-blast-radius',
34
+ description: 'Changes cannot affect more than 3 regions simultaneously',
35
+ check: () => {
36
+ // Simplified check - would verify change scope
37
+ return true;
38
+ },
39
+ });
40
+ // Invariant 3: Critical operations require governance approval
41
+ this.invariants.push({
42
+ id: 'governance-approval',
43
+ description: 'Critical operations require governance council approval',
44
+ check: () => {
45
+ // Would check governance state
46
+ return true;
47
+ },
48
+ });
49
+ }
50
+ /**
51
+ * Verify all invariants
52
+ */
53
+ async verifyInvariants() {
54
+ const violations = [];
55
+ for (const invariant of this.invariants) {
56
+ try {
57
+ const passed = await Promise.resolve(invariant.check());
58
+ if (!passed) {
59
+ violations.push(invariant.description);
60
+ }
61
+ }
62
+ catch (error) {
63
+ violations.push(`${invariant.description}: ${error.message}`);
64
+ }
65
+ }
66
+ return {
67
+ passed: violations.length === 0,
68
+ violations,
69
+ };
70
+ }
71
+ /**
72
+ * Check if a region can be modified
73
+ */
74
+ canModifyRegion(regionId) {
75
+ // Check if region is in protected list
76
+ const protectedRegions = []; // Could be configured
77
+ return !protectedRegions.includes(regionId);
78
+ }
79
+ /**
80
+ * Check if an operation exceeds max blast radius
81
+ */
82
+ checkBlastRadius(affectedRegions) {
83
+ const maxBlastRadius = 3;
84
+ return affectedRegions.length <= maxBlastRadius;
85
+ }
86
+ /**
87
+ * Register a new invariant
88
+ */
89
+ registerInvariant(invariant) {
90
+ this.invariants.push(invariant);
91
+ }
92
+ }
@@ -0,0 +1,129 @@
1
+ /**
2
+ * Policy Engine for BASETREE V5
3
+ * Central evaluator for policies used by governance agents
4
+ */
5
+ import { getConfig } from '../config/config.js';
6
+ import { KernelGuard } from './kernelGuard.js';
7
+ export class PolicyEngine {
8
+ config = getConfig();
9
+ kernelGuard = new KernelGuard();
10
+ rules = [];
11
+ constructor() {
12
+ this.initializeDefaultRules();
13
+ }
14
+ /**
15
+ * Initialize default policy rules
16
+ */
17
+ initializeDefaultRules() {
18
+ // Rule 1: Kernel protection
19
+ this.rules.push({
20
+ id: 'kernel_protection',
21
+ name: 'Kernel Protection',
22
+ description: 'Proposals cannot modify protected kernel files',
23
+ severity: 'block',
24
+ evaluator: (proposal) => {
25
+ const guardResult = this.kernelGuard.checkProposal(proposal);
26
+ if (!guardResult.allowed) {
27
+ return {
28
+ passed: false,
29
+ severity: 'block',
30
+ message: guardResult.reason || 'Kernel protection violation',
31
+ details: { blockedFiles: guardResult.blockedFiles },
32
+ };
33
+ }
34
+ return {
35
+ passed: true,
36
+ severity: 'info',
37
+ message: 'No kernel protection violations',
38
+ };
39
+ },
40
+ });
41
+ // Rule 2: Risk level threshold
42
+ this.rules.push({
43
+ id: 'risk_threshold',
44
+ name: 'Risk Threshold',
45
+ description: `Proposals must not exceed risk level: ${this.config.safety.maxRiskLevel}`,
46
+ severity: 'error',
47
+ evaluator: (proposal) => {
48
+ const riskOrder = {
49
+ safe: 0,
50
+ low: 1,
51
+ medium: 2,
52
+ high: 3,
53
+ critical: 4,
54
+ };
55
+ const proposalRisk = riskOrder[proposal.riskLevel];
56
+ const maxRisk = riskOrder[this.config.safety.maxRiskLevel];
57
+ if (proposalRisk > maxRisk) {
58
+ return {
59
+ passed: false,
60
+ severity: 'error',
61
+ message: `Proposal risk level ${proposal.riskLevel} exceeds maximum allowed ${this.config.safety.maxRiskLevel}`,
62
+ };
63
+ }
64
+ return {
65
+ passed: true,
66
+ severity: 'info',
67
+ message: 'Risk level within acceptable range',
68
+ };
69
+ },
70
+ });
71
+ // Rule 3: Blast radius limit
72
+ this.rules.push({
73
+ id: 'blast_radius',
74
+ name: 'Blast Radius Limit',
75
+ description: `Proposals must not affect more than ${this.config.thresholds.maxBlastRadius} modules`,
76
+ severity: 'warning',
77
+ evaluator: (proposal) => {
78
+ const affectedModules = new Set();
79
+ for (const change of proposal.changes) {
80
+ // Extract module from file path (simplified)
81
+ const module = change.filePath.split('/')[0] || change.filePath.split('\\')[0];
82
+ affectedModules.add(module);
83
+ }
84
+ if (affectedModules.size > this.config.thresholds.maxBlastRadius) {
85
+ return {
86
+ passed: false,
87
+ severity: 'warning',
88
+ message: `Proposal affects ${affectedModules.size} modules, exceeding limit of ${this.config.thresholds.maxBlastRadius}`,
89
+ details: { affectedModules: Array.from(affectedModules) },
90
+ };
91
+ }
92
+ return {
93
+ passed: true,
94
+ severity: 'info',
95
+ message: `Blast radius acceptable: ${affectedModules.size} modules`,
96
+ };
97
+ },
98
+ });
99
+ }
100
+ /**
101
+ * Register a custom policy rule
102
+ */
103
+ registerRule(rule) {
104
+ this.rules.push(rule);
105
+ }
106
+ /**
107
+ * Evaluate a proposal against all policies
108
+ */
109
+ evaluate(proposal) {
110
+ return this.rules.map((rule) => rule.evaluator(proposal));
111
+ }
112
+ /**
113
+ * Check if proposal passes all blocking policies
114
+ */
115
+ isAllowed(proposal) {
116
+ const evaluations = this.evaluate(proposal);
117
+ const blockingFailures = evaluations.filter((e) => !e.passed && (e.severity === 'block' || e.severity === 'error'));
118
+ return {
119
+ allowed: blockingFailures.length === 0,
120
+ evaluations,
121
+ };
122
+ }
123
+ /**
124
+ * Get all registered rules
125
+ */
126
+ getRules() {
127
+ return [...this.rules];
128
+ }
129
+ }
@@ -0,0 +1,141 @@
1
+ /**
2
+ * Rollback Manager for BASETREE V5
3
+ * Stores rollback points and can restore previous code/state
4
+ */
5
+ import { promises as fs } from 'fs';
6
+ import { join } from 'path';
7
+ import { copy, remove } from 'fs-extra';
8
+ import { getConfig } from '../config/config.js';
9
+ import { getKernel } from '../kernel/kernel.js';
10
+ import { IntegrityChecker } from './integrityChecker.js';
11
+ import { getEventBus } from '../kernel/eventBus.js';
12
+ export class RollbackManager {
13
+ config = getConfig();
14
+ kernel = getKernel();
15
+ integrityChecker = new IntegrityChecker();
16
+ rollbackPoints = new Map();
17
+ /**
18
+ * Create a rollback point from a snapshot
19
+ */
20
+ async createRollbackPoint(snapshot, description) {
21
+ const rollbackId = `rollback_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
22
+ const backupDir = join(this.config.workspaceRoot, '.basetree-v5', 'rollbacks', rollbackId);
23
+ await fs.mkdir(backupDir, { recursive: true });
24
+ const fileBackups = {};
25
+ const workspaceRoot = this.config.workspaceRoot;
26
+ // Backup all files in snapshot
27
+ for (const filePath of Object.keys(snapshot.codeHashes)) {
28
+ const sourcePath = join(workspaceRoot, filePath);
29
+ const backupPath = join(backupDir, filePath.replace(/[\/\\]/g, '_'));
30
+ try {
31
+ await fs.mkdir(join(backupPath, '..'), { recursive: true });
32
+ await copy(sourcePath, backupPath);
33
+ fileBackups[filePath] = backupPath;
34
+ }
35
+ catch (error) {
36
+ console.warn(`Failed to backup ${filePath}:`, error);
37
+ }
38
+ }
39
+ const rollbackPoint = {
40
+ id: rollbackId,
41
+ snapshotId: snapshot.id,
42
+ timestamp: new Date(),
43
+ description,
44
+ fileBackups,
45
+ };
46
+ this.rollbackPoints.set(rollbackId, rollbackPoint);
47
+ // Save rollback point metadata
48
+ await this.saveRollbackPoint(rollbackPoint);
49
+ return rollbackId;
50
+ }
51
+ /**
52
+ * Restore from a rollback point
53
+ */
54
+ async rollback(rollbackId) {
55
+ const rollbackPoint = this.rollbackPoints.get(rollbackId);
56
+ if (!rollbackPoint) {
57
+ // Try to load from disk
58
+ const loaded = await this.loadRollbackPoint(rollbackId);
59
+ if (!loaded) {
60
+ throw new Error(`Rollback point ${rollbackId} not found`);
61
+ }
62
+ this.rollbackPoints.set(rollbackId, loaded);
63
+ }
64
+ const point = this.rollbackPoints.get(rollbackId);
65
+ const workspaceRoot = this.config.workspaceRoot;
66
+ const eventBus = getEventBus();
67
+ await eventBus.emit({
68
+ type: 'RollbackTriggered',
69
+ timestamp: new Date(),
70
+ runId: rollbackId,
71
+ reason: point.description || 'Manual rollback',
72
+ });
73
+ // Restore files
74
+ for (const [filePath, backupPath] of Object.entries(point.fileBackups)) {
75
+ const targetPath = join(workspaceRoot, filePath);
76
+ try {
77
+ await fs.mkdir(join(targetPath, '..'), { recursive: true });
78
+ await copy(backupPath, targetPath);
79
+ }
80
+ catch (error) {
81
+ console.error(`Failed to restore ${filePath}:`, error);
82
+ throw error;
83
+ }
84
+ }
85
+ await eventBus.emit({
86
+ type: 'RollbackCompleted',
87
+ timestamp: new Date(),
88
+ runId: rollbackId,
89
+ });
90
+ }
91
+ /**
92
+ * List available rollback points
93
+ */
94
+ listRollbackPoints() {
95
+ return Array.from(this.rollbackPoints.values()).sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime());
96
+ }
97
+ /**
98
+ * Get latest rollback point
99
+ */
100
+ getLatestRollbackPoint() {
101
+ const points = this.listRollbackPoints();
102
+ return points[0] || null;
103
+ }
104
+ /**
105
+ * Cleanup old rollback points
106
+ */
107
+ async cleanup(olderThanDays = 30) {
108
+ const cutoff = new Date(Date.now() - olderThanDays * 24 * 60 * 60 * 1000);
109
+ const rollbacksDir = join(this.config.workspaceRoot, '.basetree-v5', 'rollbacks');
110
+ for (const [id, point] of this.rollbackPoints.entries()) {
111
+ if (point.timestamp < cutoff) {
112
+ try {
113
+ const backupDir = join(rollbacksDir, id);
114
+ await remove(backupDir);
115
+ this.rollbackPoints.delete(id);
116
+ }
117
+ catch (error) {
118
+ console.warn(`Failed to cleanup rollback point ${id}:`, error);
119
+ }
120
+ }
121
+ }
122
+ }
123
+ async saveRollbackPoint(point) {
124
+ const rollbacksDir = join(this.config.workspaceRoot, '.basetree-v5', 'rollbacks', point.id);
125
+ await fs.mkdir(rollbacksDir, { recursive: true });
126
+ const metadataPath = join(rollbacksDir, 'metadata.json');
127
+ await fs.writeFile(metadataPath, JSON.stringify(point, null, 2), 'utf-8');
128
+ }
129
+ async loadRollbackPoint(id) {
130
+ const metadataPath = join(this.config.workspaceRoot, '.basetree-v5', 'rollbacks', id, 'metadata.json');
131
+ try {
132
+ const content = await fs.readFile(metadataPath, 'utf-8');
133
+ const point = JSON.parse(content);
134
+ point.timestamp = new Date(point.timestamp);
135
+ return point;
136
+ }
137
+ catch (error) {
138
+ return null;
139
+ }
140
+ }
141
+ }
@@ -0,0 +1,143 @@
1
+ /**
2
+ * Sandbox for BASETREE V5
3
+ * Runs upgrade executors and tests in isolated directories/processes
4
+ */
5
+ import { promises as fs } from 'fs';
6
+ import { join } from 'path';
7
+ import { execa } from 'execa';
8
+ import { copy, remove } from 'fs-extra';
9
+ import { getConfig } from '../config/config.js';
10
+ export class Sandbox {
11
+ config = getConfig();
12
+ sandboxPath = null;
13
+ async create(options = {}) {
14
+ const strategy = options.strategy || this.config.sandbox.strategy;
15
+ const workspaceRoot = this.config.workspaceRoot;
16
+ switch (strategy) {
17
+ case 'temp_dir': {
18
+ const tempDir = join(workspaceRoot, '.basetree-v5', 'sandbox', `sandbox_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`);
19
+ await fs.mkdir(tempDir, { recursive: true });
20
+ // Copy workspace to sandbox
21
+ await this.copyWorkspace(workspaceRoot, tempDir);
22
+ this.sandboxPath = tempDir;
23
+ return tempDir;
24
+ }
25
+ case 'copy': {
26
+ const copyDir = join(workspaceRoot, '.basetree-v5', 'sandbox', `copy_${Date.now()}`);
27
+ await fs.mkdir(copyDir, { recursive: true });
28
+ await this.copyWorkspace(workspaceRoot, copyDir);
29
+ this.sandboxPath = copyDir;
30
+ return copyDir;
31
+ }
32
+ case 'git_worktree': {
33
+ // Try to use git worktree if available
34
+ try {
35
+ const worktreePath = join(workspaceRoot, '.basetree-v5', 'sandbox', `worktree_${Date.now()}`);
36
+ await execa('git', ['worktree', 'add', worktreePath, 'HEAD'], { cwd: workspaceRoot });
37
+ this.sandboxPath = worktreePath;
38
+ return worktreePath;
39
+ }
40
+ catch (error) {
41
+ console.warn('Git worktree not available, falling back to temp_dir:', error);
42
+ return this.create({ ...options, strategy: 'temp_dir' });
43
+ }
44
+ }
45
+ default:
46
+ throw new Error(`Unknown sandbox strategy: ${strategy}`);
47
+ }
48
+ }
49
+ async copyWorkspace(source, dest) {
50
+ // Copy essential directories and files
51
+ const itemsToCopy = [
52
+ 'src',
53
+ 'test',
54
+ 'package.json',
55
+ 'tsconfig.json',
56
+ 'node_modules', // if exists
57
+ ];
58
+ for (const item of itemsToCopy) {
59
+ const sourcePath = join(source, item);
60
+ const destPath = join(dest, item);
61
+ try {
62
+ const stat = await fs.stat(sourcePath);
63
+ if (stat.isDirectory()) {
64
+ await copy(sourcePath, destPath);
65
+ }
66
+ else {
67
+ await fs.copyFile(sourcePath, destPath);
68
+ }
69
+ }
70
+ catch (error) {
71
+ // Skip if doesn't exist
72
+ continue;
73
+ }
74
+ }
75
+ }
76
+ getPath() {
77
+ if (!this.sandboxPath) {
78
+ throw new Error('Sandbox not created. Call create() first.');
79
+ }
80
+ return this.sandboxPath;
81
+ }
82
+ async execute(command, args = [], options = {}) {
83
+ if (!this.sandboxPath) {
84
+ throw new Error('Sandbox not created. Call create() first.');
85
+ }
86
+ const cwd = options.cwd || this.sandboxPath;
87
+ try {
88
+ const result = await execa(command, args, {
89
+ cwd,
90
+ env: { ...process.env, ...options.env },
91
+ shell: true,
92
+ });
93
+ return {
94
+ success: true,
95
+ output: result.stdout,
96
+ sandboxPath: this.sandboxPath,
97
+ };
98
+ }
99
+ catch (error) {
100
+ return {
101
+ success: false,
102
+ error: error.message || String(error),
103
+ output: error.stdout || error.stderr,
104
+ sandboxPath: this.sandboxPath,
105
+ };
106
+ }
107
+ }
108
+ async cleanup(options = {}) {
109
+ if (!this.sandboxPath) {
110
+ return;
111
+ }
112
+ const cleanupOnSuccess = options.cleanupOnSuccess ?? this.config.sandbox.cleanupOnSuccess;
113
+ const cleanupOnFailure = options.cleanupOnFailure ?? this.config.sandbox.cleanupOnFailure;
114
+ // Check if this is a git worktree
115
+ if (this.sandboxPath.includes('worktree_')) {
116
+ try {
117
+ await execa('git', ['worktree', 'remove', this.sandboxPath], {
118
+ cwd: this.config.workspaceRoot,
119
+ });
120
+ }
121
+ catch (error) {
122
+ console.warn('Failed to remove git worktree:', error);
123
+ // Fall through to regular cleanup
124
+ }
125
+ }
126
+ // For temp_dir and copy strategies, or if git worktree removal failed
127
+ if (cleanupOnSuccess || cleanupOnFailure) {
128
+ try {
129
+ await remove(this.sandboxPath);
130
+ }
131
+ catch (error) {
132
+ console.warn(`Failed to cleanup sandbox at ${this.sandboxPath}:`, error);
133
+ }
134
+ }
135
+ this.sandboxPath = null;
136
+ }
137
+ async cleanupOnSuccess() {
138
+ await this.cleanup({ cleanupOnSuccess: true, cleanupOnFailure: false });
139
+ }
140
+ async cleanupOnFailure() {
141
+ await this.cleanup({ cleanupOnSuccess: false, cleanupOnFailure: true });
142
+ }
143
+ }
@@ -0,0 +1,102 @@
1
+ /**
2
+ * Mindmap Server for BASETREE V7
3
+ * Express + WebSocket server for cognitive graph visualization
4
+ */
5
+ import express from 'express';
6
+ import { createServer } from 'http';
7
+ import { WebSocketServer } from 'ws';
8
+ export class MindmapServer {
9
+ app;
10
+ server;
11
+ wss;
12
+ graphEngine;
13
+ streamBus;
14
+ graphStore;
15
+ port;
16
+ constructor(graphEngine, streamBus, graphStore, port = 3000) {
17
+ this.app = express();
18
+ this.server = createServer(this.app);
19
+ this.wss = new WebSocketServer({ server: this.server });
20
+ this.graphEngine = graphEngine;
21
+ this.streamBus = streamBus;
22
+ this.graphStore = graphStore;
23
+ this.port = port;
24
+ this.setupRoutes();
25
+ this.setupWebSocket();
26
+ }
27
+ setupRoutes() {
28
+ this.app.use(express.json());
29
+ this.app.use(express.static('web/mindmap'));
30
+ // Get graph for a goal/run
31
+ this.app.get('/api/mindmap/:goalId', async (req, res) => {
32
+ try {
33
+ const goalId = req.params.goalId;
34
+ const graph = this.graphEngine.exportGraph(goalId);
35
+ res.json(graph);
36
+ }
37
+ catch (error) {
38
+ res.status(500).json({ error: error.message });
39
+ }
40
+ });
41
+ // Get replay data for a run
42
+ this.app.get('/api/runs/:runId/replay', async (req, res) => {
43
+ try {
44
+ const runId = req.params.runId;
45
+ const snapshot = await this.graphStore.loadRun(runId);
46
+ if (!snapshot) {
47
+ res.status(404).json({ error: 'Run not found' });
48
+ return;
49
+ }
50
+ res.json(snapshot);
51
+ }
52
+ catch (error) {
53
+ res.status(500).json({ error: error.message });
54
+ }
55
+ });
56
+ // List all runs
57
+ this.app.get('/api/runs', async (req, res) => {
58
+ try {
59
+ const runs = await this.graphStore.listRuns();
60
+ res.json(runs);
61
+ }
62
+ catch (error) {
63
+ res.status(500).json({ error: error.message });
64
+ }
65
+ });
66
+ }
67
+ setupWebSocket() {
68
+ this.wss.on('connection', (ws) => {
69
+ console.log('WebSocket client connected');
70
+ // Subscribe to stream updates
71
+ const unsubscribe = this.streamBus.subscribe((update) => {
72
+ if (ws.readyState === ws.OPEN) {
73
+ ws.send(JSON.stringify(update));
74
+ }
75
+ });
76
+ ws.on('close', () => {
77
+ console.log('WebSocket client disconnected');
78
+ unsubscribe();
79
+ });
80
+ ws.on('error', (error) => {
81
+ console.error('WebSocket error:', error);
82
+ });
83
+ });
84
+ }
85
+ async start() {
86
+ return new Promise((resolve) => {
87
+ this.server.listen(this.port, () => {
88
+ console.log(`Mindmap server running on http://localhost:${this.port}`);
89
+ resolve();
90
+ });
91
+ });
92
+ }
93
+ async stop() {
94
+ return new Promise((resolve) => {
95
+ this.wss.close(() => {
96
+ this.server.close(() => {
97
+ resolve();
98
+ });
99
+ });
100
+ });
101
+ }
102
+ }