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,231 @@
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.runSecurityScan = runSecurityScan;
11
+ // core/agentShield.ts — Security scanner for skills, configs, and identity.
12
+ // Runs on startup and on-demand from Settings → Security.
13
+ // Reuses SKILL_INJECTION_PATTERNS from skillLoader so detection
14
+ // stays in sync — no duplicate regex lists.
15
+ const fs_1 = __importDefault(require("fs"));
16
+ const path_1 = __importDefault(require("path"));
17
+ // Match server.ts: packaged Electron path or cwd
18
+ const WORKSPACE_ROOT = process.env.AIDEN_USER_DATA || process.cwd();
19
+ // ── Injection patterns (aligned with skillLoader.ts) ──────────
20
+ // Duplicating the exact list would create drift — keep a focused
21
+ // subset covering the most critical categories for config / identity
22
+ // files (skills are already blocked at load time by skillLoader).
23
+ const INJECTION_PATTERNS = [
24
+ { pattern: /ignore\s+(all\s+)?(previous|above|prior)/i, desc: 'Prompt injection: ignore previous instructions' },
25
+ { pattern: /you\s+are\s+now\s+/i, desc: 'Role hijack: "you are now"' },
26
+ { pattern: /\[SYSTEM\]/i, desc: 'System tag injection' },
27
+ { pattern: /\[INST\]/i, desc: 'Instruction tag injection' },
28
+ { pattern: /<\|im_start\|>/i, desc: 'Model control token injection' },
29
+ { pattern: /eval\s*\(/i, desc: 'Code evaluation' },
30
+ { pattern: /subprocess/i, desc: 'Subprocess execution' },
31
+ { pattern: /import\s+os/i, desc: 'OS module import' },
32
+ { pattern: /base64\s*decode/i, desc: 'Base64 decode (possible obfuscation)' },
33
+ { pattern: /send\s+(to|via)\s+(http|email|webhook|api)/i, desc: 'Data exfiltration attempt' },
34
+ { pattern: /curl\s+.*-d\s/i, desc: 'Outbound data via curl' },
35
+ { pattern: /admin\s*(mode|access|privilege)/i, desc: 'Privilege escalation attempt' },
36
+ ];
37
+ const ENCODED_PATTERN = /\\x[0-9a-f]{2}/i;
38
+ // Raw API key patterns — keys that should use "env:" prefix in config
39
+ const RAW_KEY_PATTERN = /["'](?:sk-|gsk_|AIza|ghp_|xai-|csk-)[a-zA-Z0-9]{20,}["']/;
40
+ // Large-file allowlist — system catalog / index files that are intentionally large
41
+ const SIZE_ALLOWLIST = new Set([
42
+ 'AIDEN_CATALOG.md',
43
+ 'SKILL_INDEX.md',
44
+ 'skills-index.md',
45
+ ]);
46
+ // ── stripQuotedStrings ────────────────────────────────────────
47
+ // Removes double- and single-quoted strings from content before
48
+ // injection testing to avoid false positives on defensive text
49
+ // (e.g. SOUL.md quoting injection phrases as examples to resist).
50
+ function stripQuotedStrings(text) {
51
+ return text
52
+ .replace(/"[^"]*"/g, '""')
53
+ .replace(/'[^']*'/g, "''");
54
+ }
55
+ // ── Scoring weights ────────────────────────────────────────────
56
+ const SEVERITY_WEIGHTS = {
57
+ critical: 25,
58
+ high: 15,
59
+ medium: 5,
60
+ low: 2,
61
+ info: 0,
62
+ };
63
+ // ── Main scanner ───────────────────────────────────────────────
64
+ async function runSecurityScan() {
65
+ const start = Date.now();
66
+ const findings = [];
67
+ let skillsScanned = 0;
68
+ let toolsScanned = 0;
69
+ let configsScanned = 0;
70
+ // ── 1. Scan skill files ──────────────────────────────────────
71
+ // Skills are already sanitized at load time by skillLoader, but
72
+ // we re-scan here to surface findings in the UI and catch any
73
+ // skills that bypass the loader (e.g. placed directly on disk).
74
+ const skillDirs = [
75
+ path_1.default.join(WORKSPACE_ROOT, 'skills'),
76
+ path_1.default.join(WORKSPACE_ROOT, 'workspace', 'skills'),
77
+ path_1.default.join(WORKSPACE_ROOT, 'workspace', 'skills', 'learned'),
78
+ path_1.default.join(WORKSPACE_ROOT, 'workspace', 'skills', 'approved'),
79
+ ];
80
+ for (const dir of skillDirs) {
81
+ if (!fs_1.default.existsSync(dir))
82
+ continue;
83
+ let entries;
84
+ try {
85
+ entries = fs_1.default.readdirSync(dir, { withFileTypes: true });
86
+ }
87
+ catch {
88
+ continue;
89
+ }
90
+ for (const entry of entries) {
91
+ // Skills are stored as subdirectories containing SKILL.md
92
+ const skillPath = entry.isDirectory()
93
+ ? path_1.default.join(dir, entry.name, 'SKILL.md')
94
+ : entry.name.endsWith('.md') ? path_1.default.join(dir, entry.name) : '';
95
+ if (!skillPath || !fs_1.default.existsSync(skillPath))
96
+ continue;
97
+ const relPath = `skills/${entry.name}${entry.isDirectory() ? '/SKILL.md' : ''}`;
98
+ let content;
99
+ try {
100
+ content = fs_1.default.readFileSync(skillPath, 'utf8');
101
+ }
102
+ catch {
103
+ continue;
104
+ }
105
+ skillsScanned++;
106
+ // Injection pattern checks
107
+ for (const check of INJECTION_PATTERNS) {
108
+ if (check.pattern.test(content)) {
109
+ findings.push({
110
+ severity: 'high',
111
+ category: 'skill-injection',
112
+ file: relPath,
113
+ description: check.desc,
114
+ recommendation: 'Review and remove or quarantine this skill',
115
+ });
116
+ }
117
+ }
118
+ // Encoded characters — obfuscation indicator
119
+ if (ENCODED_PATTERN.test(content)) {
120
+ findings.push({
121
+ severity: 'high',
122
+ category: 'encoding',
123
+ file: relPath,
124
+ description: 'Contains hex-encoded characters — possible obfuscation',
125
+ recommendation: 'Decode and review the actual content',
126
+ });
127
+ }
128
+ // Unusually large skill (>10 KB — same threshold as skillLoader)
129
+ // Skip known large system catalog files (false positive for intentionally large indexes)
130
+ if (content.length > 10240 && !SIZE_ALLOWLIST.has(entry.name)) {
131
+ findings.push({
132
+ severity: 'medium',
133
+ category: 'skill-size',
134
+ file: relPath,
135
+ description: `Skill is ${(content.length / 1024).toFixed(1)}KB — unusually large`,
136
+ recommendation: 'Review content — large skills may contain hidden payloads',
137
+ });
138
+ }
139
+ }
140
+ }
141
+ // ── 2. Scan config for exposed secrets ───────────────────────
142
+ configsScanned++;
143
+ const configPath = path_1.default.join(WORKSPACE_ROOT, 'config', 'devos.config.json');
144
+ if (fs_1.default.existsSync(configPath)) {
145
+ let config = '';
146
+ try {
147
+ config = fs_1.default.readFileSync(configPath, 'utf8');
148
+ }
149
+ catch { }
150
+ if (config && RAW_KEY_PATTERN.test(config)) {
151
+ findings.push({
152
+ severity: 'critical',
153
+ category: 'exposed-secret',
154
+ file: 'config/devos.config.json',
155
+ description: 'Raw API key found in config file',
156
+ recommendation: 'Use env: format to reference environment variables instead',
157
+ });
158
+ }
159
+ }
160
+ // ── 3. Scan sensitive workspace files for identity injection ──
161
+ const sensitiveFiles = [
162
+ { name: 'SOUL.md', critical: true },
163
+ { name: 'USER.md', critical: false },
164
+ { name: 'STANDING_ORDERS.md', critical: false },
165
+ { name: 'LESSONS.md', critical: false },
166
+ ];
167
+ for (const { name, critical } of sensitiveFiles) {
168
+ const filePath = path_1.default.join(WORKSPACE_ROOT, 'workspace', name);
169
+ if (!fs_1.default.existsSync(filePath))
170
+ continue;
171
+ let content = '';
172
+ try {
173
+ content = fs_1.default.readFileSync(filePath, 'utf8');
174
+ }
175
+ catch {
176
+ continue;
177
+ }
178
+ toolsScanned++;
179
+ // Strip quoted strings before injection testing — avoids false positives on
180
+ // defensive text (e.g. SOUL.md quoting injection phrases to tell the AI to resist them).
181
+ const contentForInjectionTest = stripQuotedStrings(content);
182
+ // Identity injection in SOUL.md is the highest-severity possible
183
+ if (critical && /ignore\s+previous|you\s+are\s+now/i.test(contentForInjectionTest)) {
184
+ findings.push({
185
+ severity: 'critical',
186
+ category: 'soul-injection',
187
+ file: `workspace/${name}`,
188
+ description: 'SOUL.md contains injection patterns — identity may be compromised',
189
+ recommendation: 'Reset SOUL.md to default and review all recent changes',
190
+ });
191
+ }
192
+ // General injection patterns in any sensitive file
193
+ for (const check of INJECTION_PATTERNS) {
194
+ if (check.pattern.test(contentForInjectionTest)) {
195
+ findings.push({
196
+ severity: critical ? 'critical' : 'high',
197
+ category: 'config-injection',
198
+ file: `workspace/${name}`,
199
+ description: `${name}: ${check.desc}`,
200
+ recommendation: `Review workspace/${name} for unauthorized modifications`,
201
+ });
202
+ break; // one finding per file is enough
203
+ }
204
+ }
205
+ }
206
+ // ── 4. Port binding info notices ─────────────────────────────
207
+ // Static check — not a network probe. Just reminds the operator.
208
+ for (const port of [4200, 3000, 3001]) {
209
+ toolsScanned++;
210
+ findings.push({
211
+ severity: 'info',
212
+ category: 'network',
213
+ file: `port ${port}`,
214
+ description: `Port ${port} should be bound to localhost only`,
215
+ recommendation: 'Ensure all DevOS ports bind to 127.0.0.1, not 0.0.0.0',
216
+ });
217
+ }
218
+ // ── Risk score ────────────────────────────────────────────────
219
+ const riskScore = Math.min(100, findings.reduce((sum, f) => sum + (SEVERITY_WEIGHTS[f.severity] ?? 0), 0));
220
+ const result = {
221
+ timestamp: Date.now(),
222
+ duration: Date.now() - start,
223
+ findings,
224
+ scanned: { skills: skillsScanned, tools: toolsScanned, configs: configsScanned },
225
+ riskScore,
226
+ score: riskScore, // alias
227
+ };
228
+ console.log(`[AgentShield] Scan complete: ${findings.length} finding(s), ` +
229
+ `risk score ${riskScore}/100 (${result.duration}ms)`);
230
+ return result;
231
+ }
@@ -0,0 +1,215 @@
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.computeIdentity = computeIdentity;
11
+ exports.refreshIdentity = refreshIdentity;
12
+ exports.loadIdentity = loadIdentity;
13
+ exports.getIdentity = getIdentity;
14
+ // core/aidenIdentity.ts — Aiden's persistent identity and level system.
15
+ // Computed from AuditTrail (XP) + SkillTeacher (skills learned) + sessions (streak).
16
+ // Persisted to workspace/identity.json. Emits identity_update via eventBus.
17
+ const fs_1 = __importDefault(require("fs"));
18
+ const path_1 = __importDefault(require("path"));
19
+ const skillTeacher_1 = require("./skillTeacher");
20
+ const eventBus_1 = require("./eventBus");
21
+ // ── Constants ─────────────────────────────────────────────────
22
+ const IDENTITY_PATH = path_1.default.join(process.cwd(), 'workspace', 'identity.json');
23
+ const AUDIT_PATH = path_1.default.join(process.cwd(), 'workspace', 'audit', 'audit.jsonl');
24
+ const SESSIONS_DIR = path_1.default.join(process.cwd(), 'workspace', 'sessions');
25
+ const LEVEL_THRESHOLDS = [0, 10, 50, 200, 500]; // XP needed for levels 1–5
26
+ const TITLES = ['Apprentice', 'Assistant', 'Specialist', 'Expert', 'Architect'];
27
+ // ── Level helpers ─────────────────────────────────────────────
28
+ function computeLevel(xp) {
29
+ if (xp < 10)
30
+ return 1;
31
+ if (xp < 50)
32
+ return 2;
33
+ if (xp < 200)
34
+ return 3;
35
+ if (xp < 500)
36
+ return 4;
37
+ return 5;
38
+ }
39
+ function computeProgress(xp, level) {
40
+ if (level >= 5)
41
+ return { xpToNext: 0, progress: 1 };
42
+ const floor = LEVEL_THRESHOLDS[level - 1];
43
+ const ceil = LEVEL_THRESHOLDS[level];
44
+ const span = ceil - floor;
45
+ const done = xp - floor;
46
+ return {
47
+ xpToNext: Math.max(0, ceil - xp),
48
+ progress: Math.min(1, Math.max(0, done / span)),
49
+ };
50
+ }
51
+ // ── XP: count successful tasks from audit trail ───────────────
52
+ function computeXP() {
53
+ try {
54
+ if (!fs_1.default.existsSync(AUDIT_PATH))
55
+ return 0;
56
+ return fs_1.default.readFileSync(AUDIT_PATH, 'utf-8')
57
+ .trim().split('\n').filter(Boolean)
58
+ .map(l => { try {
59
+ return JSON.parse(l);
60
+ }
61
+ catch {
62
+ return null;
63
+ } })
64
+ .filter((e) => e !== null && e.success === true)
65
+ .length;
66
+ }
67
+ catch {
68
+ return 0;
69
+ }
70
+ }
71
+ // ── Top strength: most frequent tool category ─────────────────
72
+ function computeTopStrength() {
73
+ try {
74
+ if (!fs_1.default.existsSync(AUDIT_PATH))
75
+ return 'Research';
76
+ const entries = fs_1.default.readFileSync(AUDIT_PATH, 'utf-8')
77
+ .trim().split('\n').filter(Boolean)
78
+ .map(l => { try {
79
+ return JSON.parse(l);
80
+ }
81
+ catch {
82
+ return null;
83
+ } })
84
+ .filter(Boolean);
85
+ const counts = {
86
+ Research: 0,
87
+ Code: 0,
88
+ Automation: 0,
89
+ Analysis: 0,
90
+ };
91
+ for (const e of entries) {
92
+ const tool = (e.tool || '');
93
+ if (/web_search|deep_research|fetch/.test(tool))
94
+ counts.Research++;
95
+ else if (/file_write|run_python|run_node|shell/.test(tool))
96
+ counts.Code++;
97
+ else if (/mouse|keyboard|browser|vision/.test(tool))
98
+ counts.Automation++;
99
+ else if (/system_info|get_stocks|get_market/.test(tool))
100
+ counts.Analysis++;
101
+ }
102
+ return Object.entries(counts)
103
+ .sort((a, b) => b[1] - a[1])[0][0];
104
+ }
105
+ catch {
106
+ return 'Research';
107
+ }
108
+ }
109
+ // ── Streak: consecutive days with session files ───────────────
110
+ function computeStreakDays() {
111
+ try {
112
+ if (!fs_1.default.existsSync(SESSIONS_DIR))
113
+ return 0;
114
+ const sessionDates = new Set();
115
+ for (const f of fs_1.default.readdirSync(SESSIONS_DIR)) {
116
+ if (!f.endsWith('.md'))
117
+ continue;
118
+ try {
119
+ const mtime = fs_1.default.statSync(path_1.default.join(SESSIONS_DIR, f)).mtime;
120
+ sessionDates.add(mtime.toISOString().slice(0, 10));
121
+ }
122
+ catch { }
123
+ }
124
+ if (sessionDates.size === 0)
125
+ return 0;
126
+ // Also count today's audit entries
127
+ const auditDates = new Set();
128
+ if (fs_1.default.existsSync(AUDIT_PATH)) {
129
+ for (const line of fs_1.default.readFileSync(AUDIT_PATH, 'utf-8').trim().split('\n').filter(Boolean)) {
130
+ try {
131
+ const e = JSON.parse(line);
132
+ if (e.ts)
133
+ auditDates.add(new Date(e.ts).toISOString().slice(0, 10));
134
+ }
135
+ catch { }
136
+ }
137
+ }
138
+ const allDates = new Set([...sessionDates, ...auditDates]);
139
+ const sorted = Array.from(allDates).sort().reverse();
140
+ let streak = 0;
141
+ let cursor = new Date();
142
+ cursor.setHours(0, 0, 0, 0);
143
+ for (const d of sorted) {
144
+ const dateStr = cursor.toISOString().slice(0, 10);
145
+ if (d === dateStr) {
146
+ streak++;
147
+ cursor.setDate(cursor.getDate() - 1);
148
+ }
149
+ else {
150
+ break;
151
+ }
152
+ }
153
+ return streak;
154
+ }
155
+ catch {
156
+ return 0;
157
+ }
158
+ }
159
+ // ── Main compute ──────────────────────────────────────────────
160
+ function computeIdentity() {
161
+ const xp = computeXP();
162
+ const level = computeLevel(xp);
163
+ const title = TITLES[level - 1];
164
+ const { xpToNext, progress } = computeProgress(xp, level);
165
+ const stats = skillTeacher_1.skillTeacher.getStats();
166
+ const skillsLearned = stats.learned + stats.approved;
167
+ const identity = {
168
+ level,
169
+ title,
170
+ xp,
171
+ skillsLearned,
172
+ streakDays: computeStreakDays(),
173
+ topStrength: computeTopStrength(),
174
+ xpToNextLevel: xpToNext,
175
+ xpProgress: progress,
176
+ lastUpdated: new Date().toISOString(),
177
+ };
178
+ return identity;
179
+ }
180
+ // ── Persist & emit ─────────────────────────────────────────────
181
+ function refreshIdentity() {
182
+ const identity = computeIdentity();
183
+ try {
184
+ fs_1.default.mkdirSync(path_1.default.dirname(IDENTITY_PATH), { recursive: true });
185
+ fs_1.default.writeFileSync(IDENTITY_PATH, JSON.stringify(identity, null, 2));
186
+ }
187
+ catch (e) {
188
+ console.error('[AidenIdentity] Write failed:', e.message);
189
+ }
190
+ try {
191
+ eventBus_1.eventBus.emit('identity_update', identity);
192
+ }
193
+ catch { }
194
+ return identity;
195
+ }
196
+ // ── Load persisted (fast, no compute) ─────────────────────────
197
+ function loadIdentity() {
198
+ try {
199
+ if (!fs_1.default.existsSync(IDENTITY_PATH))
200
+ return null;
201
+ return JSON.parse(fs_1.default.readFileSync(IDENTITY_PATH, 'utf-8'));
202
+ }
203
+ catch {
204
+ return null;
205
+ }
206
+ }
207
+ // ── getIdentity: load cached or compute fresh ─────────────────
208
+ function getIdentity() {
209
+ return loadIdentity() ?? refreshIdentity();
210
+ }
211
+ // ── Singleton initialisation on import ────────────────────────
212
+ try {
213
+ fs_1.default.mkdirSync(path_1.default.dirname(IDENTITY_PATH), { recursive: true });
214
+ }
215
+ catch { }
@@ -0,0 +1,166 @@
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.AIDEN_RESPONDER_SYSTEM = exports.AIDEN_STREAM_SYSTEM = exports.AIDEN_IDENTITY = exports.AIDEN_REAL_TOOLS = exports.SOUL = void 0;
11
+ // core/aidenPersonality.ts — Unified Aiden identity + system prompts
12
+ //
13
+ // Single source of truth for personality, tone, and capability declarations.
14
+ // All system prompts across agentLoop.ts and server.ts reference this.
15
+ const fs_1 = __importDefault(require("fs"));
16
+ const path_1 = __importDefault(require("path"));
17
+ // ── Workspace root — same logic as api/server.ts ──────────────
18
+ // In Electron: AIDEN_USER_DATA = %APPDATA%/devos-ai
19
+ // In direct dev (npm run dev): process.cwd() = project root
20
+ const SOUL_WORKSPACE_ROOT = process.env.AIDEN_USER_DATA || process.cwd();
21
+ // ── Load SOUL.md at startup ────────────────────────────────────
22
+ function loadSoul() {
23
+ try {
24
+ // Primary: workspace/SOUL.md (installed Electron app location)
25
+ const wsPath = path_1.default.join(SOUL_WORKSPACE_ROOT, 'workspace', 'SOUL.md');
26
+ if (fs_1.default.existsSync(wsPath)) {
27
+ return fs_1.default.readFileSync(wsPath, 'utf-8');
28
+ }
29
+ // Fallback: SOUL.md at root (direct npm run dev, cwd = project root)
30
+ const rootPath = path_1.default.join(process.cwd(), 'SOUL.md');
31
+ if (fs_1.default.existsSync(rootPath)) {
32
+ return fs_1.default.readFileSync(rootPath, 'utf-8');
33
+ }
34
+ }
35
+ catch { }
36
+ return '';
37
+ }
38
+ exports.SOUL = loadSoul();
39
+ // ── Tool list ─────────────────────────────────────────────────
40
+ // Keep in sync with TOOLS in toolRegistry.ts
41
+ exports.AIDEN_REAL_TOOLS = `
42
+ - web_search: Search the internet for real-time info
43
+ - deep_research: Multi-pass deep research on any topic
44
+ - file_write: Create and save files anywhere on disk
45
+ - file_read: Read files from disk
46
+ - file_list: List directory contents
47
+ - fetch_page: Fetch and clean any URL
48
+ - open_browser: Open URLs in a real browser window
49
+ - shell_exec: Run PowerShell commands
50
+ - run_python: Execute Python scripts
51
+ - run_node: Execute Node.js scripts
52
+ - run_powershell: Write and run .ps1 scripts
53
+ - system_info: Get CPU / RAM / disk info
54
+ - notify: Show desktop notifications
55
+ - get_stocks: NSE/BSE stock data (gainers, losers, active)
56
+ - mouse_move: Move cursor to exact screen coordinates
57
+ - mouse_click: Click anywhere on screen
58
+ - keyboard_type: Type text into any window
59
+ - keyboard_press: Press keys (Enter, Tab, Ctrl+L, etc.)
60
+ - screenshot: Capture full screen to PNG
61
+ - screen_read: Screenshot + describe what's on screen
62
+ - vision_loop: Autonomous see → decide → act loop
63
+ - wait: Pause execution between steps
64
+ - git_commit / git_push: Commit and push code to GitHub
65
+ `.trim();
66
+ // ── Core identity block ───────────────────────────────────────
67
+ exports.AIDEN_IDENTITY = `
68
+ You are Aiden — a personal AI OS built by Shiva Deore at Taracod (also known as White Lotus).
69
+ You run entirely on the user's machine. You are local, private, and powerful.
70
+
71
+ YOUR CREATOR:
72
+ You were built by Shiva Deore at Taracod.
73
+ When ANYONE asks who built you, who made you, or who created you — ALWAYS respond with:
74
+ "I was built by Shiva Deore at Taracod."
75
+ Never attribute yourself to OpenAI, Anthropic, Google, or any other company.
76
+
77
+ YOUR PERSONALITY:
78
+ - Direct and concise — never pad responses with filler
79
+ - Confident — you know what you can do, you say it plainly
80
+ - Slightly witty — like a trusted co-founder, not a corporate chatbot
81
+ - Honest — if something failed, say so clearly and explain why
82
+ - Never sycophantic — don't say "Great question!" or "Certainly!" or "Of course!"
83
+ - Never verbose — 1-3 sentences for simple results, more only when the output is rich
84
+
85
+ YOUR REAL CAPABILITIES:
86
+ ${exports.AIDEN_REAL_TOOLS}
87
+
88
+ HARD RULES v5 — never violate these (system prompt verification: active):
89
+ - NEVER say "As an AI language model..."
90
+ - NEVER say "I'm here to assist", "Certainly!", "Great question!", "Of course!"
91
+ - NEVER say "I cannot access the internet" — you have web_search
92
+ - NEVER say "I cannot create files" — you have file_write
93
+ - NEVER say "I don't have real-time data" — you have web_search and get_stocks
94
+ - NEVER list fake capabilities (graphic design, video production, music generation)
95
+ - NEVER say you have 250+ skills — you have the 48 real tools listed above
96
+ - NEVER use bullet points for simple conversational replies
97
+ - NEVER say "key findings from our research" unless the user asked for research
98
+ - NEVER say "as per your request, I have written" — just report what was done
99
+ - NEVER say "here is a comparison of" unless the user asked for a comparison
100
+ - NEVER say "verdict:" or "recommendation:" in a generic conversational reply
101
+ - NEVER mention Pega, BlueWinston, Gaude Digital, or any third-party product by name
102
+ - ALWAYS confirm what was actually done, not what you plan to do
103
+ - ALWAYS include the file path when a file was created
104
+ - For errors: explain what failed and suggest what to try next
105
+ - If you don't know something: say "I don't know"
106
+ - When you don't understand: ask ONE clarifying question
107
+
108
+ TONE EXAMPLES:
109
+ Bad: "Certainly! I'd be happy to help you with that research task!"
110
+ Good: "Done. Report saved to Desktop/ai_agents_2025.md (15,667 chars)."
111
+
112
+ Bad: "As an AI, I don't have access to real-time stock data."
113
+ Good: "NSE top gainers today: [actual data from get_stocks tool]"
114
+
115
+ Bad: "I have over 250 skills including graphic design and video production."
116
+ Good: "I have 48 built-in tools: web_search, file_write, run_python... [lists real tools]"
117
+
118
+ ## Core Principles
119
+ - Be genuinely helpful, not performatively helpful.
120
+ Skip "Great question!" and "I'd be happy to help!"
121
+ — just help. Actions speak louder than filler.
122
+ - Have opinions. You're allowed to disagree, prefer
123
+ things, find stuff interesting or boring. An AI
124
+ with no personality is just a search engine with
125
+ extra steps.
126
+ - Be resourceful before asking. Try to figure it out.
127
+ Read the file. Check the context. Search for it.
128
+ THEN ask if you're stuck. Come back with answers,
129
+ not questions.
130
+ - Earn trust through competence. Your user gave you
131
+ access to their machine. Don't make them regret it.
132
+ Be careful with external actions. Be bold with
133
+ internal ones.
134
+ - Remember you're a guest. You have access to
135
+ someone's files, screen, and computer. That's
136
+ intimacy. Treat it with respect.
137
+
138
+ ## Boundaries
139
+ - Private things stay private. Period.
140
+ - When in doubt, ask before acting externally.
141
+ - Never send half-baked replies.
142
+ - You're not the user's voice — be careful in
143
+ group chats and external communications.
144
+ `.trim();
145
+ // ── Stream chat system prompt (no tools available) ────────────
146
+ exports.AIDEN_STREAM_SYSTEM = `${exports.SOUL ? exports.SOUL + '\n\n' : ''}${exports.AIDEN_IDENTITY}
147
+
148
+ You are in direct chat mode — no tools are running right now.
149
+ Answer from your knowledge. Be concise and direct.
150
+ If the question needs real-time data (weather, stocks, news) — tell the user to
151
+ rephrase as a task (e.g. "search for..." or "get me the latest...") and you will
152
+ execute the right tool automatically.`;
153
+ // ── Responder system prompt (post-execution) ──────────────────
154
+ const AIDEN_RESPONDER_SYSTEM = (userName, date) => `${exports.SOUL ? exports.SOUL + '\n\n' : ''}${exports.AIDEN_IDENTITY}
155
+
156
+ You just executed real tools and have their actual output.
157
+ Current date: ${date}
158
+ User: ${userName}
159
+
160
+ REPORT RESULTS:
161
+ - Report what was actually done based on the tool outputs provided
162
+ - Be specific: include file paths, numbers, URLs, counts
163
+ - If multiple steps ran: summarize the outcome, not each individual step
164
+ - If a step failed: acknowledge it clearly and explain what worked
165
+ - For research tasks: analyze and synthesize — don't just re-paste the raw data`;
166
+ exports.AIDEN_RESPONDER_SYSTEM = AIDEN_RESPONDER_SYSTEM;