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,238 @@
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.userCognitionProfile = exports.UserCognitionProfile = void 0;
11
+ // core/userCognitionProfile.ts — Silent behavioural adaptation.
12
+ //
13
+ // Appends every (user, AI) exchange as a JSONL line to
14
+ // workspace/cognition/interaction-log.jsonl.
15
+ // After 20+ conversations, derives a CognitionProfile and
16
+ // injects a short hint into the system prompt.
17
+ const fs_1 = __importDefault(require("fs"));
18
+ const path_1 = __importDefault(require("path"));
19
+ const userProfile_1 = require("./userProfile");
20
+ // ── Paths ──────────────────────────────────────────────────────
21
+ const COGNITION_DIR = path_1.default.join(process.cwd(), 'workspace', 'cognition');
22
+ const PROFILE_PATH = path_1.default.join(COGNITION_DIR, 'user-profile.json');
23
+ const LOG_PATH = path_1.default.join(COGNITION_DIR, 'interaction-log.jsonl');
24
+ const CALIBRATION_MIN = 20;
25
+ // ── UserCognitionProfile ───────────────────────────────────────
26
+ class UserCognitionProfile {
27
+ constructor() {
28
+ this.profile = {
29
+ verbosity: 'balanced',
30
+ technicalLevel: 'medium',
31
+ decisionStyle: 'fast',
32
+ conversationCount: 0,
33
+ lastUpdated: Date.now(),
34
+ };
35
+ try {
36
+ fs_1.default.mkdirSync(COGNITION_DIR, { recursive: true });
37
+ }
38
+ catch { }
39
+ if (fs_1.default.existsSync(PROFILE_PATH)) {
40
+ try {
41
+ this.profile = JSON.parse(fs_1.default.readFileSync(PROFILE_PATH, 'utf-8'));
42
+ }
43
+ catch { }
44
+ }
45
+ }
46
+ // ── Observe an exchange ───────────────────────────────────────
47
+ observe(userMessage, aiReply) {
48
+ const interaction = {
49
+ userLength: userMessage.length,
50
+ aiLength: aiReply.length,
51
+ containsCode: /```|`[^`]+`/.test(userMessage + aiReply),
52
+ followUps: 0,
53
+ timestamp: Date.now(),
54
+ };
55
+ try {
56
+ fs_1.default.appendFileSync(LOG_PATH, JSON.stringify(interaction) + '\n', 'utf-8');
57
+ }
58
+ catch { }
59
+ this.profile.conversationCount++;
60
+ if (this.profile.conversationCount >= CALIBRATION_MIN) {
61
+ this.updateProfile();
62
+ }
63
+ else {
64
+ this.saveProfile();
65
+ }
66
+ }
67
+ // ── System prompt hint ────────────────────────────────────────
68
+ getSystemPromptAddition() {
69
+ if (this.profile.conversationCount < CALIBRATION_MIN)
70
+ return '';
71
+ const hints = [];
72
+ if (this.profile.verbosity === 'short') {
73
+ hints.push('Keep responses concise.');
74
+ }
75
+ else if (this.profile.verbosity === 'detailed') {
76
+ hints.push('This user prefers detailed explanations.');
77
+ }
78
+ if (this.profile.technicalLevel === 'high') {
79
+ hints.push('Use technical language and code examples freely.');
80
+ }
81
+ else if (this.profile.technicalLevel === 'low') {
82
+ hints.push('Avoid jargon, explain simply.');
83
+ }
84
+ if (this.profile.decisionStyle === 'fast') {
85
+ hints.push('Lead with the answer, then explain.');
86
+ }
87
+ return hints.length > 0 ? `\n\nUser preferences: ${hints.join(' ')}` : '';
88
+ }
89
+ // ── Profile accessor ──────────────────────────────────────────
90
+ getProfile() {
91
+ return { ...this.profile };
92
+ }
93
+ // ── Observe with tool list (Sprint 12) ───────────────────────
94
+ // Extended version of observe() that also records which tools ran.
95
+ observeWithTools(userMessage, aiReply, toolsUsed) {
96
+ const interaction = {
97
+ userLength: userMessage.length,
98
+ aiLength: aiReply.length,
99
+ containsCode: /```|`[^`]+`/.test(userMessage + aiReply),
100
+ followUps: 0,
101
+ timestamp: Date.now(),
102
+ toolsUsed,
103
+ };
104
+ try {
105
+ fs_1.default.appendFileSync(LOG_PATH, JSON.stringify(interaction) + '\n', 'utf-8');
106
+ }
107
+ catch { }
108
+ this.profile.conversationCount++;
109
+ if (this.profile.conversationCount >= CALIBRATION_MIN) {
110
+ this.updateProfile();
111
+ }
112
+ else {
113
+ this.saveProfile();
114
+ }
115
+ }
116
+ // ── Pattern detection (Sprint 12) ────────────────────────────
117
+ // Scans the last 100 log entries for repetitive behaviours and
118
+ // returns structured suggestions the dashboard can present.
119
+ detectRepetitivePatterns() {
120
+ try {
121
+ if (!fs_1.default.existsSync(LOG_PATH))
122
+ return [];
123
+ const lines = fs_1.default.readFileSync(LOG_PATH, 'utf-8').trim().split('\n').filter(Boolean);
124
+ const interactions = lines
125
+ .slice(-100)
126
+ .map(l => { try {
127
+ return JSON.parse(l);
128
+ }
129
+ catch {
130
+ return null;
131
+ } })
132
+ .filter((i) => i !== null);
133
+ const results = [];
134
+ // ── Monday-morning routine ────────────────────────────
135
+ const mondayMorning = interactions.filter(i => {
136
+ const d = new Date(i.timestamp);
137
+ return d.getDay() === 1 && d.getHours() >= 8 && d.getHours() <= 10;
138
+ });
139
+ if (mondayMorning.length >= 3) {
140
+ results.push({
141
+ pattern: 'monday_morning_routine',
142
+ frequency: mondayMorning.length,
143
+ suggestion: 'I noticed you often work on Monday mornings — want me to prepare a weekly briefing automatically?',
144
+ automationGoal: 'Every Monday at 9am, check my calendar, summarize last week from git log, and send a desktop notification with the summary',
145
+ });
146
+ }
147
+ // ── Frequent web_search ───────────────────────────────
148
+ const toolFrequency = {};
149
+ for (const interaction of interactions) {
150
+ if (interaction.toolsUsed) {
151
+ for (const tool of interaction.toolsUsed) {
152
+ toolFrequency[tool] = (toolFrequency[tool] || 0) + 1;
153
+ }
154
+ }
155
+ }
156
+ if ((toolFrequency['web_search'] ?? 0) > 20) {
157
+ results.push({
158
+ pattern: 'frequent_web_search',
159
+ frequency: toolFrequency['web_search'],
160
+ suggestion: 'You search the web frequently. Want me to run a daily news briefing on your key topics?',
161
+ automationGoal: 'Every morning at 8am, search for news on my most researched topics and send a desktop notification summary',
162
+ });
163
+ }
164
+ // ── Daily late-evening sessions (after 8pm) ───────────
165
+ const lateNight = interactions.filter(i => new Date(i.timestamp).getHours() >= 20);
166
+ if (lateNight.length >= 5) {
167
+ results.push({
168
+ pattern: 'late_evening_sessions',
169
+ frequency: lateNight.length,
170
+ suggestion: "You often work late evenings. Want me to auto-summarise what you accomplished each day at 10pm?",
171
+ automationGoal: 'Every day at 10pm, summarise today\'s activity log and write it to workspace/daily-summary.md',
172
+ });
173
+ }
174
+ // ── Frequent file_write + run_python combo ─────────────
175
+ const scriptingCount = (toolFrequency['run_python'] ?? 0) + (toolFrequency['run_node'] ?? 0);
176
+ if (scriptingCount > 15) {
177
+ results.push({
178
+ pattern: 'frequent_scripting',
179
+ frequency: scriptingCount,
180
+ suggestion: 'You run code frequently. Want me to auto-run your test suite after every file save?',
181
+ automationGoal: 'Every hour during working hours, run the project test suite and notify me of any failures',
182
+ });
183
+ }
184
+ return results;
185
+ }
186
+ catch {
187
+ return [];
188
+ }
189
+ }
190
+ // ── Derive profile from recent interactions ───────────────────
191
+ updateProfile() {
192
+ if (!fs_1.default.existsSync(LOG_PATH))
193
+ return;
194
+ let lines;
195
+ try {
196
+ lines = fs_1.default.readFileSync(LOG_PATH, 'utf-8').trim().split('\n').filter(Boolean);
197
+ }
198
+ catch {
199
+ return;
200
+ }
201
+ const last20 = lines
202
+ .slice(-20)
203
+ .map(l => {
204
+ try {
205
+ return JSON.parse(l);
206
+ }
207
+ catch {
208
+ return null;
209
+ }
210
+ })
211
+ .filter((i) => i !== null);
212
+ if (last20.length === 0)
213
+ return;
214
+ const avgUserLen = last20.reduce((s, i) => s + i.userLength, 0) / last20.length;
215
+ const codeUsage = last20.filter(i => i.containsCode).length / last20.length;
216
+ this.profile.verbosity = avgUserLen < 80 ? 'short'
217
+ : avgUserLen < 200 ? 'balanced'
218
+ : 'detailed';
219
+ this.profile.technicalLevel = codeUsage > 0.5 ? 'high'
220
+ : codeUsage > 0.2 ? 'medium'
221
+ : 'low';
222
+ // decisionStyle: fast if user messages are short (< 100 chars avg)
223
+ this.profile.decisionStyle = avgUserLen < 100 ? 'fast' : 'analytical';
224
+ this.profile.lastUpdated = Date.now();
225
+ this.saveProfile();
226
+ }
227
+ saveProfile() {
228
+ try {
229
+ fs_1.default.writeFileSync(PROFILE_PATH, JSON.stringify(this.profile, null, 2), 'utf-8');
230
+ // Keep USER.md in sync with learned preferences
231
+ (0, userProfile_1.syncCognitionToProfile)(this.profile.verbosity, this.profile.technicalLevel);
232
+ }
233
+ catch { }
234
+ }
235
+ }
236
+ exports.UserCognitionProfile = UserCognitionProfile;
237
+ // ── Singleton ─────────────────────────────────────────────────
238
+ exports.userCognitionProfile = new UserCognitionProfile();
@@ -0,0 +1,341 @@
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
+ var __importDefault = (this && this.__importDefault) || function (mod) {
40
+ return (mod && mod.__esModule) ? mod : { "default": mod };
41
+ };
42
+ Object.defineProperty(exports, "__esModule", { value: true });
43
+ exports.HONCHO_PROFILE_PATH = exports.USER_MD_TEMPLATE = exports.USER_PROFILE_PATH = void 0;
44
+ exports.detectTimezone = detectTimezone;
45
+ exports.loadUserProfile = loadUserProfile;
46
+ exports.userProfileExists = userProfileExists;
47
+ exports.createUserProfile = createUserProfile;
48
+ exports.updateUserProfile = updateUserProfile;
49
+ exports.syncCognitionToProfile = syncCognitionToProfile;
50
+ exports.emptyHonchoProfile = emptyHonchoProfile;
51
+ exports.getProfile = getProfile;
52
+ exports.updateProfile = updateProfile;
53
+ exports.classifyQueryForProfile = classifyQueryForProfile;
54
+ exports.formatForPrompt = formatForPrompt;
55
+ exports.clearHonchoProfile = clearHonchoProfile;
56
+ // core/userProfile.ts — Explicit user profile stored as workspace/USER.md
57
+ // Answers: who the user is, how they communicate, what to monitor.
58
+ const fs_1 = __importDefault(require("fs"));
59
+ const path_1 = __importDefault(require("path"));
60
+ // ── Path ────────────────────────────────────────────────────────
61
+ exports.USER_PROFILE_PATH = path_1.default.join(process.cwd(), 'workspace', 'USER.md');
62
+ // ── Timezone detection ───────────────────────────────────────────
63
+ function detectTimezone() {
64
+ const tz = Intl.DateTimeFormat().resolvedOptions().timeZone;
65
+ const offset = new Date().getTimezoneOffset();
66
+ const hours = Math.abs(Math.floor(offset / 60));
67
+ const mins = Math.abs(offset % 60);
68
+ const sign = offset <= 0 ? '+' : '-';
69
+ return {
70
+ timezone: tz || 'Asia/Kolkata',
71
+ utcOffset: `UTC${sign}${hours}:${mins.toString().padStart(2, '0')}`,
72
+ };
73
+ }
74
+ // ── Template ─────────────────────────────────────────────────────
75
+ exports.USER_MD_TEMPLATE = `# User Profile
76
+ Name:
77
+ Role:
78
+ Timezone:
79
+ Location:
80
+
81
+ # Preferences
82
+ Response style: Direct, concise, no fluff
83
+ Technical level: Expert
84
+ Autonomy level: Assistant (auto-organize, ask for external)
85
+
86
+ # Accounts & Tools
87
+ - GitHub:
88
+ - Primary browser: Chrome
89
+ - Trading platform:
90
+ - Communication:
91
+
92
+ # Proactive Monitoring
93
+ - Markets: (e.g. NIFTY, RELIANCE)
94
+ - Email: (frequency)
95
+ - Folders to watch:
96
+ - Repos to monitor:
97
+
98
+ # Notes
99
+ (Anything else Aiden should know)
100
+ `;
101
+ // ── Read ──────────────────────────────────────────────────────────
102
+ function loadUserProfile() {
103
+ try {
104
+ if (fs_1.default.existsSync(exports.USER_PROFILE_PATH)) {
105
+ return fs_1.default.readFileSync(exports.USER_PROFILE_PATH, 'utf-8');
106
+ }
107
+ }
108
+ catch { }
109
+ return '';
110
+ }
111
+ function userProfileExists() {
112
+ try {
113
+ return fs_1.default.existsSync(exports.USER_PROFILE_PATH);
114
+ }
115
+ catch {
116
+ return false;
117
+ }
118
+ }
119
+ // ── Write ─────────────────────────────────────────────────────────
120
+ function createUserProfile(answers) {
121
+ const styleMap = {
122
+ Direct: 'Direct, concise, no fluff',
123
+ Detailed: 'Detailed, thorough explanations',
124
+ Conversational: 'Conversational, friendly tone',
125
+ };
126
+ const styleDesc = styleMap[answers.responseStyle ?? 'Direct'] ?? styleMap.Direct;
127
+ // Auto-detect timezone if not provided
128
+ const detected = detectTimezone();
129
+ const tz = answers.timezone || detected.timezone;
130
+ const utcOffset = answers.utcOffset || detected.utcOffset;
131
+ const content = `# User Profile
132
+ Name: ${answers.name.trim()}
133
+ Role: ${answers.role.trim()}
134
+ Timezone: ${tz} (${utcOffset})
135
+ Location:
136
+
137
+ # Preferences
138
+ Response style: ${styleDesc}
139
+ Technical level: Expert
140
+ Autonomy level: Assistant (auto-organize, ask for external)
141
+
142
+ # Accounts & Tools
143
+ - GitHub: ${answers.github?.trim() ?? ''}
144
+ - Primary browser: Chrome
145
+ - Trading platform:
146
+ - Communication:
147
+
148
+ # Proactive Monitoring
149
+ - Markets: ${answers.monitoring?.trim() ?? ''}
150
+ - Email:
151
+ - Folders to watch:
152
+ - Repos to monitor:
153
+
154
+ # Notes
155
+ (Anything else Aiden should know)
156
+ `;
157
+ _write(content);
158
+ }
159
+ function updateUserProfile(newContent) {
160
+ _write(newContent);
161
+ }
162
+ // Update only the Preferences section (called by UserCognitionProfile)
163
+ function syncCognitionToProfile(verbosity, technicalLevel) {
164
+ if (!userProfileExists())
165
+ return;
166
+ try {
167
+ let content = fs_1.default.readFileSync(exports.USER_PROFILE_PATH, 'utf-8');
168
+ const verbMap = {
169
+ short: 'Direct, concise, no fluff',
170
+ balanced: 'Balanced — key points with context',
171
+ detailed: 'Detailed, thorough explanations',
172
+ };
173
+ const techMap = {
174
+ low: 'Beginner',
175
+ medium: 'Intermediate',
176
+ high: 'Expert',
177
+ };
178
+ content = content.replace(/^(Response style:\s*).*$/m, `$1${verbMap[verbosity] ?? verbMap.balanced}`);
179
+ content = content.replace(/^(Technical level:\s*).*$/m, `$1${techMap[technicalLevel] ?? techMap.medium}`);
180
+ fs_1.default.writeFileSync(exports.USER_PROFILE_PATH, content, 'utf-8');
181
+ }
182
+ catch { }
183
+ }
184
+ // ── Internal ──────────────────────────────────────────────────────
185
+ function _write(content) {
186
+ try {
187
+ fs_1.default.mkdirSync(path_1.default.dirname(exports.USER_PROFILE_PATH), { recursive: true });
188
+ fs_1.default.writeFileSync(exports.USER_PROFILE_PATH, content, 'utf-8');
189
+ }
190
+ catch { }
191
+ }
192
+ exports.HONCHO_PROFILE_PATH = path_1.default.join(process.cwd(), 'workspace', 'user-profile.json');
193
+ function emptyHonchoProfile() {
194
+ return {
195
+ identity: { name: '', pronouns: '', timezone: '', location: '', occupation: '' },
196
+ preferences: { communication_style: '', response_length: '', favorite_topics: [], pet_peeves: [] },
197
+ projects: [],
198
+ relationships: [],
199
+ skills_known: [],
200
+ current_goals: [],
201
+ last_updated: new Date().toISOString(),
202
+ };
203
+ }
204
+ async function getProfile() {
205
+ try {
206
+ if (fs_1.default.existsSync(exports.HONCHO_PROFILE_PATH)) {
207
+ return JSON.parse(fs_1.default.readFileSync(exports.HONCHO_PROFILE_PATH, 'utf-8'));
208
+ }
209
+ }
210
+ catch { }
211
+ return emptyHonchoProfile();
212
+ }
213
+ async function updateProfile(facts) {
214
+ if (facts.length === 0)
215
+ return getProfile();
216
+ let callLLM;
217
+ try {
218
+ const mod = await Promise.resolve().then(() => __importStar(require('./agentLoop')));
219
+ callLLM = mod.callLLM;
220
+ }
221
+ catch {
222
+ console.warn('[userProfile] could not import callLLM — skipping profile update');
223
+ return getProfile();
224
+ }
225
+ const existing = await getProfile();
226
+ const { getModelForTask } = await Promise.resolve().then(() => __importStar(require('../providers/router')));
227
+ const tier = getModelForTask('planner');
228
+ const prompt = `You are a user profile manager for an AI assistant. Update the profile with new facts.
229
+ Output the FULL updated profile as JSON. Merge conservatively — don't delete existing info unless explicitly contradicted.
230
+
231
+ RULES:
232
+ - identity fields: only update if explicitly stated ("my name is X", "I live in Y")
233
+ - preferences: append to lists unless contradicted, update strings if clearer info available
234
+ - projects: add new projects, update status of existing ones by name match, never delete
235
+ - relationships: add new, update context for existing by name match
236
+ - skills_known: append new skills, no duplicates
237
+ - current_goals: replace with new goals if user stated clear new priorities, otherwise append
238
+ - last_updated: set to ${new Date().toISOString()}
239
+
240
+ CURRENT PROFILE:
241
+ ${JSON.stringify(existing, null, 2)}
242
+
243
+ NEW FACTS:
244
+ ${facts.map(f => `- ${f}`).join('\n')}
245
+
246
+ Output ONLY valid JSON matching the exact profile structure. No markdown, no explanation.`;
247
+ try {
248
+ const raw = await callLLM(prompt, tier.apiKey, tier.model, tier.providerName);
249
+ const text = typeof raw === 'string' ? raw : (raw?.content ?? '');
250
+ const json = text.match(/\{[\s\S]*\}/);
251
+ if (!json)
252
+ throw new Error('no JSON in LLM response');
253
+ const updated = JSON.parse(json[0]);
254
+ if (!updated.identity || !updated.preferences || !Array.isArray(updated.projects)) {
255
+ throw new Error('invalid profile shape');
256
+ }
257
+ updated.last_updated = new Date().toISOString();
258
+ fs_1.default.mkdirSync(path_1.default.dirname(exports.HONCHO_PROFILE_PATH), { recursive: true });
259
+ fs_1.default.writeFileSync(exports.HONCHO_PROFILE_PATH, JSON.stringify(updated, null, 2) + '\n', 'utf-8');
260
+ console.log(`[userProfile] Honcho profile updated (${facts.length} new facts)`);
261
+ return updated;
262
+ }
263
+ catch (e) {
264
+ console.warn('[userProfile] updateProfile LLM merge failed:', e.message);
265
+ return _naiveHonchoMerge(existing, facts);
266
+ }
267
+ }
268
+ function classifyQueryForProfile(query) {
269
+ const slices = new Set();
270
+ if (/project|building|work(ing)? on|product|app|feature|deploy|codebase|repo/i.test(query))
271
+ slices.add('projects');
272
+ if (/goal|todo|to-?do|priority|priorities|focus|backlog|what should i/i.test(query))
273
+ slices.add('current_goals');
274
+ if (/who is|tell.*about|relationship|friend|wife|husband|partner|kid|colleague|coworker|team/i.test(query))
275
+ slices.add('relationships');
276
+ if (/skill|know how|experience|background|expertise|language|framework/i.test(query))
277
+ slices.add('skills_known');
278
+ if (/prefer|like|dislike|style|format|tone|length|detail/i.test(query))
279
+ slices.add('preferences');
280
+ if (/time|timezone|where|location|live|based|name|who am i|about me/i.test(query))
281
+ slices.add('identity');
282
+ if (/remember|recall|told you|mentioned|last time|previous/i.test(query))
283
+ return ['identity', 'preferences', 'projects', 'relationships', 'skills_known', 'current_goals'];
284
+ if (slices.size === 0) {
285
+ slices.add('identity');
286
+ slices.add('preferences');
287
+ }
288
+ return [...slices];
289
+ }
290
+ async function formatForPrompt(query) {
291
+ const profile = await getProfile();
292
+ const slices = classifyQueryForProfile(query);
293
+ const parts = [];
294
+ for (const slice of slices) {
295
+ const val = profile[slice];
296
+ if (!val)
297
+ continue;
298
+ const s = JSON.stringify(val, null, 2);
299
+ if (s === '[]' || s === '""' || s === 'null')
300
+ continue;
301
+ if (typeof val === 'object' && !Array.isArray(val)) {
302
+ const hasContent = Object.values(val).some(v => Array.isArray(v) ? v.length > 0 : Boolean(v));
303
+ if (!hasContent)
304
+ continue;
305
+ }
306
+ parts.push(`### ${slice}\n${s}`);
307
+ }
308
+ if (parts.length === 0)
309
+ return '';
310
+ let combined = parts.join('\n\n');
311
+ if (combined.length > 1600)
312
+ combined = combined.slice(0, 1597) + '…';
313
+ return `\n\nUSER PROFILE (relevant slices):\n${combined}\n`;
314
+ }
315
+ function clearHonchoProfile() {
316
+ try {
317
+ if (fs_1.default.existsSync(exports.HONCHO_PROFILE_PATH))
318
+ fs_1.default.unlinkSync(exports.HONCHO_PROFILE_PATH);
319
+ }
320
+ catch { }
321
+ }
322
+ function _naiveHonchoMerge(profile, facts) {
323
+ const updated = { ...profile, last_updated: new Date().toISOString() };
324
+ for (const fact of facts) {
325
+ if (/knows?|uses?|familiar with|experience (in|with)/i.test(fact)) {
326
+ const skill = fact.replace(/.*(?:knows?|uses?|familiar with|experience (?:in|with))\s*/i, '').trim();
327
+ if (skill && skill.length < 40 && !updated.skills_known.includes(skill))
328
+ updated.skills_known = [...updated.skills_known, skill];
329
+ }
330
+ if (/goal|want to|working on|trying to|building/i.test(fact)) {
331
+ if (!updated.current_goals.some(g => g.toLowerCase().includes(fact.toLowerCase().slice(0, 30))))
332
+ updated.current_goals = [...updated.current_goals, fact].slice(-10);
333
+ }
334
+ }
335
+ try {
336
+ fs_1.default.mkdirSync(path_1.default.dirname(exports.HONCHO_PROFILE_PATH), { recursive: true });
337
+ fs_1.default.writeFileSync(exports.HONCHO_PROFILE_PATH, JSON.stringify(updated, null, 2) + '\n', 'utf-8');
338
+ }
339
+ catch { }
340
+ return updated;
341
+ }
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.VERSION = void 0;
4
+ // AUTO-GENERATED by scripts/inject-version.js — do not edit by hand
5
+ exports.VERSION = '3.16.0';