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,212 @@
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.memoryExtractor = void 0;
11
+ // core/memoryExtractor.ts — Post-conversation durable memory extraction.
12
+ // After every conversation ends, scans messages and writes facts to
13
+ // workspace/memory/ as typed frontmatter markdown files.
14
+ // Maintains workspace/memory/MEMORY_INDEX.md (max 100 entries).
15
+ const fs_1 = __importDefault(require("fs"));
16
+ const path_1 = __importDefault(require("path"));
17
+ const auxiliaryClient_1 = require("./auxiliaryClient");
18
+ const MEMORY_DIR = path_1.default.join(process.cwd(), 'workspace', 'memory');
19
+ const INDEX_PATH = path_1.default.join(MEMORY_DIR, 'MEMORY_INDEX.md');
20
+ const SESSIONS_DIR = path_1.default.join(process.cwd(), 'workspace', 'sessions');
21
+ const SOURCE_CONFIDENCE = {
22
+ user_stated: 1.0,
23
+ tool_result: 0.8,
24
+ llm_inferred: 0.5,
25
+ };
26
+ // ── Helpers ───────────────────────────────────────────────────
27
+ function memoryFilePath(filename) {
28
+ return path_1.default.join(MEMORY_DIR, filename);
29
+ }
30
+ function today() {
31
+ return new Date().toISOString().split('T')[0];
32
+ }
33
+ function readIndex() {
34
+ try {
35
+ if (!fs_1.default.existsSync(INDEX_PATH))
36
+ return [];
37
+ const content = fs_1.default.readFileSync(INDEX_PATH, 'utf-8');
38
+ return content.trim().split('\n')
39
+ .filter(l => l.startsWith('- ['))
40
+ .map(l => {
41
+ const m = l.match(/^- \[(.+?)\]\((.+?)\) — (.+)$/);
42
+ if (!m)
43
+ return null;
44
+ return { filename: m[2], title: m[1], type: 'project_fact', summary: m[3] };
45
+ })
46
+ .filter((e) => e !== null);
47
+ }
48
+ catch {
49
+ return [];
50
+ }
51
+ }
52
+ function writeIndex(entries) {
53
+ try {
54
+ const lines = entries.slice(0, 100).map(e => `- [${e.title}](${e.filename}) — ${e.summary}`);
55
+ fs_1.default.writeFileSync(INDEX_PATH, lines.join('\n') + '\n', 'utf-8');
56
+ }
57
+ catch (e) {
58
+ console.error('[MemoryExtractor] Index write failed:', e.message);
59
+ }
60
+ }
61
+ function buildExtractionPrompt(sessionContent, existingIndex) {
62
+ return `You are a memory extractor for DevOS. Read the session below and extract durable facts worth remembering.
63
+
64
+ EXISTING MEMORY INDEX:
65
+ ${existingIndex || '(empty)'}
66
+
67
+ SESSION CONTENT:
68
+ ${sessionContent.slice(0, 3000)}
69
+
70
+ Extract 1-5 memory items. For each one output JSON in this format:
71
+ [
72
+ {
73
+ "type": "user_preference|project_fact|tool_pattern|learned_behavior",
74
+ "filename": "user_name.md or project_architecture.md (use type prefix + snake_case descriptor)",
75
+ "title": "Short descriptive title",
76
+ "content": "Concise actionable fact. 1-4 sentences.",
77
+ "summary": "One-line summary for index",
78
+ "source": "user_stated|tool_result|llm_inferred",
79
+ "confidence": 0.5
80
+ }
81
+ ]
82
+
83
+ Rules:
84
+ - Only extract facts that are genuinely useful in a future conversation
85
+ - Skip trivial or already-indexed facts
86
+ - learned_behavior: corrections, things to avoid
87
+ - tool_pattern: commands that work/fail, file paths
88
+ - project_fact: architecture, design decisions
89
+ - user_preference: communication style, preferences
90
+ - source rules:
91
+ - "user_stated": the user directly said/told this fact → confidence 1.0
92
+ - "tool_result": fact came from a tool's returned data → confidence 0.8
93
+ - "llm_inferred": you are summarizing or inferring from context → confidence 0.5
94
+ - Output ONLY valid JSON array, nothing else`;
95
+ }
96
+ // ── MemoryExtractor ───────────────────────────────────────────
97
+ class MemoryExtractor {
98
+ constructor() {
99
+ try {
100
+ fs_1.default.mkdirSync(MEMORY_DIR, { recursive: true });
101
+ }
102
+ catch { }
103
+ }
104
+ // ── Extract from session ───────────────────────────────────
105
+ async extractFromSession(sessionId) {
106
+ const sessionFile = path_1.default.join(SESSIONS_DIR, `${sessionId}.md`);
107
+ if (!fs_1.default.existsSync(sessionFile))
108
+ return;
109
+ try {
110
+ const sessionContent = fs_1.default.readFileSync(sessionFile, 'utf-8');
111
+ if (sessionContent.length < 100)
112
+ return; // too short
113
+ const existingIndex = fs_1.default.existsSync(INDEX_PATH)
114
+ ? fs_1.default.readFileSync(INDEX_PATH, 'utf-8').slice(0, 2000)
115
+ : '';
116
+ const prompt = buildExtractionPrompt(sessionContent, existingIndex);
117
+ const raw = await auxiliaryClient_1.auxiliaryClient.complete(prompt, { task: 'memory_extraction', maxTokens: 300 });
118
+ if (!raw)
119
+ return;
120
+ // Parse JSON array from response
121
+ const jsonMatch = raw.replace(/```json\s*/g, '').replace(/```\s*/g, '').match(/\[[\s\S]*\]/);
122
+ if (!jsonMatch)
123
+ return;
124
+ const items = JSON.parse(jsonMatch[0]);
125
+ if (!Array.isArray(items) || items.length === 0)
126
+ return;
127
+ const existingEntries = readIndex();
128
+ for (const item of items) {
129
+ if (!item.filename || !item.title || !item.content)
130
+ continue;
131
+ const source = item.source || 'llm_inferred';
132
+ const confidence = item.confidence ?? SOURCE_CONFIDENCE[source];
133
+ await this.writeMemoryFile(item.filename, item.type, item.title, item.content, existingEntries, source, confidence, sessionId);
134
+ }
135
+ // Update index
136
+ writeIndex(existingEntries);
137
+ console.log(`[MemoryExtractor] Extracted ${items.length} memory item(s) from session ${sessionId}`);
138
+ }
139
+ catch (e) {
140
+ console.error('[MemoryExtractor] Extraction failed:', e.message);
141
+ }
142
+ }
143
+ // ── Write a single memory file ─────────────────────────────
144
+ async writeMemoryFile(filename, type, title, content, indexEntries, source = 'llm_inferred', confidence = 0.5, sessionId = '') {
145
+ const filePath = memoryFilePath(filename);
146
+ const now = today();
147
+ // Check if file already exists — update rather than duplicate
148
+ let created = now;
149
+ if (fs_1.default.existsSync(filePath)) {
150
+ try {
151
+ const existing = fs_1.default.readFileSync(filePath, 'utf-8');
152
+ const m = existing.match(/^created:\s*(.+)$/m);
153
+ if (m)
154
+ created = m[1].trim();
155
+ }
156
+ catch { }
157
+ }
158
+ const frontmatter = `---
159
+ title: ${title}
160
+ type: ${type}
161
+ created: ${created}
162
+ updated: ${now}
163
+ source: ${source}
164
+ confidence: ${confidence}
165
+ session: ${sessionId}
166
+ ---
167
+
168
+ ${content.trim()}
169
+ `;
170
+ try {
171
+ fs_1.default.writeFileSync(filePath, frontmatter, 'utf-8');
172
+ }
173
+ catch (e) {
174
+ console.error(`[MemoryExtractor] Write failed for ${filename}:`, e.message);
175
+ return;
176
+ }
177
+ // Update or add index entry
178
+ const existing = indexEntries.findIndex(e => e.filename === filename);
179
+ const entry = { filename, title, type, summary: content.slice(0, 80).replace(/\n/g, ' ') };
180
+ if (existing >= 0) {
181
+ indexEntries[existing] = entry;
182
+ }
183
+ else {
184
+ indexEntries.unshift(entry);
185
+ }
186
+ }
187
+ // ── Load memory index for system prompt injection ──────────
188
+ loadMemoryIndex() {
189
+ try {
190
+ if (!fs_1.default.existsSync(INDEX_PATH))
191
+ return '';
192
+ return fs_1.default.readFileSync(INDEX_PATH, 'utf-8');
193
+ }
194
+ catch {
195
+ return '';
196
+ }
197
+ }
198
+ // ── Load a specific memory file ────────────────────────────
199
+ loadMemoryFile(filename) {
200
+ try {
201
+ const p = memoryFilePath(filename);
202
+ if (!fs_1.default.existsSync(p))
203
+ return '';
204
+ return fs_1.default.readFileSync(p, 'utf-8');
205
+ }
206
+ catch {
207
+ return '';
208
+ }
209
+ }
210
+ }
211
+ // ── Singleton ──────────────────────────────────────────────────
212
+ exports.memoryExtractor = new MemoryExtractor();
@@ -0,0 +1,213 @@
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.nextId = nextId;
41
+ exports.appendRecord = appendRecord;
42
+ exports.loadAllRecords = loadAllRecords;
43
+ exports.loadRecordById = loadRecordById;
44
+ exports.assignId = assignId;
45
+ exports.runMigrationIfNeeded = runMigrationIfNeeded;
46
+ /**
47
+ * core/memoryIds.ts — Stable mem_NNNNNN IDs + append-only records.jsonl
48
+ *
49
+ * Sits on top of the existing 6-layer memory architecture.
50
+ * Does NOT touch conversationMemory, semanticMemory, knowledgeBase, etc.
51
+ */
52
+ const fs = __importStar(require("fs"));
53
+ const path = __importStar(require("path"));
54
+ // ── Paths ──────────────────────────────────────────────────────────────────
55
+ const MEM_DIR = path.join(process.cwd(), 'workspace', 'memory');
56
+ const SEQUENCE_FILE = path.join(MEM_DIR, 'sequence.json');
57
+ const RECORDS_FILE = path.join(MEM_DIR, 'records.jsonl');
58
+ // ── Sequence counter ────────────────────────────────────────────────────────
59
+ function _ensureDir() {
60
+ fs.mkdirSync(MEM_DIR, { recursive: true });
61
+ }
62
+ function _readSeq() {
63
+ try {
64
+ if (!fs.existsSync(SEQUENCE_FILE))
65
+ return 0;
66
+ const d = JSON.parse(fs.readFileSync(SEQUENCE_FILE, 'utf-8'));
67
+ return typeof d.next === 'number' ? d.next : 0;
68
+ }
69
+ catch {
70
+ return 0;
71
+ }
72
+ }
73
+ function _writeSeq(n) {
74
+ _ensureDir();
75
+ fs.writeFileSync(SEQUENCE_FILE, JSON.stringify({ next: n }), 'utf-8');
76
+ }
77
+ function nextId() {
78
+ const n = _readSeq();
79
+ _writeSeq(n + 1);
80
+ return `mem_${String(n + 1).padStart(6, '0')}`;
81
+ }
82
+ // ── Record persistence ──────────────────────────────────────────────────────
83
+ function appendRecord(record) {
84
+ _ensureDir();
85
+ fs.appendFileSync(RECORDS_FILE, JSON.stringify(record) + '\n', 'utf-8');
86
+ }
87
+ function loadAllRecords() {
88
+ try {
89
+ if (!fs.existsSync(RECORDS_FILE))
90
+ return [];
91
+ return fs.readFileSync(RECORDS_FILE, 'utf-8')
92
+ .split('\n')
93
+ .filter(l => l.trim())
94
+ .map(l => {
95
+ try {
96
+ return JSON.parse(l);
97
+ }
98
+ catch {
99
+ return null;
100
+ }
101
+ })
102
+ .filter((r) => r !== null);
103
+ }
104
+ catch {
105
+ return [];
106
+ }
107
+ }
108
+ function loadRecordById(id) {
109
+ const all = loadAllRecords();
110
+ return all.find(r => r.id === id) ?? null;
111
+ }
112
+ // ── ID assignment helper ────────────────────────────────────────────────────
113
+ function assignId(partial) {
114
+ const record = {
115
+ id: partial.id ?? nextId(),
116
+ timestamp: partial.timestamp ?? new Date().toISOString(),
117
+ type: partial.type ?? 'observation',
118
+ content: partial.content ?? '',
119
+ summary: partial.summary ?? _autoSummary(partial.content ?? ''),
120
+ sessionId: partial.sessionId,
121
+ tags: partial.tags,
122
+ entityRefs: partial.entityRefs,
123
+ };
124
+ appendRecord(record);
125
+ return record;
126
+ }
127
+ function _autoSummary(content) {
128
+ // Take first non-empty line, trim to 100 chars
129
+ const first = content.split('\n').find(l => l.trim()) ?? content;
130
+ return first.slice(0, 100).trim();
131
+ }
132
+ // ── One-time migration ──────────────────────────────────────────────────────
133
+ function runMigrationIfNeeded() {
134
+ if (fs.existsSync(RECORDS_FILE))
135
+ return 0; // already migrated
136
+ _ensureDir();
137
+ const records = [];
138
+ // Source 1: workspace/memory/memory.json (task/agent results)
139
+ try {
140
+ const raw = fs.readFileSync(path.join(MEM_DIR, 'memory.json'), 'utf-8');
141
+ const parsed = JSON.parse(raw);
142
+ const items = Array.isArray(parsed) ? parsed : (parsed.value ?? []);
143
+ for (const item of items) {
144
+ const v = item.value ?? {};
145
+ const content = [
146
+ v.goal ? `Goal: ${v.goal}` : '',
147
+ v.result ? `Result: ${String(v.result).slice(0, 800)}` : '',
148
+ v.role ? `Role: ${v.role}` : '',
149
+ ].filter(Boolean).join('\n');
150
+ if (!content)
151
+ continue;
152
+ records.push({
153
+ timestamp: item.createdAt ?? new Date().toISOString(),
154
+ type: item.tags?.includes('task') ? 'interaction' : 'observation',
155
+ content,
156
+ summary: _autoSummary(v.goal ?? v.result ?? content),
157
+ tags: item.tags ?? [],
158
+ });
159
+ }
160
+ }
161
+ catch { /* non-fatal */ }
162
+ // Source 2: workspace/conversation-memory.json (conversation messages)
163
+ try {
164
+ const raw = fs.readFileSync(path.join(process.cwd(), 'workspace', 'conversation-memory.json'), 'utf-8');
165
+ const parsed = JSON.parse(raw);
166
+ const msgs = parsed.messages ?? [];
167
+ // Only migrate assistant messages that have meaningful content
168
+ for (const msg of msgs) {
169
+ if (msg.role !== 'assistant')
170
+ continue;
171
+ const content = String(msg.content ?? '').trim();
172
+ if (content.length < 20)
173
+ continue;
174
+ records.push({
175
+ timestamp: msg.timestamp ?? new Date().toISOString(),
176
+ type: 'interaction',
177
+ content: content.slice(0, 1000),
178
+ summary: _autoSummary(content),
179
+ sessionId: msg.sessionId,
180
+ tags: ['conversation'],
181
+ });
182
+ }
183
+ }
184
+ catch { /* non-fatal */ }
185
+ // Source 3: workspace/memory/MEMORY_INDEX.md (.md lines as facts)
186
+ try {
187
+ const raw = fs.readFileSync(path.join(MEM_DIR, 'MEMORY_INDEX.md'), 'utf-8');
188
+ const lines = raw.split('\n').filter(l => l.startsWith('- '));
189
+ for (const line of lines) {
190
+ const cleaned = line.replace(/^-\s*/, '').trim();
191
+ if (cleaned.length < 10)
192
+ continue;
193
+ records.push({
194
+ timestamp: new Date().toISOString(),
195
+ type: 'fact',
196
+ content: cleaned,
197
+ summary: cleaned.slice(0, 100),
198
+ tags: ['index'],
199
+ });
200
+ }
201
+ }
202
+ catch { /* non-fatal */ }
203
+ // Sort by timestamp ascending, assign IDs, write
204
+ records.sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());
205
+ let count = 0;
206
+ for (const rec of records) {
207
+ const id = nextId();
208
+ const record = { id, ...rec };
209
+ appendRecord(record);
210
+ count++;
211
+ }
212
+ return count;
213
+ }
@@ -0,0 +1,113 @@
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.buildGreetingPreamble = buildGreetingPreamble;
11
+ // core/memoryPreamble.ts — Phase 4: Greeting fast-path memory surface.
12
+ //
13
+ // When the user sends a greeting ("hi", "good morning", etc.) the semantic
14
+ // memory recall in streamChat produces no matches because there is no
15
+ // substantive query to match against. This module builds a compact
16
+ // "what I know right now" preamble from the live conversation facts so
17
+ // Aiden can open with context-aware continuity even on the very first
18
+ // sentence of a new session.
19
+ //
20
+ // Usage:
21
+ // const preamble = await buildGreetingPreamble()
22
+ // // => "GREETING CONTEXT:\nRecent files: report.py\nActive goals: ..." | null
23
+ const fs_1 = __importDefault(require("fs"));
24
+ const path_1 = __importDefault(require("path"));
25
+ const conversationMemory_1 = require("./conversationMemory");
26
+ const goalTracker_1 = require("./goalTracker");
27
+ const sessionMemory_1 = require("./sessionMemory");
28
+ const USER_MD = path_1.default.join(process.env.AIDEN_USER_DATA || process.cwd(), 'workspace', 'USER.md');
29
+ function readUserName() {
30
+ try {
31
+ if (!fs_1.default.existsSync(USER_MD))
32
+ return null;
33
+ const content = fs_1.default.readFileSync(USER_MD, 'utf-8');
34
+ const match = content.match(/^Name:\s*(.+)/m);
35
+ if (!match)
36
+ return null;
37
+ const name = match[1].trim();
38
+ if (!name || name.toLowerCase() === 'user')
39
+ return null;
40
+ return name;
41
+ }
42
+ catch {
43
+ return null;
44
+ }
45
+ }
46
+ function extractLastSessionSummary(raw) {
47
+ if (!raw)
48
+ return null;
49
+ const titleMatch = raw.match(/# Session Title\s*\n_?([^\n_#]+)/);
50
+ const stateMatch = raw.match(/# Current State\s*\n_?([\s\S]*?)(?=\n#|$)/);
51
+ const parts = [];
52
+ if (titleMatch?.[1]?.trim())
53
+ parts.push(`Last session: ${titleMatch[1].trim()}`);
54
+ if (stateMatch?.[1]?.trim()) {
55
+ const state = stateMatch[1].replace(/^_|_$/g, '').trim().slice(0, 120);
56
+ if (state)
57
+ parts.push(`State: ${state}`);
58
+ }
59
+ return parts.length > 0 ? parts.join(' — ') : null;
60
+ }
61
+ // ── Main export ───────────────────────────────────────────────────────────────
62
+ /**
63
+ * Build a compact preamble from live memory facts.
64
+ * Returns null when there is nothing meaningful to surface
65
+ * (e.g. a brand-new session with no prior history).
66
+ */
67
+ async function buildGreetingPreamble(sessionId) {
68
+ try {
69
+ const facts = conversationMemory_1.conversationMemory.getFacts();
70
+ const goals = (0, goalTracker_1.getActiveGoalsSummary)();
71
+ const parts = [];
72
+ // User name from USER.md
73
+ const name = readUserName();
74
+ if (name)
75
+ parts.push(`User name: ${name}`);
76
+ // Last session context
77
+ if (sessionId) {
78
+ const lastCtx = sessionMemory_1.sessionMemory.getLastContext(sessionId);
79
+ const sessionSummary = extractLastSessionSummary(lastCtx);
80
+ if (sessionSummary)
81
+ parts.push(sessionSummary);
82
+ }
83
+ if (facts.lastFilesCreated.length > 0) {
84
+ parts.push(`Recent files: ${facts.lastFilesCreated.slice(-3).join(', ')}`);
85
+ }
86
+ if (facts.lastSearchQueries.length > 0) {
87
+ parts.push(`Recent searches: ${facts.lastSearchQueries.slice(-2).join(', ')}`);
88
+ }
89
+ if (facts.mentionedEntities.length > 0) {
90
+ parts.push(`Recent topics: ${facts.mentionedEntities.slice(-6).join(', ')}`);
91
+ }
92
+ if (facts.preferredPaths.length > 0) {
93
+ parts.push(`Frequent paths: ${facts.preferredPaths.slice(-2).join(', ')}`);
94
+ }
95
+ if (goals) {
96
+ // getActiveGoalsSummary() returns "Active goals:\n- title [status]: action\n..."
97
+ // Extract compact single-line titles to avoid double-labeling and regex capture bugs
98
+ const goalLines = goals.split('\n').filter((l) => l.trim().startsWith('- '));
99
+ const goalTitles = goalLines.map((l) => {
100
+ const m = l.match(/^-\s+(.+?)\s+\[/);
101
+ return m ? m[1] : l.replace(/^-\s+/, '').split('[')[0].trim();
102
+ }).filter(Boolean).join(', ');
103
+ if (goalTitles)
104
+ parts.push(`Active goals: ${goalTitles}`);
105
+ }
106
+ if (parts.length === 0)
107
+ return null;
108
+ return `GREETING CONTEXT (reference naturally if relevant — do not recite mechanically):\n${parts.join('\n')}`;
109
+ }
110
+ catch {
111
+ return null;
112
+ }
113
+ }
@@ -0,0 +1,136 @@
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.trackCitation = trackCitation;
8
+ exports.getSessionCitations = getSessionCitations;
9
+ exports.clearSessionCitations = clearSessionCitations;
10
+ exports.memsearch = memsearch;
11
+ exports.memtimeline = memtimeline;
12
+ exports.memget = memget;
13
+ /**
14
+ * core/memoryQuery.ts — 3-layer progressive disclosure memory query
15
+ *
16
+ * Layer 1 memsearch() — [{id, summary, type, date, score}] ~50 tok/hit
17
+ * Layer 2 memtimeline() — chronological ±window around a record ~200 tok
18
+ * Layer 3 memget() — full record bodies for selected IDs ~500-1000 tok each
19
+ */
20
+ const memoryIds_1 = require("./memoryIds");
21
+ const _sessionCitations = new Map();
22
+ function trackCitation(id, summary) {
23
+ const c = _sessionCitations.get(id);
24
+ if (c) {
25
+ c.refs++;
26
+ }
27
+ else {
28
+ _sessionCitations.set(id, { id, summary, refs: 1 });
29
+ }
30
+ }
31
+ function getSessionCitations() {
32
+ return Array.from(_sessionCitations.values());
33
+ }
34
+ function clearSessionCitations() {
35
+ _sessionCitations.clear();
36
+ }
37
+ async function memsearch(query, opts = {}) {
38
+ const limit = opts.limit ?? 10;
39
+ const records = (0, memoryIds_1.loadAllRecords)();
40
+ const words = query.toLowerCase().split(/\s+/).filter(w => w.length > 1);
41
+ if (words.length === 0) {
42
+ // No query words — return most recent
43
+ return records
44
+ .slice(-limit)
45
+ .reverse()
46
+ .map(r => _toHit(r, 0));
47
+ }
48
+ // Filter by type
49
+ let filtered = opts.type
50
+ ? records.filter(r => r.type === opts.type)
51
+ : records;
52
+ // Filter by since
53
+ if (opts.since) {
54
+ const sinceMs = new Date(opts.since).getTime();
55
+ filtered = filtered.filter(r => new Date(r.timestamp).getTime() >= sinceMs);
56
+ }
57
+ // Score each record
58
+ const scored = filtered.map(r => {
59
+ const hay = (r.summary + ' ' + r.content).toLowerCase();
60
+ const hits = words.filter(w => hay.includes(w)).length;
61
+ const score = hits / words.length;
62
+ return { record: r, score };
63
+ });
64
+ // Filter zero-score, sort desc by score then recency
65
+ const hits = scored
66
+ .filter(x => x.score > 0)
67
+ .sort((a, b) => {
68
+ if (Math.abs(a.score - b.score) > 0.01)
69
+ return b.score - a.score;
70
+ return new Date(b.record.timestamp).getTime() - new Date(a.record.timestamp).getTime();
71
+ })
72
+ .slice(0, limit)
73
+ .map(x => _toHit(x.record, x.score));
74
+ // Track citations for pulse
75
+ for (const h of hits)
76
+ trackCitation(h.id, h.summary);
77
+ return hits;
78
+ }
79
+ function _toHit(r, score) {
80
+ return {
81
+ id: r.id,
82
+ summary: r.summary.slice(0, 120),
83
+ type: r.type,
84
+ date: r.timestamp.slice(0, 10),
85
+ score: Math.round(score * 100) / 100,
86
+ };
87
+ }
88
+ async function memtimeline(centerId, opts = {}) {
89
+ const center = (0, memoryIds_1.loadRecordById)(centerId);
90
+ if (!center)
91
+ return null;
92
+ const windowMs = (opts.windowHours ?? 6) * 60 * 60 * 1000;
93
+ const centerMs = new Date(center.timestamp).getTime();
94
+ const allRecords = (0, memoryIds_1.loadAllRecords)();
95
+ const before = [];
96
+ const after = [];
97
+ for (const r of allRecords) {
98
+ if (r.id === centerId)
99
+ continue;
100
+ const t = new Date(r.timestamp).getTime();
101
+ const delta = t - centerMs;
102
+ if (Math.abs(delta) > windowMs)
103
+ continue;
104
+ const slim = {
105
+ id: r.id,
106
+ summary: r.summary.slice(0, 100),
107
+ type: r.type,
108
+ timestamp: r.timestamp,
109
+ };
110
+ if (delta < 0)
111
+ before.push(slim);
112
+ else
113
+ after.push(slim);
114
+ }
115
+ // Keep at most 5 before (most recent 5) and 5 after (earliest 5)
116
+ before.sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime());
117
+ after.sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());
118
+ // Track citation
119
+ trackCitation(center.id, center.summary);
120
+ return {
121
+ center,
122
+ before: before.slice(0, 5),
123
+ after: after.slice(0, 5),
124
+ sessionContext: center.sessionId,
125
+ };
126
+ }
127
+ async function memget(ids) {
128
+ const allRecords = (0, memoryIds_1.loadAllRecords)();
129
+ const byId = new Map(allRecords.map(r => [r.id, r]));
130
+ return ids.map(id => {
131
+ const record = byId.get(id) ?? null;
132
+ if (record)
133
+ trackCitation(id, record.summary);
134
+ return { id, record, found: record !== null };
135
+ });
136
+ }