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.
Files changed (159) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +465 -0
  3. package/config/devos.config.json +186 -0
  4. package/config/hardware.json +9 -0
  5. package/config/model-selection.json +7 -0
  6. package/config/setup-complete.json +20 -0
  7. package/dist/api/routes/computerUse.js +112 -0
  8. package/dist/api/server.js +6870 -0
  9. package/dist/bin/npx-init.js +71 -0
  10. package/dist/coordination/commandGate.js +115 -0
  11. package/dist/coordination/livePulse.js +127 -0
  12. package/dist/core/agentLoop.js +2718 -0
  13. package/dist/core/agentShield.js +231 -0
  14. package/dist/core/aidenIdentity.js +215 -0
  15. package/dist/core/aidenPersonality.js +166 -0
  16. package/dist/core/aidenSdk.js +374 -0
  17. package/dist/core/asyncTasks.js +82 -0
  18. package/dist/core/auditTrail.js +61 -0
  19. package/dist/core/auxiliaryClient.js +114 -0
  20. package/dist/core/bgLLM.js +108 -0
  21. package/dist/core/bm25.js +68 -0
  22. package/dist/core/callbackSystem.js +64 -0
  23. package/dist/core/channels/adapter.js +6 -0
  24. package/dist/core/channels/discord.js +173 -0
  25. package/dist/core/channels/email.js +253 -0
  26. package/dist/core/channels/imessage.js +164 -0
  27. package/dist/core/channels/manager.js +96 -0
  28. package/dist/core/channels/signal.js +140 -0
  29. package/dist/core/channels/slack.js +139 -0
  30. package/dist/core/channels/twilio.js +144 -0
  31. package/dist/core/channels/webhook.js +186 -0
  32. package/dist/core/channels/whatsapp.js +185 -0
  33. package/dist/core/clarifyBus.js +75 -0
  34. package/dist/core/codeInterpreter.js +82 -0
  35. package/dist/core/computerControl.js +439 -0
  36. package/dist/core/conversationMemory.js +334 -0
  37. package/dist/core/costTracker.js +221 -0
  38. package/dist/core/cronManager.js +217 -0
  39. package/dist/core/deepKB.js +77 -0
  40. package/dist/core/doctor.js +279 -0
  41. package/dist/core/dreamEngine.js +334 -0
  42. package/dist/core/entityGraph.js +169 -0
  43. package/dist/core/eventBus.js +16 -0
  44. package/dist/core/evolutionAnalyzer.js +153 -0
  45. package/dist/core/executionLoop.js +309 -0
  46. package/dist/core/executor.js +224 -0
  47. package/dist/core/failureAnalyzer.js +166 -0
  48. package/dist/core/fastPathExpansion.js +82 -0
  49. package/dist/core/faultEngine.js +106 -0
  50. package/dist/core/featureGates.js +70 -0
  51. package/dist/core/fileIngestion.js +113 -0
  52. package/dist/core/gateway.js +97 -0
  53. package/dist/core/goalTracker.js +75 -0
  54. package/dist/core/growthEngine.js +168 -0
  55. package/dist/core/hardwareDetector.js +98 -0
  56. package/dist/core/hooks.js +45 -0
  57. package/dist/core/httpKeepalive.js +46 -0
  58. package/dist/core/hybridSearch.js +101 -0
  59. package/dist/core/importers.js +164 -0
  60. package/dist/core/instinctSystem.js +223 -0
  61. package/dist/core/knowledgeBase.js +351 -0
  62. package/dist/core/learningMemory.js +121 -0
  63. package/dist/core/lessonsBrowser.js +125 -0
  64. package/dist/core/licenseManager.js +399 -0
  65. package/dist/core/logBuffer.js +85 -0
  66. package/dist/core/machineId.js +87 -0
  67. package/dist/core/mcpClient.js +442 -0
  68. package/dist/core/memoryDistiller.js +165 -0
  69. package/dist/core/memoryExtractor.js +212 -0
  70. package/dist/core/memoryIds.js +213 -0
  71. package/dist/core/memoryPreamble.js +113 -0
  72. package/dist/core/memoryQuery.js +136 -0
  73. package/dist/core/memoryRecall.js +140 -0
  74. package/dist/core/memoryStrategy.js +201 -0
  75. package/dist/core/messageValidator.js +85 -0
  76. package/dist/core/modelDiscovery.js +108 -0
  77. package/dist/core/modelRouter.js +118 -0
  78. package/dist/core/morningBriefing.js +203 -0
  79. package/dist/core/multiGoalValidator.js +51 -0
  80. package/dist/core/parallelExecutor.js +43 -0
  81. package/dist/core/passiveSkillObserver.js +204 -0
  82. package/dist/core/paths.js +57 -0
  83. package/dist/core/patternDetector.js +83 -0
  84. package/dist/core/planResponseRepair.js +64 -0
  85. package/dist/core/planTool.js +111 -0
  86. package/dist/core/playwrightBridge.js +356 -0
  87. package/dist/core/pluginSystem.js +121 -0
  88. package/dist/core/privateMode.js +85 -0
  89. package/dist/core/reactLoop.js +156 -0
  90. package/dist/core/recipeEngine.js +166 -0
  91. package/dist/core/responseCache.js +128 -0
  92. package/dist/core/runSandbox.js +132 -0
  93. package/dist/core/sandboxRunner.js +200 -0
  94. package/dist/core/scheduler.js +543 -0
  95. package/dist/core/secretScanner.js +49 -0
  96. package/dist/core/semanticMemory.js +223 -0
  97. package/dist/core/sessionMemory.js +259 -0
  98. package/dist/core/sessionRouter.js +91 -0
  99. package/dist/core/sessionSearch.js +163 -0
  100. package/dist/core/setupWizard.js +225 -0
  101. package/dist/core/skillImporter.js +303 -0
  102. package/dist/core/skillLibrary.js +144 -0
  103. package/dist/core/skillLoader.js +471 -0
  104. package/dist/core/skillTeacher.js +352 -0
  105. package/dist/core/skillValidator.js +210 -0
  106. package/dist/core/skillWriter.js +384 -0
  107. package/dist/core/slashAsTool.js +226 -0
  108. package/dist/core/spawnManager.js +197 -0
  109. package/dist/core/statusVerbs.js +43 -0
  110. package/dist/core/swarmManager.js +109 -0
  111. package/dist/core/taskQueue.js +119 -0
  112. package/dist/core/taskRecovery.js +128 -0
  113. package/dist/core/taskState.js +168 -0
  114. package/dist/core/telegramBot.js +152 -0
  115. package/dist/core/todoManager.js +70 -0
  116. package/dist/core/toolNameRepair.js +71 -0
  117. package/dist/core/toolRegistry.js +2730 -0
  118. package/dist/core/tools/calendarTool.js +98 -0
  119. package/dist/core/tools/companyFilingsTool.js +98 -0
  120. package/dist/core/tools/gmailTool.js +87 -0
  121. package/dist/core/tools/marketDataTool.js +135 -0
  122. package/dist/core/tools/socialResearchTool.js +121 -0
  123. package/dist/core/truthCheck.js +57 -0
  124. package/dist/core/updateChecker.js +74 -0
  125. package/dist/core/userCognitionProfile.js +238 -0
  126. package/dist/core/userProfile.js +341 -0
  127. package/dist/core/version.js +5 -0
  128. package/dist/core/visionAnalyze.js +161 -0
  129. package/dist/core/voice/audio.js +187 -0
  130. package/dist/core/voice/stt.js +226 -0
  131. package/dist/core/voice/tts.js +310 -0
  132. package/dist/core/voiceInput.js +118 -0
  133. package/dist/core/voiceOutput.js +130 -0
  134. package/dist/core/webSearch.js +326 -0
  135. package/dist/core/workflowTracker.js +72 -0
  136. package/dist/core/workspaceMemory.js +54 -0
  137. package/dist/core/youtubeTranscript.js +224 -0
  138. package/dist/integrations/computerUse/apiRegistry.js +113 -0
  139. package/dist/integrations/computerUse/screenAgent.js +203 -0
  140. package/dist/integrations/computerUse/visionLoop.js +296 -0
  141. package/dist/memory/memoryLayers.js +143 -0
  142. package/dist/providers/boa.js +93 -0
  143. package/dist/providers/cerebras.js +70 -0
  144. package/dist/providers/custom.js +89 -0
  145. package/dist/providers/gemini.js +82 -0
  146. package/dist/providers/groq.js +92 -0
  147. package/dist/providers/index.js +149 -0
  148. package/dist/providers/nvidia.js +70 -0
  149. package/dist/providers/ollama.js +99 -0
  150. package/dist/providers/openrouter.js +74 -0
  151. package/dist/providers/router.js +497 -0
  152. package/dist/providers/types.js +6 -0
  153. package/dist/security/browserVault.js +129 -0
  154. package/dist/security/dataGuard.js +89 -0
  155. package/dist/tools/eonetTool.js +72 -0
  156. package/dist/types/computerUse.js +2 -0
  157. package/dist/types/executor.js +2 -0
  158. package/dist-bundle/cli.js +357859 -0
  159. 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();