@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.
- package/.env.example +10 -0
- package/README.md +369 -0
- package/dist/agents/alignmentAgent.js +68 -0
- package/dist/agents/governanceOrchestrator.js +152 -0
- package/dist/agents/planet/climateAgent.js +39 -0
- package/dist/agents/planet/diplomacyAgent.js +52 -0
- package/dist/agents/planet/discoveryAgent.js +41 -0
- package/dist/agents/planet/economicAgent.js +64 -0
- package/dist/agents/planet/educationAgent.js +41 -0
- package/dist/agents/planet/governanceCouncilAgent.js +76 -0
- package/dist/agents/planet/healthcareAgent.js +42 -0
- package/dist/agents/planet/infrastructureAgent.js +49 -0
- package/dist/agents/planet/planetAgent.js +5 -0
- package/dist/agents/planet/riskStabilityAgent.js +84 -0
- package/dist/agents/planet/urbanSystemsAgent.js +42 -0
- package/dist/agents/policyAgent.js +31 -0
- package/dist/agents/promptGenomeAgent.js +120 -0
- package/dist/agents/reasoningOptimizerAgent.js +72 -0
- package/dist/agents/regressionAgent.js +162 -0
- package/dist/agents/reinforcementLearnerAgent.js +108 -0
- package/dist/agents/riskEvaluationAgent.js +131 -0
- package/dist/agents/rollbackAgent.js +53 -0
- package/dist/agents/stabilityAgent.js +90 -0
- package/dist/agents/strategyMutationAgent.js +74 -0
- package/dist/agents/systemIntrospectionAgent.js +274 -0
- package/dist/agents/upgradeExecutorAgent.js +146 -0
- package/dist/agents/upgradePlannerAgent.js +80 -0
- package/dist/agents/venture/businessModelAgent.js +81 -0
- package/dist/agents/venture/growthAgent.js +82 -0
- package/dist/agents/venture/ideationAgent.js +89 -0
- package/dist/agents/venture/investorAgent.js +90 -0
- package/dist/agents/venture/legalAgent.js +112 -0
- package/dist/agents/venture/marketResearchAgent.js +80 -0
- package/dist/agents/venture/productAgent.js +96 -0
- package/dist/agents/venture/revenueAgent.js +63 -0
- package/dist/agents/venture/validationAgent.js +189 -0
- package/dist/bootstrap.js +200 -0
- package/dist/cli.js +453 -0
- package/dist/cognitiveGraph/cognitiveGraphEngine.js +180 -0
- package/dist/cognitiveGraph/graphStore.js +81 -0
- package/dist/cognitiveGraph/reasoningStreamBus.js +190 -0
- package/dist/config/config.js +76 -0
- package/dist/core/agent/AdaptivePlanner.js +49 -0
- package/dist/core/agent/AutoFixEngine.js +37 -0
- package/dist/core/agent/ExecutorAgent.js +79 -0
- package/dist/core/agent/LearningMemoryAgent.js +67 -0
- package/dist/core/agent/MemoryAgent.js +35 -0
- package/dist/core/agent/MetaCognitionAgent.js +38 -0
- package/dist/core/agent/PlannerAgent.js +59 -0
- package/dist/core/agent/ReflectionLoop.js +34 -0
- package/dist/core/agent/ReviewerAgent.js +34 -0
- package/dist/core/agent/VerificationAgent.js +20 -0
- package/dist/core/agent/specialists/SpecializedAgents.js +43 -0
- package/dist/core/ai/GeminiProvider.js +113 -0
- package/dist/core/ai/listModels.js +73 -0
- package/dist/core/monitor/PerformanceMonitor.js +18 -0
- package/dist/core/swarm/AgentSwarm.js +56 -0
- package/dist/core/swarm/ReasoningBus.js +26 -0
- package/dist/core/swarm/SwarmOrchestrator.js +36 -0
- package/dist/discovery/experimentOrchestrator.js +75 -0
- package/dist/discovery/hypothesisEngine.js +79 -0
- package/dist/discovery/knowledgeSynthesizer.js +83 -0
- package/dist/discovery/simulationPipeline.js +57 -0
- package/dist/experiments/experimentationEngine.js +174 -0
- package/dist/index.js +67 -0
- package/dist/kernel/eventBus.js +89 -0
- package/dist/kernel/kernel.js +146 -0
- package/dist/llm/tokenEfficiencyOptimizer.js +91 -0
- package/dist/memory/civilizationMemory.js +147 -0
- package/dist/memory/globalVectorMemory.js +87 -0
- package/dist/mesh/crossOrgProtocol.js +110 -0
- package/dist/mesh/globalReasoningBus.js +99 -0
- package/dist/observability/businessDashboard.js +103 -0
- package/dist/observability/businessMetrics.js +105 -0
- package/dist/observability/cognitiveMetrics.js +119 -0
- package/dist/observability/failureSurfaceMapper.js +135 -0
- package/dist/observability/metricsCollector.js +94 -0
- package/dist/observability/planetaryDashboard.js +97 -0
- package/dist/observability/planetaryMetrics.js +127 -0
- package/dist/observability/reportRenderer.js +100 -0
- package/dist/performance/memoryProfiler.js +107 -0
- package/dist/performance/profiler.js +130 -0
- package/dist/pipelines/evolvePipeline.js +150 -0
- package/dist/pipelines/governanceReviewPipeline.js +68 -0
- package/dist/pipelines/introspectPipeline.js +73 -0
- package/dist/pipelines/venture/growPipeline.js +51 -0
- package/dist/pipelines/venture/launchPipeline.js +55 -0
- package/dist/pipelines/venture/monetizePipeline.js +46 -0
- package/dist/pipelines/venture/shutdownPipeline.js +40 -0
- package/dist/pipelines/venture/startupPipeline.js +145 -0
- package/dist/pipelines/venture/validatePipeline.js +40 -0
- package/dist/planet/controlPlane.js +131 -0
- package/dist/planet/executionEngine.js +142 -0
- package/dist/planet/globalTypes.js +5 -0
- package/dist/planet/regionManager.js +114 -0
- package/dist/quality/codeQualityAuditor.js +161 -0
- package/dist/safety/containmentProtocols.js +87 -0
- package/dist/safety/integrityChecker.js +110 -0
- package/dist/safety/kernelGuard.js +57 -0
- package/dist/safety/killSwitch.js +100 -0
- package/dist/safety/planetaryKernel.js +92 -0
- package/dist/safety/policyEngine.js +129 -0
- package/dist/safety/rollbackManager.js +141 -0
- package/dist/safety/sandbox.js +143 -0
- package/dist/server/mindmapServer.js +102 -0
- package/dist/state/distributedState.js +241 -0
- package/dist/state/fileStateStore.js +264 -0
- package/dist/state/snapshotter.js +96 -0
- package/dist/state/stateStore.js +5 -0
- package/dist/tools/FileTools.js +25 -0
- package/dist/tools/GitTools.js +16 -0
- package/dist/tools/ShellTools.js +24 -0
- package/dist/types/architecture.js +5 -0
- package/dist/types/core.js +35 -0
- package/dist/types/governance.js +5 -0
- package/dist/types/venture.js +5 -0
- package/dist/ui/App.js +32 -0
- package/dist/ui/animation/AnimationEngine.js +117 -0
- package/dist/ui/animation/Easing.js +61 -0
- package/dist/ui/cli.js +50 -0
- package/dist/ui/command/ActionPreview.js +47 -0
- package/dist/ui/command/CommandPalette.js +55 -0
- package/dist/ui/command/NaturalLanguageBar.js +77 -0
- package/dist/ui/emotion/AnimationSequences.js +59 -0
- package/dist/ui/emotion/EmotionalUXEngine.js +86 -0
- package/dist/ui/integration/BackendAdapter.js +50 -0
- package/dist/ui/integration/WebSocketAdapter.js +90 -0
- package/dist/ui/intelligence/AdaptiveUIEngine.js +75 -0
- package/dist/ui/intelligence/UserBehaviorTracker.js +88 -0
- package/dist/ui/layout/LayoutEngine.js +115 -0
- package/dist/ui/mindmap/CognitiveMindmapRenderer.js +53 -0
- package/dist/ui/mindmap/EdgeRenderer.js +35 -0
- package/dist/ui/mindmap/GraphLayout.js +137 -0
- package/dist/ui/mindmap/MindmapControls.js +53 -0
- package/dist/ui/mindmap/NodeRenderer.js +53 -0
- package/dist/ui/modes/CognitiveMode.js +31 -0
- package/dist/ui/modes/CommandMode.js +6 -0
- package/dist/ui/modes/GovernanceMode.js +6 -0
- package/dist/ui/modes/MissionControlMode.js +6 -0
- package/dist/ui/modes/ModeManager.js +67 -0
- package/dist/ui/modes/ObservatoryMode.js +10 -0
- package/dist/ui/modes/TimelineMode.js +27 -0
- package/dist/ui/terminalOS.js +180 -0
- package/dist/ui/theme/ThemeEngine.js +164 -0
- package/dist/ui/visual/ColorGradient.js +91 -0
- package/dist/ui/visual/Typography.js +128 -0
- package/dist/ui/visual/UnicodeRenderer.js +86 -0
- package/dist/venture/ventureMemory.js +62 -0
- package/package.json +70 -0
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Distributed State Store for BASETREE V7
|
|
3
|
+
* Sharded state across regions and zones
|
|
4
|
+
*/
|
|
5
|
+
import { FileStateStore } from './fileStateStore.js';
|
|
6
|
+
/**
|
|
7
|
+
* Hash-based shard router
|
|
8
|
+
*/
|
|
9
|
+
export class HashShardRouter {
|
|
10
|
+
regions;
|
|
11
|
+
constructor(regions) {
|
|
12
|
+
this.regions = regions;
|
|
13
|
+
}
|
|
14
|
+
route(key) {
|
|
15
|
+
// Simple hash-based routing
|
|
16
|
+
let hash = 0;
|
|
17
|
+
for (let i = 0; i < key.length; i++) {
|
|
18
|
+
hash = ((hash << 5) - hash + key.charCodeAt(i)) | 0;
|
|
19
|
+
}
|
|
20
|
+
const index = Math.abs(hash) % this.regions.length;
|
|
21
|
+
return this.regions[index];
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Distributed state store that routes to region-specific stores
|
|
26
|
+
*/
|
|
27
|
+
export class DistributedStateStore {
|
|
28
|
+
router;
|
|
29
|
+
regionStores = new Map();
|
|
30
|
+
constructor(router, regions) {
|
|
31
|
+
this.router = router;
|
|
32
|
+
// Initialize stores for each region
|
|
33
|
+
for (const regionId of regions) {
|
|
34
|
+
this.regionStores.set(regionId, new FileStateStore(`.basetree-v7/regions/${regionId}/state.json`));
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
getStore(key) {
|
|
38
|
+
const regionId = this.router.route(key);
|
|
39
|
+
const store = this.regionStores.get(regionId);
|
|
40
|
+
if (!store) {
|
|
41
|
+
throw new Error(`No store found for region ${regionId}`);
|
|
42
|
+
}
|
|
43
|
+
return store;
|
|
44
|
+
}
|
|
45
|
+
// Delegate all IStateStore methods to routed stores
|
|
46
|
+
async saveSnapshot(snapshot) {
|
|
47
|
+
return this.getStore(snapshot.id).saveSnapshot(snapshot);
|
|
48
|
+
}
|
|
49
|
+
async getSnapshot(id) {
|
|
50
|
+
// Try all regions (or use a global index in production)
|
|
51
|
+
for (const store of this.regionStores.values()) {
|
|
52
|
+
const snapshot = await store.getSnapshot(id);
|
|
53
|
+
if (snapshot) {
|
|
54
|
+
return snapshot;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
async listSnapshots(limit) {
|
|
60
|
+
// Aggregate from all regions
|
|
61
|
+
const allSnapshots = [];
|
|
62
|
+
for (const store of this.regionStores.values()) {
|
|
63
|
+
const snapshots = await store.listSnapshots();
|
|
64
|
+
allSnapshots.push(...snapshots);
|
|
65
|
+
}
|
|
66
|
+
allSnapshots.sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime());
|
|
67
|
+
return limit ? allSnapshots.slice(0, limit) : allSnapshots;
|
|
68
|
+
}
|
|
69
|
+
async getLatestSnapshot() {
|
|
70
|
+
const snapshots = await this.listSnapshots(1);
|
|
71
|
+
return snapshots[0] || null;
|
|
72
|
+
}
|
|
73
|
+
async saveProposal(proposal) {
|
|
74
|
+
return this.getStore(proposal.id).saveProposal(proposal);
|
|
75
|
+
}
|
|
76
|
+
async getProposal(id) {
|
|
77
|
+
for (const store of this.regionStores.values()) {
|
|
78
|
+
const proposal = await store.getProposal(id);
|
|
79
|
+
if (proposal) {
|
|
80
|
+
return proposal;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
async listProposals(status, limit) {
|
|
86
|
+
const allProposals = [];
|
|
87
|
+
for (const store of this.regionStores.values()) {
|
|
88
|
+
const proposals = await store.listProposals(status);
|
|
89
|
+
allProposals.push(...proposals);
|
|
90
|
+
}
|
|
91
|
+
allProposals.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
|
|
92
|
+
return limit ? allProposals.slice(0, limit) : allProposals;
|
|
93
|
+
}
|
|
94
|
+
async updateProposal(id, updates) {
|
|
95
|
+
// Find which region has this proposal
|
|
96
|
+
for (const store of this.regionStores.values()) {
|
|
97
|
+
const proposal = await store.getProposal(id);
|
|
98
|
+
if (proposal) {
|
|
99
|
+
return store.updateProposal(id, updates);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
throw new Error(`Proposal ${id} not found`);
|
|
103
|
+
}
|
|
104
|
+
async saveRun(run) {
|
|
105
|
+
return this.getStore(run.id).saveRun(run);
|
|
106
|
+
}
|
|
107
|
+
async getRun(id) {
|
|
108
|
+
for (const store of this.regionStores.values()) {
|
|
109
|
+
const run = await store.getRun(id);
|
|
110
|
+
if (run) {
|
|
111
|
+
return run;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
async listRuns(proposalId, limit) {
|
|
117
|
+
const allRuns = [];
|
|
118
|
+
for (const store of this.regionStores.values()) {
|
|
119
|
+
const runs = await store.listRuns(proposalId);
|
|
120
|
+
allRuns.push(...runs);
|
|
121
|
+
}
|
|
122
|
+
allRuns.sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime());
|
|
123
|
+
return limit ? allRuns.slice(0, limit) : allRuns;
|
|
124
|
+
}
|
|
125
|
+
async updateRun(id, updates) {
|
|
126
|
+
for (const store of this.regionStores.values()) {
|
|
127
|
+
const run = await store.getRun(id);
|
|
128
|
+
if (run) {
|
|
129
|
+
return store.updateRun(id, updates);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
throw new Error(`Run ${id} not found`);
|
|
133
|
+
}
|
|
134
|
+
async saveMetric(metric) {
|
|
135
|
+
return this.getStore(metric.id).saveMetric(metric);
|
|
136
|
+
}
|
|
137
|
+
async getMetric(id) {
|
|
138
|
+
for (const store of this.regionStores.values()) {
|
|
139
|
+
const metric = await store.getMetric(id);
|
|
140
|
+
if (metric) {
|
|
141
|
+
return metric;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return null;
|
|
145
|
+
}
|
|
146
|
+
async listMetrics(name, tags, limit) {
|
|
147
|
+
const allMetrics = [];
|
|
148
|
+
for (const store of this.regionStores.values()) {
|
|
149
|
+
const metrics = await store.listMetrics(name, tags);
|
|
150
|
+
allMetrics.push(...metrics);
|
|
151
|
+
}
|
|
152
|
+
allMetrics.sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime());
|
|
153
|
+
return limit ? allMetrics.slice(0, limit) : allMetrics;
|
|
154
|
+
}
|
|
155
|
+
async aggregateMetrics(name, startTime, endTime) {
|
|
156
|
+
const allMetrics = [];
|
|
157
|
+
for (const store of this.regionStores.values()) {
|
|
158
|
+
const metrics = await store.aggregateMetrics(name, startTime, endTime);
|
|
159
|
+
allMetrics.push(...metrics);
|
|
160
|
+
}
|
|
161
|
+
return allMetrics;
|
|
162
|
+
}
|
|
163
|
+
// V6 Venture methods
|
|
164
|
+
async saveVenture(venture) {
|
|
165
|
+
return this.getStore(venture.id).saveVenture(venture);
|
|
166
|
+
}
|
|
167
|
+
async getVenture(id) {
|
|
168
|
+
for (const store of this.regionStores.values()) {
|
|
169
|
+
const venture = await store.getVenture(id);
|
|
170
|
+
if (venture) {
|
|
171
|
+
return venture;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
return null;
|
|
175
|
+
}
|
|
176
|
+
async listVentures(stage, limit) {
|
|
177
|
+
const allVentures = [];
|
|
178
|
+
for (const store of this.regionStores.values()) {
|
|
179
|
+
const ventures = await store.listVentures(stage);
|
|
180
|
+
allVentures.push(...ventures);
|
|
181
|
+
}
|
|
182
|
+
allVentures.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
|
|
183
|
+
return limit ? allVentures.slice(0, limit) : allVentures;
|
|
184
|
+
}
|
|
185
|
+
async updateVenture(id, updates) {
|
|
186
|
+
for (const store of this.regionStores.values()) {
|
|
187
|
+
const venture = await store.getVenture(id);
|
|
188
|
+
if (venture) {
|
|
189
|
+
return store.updateVenture(id, updates);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
throw new Error(`Venture ${id} not found`);
|
|
193
|
+
}
|
|
194
|
+
async saveExperiment(experiment) {
|
|
195
|
+
return this.getStore(experiment.id).saveExperiment(experiment);
|
|
196
|
+
}
|
|
197
|
+
async getExperiment(id) {
|
|
198
|
+
for (const store of this.regionStores.values()) {
|
|
199
|
+
const experiment = await store.getExperiment(id);
|
|
200
|
+
if (experiment) {
|
|
201
|
+
return experiment;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
return null;
|
|
205
|
+
}
|
|
206
|
+
async listExperiments(ventureId, limit) {
|
|
207
|
+
const allExperiments = [];
|
|
208
|
+
for (const store of this.regionStores.values()) {
|
|
209
|
+
const experiments = await store.listExperiments(ventureId);
|
|
210
|
+
allExperiments.push(...experiments);
|
|
211
|
+
}
|
|
212
|
+
allExperiments.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
|
|
213
|
+
return limit ? allExperiments.slice(0, limit) : allExperiments;
|
|
214
|
+
}
|
|
215
|
+
async updateExperiment(id, updates) {
|
|
216
|
+
for (const store of this.regionStores.values()) {
|
|
217
|
+
const experiment = await store.getExperiment(id);
|
|
218
|
+
if (experiment) {
|
|
219
|
+
return store.updateExperiment(id, updates);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
throw new Error(`Experiment ${id} not found`);
|
|
223
|
+
}
|
|
224
|
+
async saveVentureMemory(record) {
|
|
225
|
+
return this.getStore(record.id).saveVentureMemory(record);
|
|
226
|
+
}
|
|
227
|
+
async listVentureMemory(options) {
|
|
228
|
+
const allRecords = [];
|
|
229
|
+
for (const store of this.regionStores.values()) {
|
|
230
|
+
const records = await store.listVentureMemory(options);
|
|
231
|
+
allRecords.push(...records);
|
|
232
|
+
}
|
|
233
|
+
allRecords.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
|
|
234
|
+
return options?.limit ? allRecords.slice(0, options.limit) : allRecords;
|
|
235
|
+
}
|
|
236
|
+
async cleanup(olderThan) {
|
|
237
|
+
for (const store of this.regionStores.values()) {
|
|
238
|
+
await store.cleanup(olderThan);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File-based State Store implementation for BASETREE V5
|
|
3
|
+
* Uses JSON files for local development
|
|
4
|
+
*/
|
|
5
|
+
import { promises as fs } from 'fs';
|
|
6
|
+
import { join, dirname } from 'path';
|
|
7
|
+
import { existsSync, mkdirSync } from 'fs';
|
|
8
|
+
import { getConfig } from '../config/config.js';
|
|
9
|
+
export class FileStateStore {
|
|
10
|
+
dataPath;
|
|
11
|
+
data;
|
|
12
|
+
constructor(dataPath) {
|
|
13
|
+
const config = getConfig();
|
|
14
|
+
this.dataPath = dataPath || join(config.stateStorePath, 'state.json');
|
|
15
|
+
this.data = {
|
|
16
|
+
snapshots: {},
|
|
17
|
+
proposals: {},
|
|
18
|
+
runs: {},
|
|
19
|
+
metrics: {},
|
|
20
|
+
ventures: {},
|
|
21
|
+
experiments: {},
|
|
22
|
+
ventureMemory: {},
|
|
23
|
+
};
|
|
24
|
+
this.ensureDirectory();
|
|
25
|
+
this.load();
|
|
26
|
+
}
|
|
27
|
+
ensureDirectory() {
|
|
28
|
+
const dir = dirname(this.dataPath);
|
|
29
|
+
if (!existsSync(dir)) {
|
|
30
|
+
mkdirSync(dir, { recursive: true });
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
async load() {
|
|
34
|
+
try {
|
|
35
|
+
if (existsSync(this.dataPath)) {
|
|
36
|
+
const content = await fs.readFile(this.dataPath, 'utf-8');
|
|
37
|
+
this.data = JSON.parse(content);
|
|
38
|
+
// Convert date strings back to Date objects
|
|
39
|
+
this.normalizeDates();
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
console.warn(`Failed to load state store from ${this.dataPath}:`, error);
|
|
44
|
+
this.data = {
|
|
45
|
+
snapshots: {},
|
|
46
|
+
proposals: {},
|
|
47
|
+
runs: {},
|
|
48
|
+
metrics: {},
|
|
49
|
+
ventures: {},
|
|
50
|
+
experiments: {},
|
|
51
|
+
ventureMemory: {},
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
normalizeDates() {
|
|
56
|
+
// Convert ISO date strings back to Date objects
|
|
57
|
+
const normalize = (obj) => {
|
|
58
|
+
if (obj === null || typeof obj !== 'object') {
|
|
59
|
+
return obj;
|
|
60
|
+
}
|
|
61
|
+
if (Array.isArray(obj)) {
|
|
62
|
+
return obj.map(normalize);
|
|
63
|
+
}
|
|
64
|
+
for (const key in obj) {
|
|
65
|
+
if (key === 'timestamp' || key === 'createdAt' || key === 'updatedAt') {
|
|
66
|
+
obj[key] = new Date(obj[key]);
|
|
67
|
+
}
|
|
68
|
+
else if (typeof obj[key] === 'object') {
|
|
69
|
+
obj[key] = normalize(obj[key]);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return obj;
|
|
73
|
+
};
|
|
74
|
+
this.data = normalize(this.data);
|
|
75
|
+
}
|
|
76
|
+
async save() {
|
|
77
|
+
try {
|
|
78
|
+
await fs.writeFile(this.dataPath, JSON.stringify(this.data, null, 2), 'utf-8');
|
|
79
|
+
}
|
|
80
|
+
catch (error) {
|
|
81
|
+
console.error(`Failed to save state store to ${this.dataPath}:`, error);
|
|
82
|
+
throw error;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
// Snapshots
|
|
86
|
+
async saveSnapshot(snapshot) {
|
|
87
|
+
this.data.snapshots[snapshot.id] = snapshot;
|
|
88
|
+
await this.save();
|
|
89
|
+
}
|
|
90
|
+
async getSnapshot(id) {
|
|
91
|
+
return this.data.snapshots[id] || null;
|
|
92
|
+
}
|
|
93
|
+
async listSnapshots(limit) {
|
|
94
|
+
const snapshots = Object.values(this.data.snapshots);
|
|
95
|
+
snapshots.sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime());
|
|
96
|
+
return limit ? snapshots.slice(0, limit) : snapshots;
|
|
97
|
+
}
|
|
98
|
+
async getLatestSnapshot() {
|
|
99
|
+
const snapshots = await this.listSnapshots(1);
|
|
100
|
+
return snapshots[0] || null;
|
|
101
|
+
}
|
|
102
|
+
// Proposals
|
|
103
|
+
async saveProposal(proposal) {
|
|
104
|
+
this.data.proposals[proposal.id] = proposal;
|
|
105
|
+
await this.save();
|
|
106
|
+
}
|
|
107
|
+
async getProposal(id) {
|
|
108
|
+
return this.data.proposals[id] || null;
|
|
109
|
+
}
|
|
110
|
+
async listProposals(status, limit) {
|
|
111
|
+
let proposals = Object.values(this.data.proposals);
|
|
112
|
+
if (status) {
|
|
113
|
+
proposals = proposals.filter((p) => p.governanceDecision === status);
|
|
114
|
+
}
|
|
115
|
+
proposals.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
|
|
116
|
+
return limit ? proposals.slice(0, limit) : proposals;
|
|
117
|
+
}
|
|
118
|
+
async updateProposal(id, updates) {
|
|
119
|
+
const proposal = this.data.proposals[id];
|
|
120
|
+
if (!proposal) {
|
|
121
|
+
throw new Error(`Proposal ${id} not found`);
|
|
122
|
+
}
|
|
123
|
+
Object.assign(proposal, updates);
|
|
124
|
+
proposal.updatedAt = new Date();
|
|
125
|
+
await this.save();
|
|
126
|
+
}
|
|
127
|
+
// Runs
|
|
128
|
+
async saveRun(run) {
|
|
129
|
+
this.data.runs[run.id] = run;
|
|
130
|
+
await this.save();
|
|
131
|
+
}
|
|
132
|
+
async getRun(id) {
|
|
133
|
+
return this.data.runs[id] || null;
|
|
134
|
+
}
|
|
135
|
+
async listRuns(proposalId, limit) {
|
|
136
|
+
let runs = Object.values(this.data.runs);
|
|
137
|
+
if (proposalId) {
|
|
138
|
+
runs = runs.filter((r) => r.proposalId === proposalId);
|
|
139
|
+
}
|
|
140
|
+
runs.sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime());
|
|
141
|
+
return limit ? runs.slice(0, limit) : runs;
|
|
142
|
+
}
|
|
143
|
+
async updateRun(id, updates) {
|
|
144
|
+
const run = this.data.runs[id];
|
|
145
|
+
if (!run) {
|
|
146
|
+
throw new Error(`Run ${id} not found`);
|
|
147
|
+
}
|
|
148
|
+
Object.assign(run, updates);
|
|
149
|
+
await this.save();
|
|
150
|
+
}
|
|
151
|
+
// Metrics
|
|
152
|
+
async saveMetric(metric) {
|
|
153
|
+
this.data.metrics[metric.id] = metric;
|
|
154
|
+
await this.save();
|
|
155
|
+
}
|
|
156
|
+
async getMetric(id) {
|
|
157
|
+
return this.data.metrics[id] || null;
|
|
158
|
+
}
|
|
159
|
+
async listMetrics(name, tags, limit) {
|
|
160
|
+
let metrics = Object.values(this.data.metrics);
|
|
161
|
+
if (name) {
|
|
162
|
+
metrics = metrics.filter((m) => m.name === name);
|
|
163
|
+
}
|
|
164
|
+
if (tags) {
|
|
165
|
+
metrics = metrics.filter((m) => {
|
|
166
|
+
if (!m.tags)
|
|
167
|
+
return false;
|
|
168
|
+
return Object.entries(tags).every(([key, value]) => m.tags[key] === value);
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
metrics.sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime());
|
|
172
|
+
return limit ? metrics.slice(0, limit) : metrics;
|
|
173
|
+
}
|
|
174
|
+
async aggregateMetrics(name, startTime, endTime) {
|
|
175
|
+
const metrics = await this.listMetrics(name);
|
|
176
|
+
return metrics.filter((m) => m.timestamp >= startTime && m.timestamp <= endTime);
|
|
177
|
+
}
|
|
178
|
+
// Ventures
|
|
179
|
+
async saveVenture(venture) {
|
|
180
|
+
this.data.ventures[venture.id] = venture;
|
|
181
|
+
await this.save();
|
|
182
|
+
}
|
|
183
|
+
async getVenture(id) {
|
|
184
|
+
return this.data.ventures[id] || null;
|
|
185
|
+
}
|
|
186
|
+
async listVentures(stage, limit) {
|
|
187
|
+
let ventures = Object.values(this.data.ventures);
|
|
188
|
+
if (stage) {
|
|
189
|
+
ventures = ventures.filter((v) => v.stage === stage);
|
|
190
|
+
}
|
|
191
|
+
ventures.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
|
|
192
|
+
return limit ? ventures.slice(0, limit) : ventures;
|
|
193
|
+
}
|
|
194
|
+
async updateVenture(id, updates) {
|
|
195
|
+
const venture = this.data.ventures[id];
|
|
196
|
+
if (!venture) {
|
|
197
|
+
throw new Error(`Venture ${id} not found`);
|
|
198
|
+
}
|
|
199
|
+
Object.assign(venture, updates);
|
|
200
|
+
venture.updatedAt = new Date();
|
|
201
|
+
await this.save();
|
|
202
|
+
}
|
|
203
|
+
// Experiments
|
|
204
|
+
async saveExperiment(experiment) {
|
|
205
|
+
this.data.experiments[experiment.id] = experiment;
|
|
206
|
+
await this.save();
|
|
207
|
+
}
|
|
208
|
+
async getExperiment(id) {
|
|
209
|
+
return this.data.experiments[id] || null;
|
|
210
|
+
}
|
|
211
|
+
async listExperiments(ventureId, limit) {
|
|
212
|
+
let experiments = Object.values(this.data.experiments);
|
|
213
|
+
if (ventureId) {
|
|
214
|
+
experiments = experiments.filter((e) => e.ventureId === ventureId);
|
|
215
|
+
}
|
|
216
|
+
experiments.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
|
|
217
|
+
return limit ? experiments.slice(0, limit) : experiments;
|
|
218
|
+
}
|
|
219
|
+
async updateExperiment(id, updates) {
|
|
220
|
+
const experiment = this.data.experiments[id];
|
|
221
|
+
if (!experiment) {
|
|
222
|
+
throw new Error(`Experiment ${id} not found`);
|
|
223
|
+
}
|
|
224
|
+
Object.assign(experiment, updates);
|
|
225
|
+
await this.save();
|
|
226
|
+
}
|
|
227
|
+
// Venture memory
|
|
228
|
+
async saveVentureMemory(record) {
|
|
229
|
+
this.data.ventureMemory[record.id] = record;
|
|
230
|
+
await this.save();
|
|
231
|
+
}
|
|
232
|
+
async listVentureMemory(options) {
|
|
233
|
+
let records = Object.values(this.data.ventureMemory);
|
|
234
|
+
if (options?.ventureId) {
|
|
235
|
+
records = records.filter((r) => r.ventureId === options.ventureId);
|
|
236
|
+
}
|
|
237
|
+
if (options?.kind) {
|
|
238
|
+
records = records.filter((r) => r.kind === options.kind);
|
|
239
|
+
}
|
|
240
|
+
if (options?.tag) {
|
|
241
|
+
records = records.filter((r) => r.tags.includes(options.tag));
|
|
242
|
+
}
|
|
243
|
+
records.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
|
|
244
|
+
return options?.limit ? records.slice(0, options.limit) : records;
|
|
245
|
+
}
|
|
246
|
+
// Cleanup
|
|
247
|
+
async cleanup(olderThan) {
|
|
248
|
+
const cutoff = olderThan || new Date(Date.now() - 30 * 24 * 60 * 60 * 1000); // 30 days default
|
|
249
|
+
// Clean snapshots
|
|
250
|
+
for (const id in this.data.snapshots) {
|
|
251
|
+
if (this.data.snapshots[id].timestamp < cutoff) {
|
|
252
|
+
delete this.data.snapshots[id];
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
// Clean metrics
|
|
256
|
+
for (const id in this.data.metrics) {
|
|
257
|
+
if (this.data.metrics[id].timestamp < cutoff) {
|
|
258
|
+
delete this.data.metrics[id];
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
// Optionally prune old venture memory (keep lessons; do not delete by default)
|
|
262
|
+
await this.save();
|
|
263
|
+
}
|
|
264
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Snapshotter for BASETREE V5
|
|
3
|
+
* Logic to snapshot current system state (code hashes, config, metrics)
|
|
4
|
+
*/
|
|
5
|
+
import { createHash } from 'crypto';
|
|
6
|
+
import { promises as fs } from 'fs';
|
|
7
|
+
import { join } from 'path';
|
|
8
|
+
import { globby } from 'globby';
|
|
9
|
+
import { getConfig } from '../config/config.js';
|
|
10
|
+
import { getEventBus } from '../kernel/eventBus.js';
|
|
11
|
+
export class Snapshotter {
|
|
12
|
+
config = getConfig();
|
|
13
|
+
async createSnapshot() {
|
|
14
|
+
const snapshotId = `snapshot_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
15
|
+
const timestamp = new Date();
|
|
16
|
+
// Compute code hashes
|
|
17
|
+
const codeHashes = await this.computeCodeHashes();
|
|
18
|
+
// Capture current config
|
|
19
|
+
const config = {
|
|
20
|
+
...this.config,
|
|
21
|
+
// Don't include paths that change
|
|
22
|
+
workspaceRoot: this.config.workspaceRoot,
|
|
23
|
+
};
|
|
24
|
+
// Get current metrics (if any)
|
|
25
|
+
const metrics = [];
|
|
26
|
+
const snapshot = {
|
|
27
|
+
id: snapshotId,
|
|
28
|
+
timestamp,
|
|
29
|
+
codeHashes,
|
|
30
|
+
config: config,
|
|
31
|
+
metrics,
|
|
32
|
+
metadata: {
|
|
33
|
+
nodeVersion: process.version,
|
|
34
|
+
platform: process.platform,
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
// Emit event
|
|
38
|
+
const eventBus = getEventBus();
|
|
39
|
+
await eventBus.emit({
|
|
40
|
+
type: 'SnapshotCreated',
|
|
41
|
+
timestamp,
|
|
42
|
+
snapshotId,
|
|
43
|
+
});
|
|
44
|
+
return snapshot;
|
|
45
|
+
}
|
|
46
|
+
async computeCodeHashes() {
|
|
47
|
+
const hashes = {};
|
|
48
|
+
const srcPath = join(this.config.workspaceRoot, this.config.srcPath);
|
|
49
|
+
try {
|
|
50
|
+
// Find all TypeScript/JavaScript files
|
|
51
|
+
const files = await globby([
|
|
52
|
+
`${this.config.srcPath}/**/*.{ts,js,tsx,jsx}`,
|
|
53
|
+
`${this.config.testPath}/**/*.{ts,js,tsx,jsx}`,
|
|
54
|
+
], {
|
|
55
|
+
cwd: this.config.workspaceRoot,
|
|
56
|
+
ignore: ['node_modules', 'dist', '.basetree-v5'],
|
|
57
|
+
});
|
|
58
|
+
for (const file of files) {
|
|
59
|
+
try {
|
|
60
|
+
const fullPath = join(this.config.workspaceRoot, file);
|
|
61
|
+
const content = await fs.readFile(fullPath, 'utf-8');
|
|
62
|
+
const hash = createHash('sha256').update(content).digest('hex');
|
|
63
|
+
hashes[file] = hash;
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
console.warn(`Failed to hash file ${file}:`, error);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
console.warn('Failed to compute code hashes:', error);
|
|
72
|
+
}
|
|
73
|
+
return hashes;
|
|
74
|
+
}
|
|
75
|
+
async compareSnapshots(before, after) {
|
|
76
|
+
const changed = [];
|
|
77
|
+
const added = [];
|
|
78
|
+
const removed = [];
|
|
79
|
+
// Find changed and removed files
|
|
80
|
+
for (const file in before.codeHashes) {
|
|
81
|
+
if (!after.codeHashes[file]) {
|
|
82
|
+
removed.push(file);
|
|
83
|
+
}
|
|
84
|
+
else if (before.codeHashes[file] !== after.codeHashes[file]) {
|
|
85
|
+
changed.push(file);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
// Find added files
|
|
89
|
+
for (const file in after.codeHashes) {
|
|
90
|
+
if (!before.codeHashes[file]) {
|
|
91
|
+
added.push(file);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return { changed, added, removed };
|
|
95
|
+
}
|
|
96
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import fs from "fs-extra";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { globby } from "globby";
|
|
4
|
+
export class FileTools {
|
|
5
|
+
static async readFile(filePath) {
|
|
6
|
+
const absolutePath = path.resolve(process.cwd(), filePath);
|
|
7
|
+
return await fs.readFile(absolutePath, "utf-8");
|
|
8
|
+
}
|
|
9
|
+
static async writeFile(filePath, content) {
|
|
10
|
+
const absolutePath = path.resolve(process.cwd(), filePath);
|
|
11
|
+
await fs.ensureDir(path.dirname(absolutePath));
|
|
12
|
+
await fs.writeFile(absolutePath, content, "utf-8");
|
|
13
|
+
}
|
|
14
|
+
static async listFiles(pattern = "**/*", ignore = ["node_modules/**", "dist/**", ".git/**"]) {
|
|
15
|
+
return await globby(pattern, { ignore });
|
|
16
|
+
}
|
|
17
|
+
static async exists(filePath) {
|
|
18
|
+
const absolutePath = path.resolve(process.cwd(), filePath);
|
|
19
|
+
return await fs.pathExists(absolutePath);
|
|
20
|
+
}
|
|
21
|
+
static async deleteFile(filePath) {
|
|
22
|
+
const absolutePath = path.resolve(process.cwd(), filePath);
|
|
23
|
+
await fs.remove(absolutePath);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { ShellTools } from "./ShellTools.js";
|
|
2
|
+
export class GitTools {
|
|
3
|
+
static async getStatus() {
|
|
4
|
+
const result = await ShellTools.execute("git status --short");
|
|
5
|
+
return result.stdout;
|
|
6
|
+
}
|
|
7
|
+
static async commit(message) {
|
|
8
|
+
await ShellTools.execute("git add .");
|
|
9
|
+
const result = await ShellTools.execute(`git commit -m "${message}"`);
|
|
10
|
+
return result.stdout;
|
|
11
|
+
}
|
|
12
|
+
static async getDiff() {
|
|
13
|
+
const result = await ShellTools.execute("git diff");
|
|
14
|
+
return result.stdout;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { execa } from "execa";
|
|
2
|
+
export class ShellTools {
|
|
3
|
+
static async execute(command, args = []) {
|
|
4
|
+
try {
|
|
5
|
+
const result = await execa(command, args, {
|
|
6
|
+
shell: true,
|
|
7
|
+
all: true,
|
|
8
|
+
reject: false,
|
|
9
|
+
});
|
|
10
|
+
return {
|
|
11
|
+
stdout: result.stdout || "",
|
|
12
|
+
stderr: result.stderr || "",
|
|
13
|
+
exitCode: result.exitCode ?? 0
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
catch (error) {
|
|
17
|
+
return {
|
|
18
|
+
stdout: error.stdout || "",
|
|
19
|
+
stderr: error.stderr || error.message,
|
|
20
|
+
exitCode: error.exitCode ?? 1,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|