aiden-runtime 3.16.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/LICENSE +661 -0
- package/README.md +465 -0
- package/config/devos.config.json +186 -0
- package/config/hardware.json +9 -0
- package/config/model-selection.json +7 -0
- package/config/setup-complete.json +20 -0
- package/dist/api/routes/computerUse.js +112 -0
- package/dist/api/server.js +6870 -0
- package/dist/bin/npx-init.js +71 -0
- package/dist/coordination/commandGate.js +115 -0
- package/dist/coordination/livePulse.js +127 -0
- package/dist/core/agentLoop.js +2718 -0
- package/dist/core/agentShield.js +231 -0
- package/dist/core/aidenIdentity.js +215 -0
- package/dist/core/aidenPersonality.js +166 -0
- package/dist/core/aidenSdk.js +374 -0
- package/dist/core/asyncTasks.js +82 -0
- package/dist/core/auditTrail.js +61 -0
- package/dist/core/auxiliaryClient.js +114 -0
- package/dist/core/bgLLM.js +108 -0
- package/dist/core/bm25.js +68 -0
- package/dist/core/callbackSystem.js +64 -0
- package/dist/core/channels/adapter.js +6 -0
- package/dist/core/channels/discord.js +173 -0
- package/dist/core/channels/email.js +253 -0
- package/dist/core/channels/imessage.js +164 -0
- package/dist/core/channels/manager.js +96 -0
- package/dist/core/channels/signal.js +140 -0
- package/dist/core/channels/slack.js +139 -0
- package/dist/core/channels/twilio.js +144 -0
- package/dist/core/channels/webhook.js +186 -0
- package/dist/core/channels/whatsapp.js +185 -0
- package/dist/core/clarifyBus.js +75 -0
- package/dist/core/codeInterpreter.js +82 -0
- package/dist/core/computerControl.js +439 -0
- package/dist/core/conversationMemory.js +334 -0
- package/dist/core/costTracker.js +221 -0
- package/dist/core/cronManager.js +217 -0
- package/dist/core/deepKB.js +77 -0
- package/dist/core/doctor.js +279 -0
- package/dist/core/dreamEngine.js +334 -0
- package/dist/core/entityGraph.js +169 -0
- package/dist/core/eventBus.js +16 -0
- package/dist/core/evolutionAnalyzer.js +153 -0
- package/dist/core/executionLoop.js +309 -0
- package/dist/core/executor.js +224 -0
- package/dist/core/failureAnalyzer.js +166 -0
- package/dist/core/fastPathExpansion.js +82 -0
- package/dist/core/faultEngine.js +106 -0
- package/dist/core/featureGates.js +70 -0
- package/dist/core/fileIngestion.js +113 -0
- package/dist/core/gateway.js +97 -0
- package/dist/core/goalTracker.js +75 -0
- package/dist/core/growthEngine.js +168 -0
- package/dist/core/hardwareDetector.js +98 -0
- package/dist/core/hooks.js +45 -0
- package/dist/core/httpKeepalive.js +46 -0
- package/dist/core/hybridSearch.js +101 -0
- package/dist/core/importers.js +164 -0
- package/dist/core/instinctSystem.js +223 -0
- package/dist/core/knowledgeBase.js +351 -0
- package/dist/core/learningMemory.js +121 -0
- package/dist/core/lessonsBrowser.js +125 -0
- package/dist/core/licenseManager.js +399 -0
- package/dist/core/logBuffer.js +85 -0
- package/dist/core/machineId.js +87 -0
- package/dist/core/mcpClient.js +442 -0
- package/dist/core/memoryDistiller.js +165 -0
- package/dist/core/memoryExtractor.js +212 -0
- package/dist/core/memoryIds.js +213 -0
- package/dist/core/memoryPreamble.js +113 -0
- package/dist/core/memoryQuery.js +136 -0
- package/dist/core/memoryRecall.js +140 -0
- package/dist/core/memoryStrategy.js +201 -0
- package/dist/core/messageValidator.js +85 -0
- package/dist/core/modelDiscovery.js +108 -0
- package/dist/core/modelRouter.js +118 -0
- package/dist/core/morningBriefing.js +203 -0
- package/dist/core/multiGoalValidator.js +51 -0
- package/dist/core/parallelExecutor.js +43 -0
- package/dist/core/passiveSkillObserver.js +204 -0
- package/dist/core/paths.js +57 -0
- package/dist/core/patternDetector.js +83 -0
- package/dist/core/planResponseRepair.js +64 -0
- package/dist/core/planTool.js +111 -0
- package/dist/core/playwrightBridge.js +356 -0
- package/dist/core/pluginSystem.js +121 -0
- package/dist/core/privateMode.js +85 -0
- package/dist/core/reactLoop.js +156 -0
- package/dist/core/recipeEngine.js +166 -0
- package/dist/core/responseCache.js +128 -0
- package/dist/core/runSandbox.js +132 -0
- package/dist/core/sandboxRunner.js +200 -0
- package/dist/core/scheduler.js +543 -0
- package/dist/core/secretScanner.js +49 -0
- package/dist/core/semanticMemory.js +223 -0
- package/dist/core/sessionMemory.js +259 -0
- package/dist/core/sessionRouter.js +91 -0
- package/dist/core/sessionSearch.js +163 -0
- package/dist/core/setupWizard.js +225 -0
- package/dist/core/skillImporter.js +303 -0
- package/dist/core/skillLibrary.js +144 -0
- package/dist/core/skillLoader.js +471 -0
- package/dist/core/skillTeacher.js +352 -0
- package/dist/core/skillValidator.js +210 -0
- package/dist/core/skillWriter.js +384 -0
- package/dist/core/slashAsTool.js +226 -0
- package/dist/core/spawnManager.js +197 -0
- package/dist/core/statusVerbs.js +43 -0
- package/dist/core/swarmManager.js +109 -0
- package/dist/core/taskQueue.js +119 -0
- package/dist/core/taskRecovery.js +128 -0
- package/dist/core/taskState.js +168 -0
- package/dist/core/telegramBot.js +152 -0
- package/dist/core/todoManager.js +70 -0
- package/dist/core/toolNameRepair.js +71 -0
- package/dist/core/toolRegistry.js +2730 -0
- package/dist/core/tools/calendarTool.js +98 -0
- package/dist/core/tools/companyFilingsTool.js +98 -0
- package/dist/core/tools/gmailTool.js +87 -0
- package/dist/core/tools/marketDataTool.js +135 -0
- package/dist/core/tools/socialResearchTool.js +121 -0
- package/dist/core/truthCheck.js +57 -0
- package/dist/core/updateChecker.js +74 -0
- package/dist/core/userCognitionProfile.js +238 -0
- package/dist/core/userProfile.js +341 -0
- package/dist/core/version.js +5 -0
- package/dist/core/visionAnalyze.js +161 -0
- package/dist/core/voice/audio.js +187 -0
- package/dist/core/voice/stt.js +226 -0
- package/dist/core/voice/tts.js +310 -0
- package/dist/core/voiceInput.js +118 -0
- package/dist/core/voiceOutput.js +130 -0
- package/dist/core/webSearch.js +326 -0
- package/dist/core/workflowTracker.js +72 -0
- package/dist/core/workspaceMemory.js +54 -0
- package/dist/core/youtubeTranscript.js +224 -0
- package/dist/integrations/computerUse/apiRegistry.js +113 -0
- package/dist/integrations/computerUse/screenAgent.js +203 -0
- package/dist/integrations/computerUse/visionLoop.js +296 -0
- package/dist/memory/memoryLayers.js +143 -0
- package/dist/providers/boa.js +93 -0
- package/dist/providers/cerebras.js +70 -0
- package/dist/providers/custom.js +89 -0
- package/dist/providers/gemini.js +82 -0
- package/dist/providers/groq.js +92 -0
- package/dist/providers/index.js +149 -0
- package/dist/providers/nvidia.js +70 -0
- package/dist/providers/ollama.js +99 -0
- package/dist/providers/openrouter.js +74 -0
- package/dist/providers/router.js +497 -0
- package/dist/providers/types.js +6 -0
- package/dist/security/browserVault.js +129 -0
- package/dist/security/dataGuard.js +89 -0
- package/dist/tools/eonetTool.js +72 -0
- package/dist/types/computerUse.js +2 -0
- package/dist/types/executor.js +2 -0
- package/dist-bundle/cli.js +357859 -0
- package/package.json +256 -0
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ============================================================
|
|
3
|
+
// DevOS — Autonomous AI Execution System
|
|
4
|
+
// Copyright (c) 2026 Shiva Deore. All rights reserved.
|
|
5
|
+
// ============================================================
|
|
6
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
7
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
8
|
+
};
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.runDream = runDream;
|
|
11
|
+
exports.checkAndRunDream = checkAndRunDream;
|
|
12
|
+
// core/dreamEngine.ts — Background memory consolidation.
|
|
13
|
+
// Runs when: time since last dream >= 24h AND 5+ new sessions AND no lock.
|
|
14
|
+
// 4-phase: Orient → Gather → Consolidate → Prune.
|
|
15
|
+
// Restricted to read-only bash + write to workspace/memory/ only.
|
|
16
|
+
const fs_1 = __importDefault(require("fs"));
|
|
17
|
+
const path_1 = __importDefault(require("path"));
|
|
18
|
+
const auxiliaryClient_1 = require("./auxiliaryClient");
|
|
19
|
+
const auditTrail_1 = require("./auditTrail");
|
|
20
|
+
const LOCK_FILE = path_1.default.join(process.cwd(), 'workspace', 'dream.lock');
|
|
21
|
+
const MEMORY_DIR = path_1.default.join(process.cwd(), 'workspace', 'memory');
|
|
22
|
+
const SESSIONS_DIR = path_1.default.join(process.cwd(), 'workspace', 'sessions');
|
|
23
|
+
const INDEX_PATH = path_1.default.join(MEMORY_DIR, 'MEMORY_INDEX.md');
|
|
24
|
+
const GATE_HOURS = 24; // hours since last dream
|
|
25
|
+
const GATE_SESSIONS = 5; // new sessions required
|
|
26
|
+
function acquireLock() {
|
|
27
|
+
try {
|
|
28
|
+
fs_1.default.mkdirSync(path_1.default.dirname(LOCK_FILE), { recursive: true });
|
|
29
|
+
if (fs_1.default.existsSync(LOCK_FILE)) {
|
|
30
|
+
// Check if the lock holder is still alive
|
|
31
|
+
const raw = JSON.parse(fs_1.default.readFileSync(LOCK_FILE, 'utf-8'));
|
|
32
|
+
const alive = isPidAlive(raw.pid);
|
|
33
|
+
if (alive) {
|
|
34
|
+
console.log(`[DreamEngine] Lock held by PID ${raw.pid} — skipping`);
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
// PID is dead — steal the lock
|
|
38
|
+
console.log(`[DreamEngine] Stale lock (PID ${raw.pid} dead) — stealing`);
|
|
39
|
+
}
|
|
40
|
+
const data = { pid: process.pid, startedAt: new Date().toISOString() };
|
|
41
|
+
fs_1.default.writeFileSync(LOCK_FILE, JSON.stringify(data));
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function releaseLock(prevMtime) {
|
|
49
|
+
try {
|
|
50
|
+
if (prevMtime !== undefined) {
|
|
51
|
+
// Update mtime to now (marks lastConsolidatedAt)
|
|
52
|
+
const now = Date.now() / 1000;
|
|
53
|
+
fs_1.default.utimesSync(LOCK_FILE, now, now);
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
// On failure — restore prev mtime or just remove
|
|
57
|
+
fs_1.default.unlinkSync(LOCK_FILE);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
catch { }
|
|
61
|
+
}
|
|
62
|
+
function isPidAlive(pid) {
|
|
63
|
+
try {
|
|
64
|
+
process.kill(pid, 0);
|
|
65
|
+
return true;
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
function getLockMtime() {
|
|
72
|
+
try {
|
|
73
|
+
if (!fs_1.default.existsSync(LOCK_FILE))
|
|
74
|
+
return 0;
|
|
75
|
+
return fs_1.default.statSync(LOCK_FILE).mtimeMs;
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
return 0;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
// ── Gate checks ───────────────────────────────────────────────
|
|
82
|
+
function checkTimeGate(lockMtime) {
|
|
83
|
+
if (lockMtime === 0)
|
|
84
|
+
return true; // never run
|
|
85
|
+
const hoursSince = (Date.now() - lockMtime) / (1000 * 60 * 60);
|
|
86
|
+
return hoursSince >= GATE_HOURS;
|
|
87
|
+
}
|
|
88
|
+
function checkSessionGate(lockMtime) {
|
|
89
|
+
try {
|
|
90
|
+
if (!fs_1.default.existsSync(SESSIONS_DIR))
|
|
91
|
+
return false;
|
|
92
|
+
const cutoff = lockMtime || 0;
|
|
93
|
+
const newSessions = fs_1.default.readdirSync(SESSIONS_DIR)
|
|
94
|
+
.filter(f => f.endsWith('.md'))
|
|
95
|
+
.filter(f => {
|
|
96
|
+
try {
|
|
97
|
+
return fs_1.default.statSync(path_1.default.join(SESSIONS_DIR, f)).mtimeMs > cutoff;
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
return newSessions.length >= GATE_SESSIONS;
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
return false;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
function allGatesPass() {
|
|
110
|
+
const lockMtime = getLockMtime();
|
|
111
|
+
return checkTimeGate(lockMtime) && checkSessionGate(lockMtime);
|
|
112
|
+
}
|
|
113
|
+
// ── Dream phases ──────────────────────────────────────────────
|
|
114
|
+
async function phaseOrient() {
|
|
115
|
+
// List memory dir, read index, get overview
|
|
116
|
+
try {
|
|
117
|
+
const indexContent = fs_1.default.existsSync(INDEX_PATH)
|
|
118
|
+
? fs_1.default.readFileSync(INDEX_PATH, 'utf-8')
|
|
119
|
+
: '(empty)';
|
|
120
|
+
const memFiles = fs_1.default.existsSync(MEMORY_DIR)
|
|
121
|
+
? fs_1.default.readdirSync(MEMORY_DIR).filter(f => f.endsWith('.md') && f !== 'MEMORY_INDEX.md')
|
|
122
|
+
: [];
|
|
123
|
+
return `MEMORY DIRECTORY (${memFiles.length} files):\n${memFiles.join('\n')}\n\nCURRENT INDEX:\n${indexContent.slice(0, 2000)}`;
|
|
124
|
+
}
|
|
125
|
+
catch {
|
|
126
|
+
return '(unable to read memory directory)';
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
async function phaseGather(lockMtime) {
|
|
130
|
+
// Scan recent session transcripts for signal
|
|
131
|
+
try {
|
|
132
|
+
if (!fs_1.default.existsSync(SESSIONS_DIR))
|
|
133
|
+
return '(no sessions)';
|
|
134
|
+
const recentSessions = fs_1.default.readdirSync(SESSIONS_DIR)
|
|
135
|
+
.filter(f => f.endsWith('.md'))
|
|
136
|
+
.filter(f => {
|
|
137
|
+
try {
|
|
138
|
+
return fs_1.default.statSync(path_1.default.join(SESSIONS_DIR, f)).mtimeMs > lockMtime;
|
|
139
|
+
}
|
|
140
|
+
catch {
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
})
|
|
144
|
+
.slice(0, 10);
|
|
145
|
+
if (recentSessions.length === 0)
|
|
146
|
+
return '(no new sessions)';
|
|
147
|
+
const excerpts = recentSessions.map(f => {
|
|
148
|
+
try {
|
|
149
|
+
const content = fs_1.default.readFileSync(path_1.default.join(SESSIONS_DIR, f), 'utf-8');
|
|
150
|
+
return `=== ${f} ===\n${content.slice(0, 800)}`;
|
|
151
|
+
}
|
|
152
|
+
catch {
|
|
153
|
+
return `=== ${f} === (unreadable)`;
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
return excerpts.join('\n\n');
|
|
157
|
+
}
|
|
158
|
+
catch {
|
|
159
|
+
return '(unable to gather sessions)';
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
async function phaseConsolidate(orientData, gatherData) {
|
|
163
|
+
const prompt = `You are the DevOS Dream Engine performing memory consolidation.
|
|
164
|
+
|
|
165
|
+
CURRENT MEMORY STATE:
|
|
166
|
+
${orientData}
|
|
167
|
+
|
|
168
|
+
RECENT SESSION SIGNALS:
|
|
169
|
+
${gatherData}
|
|
170
|
+
|
|
171
|
+
Your job: identify facts from the sessions that should be preserved in long-term memory.
|
|
172
|
+
|
|
173
|
+
For each memory to write/update, output JSON:
|
|
174
|
+
[
|
|
175
|
+
{
|
|
176
|
+
"filename": "type_descriptor.md (e.g. user_coding_style.md, project_api_structure.md)",
|
|
177
|
+
"title": "Short descriptive title",
|
|
178
|
+
"type": "user_preference|project_fact|tool_pattern|learned_behavior",
|
|
179
|
+
"content": "Concise actionable content. 2-6 sentences. Convert relative dates to absolute (e.g. 'last week' → '2026-03-25').",
|
|
180
|
+
"summary": "One-line summary"
|
|
181
|
+
}
|
|
182
|
+
]
|
|
183
|
+
|
|
184
|
+
Rules:
|
|
185
|
+
- Merge with existing rather than create duplicates
|
|
186
|
+
- Focus on patterns, not one-off events
|
|
187
|
+
- Absolute dates only
|
|
188
|
+
- Output ONLY valid JSON array`;
|
|
189
|
+
try {
|
|
190
|
+
const raw = await auxiliaryClient_1.auxiliaryClient.complete(prompt, { task: 'dream', maxTokens: 500 });
|
|
191
|
+
if (!raw)
|
|
192
|
+
return { filesUpdated: 0 };
|
|
193
|
+
const jsonMatch = raw.replace(/```json\s*/g, '').replace(/```\s*/g, '').match(/\[[\s\S]*\]/);
|
|
194
|
+
if (!jsonMatch)
|
|
195
|
+
return { filesUpdated: 0 };
|
|
196
|
+
const items = JSON.parse(jsonMatch[0]);
|
|
197
|
+
if (!Array.isArray(items))
|
|
198
|
+
return { filesUpdated: 0 };
|
|
199
|
+
let filesUpdated = 0;
|
|
200
|
+
const now = new Date().toISOString().split('T')[0];
|
|
201
|
+
for (const item of items) {
|
|
202
|
+
if (!item.filename || !item.content)
|
|
203
|
+
continue;
|
|
204
|
+
const filePath = path_1.default.join(MEMORY_DIR, item.filename);
|
|
205
|
+
let created = now;
|
|
206
|
+
if (fs_1.default.existsSync(filePath)) {
|
|
207
|
+
try {
|
|
208
|
+
const existing = fs_1.default.readFileSync(filePath, 'utf-8');
|
|
209
|
+
const m = existing.match(/^created:\s*(.+)$/m);
|
|
210
|
+
if (m)
|
|
211
|
+
created = m[1].trim();
|
|
212
|
+
}
|
|
213
|
+
catch { }
|
|
214
|
+
}
|
|
215
|
+
const fileContent = `---
|
|
216
|
+
title: ${item.title}
|
|
217
|
+
type: ${item.type}
|
|
218
|
+
created: ${created}
|
|
219
|
+
updated: ${now}
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
${item.content.trim()}
|
|
223
|
+
`;
|
|
224
|
+
try {
|
|
225
|
+
fs_1.default.writeFileSync(filePath, fileContent, 'utf-8');
|
|
226
|
+
filesUpdated++;
|
|
227
|
+
}
|
|
228
|
+
catch { }
|
|
229
|
+
}
|
|
230
|
+
return { filesUpdated };
|
|
231
|
+
}
|
|
232
|
+
catch (e) {
|
|
233
|
+
console.error('[DreamEngine] Consolidate phase failed:', e.message);
|
|
234
|
+
return { filesUpdated: 0 };
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
async function phasePrune(filesUpdated) {
|
|
238
|
+
// Rebuild MEMORY_INDEX.md — max 100 entries
|
|
239
|
+
try {
|
|
240
|
+
if (!fs_1.default.existsSync(MEMORY_DIR))
|
|
241
|
+
return;
|
|
242
|
+
const files = fs_1.default.readdirSync(MEMORY_DIR)
|
|
243
|
+
.filter(f => f.endsWith('.md') && f !== 'MEMORY_INDEX.md')
|
|
244
|
+
.map(f => {
|
|
245
|
+
try {
|
|
246
|
+
const content = fs_1.default.readFileSync(path_1.default.join(MEMORY_DIR, f), 'utf-8');
|
|
247
|
+
const titleM = content.match(/^title:\s*(.+)$/m);
|
|
248
|
+
const sumM = content.match(/---\n+([\s\S]+?)(?:\n\n|$)/);
|
|
249
|
+
const title = titleM ? titleM[1].trim() : f.replace('.md', '');
|
|
250
|
+
const summary = sumM
|
|
251
|
+
? sumM[1].trim().replace(/\n/g, ' ').slice(0, 80)
|
|
252
|
+
: '';
|
|
253
|
+
return `- [${title}](${f}) — ${summary}`;
|
|
254
|
+
}
|
|
255
|
+
catch {
|
|
256
|
+
return null;
|
|
257
|
+
}
|
|
258
|
+
})
|
|
259
|
+
.filter((l) => l !== null)
|
|
260
|
+
.slice(0, 100);
|
|
261
|
+
fs_1.default.writeFileSync(INDEX_PATH, files.join('\n') + '\n', 'utf-8');
|
|
262
|
+
console.log(`[DreamEngine] Pruned index to ${files.length} entries (${filesUpdated} files updated)`);
|
|
263
|
+
}
|
|
264
|
+
catch (e) {
|
|
265
|
+
console.error('[DreamEngine] Prune phase failed:', e.message);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
// ── Main dream runner ─────────────────────────────────────────
|
|
269
|
+
async function runDream() {
|
|
270
|
+
if (!allGatesPass()) {
|
|
271
|
+
console.log('[DreamEngine] Gates not met — skipping');
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
const prevMtime = getLockMtime();
|
|
275
|
+
if (!acquireLock())
|
|
276
|
+
return;
|
|
277
|
+
const traceId = `dream_${Date.now()}`;
|
|
278
|
+
console.log('[DreamEngine] Dream starting...');
|
|
279
|
+
let sessionsReviewed = 0;
|
|
280
|
+
let filesUpdated = 0;
|
|
281
|
+
try {
|
|
282
|
+
fs_1.default.mkdirSync(MEMORY_DIR, { recursive: true });
|
|
283
|
+
// Phase 1: Orient
|
|
284
|
+
console.log('[DreamEngine] Phase 1: Orient');
|
|
285
|
+
const orientData = await phaseOrient();
|
|
286
|
+
// Phase 2: Gather
|
|
287
|
+
console.log('[DreamEngine] Phase 2: Gather');
|
|
288
|
+
const gatherData = await phaseGather(prevMtime);
|
|
289
|
+
sessionsReviewed = (gatherData.match(/=== .+\.md ===/g) || []).length;
|
|
290
|
+
// Phase 3: Consolidate
|
|
291
|
+
console.log('[DreamEngine] Phase 3: Consolidate');
|
|
292
|
+
const result = await phaseConsolidate(orientData, gatherData);
|
|
293
|
+
filesUpdated = result.filesUpdated;
|
|
294
|
+
// Phase 4: Prune
|
|
295
|
+
console.log('[DreamEngine] Phase 4: Prune');
|
|
296
|
+
await phasePrune(filesUpdated);
|
|
297
|
+
// Update lock mtime = lastConsolidatedAt
|
|
298
|
+
releaseLock(prevMtime);
|
|
299
|
+
// Log to AuditTrail
|
|
300
|
+
try {
|
|
301
|
+
auditTrail_1.auditTrail.record({
|
|
302
|
+
action: 'system',
|
|
303
|
+
tool: 'dream_completed',
|
|
304
|
+
input: JSON.stringify({ traceId }),
|
|
305
|
+
output: JSON.stringify({ filesUpdated, sessionsReviewed }),
|
|
306
|
+
durationMs: 0,
|
|
307
|
+
success: true,
|
|
308
|
+
traceId,
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
catch { }
|
|
312
|
+
console.log(`[DreamEngine] Dream complete — ${filesUpdated} files updated, ${sessionsReviewed} sessions reviewed`);
|
|
313
|
+
}
|
|
314
|
+
catch (e) {
|
|
315
|
+
console.error('[DreamEngine] Dream failed:', e.message);
|
|
316
|
+
// Roll back lock mtime
|
|
317
|
+
try {
|
|
318
|
+
if (prevMtime > 0) {
|
|
319
|
+
const t = prevMtime / 1000;
|
|
320
|
+
fs_1.default.utimesSync(LOCK_FILE, t, t);
|
|
321
|
+
}
|
|
322
|
+
else {
|
|
323
|
+
fs_1.default.unlinkSync(LOCK_FILE);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
catch { }
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
// ── Check and run (called by scheduler) ───────────────────────
|
|
330
|
+
function checkAndRunDream() {
|
|
331
|
+
if (!allGatesPass())
|
|
332
|
+
return;
|
|
333
|
+
runDream().catch(e => console.error('[DreamEngine] Unhandled error:', e.message));
|
|
334
|
+
}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ============================================================
|
|
3
|
+
// DevOS — Autonomous AI Execution System
|
|
4
|
+
// Copyright (c) 2026 Shiva Deore. All rights reserved.
|
|
5
|
+
// ============================================================
|
|
6
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
7
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
8
|
+
};
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.entityGraph = exports.EntityGraph = void 0;
|
|
11
|
+
// core/entityGraph.ts — Lightweight entity graph that auto-extracts
|
|
12
|
+
// topics, files, tools, and searches from conversation text, and
|
|
13
|
+
// tracks weighted relationships between them.
|
|
14
|
+
const fs_1 = __importDefault(require("fs"));
|
|
15
|
+
const path_1 = __importDefault(require("path"));
|
|
16
|
+
const GRAPH_PATH = path_1.default.join(process.cwd(), 'workspace', 'entity_graph.json');
|
|
17
|
+
class EntityGraph {
|
|
18
|
+
constructor() {
|
|
19
|
+
this.graph = { nodes: [], edges: [] };
|
|
20
|
+
this.load();
|
|
21
|
+
}
|
|
22
|
+
// ── Persistence ───────────────────────────────────────────────
|
|
23
|
+
load() {
|
|
24
|
+
try {
|
|
25
|
+
if (fs_1.default.existsSync(GRAPH_PATH)) {
|
|
26
|
+
this.graph = JSON.parse(fs_1.default.readFileSync(GRAPH_PATH, 'utf-8'));
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
catch { }
|
|
30
|
+
}
|
|
31
|
+
save() {
|
|
32
|
+
try {
|
|
33
|
+
fs_1.default.mkdirSync(path_1.default.dirname(GRAPH_PATH), { recursive: true });
|
|
34
|
+
fs_1.default.writeFileSync(GRAPH_PATH, JSON.stringify(this.graph, null, 2));
|
|
35
|
+
}
|
|
36
|
+
catch { }
|
|
37
|
+
}
|
|
38
|
+
// ── Entity extraction ─────────────────────────────────────────
|
|
39
|
+
extractAndAdd(text, context) {
|
|
40
|
+
const extracted = [];
|
|
41
|
+
// Extract Windows file paths
|
|
42
|
+
const filePaths = text.match(/[A-Z]:\\[^\s"']+\.[a-z]+/gi) || [];
|
|
43
|
+
filePaths.forEach(f => extracted.push({ name: f, type: 'file' }));
|
|
44
|
+
// Extract quoted terms
|
|
45
|
+
const quoted = text.match(/"([^"]{3,40})"/g)?.map(q => q.replace(/"/g, '')) || [];
|
|
46
|
+
quoted.forEach(q => extracted.push({ name: q, type: 'concept' }));
|
|
47
|
+
// Extract capitalized multi-word phrases (likely proper nouns / product names)
|
|
48
|
+
const phrases = text.match(/\b([A-Z][a-zA-Z]+(?:\s[A-Z][a-zA-Z]+){0,2})\b/g) || [];
|
|
49
|
+
const skipWords = new Set([
|
|
50
|
+
'The', 'This', 'That', 'You', 'Your', 'I', 'We', 'It',
|
|
51
|
+
'In', 'On', 'At', 'To', 'For', 'Of', 'And', 'Or', 'But',
|
|
52
|
+
'Aiden', 'DevOS', 'Windows', 'Step', 'Phase', 'Task',
|
|
53
|
+
]);
|
|
54
|
+
phrases
|
|
55
|
+
.filter(p => !skipWords.has(p) && p.length > 3)
|
|
56
|
+
.slice(0, 10)
|
|
57
|
+
.forEach(p => extracted.push({ name: p, type: 'topic' }));
|
|
58
|
+
// Add context entities
|
|
59
|
+
if (context?.files) {
|
|
60
|
+
context.files.forEach(f => extracted.push({ name: f, type: 'file' }));
|
|
61
|
+
}
|
|
62
|
+
if (context?.tools) {
|
|
63
|
+
context.tools.forEach(t => extracted.push({ name: t, type: 'tool' }));
|
|
64
|
+
}
|
|
65
|
+
if (context?.searchQuery) {
|
|
66
|
+
extracted.push({ name: context.searchQuery, type: 'search' });
|
|
67
|
+
}
|
|
68
|
+
// Upsert all extracted entities as nodes
|
|
69
|
+
extracted.forEach(({ name, type }) => this.addNode(name, type));
|
|
70
|
+
// Create edges between co-occurring entities (sliding window of 3)
|
|
71
|
+
const names = extracted.map(e => e.name);
|
|
72
|
+
for (let i = 0; i < names.length; i++) {
|
|
73
|
+
for (let j = i + 1; j < names.length && j < i + 3; j++) {
|
|
74
|
+
this.addEdge(names[i], names[j], 'related_to');
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
// Semantic relationship: search query → files created
|
|
78
|
+
if (context?.files && context?.searchQuery) {
|
|
79
|
+
context.files.forEach(f => {
|
|
80
|
+
this.addEdge(context.searchQuery, f, 'saved_to');
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
this.save();
|
|
84
|
+
}
|
|
85
|
+
// ── Graph mutation ────────────────────────────────────────────
|
|
86
|
+
addNode(name, type) {
|
|
87
|
+
if (!name || name.length < 2 || name.length > 200)
|
|
88
|
+
return;
|
|
89
|
+
const existing = this.graph.nodes.find(n => n.name === name);
|
|
90
|
+
if (existing) {
|
|
91
|
+
existing.lastSeen = Date.now();
|
|
92
|
+
existing.frequency++;
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
this.graph.nodes.push({
|
|
96
|
+
name,
|
|
97
|
+
type,
|
|
98
|
+
firstSeen: Date.now(),
|
|
99
|
+
lastSeen: Date.now(),
|
|
100
|
+
frequency: 1,
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
// Cap node count
|
|
104
|
+
if (this.graph.nodes.length > 1000) {
|
|
105
|
+
this.graph.nodes = this.graph.nodes
|
|
106
|
+
.sort((a, b) => b.frequency - a.frequency)
|
|
107
|
+
.slice(0, 800);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
addEdge(from, to, relation) {
|
|
111
|
+
if (from === to)
|
|
112
|
+
return;
|
|
113
|
+
const existing = this.graph.edges.find(e => e.from === from && e.to === to && e.relation === relation);
|
|
114
|
+
if (existing) {
|
|
115
|
+
existing.weight++;
|
|
116
|
+
existing.timestamp = Date.now();
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
this.graph.edges.push({ from, to, relation, weight: 1, timestamp: Date.now() });
|
|
120
|
+
}
|
|
121
|
+
// Cap edge count
|
|
122
|
+
if (this.graph.edges.length > 2000) {
|
|
123
|
+
this.graph.edges = this.graph.edges
|
|
124
|
+
.sort((a, b) => b.weight - a.weight)
|
|
125
|
+
.slice(0, 1500);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
// ── Public API ────────────────────────────────────────────────
|
|
129
|
+
getRelated(entity, maxResults = 5) {
|
|
130
|
+
const related = this.graph.edges
|
|
131
|
+
.filter(e => e.from === entity || e.to === entity)
|
|
132
|
+
.sort((a, b) => b.weight - a.weight)
|
|
133
|
+
.slice(0, maxResults)
|
|
134
|
+
.map(e => {
|
|
135
|
+
const other = e.from === entity ? e.to : e.from;
|
|
136
|
+
return `${other} (${e.relation})`;
|
|
137
|
+
});
|
|
138
|
+
return [...new Set(related)];
|
|
139
|
+
}
|
|
140
|
+
getFrequent(topN = 10) {
|
|
141
|
+
return [...this.graph.nodes]
|
|
142
|
+
.sort((a, b) => b.frequency - a.frequency)
|
|
143
|
+
.slice(0, topN);
|
|
144
|
+
}
|
|
145
|
+
buildContextString(_query) {
|
|
146
|
+
const frequent = this.getFrequent(5);
|
|
147
|
+
if (frequent.length === 0)
|
|
148
|
+
return '';
|
|
149
|
+
const lines = ['KNOWN ENTITIES:'];
|
|
150
|
+
frequent.forEach(node => {
|
|
151
|
+
const related = this.getRelated(node.name, 3);
|
|
152
|
+
if (related.length > 0) {
|
|
153
|
+
lines.push(`- ${node.name} (${node.type}) → ${related.join(', ')}`);
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
lines.push(`- ${node.name} (${node.type})`);
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
return lines.join('\n');
|
|
160
|
+
}
|
|
161
|
+
getStats() {
|
|
162
|
+
return {
|
|
163
|
+
nodes: this.graph.nodes.length,
|
|
164
|
+
edges: this.graph.edges.length,
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
exports.EntityGraph = EntityGraph;
|
|
169
|
+
exports.entityGraph = new EntityGraph();
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ============================================================
|
|
3
|
+
// DevOS — Autonomous AI Execution System
|
|
4
|
+
// Copyright (c) 2026 Shiva Deore. All rights reserved.
|
|
5
|
+
// ============================================================
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.eventBus = void 0;
|
|
8
|
+
// core/eventBus.ts — Lightweight in-process event bus.
|
|
9
|
+
// Used by costTracker and aidenIdentity to push updates to
|
|
10
|
+
// any subscriber (e.g. api/server.ts → WebSocket clients).
|
|
11
|
+
const events_1 = require("events");
|
|
12
|
+
class DevOSEventBus extends events_1.EventEmitter {
|
|
13
|
+
}
|
|
14
|
+
exports.eventBus = new DevOSEventBus();
|
|
15
|
+
// Increase listener limit — many subsystems may subscribe
|
|
16
|
+
exports.eventBus.setMaxListeners(50);
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ============================================================
|
|
3
|
+
// DevOS — Autonomous AI Execution System
|
|
4
|
+
// Copyright (c) 2026 Shiva Deore. All rights reserved.
|
|
5
|
+
// ============================================================
|
|
6
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
7
|
+
if (k2 === undefined) k2 = k;
|
|
8
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
9
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
10
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
11
|
+
}
|
|
12
|
+
Object.defineProperty(o, k2, desc);
|
|
13
|
+
}) : (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
o[k2] = m[k];
|
|
16
|
+
}));
|
|
17
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
18
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
19
|
+
}) : function(o, v) {
|
|
20
|
+
o["default"] = v;
|
|
21
|
+
});
|
|
22
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
23
|
+
var ownKeys = function(o) {
|
|
24
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
25
|
+
var ar = [];
|
|
26
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
27
|
+
return ar;
|
|
28
|
+
};
|
|
29
|
+
return ownKeys(o);
|
|
30
|
+
};
|
|
31
|
+
return function (mod) {
|
|
32
|
+
if (mod && mod.__esModule) return mod;
|
|
33
|
+
var result = {};
|
|
34
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
35
|
+
__setModuleDefault(result, mod);
|
|
36
|
+
return result;
|
|
37
|
+
};
|
|
38
|
+
})();
|
|
39
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
|
+
exports.evolutionAnalyzer = void 0;
|
|
41
|
+
// core/evolutionAnalyzer.ts — Self-evolution: tracks execution reports,
|
|
42
|
+
// computes per-skill stats, and decides which skills need attention.
|
|
43
|
+
const fs = __importStar(require("fs"));
|
|
44
|
+
const path = __importStar(require("path"));
|
|
45
|
+
// ── File paths ────────────────────────────────────────────────
|
|
46
|
+
const REPORTS_FILE = path.join(process.cwd(), 'workspace', 'evolution-reports.json');
|
|
47
|
+
const STATS_FILE = path.join(process.cwd(), 'workspace', 'evolution-stats.json');
|
|
48
|
+
const HISTORY_FILE = path.join(process.cwd(), 'workspace', 'evolution-history.json');
|
|
49
|
+
// ── Helpers ───────────────────────────────────────────────────
|
|
50
|
+
function readJSON(file, fallback) {
|
|
51
|
+
try {
|
|
52
|
+
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
53
|
+
return JSON.parse(fs.readFileSync(file, 'utf-8'));
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
return fallback;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
function writeJSON(file, data) {
|
|
60
|
+
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
61
|
+
fs.writeFileSync(file, JSON.stringify(data, null, 2), 'utf-8');
|
|
62
|
+
}
|
|
63
|
+
// ── EvolutionAnalyzer ─────────────────────────────────────────
|
|
64
|
+
class EvolutionAnalyzer {
|
|
65
|
+
/** Store a completed execution report, then re-analyse. */
|
|
66
|
+
collect(report) {
|
|
67
|
+
const reports = readJSON(REPORTS_FILE, []);
|
|
68
|
+
reports.push(report);
|
|
69
|
+
writeJSON(REPORTS_FILE, reports.slice(-200));
|
|
70
|
+
this.analyze();
|
|
71
|
+
}
|
|
72
|
+
/** Extract per-skill stats from all stored reports. */
|
|
73
|
+
analyze() {
|
|
74
|
+
const reports = readJSON(REPORTS_FILE, []);
|
|
75
|
+
const skillMap = {};
|
|
76
|
+
for (const report of reports) {
|
|
77
|
+
for (const step of report.steps) {
|
|
78
|
+
if (!skillMap[step.skill]) {
|
|
79
|
+
skillMap[step.skill] = { runs: 0, successes: 0, times: [], errors: [] };
|
|
80
|
+
}
|
|
81
|
+
skillMap[step.skill].runs++;
|
|
82
|
+
if (step.success)
|
|
83
|
+
skillMap[step.skill].successes++;
|
|
84
|
+
skillMap[step.skill].times.push(step.duration);
|
|
85
|
+
if (step.error)
|
|
86
|
+
skillMap[step.skill].errors.push(step.error);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
const stats = Object.entries(skillMap).map(([skill, data]) => {
|
|
90
|
+
const successRate = data.successes / data.runs;
|
|
91
|
+
const avgTime = data.times.reduce((a, b) => a + b, 0) / data.times.length;
|
|
92
|
+
// Count common errors
|
|
93
|
+
const errorCount = {};
|
|
94
|
+
data.errors.forEach(e => { errorCount[e] = (errorCount[e] || 0) + 1; });
|
|
95
|
+
const commonErrors = Object.entries(errorCount)
|
|
96
|
+
.sort((a, b) => b[1] - a[1])
|
|
97
|
+
.slice(0, 3)
|
|
98
|
+
.map(([e]) => e);
|
|
99
|
+
// Decision engine — rules based
|
|
100
|
+
let decision = 'GOOD';
|
|
101
|
+
if (data.runs < 3)
|
|
102
|
+
decision = 'GOOD'; // not enough data
|
|
103
|
+
else if (successRate < 0.3)
|
|
104
|
+
decision = 'REPLACE';
|
|
105
|
+
else if (successRate < 0.6)
|
|
106
|
+
decision = 'IMPROVE';
|
|
107
|
+
else if (avgTime > 30000)
|
|
108
|
+
decision = 'OPTIMIZE';
|
|
109
|
+
else if (data.runs === 0)
|
|
110
|
+
decision = 'REMOVE';
|
|
111
|
+
return {
|
|
112
|
+
skill,
|
|
113
|
+
totalRuns: data.runs,
|
|
114
|
+
successRate,
|
|
115
|
+
avgTime,
|
|
116
|
+
commonErrors,
|
|
117
|
+
decision,
|
|
118
|
+
lastUpdated: Date.now(),
|
|
119
|
+
};
|
|
120
|
+
});
|
|
121
|
+
writeJSON(STATS_FILE, stats);
|
|
122
|
+
return stats;
|
|
123
|
+
}
|
|
124
|
+
/** Get current stats (from file cache). */
|
|
125
|
+
getStats() {
|
|
126
|
+
return readJSON(STATS_FILE, []);
|
|
127
|
+
}
|
|
128
|
+
/** Get skills that need attention (not GOOD). */
|
|
129
|
+
getDecisions() {
|
|
130
|
+
return this.getStats().filter(s => s.decision !== 'GOOD');
|
|
131
|
+
}
|
|
132
|
+
/** Log an evolution event (what changed and measured impact). */
|
|
133
|
+
recordEvolution(entry) {
|
|
134
|
+
const history = readJSON(HISTORY_FILE, []);
|
|
135
|
+
history.push({ ...entry, timestamp: Date.now() });
|
|
136
|
+
writeJSON(HISTORY_FILE, history.slice(-100));
|
|
137
|
+
}
|
|
138
|
+
/** Get full evolution history. */
|
|
139
|
+
getHistory() {
|
|
140
|
+
return readJSON(HISTORY_FILE, []);
|
|
141
|
+
}
|
|
142
|
+
/** Summary string for devos doctor. */
|
|
143
|
+
getSummary() {
|
|
144
|
+
const stats = this.getStats();
|
|
145
|
+
const decisions = this.getDecisions();
|
|
146
|
+
const reports = readJSON(REPORTS_FILE, []);
|
|
147
|
+
const avgSuccess = stats.length
|
|
148
|
+
? stats.reduce((a, s) => a + s.successRate, 0) / stats.length
|
|
149
|
+
: 0;
|
|
150
|
+
return `${reports.length} executions tracked · ${stats.length} skills · ${decisions.length} need attention · avg success ${Math.round(avgSuccess * 100)}%`;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
exports.evolutionAnalyzer = new EvolutionAnalyzer();
|