@usejarvis/brain 0.1.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 (266) hide show
  1. package/LICENSE +153 -0
  2. package/README.md +278 -0
  3. package/bin/jarvis.ts +413 -0
  4. package/package.json +74 -0
  5. package/scripts/ensure-bun.cjs +8 -0
  6. package/src/actions/README.md +421 -0
  7. package/src/actions/app-control/desktop-controller.test.ts +26 -0
  8. package/src/actions/app-control/desktop-controller.ts +438 -0
  9. package/src/actions/app-control/interface.ts +64 -0
  10. package/src/actions/app-control/linux.ts +273 -0
  11. package/src/actions/app-control/macos.ts +54 -0
  12. package/src/actions/app-control/sidecar-launcher.test.ts +23 -0
  13. package/src/actions/app-control/sidecar-launcher.ts +286 -0
  14. package/src/actions/app-control/windows.ts +44 -0
  15. package/src/actions/browser/cdp.ts +138 -0
  16. package/src/actions/browser/chrome-launcher.ts +252 -0
  17. package/src/actions/browser/session.ts +437 -0
  18. package/src/actions/browser/stealth.ts +49 -0
  19. package/src/actions/index.ts +20 -0
  20. package/src/actions/terminal/executor.ts +157 -0
  21. package/src/actions/terminal/wsl-bridge.ts +126 -0
  22. package/src/actions/test.ts +93 -0
  23. package/src/actions/tools/agents.ts +321 -0
  24. package/src/actions/tools/builtin.ts +846 -0
  25. package/src/actions/tools/commitments.ts +192 -0
  26. package/src/actions/tools/content.ts +217 -0
  27. package/src/actions/tools/delegate.ts +147 -0
  28. package/src/actions/tools/desktop.test.ts +55 -0
  29. package/src/actions/tools/desktop.ts +305 -0
  30. package/src/actions/tools/goals.ts +376 -0
  31. package/src/actions/tools/local-tools-guard.ts +20 -0
  32. package/src/actions/tools/registry.ts +171 -0
  33. package/src/actions/tools/research.ts +111 -0
  34. package/src/actions/tools/sidecar-list.ts +57 -0
  35. package/src/actions/tools/sidecar-route.ts +105 -0
  36. package/src/actions/tools/workflows.ts +216 -0
  37. package/src/agents/agent.ts +132 -0
  38. package/src/agents/delegation.ts +107 -0
  39. package/src/agents/hierarchy.ts +113 -0
  40. package/src/agents/index.ts +19 -0
  41. package/src/agents/messaging.ts +125 -0
  42. package/src/agents/orchestrator.ts +576 -0
  43. package/src/agents/role-discovery.ts +61 -0
  44. package/src/agents/sub-agent-runner.ts +307 -0
  45. package/src/agents/task-manager.ts +151 -0
  46. package/src/authority/approval-delivery.ts +59 -0
  47. package/src/authority/approval.ts +196 -0
  48. package/src/authority/audit.ts +158 -0
  49. package/src/authority/authority.test.ts +519 -0
  50. package/src/authority/deferred-executor.ts +103 -0
  51. package/src/authority/emergency.ts +66 -0
  52. package/src/authority/engine.ts +297 -0
  53. package/src/authority/index.ts +12 -0
  54. package/src/authority/learning.ts +111 -0
  55. package/src/authority/tool-action-map.ts +74 -0
  56. package/src/awareness/analytics.ts +466 -0
  57. package/src/awareness/awareness.test.ts +332 -0
  58. package/src/awareness/capture-engine.ts +305 -0
  59. package/src/awareness/context-graph.ts +130 -0
  60. package/src/awareness/context-tracker.ts +349 -0
  61. package/src/awareness/index.ts +25 -0
  62. package/src/awareness/intelligence.ts +321 -0
  63. package/src/awareness/ocr-engine.ts +88 -0
  64. package/src/awareness/service.ts +528 -0
  65. package/src/awareness/struggle-detector.ts +342 -0
  66. package/src/awareness/suggestion-engine.ts +476 -0
  67. package/src/awareness/types.ts +201 -0
  68. package/src/cli/autostart.ts +241 -0
  69. package/src/cli/deps.ts +449 -0
  70. package/src/cli/doctor.ts +230 -0
  71. package/src/cli/helpers.ts +401 -0
  72. package/src/cli/onboard.ts +580 -0
  73. package/src/comms/README.md +329 -0
  74. package/src/comms/auth-error.html +48 -0
  75. package/src/comms/channels/discord.ts +228 -0
  76. package/src/comms/channels/signal.ts +56 -0
  77. package/src/comms/channels/telegram.ts +316 -0
  78. package/src/comms/channels/whatsapp.ts +60 -0
  79. package/src/comms/channels.test.ts +173 -0
  80. package/src/comms/desktop-notify.ts +114 -0
  81. package/src/comms/example.ts +129 -0
  82. package/src/comms/index.ts +129 -0
  83. package/src/comms/streaming.ts +142 -0
  84. package/src/comms/voice.test.ts +152 -0
  85. package/src/comms/voice.ts +291 -0
  86. package/src/comms/websocket.test.ts +409 -0
  87. package/src/comms/websocket.ts +473 -0
  88. package/src/config/README.md +387 -0
  89. package/src/config/index.ts +6 -0
  90. package/src/config/loader.test.ts +137 -0
  91. package/src/config/loader.ts +142 -0
  92. package/src/config/types.ts +260 -0
  93. package/src/daemon/README.md +232 -0
  94. package/src/daemon/agent-service-interface.ts +9 -0
  95. package/src/daemon/agent-service.ts +600 -0
  96. package/src/daemon/api-routes.ts +2119 -0
  97. package/src/daemon/background-agent-service.ts +396 -0
  98. package/src/daemon/background-agent.test.ts +78 -0
  99. package/src/daemon/channel-service.ts +201 -0
  100. package/src/daemon/commitment-executor.ts +297 -0
  101. package/src/daemon/event-classifier.ts +239 -0
  102. package/src/daemon/event-coalescer.ts +123 -0
  103. package/src/daemon/event-reactor.ts +214 -0
  104. package/src/daemon/health.ts +220 -0
  105. package/src/daemon/index.ts +1004 -0
  106. package/src/daemon/llm-settings.ts +316 -0
  107. package/src/daemon/observer-service.ts +150 -0
  108. package/src/daemon/pid.ts +98 -0
  109. package/src/daemon/research-queue.ts +155 -0
  110. package/src/daemon/services.ts +175 -0
  111. package/src/daemon/ws-service.ts +788 -0
  112. package/src/goals/accountability.ts +240 -0
  113. package/src/goals/awareness-bridge.ts +185 -0
  114. package/src/goals/estimator.ts +185 -0
  115. package/src/goals/events.ts +28 -0
  116. package/src/goals/goals.test.ts +400 -0
  117. package/src/goals/integration.test.ts +329 -0
  118. package/src/goals/nl-builder.test.ts +220 -0
  119. package/src/goals/nl-builder.ts +256 -0
  120. package/src/goals/rhythm.test.ts +177 -0
  121. package/src/goals/rhythm.ts +275 -0
  122. package/src/goals/service.test.ts +135 -0
  123. package/src/goals/service.ts +348 -0
  124. package/src/goals/types.ts +106 -0
  125. package/src/goals/workflow-bridge.ts +96 -0
  126. package/src/integrations/google-api.ts +134 -0
  127. package/src/integrations/google-auth.ts +175 -0
  128. package/src/llm/README.md +291 -0
  129. package/src/llm/anthropic.ts +386 -0
  130. package/src/llm/gemini.ts +371 -0
  131. package/src/llm/index.ts +19 -0
  132. package/src/llm/manager.ts +153 -0
  133. package/src/llm/ollama.ts +307 -0
  134. package/src/llm/openai.ts +350 -0
  135. package/src/llm/provider.test.ts +231 -0
  136. package/src/llm/provider.ts +60 -0
  137. package/src/llm/test.ts +87 -0
  138. package/src/observers/README.md +278 -0
  139. package/src/observers/calendar.ts +113 -0
  140. package/src/observers/clipboard.ts +136 -0
  141. package/src/observers/email.ts +109 -0
  142. package/src/observers/example.ts +58 -0
  143. package/src/observers/file-watcher.ts +124 -0
  144. package/src/observers/index.ts +159 -0
  145. package/src/observers/notifications.ts +197 -0
  146. package/src/observers/observers.test.ts +203 -0
  147. package/src/observers/processes.ts +225 -0
  148. package/src/personality/README.md +61 -0
  149. package/src/personality/adapter.ts +196 -0
  150. package/src/personality/index.ts +20 -0
  151. package/src/personality/learner.ts +209 -0
  152. package/src/personality/model.ts +132 -0
  153. package/src/personality/personality.test.ts +236 -0
  154. package/src/roles/README.md +252 -0
  155. package/src/roles/authority.ts +119 -0
  156. package/src/roles/example-usage.ts +198 -0
  157. package/src/roles/index.ts +42 -0
  158. package/src/roles/loader.ts +143 -0
  159. package/src/roles/prompt-builder.ts +194 -0
  160. package/src/roles/test-multi.ts +102 -0
  161. package/src/roles/test-role.yaml +77 -0
  162. package/src/roles/test-utils.ts +93 -0
  163. package/src/roles/test.ts +106 -0
  164. package/src/roles/tool-guide.ts +190 -0
  165. package/src/roles/types.ts +36 -0
  166. package/src/roles/utils.ts +200 -0
  167. package/src/scripts/google-setup.ts +168 -0
  168. package/src/sidecar/connection.ts +179 -0
  169. package/src/sidecar/index.ts +6 -0
  170. package/src/sidecar/manager.ts +542 -0
  171. package/src/sidecar/protocol.ts +85 -0
  172. package/src/sidecar/rpc.ts +161 -0
  173. package/src/sidecar/scheduler.ts +136 -0
  174. package/src/sidecar/types.ts +112 -0
  175. package/src/sidecar/validator.ts +144 -0
  176. package/src/vault/README.md +110 -0
  177. package/src/vault/awareness.ts +341 -0
  178. package/src/vault/commitments.ts +299 -0
  179. package/src/vault/content-pipeline.ts +260 -0
  180. package/src/vault/conversations.ts +173 -0
  181. package/src/vault/entities.ts +180 -0
  182. package/src/vault/extractor.test.ts +356 -0
  183. package/src/vault/extractor.ts +345 -0
  184. package/src/vault/facts.ts +190 -0
  185. package/src/vault/goals.ts +477 -0
  186. package/src/vault/index.ts +87 -0
  187. package/src/vault/keychain.ts +99 -0
  188. package/src/vault/observations.ts +115 -0
  189. package/src/vault/relationships.ts +178 -0
  190. package/src/vault/retrieval.test.ts +126 -0
  191. package/src/vault/retrieval.ts +227 -0
  192. package/src/vault/schema.ts +658 -0
  193. package/src/vault/settings.ts +38 -0
  194. package/src/vault/vectors.ts +92 -0
  195. package/src/vault/workflows.ts +403 -0
  196. package/src/workflows/auto-suggest.ts +290 -0
  197. package/src/workflows/engine.ts +366 -0
  198. package/src/workflows/events.ts +24 -0
  199. package/src/workflows/executor.ts +207 -0
  200. package/src/workflows/nl-builder.ts +198 -0
  201. package/src/workflows/nodes/actions/agent-task.ts +73 -0
  202. package/src/workflows/nodes/actions/calendar-action.ts +85 -0
  203. package/src/workflows/nodes/actions/code-execution.ts +73 -0
  204. package/src/workflows/nodes/actions/discord.ts +77 -0
  205. package/src/workflows/nodes/actions/file-write.ts +73 -0
  206. package/src/workflows/nodes/actions/gmail.ts +69 -0
  207. package/src/workflows/nodes/actions/http-request.ts +117 -0
  208. package/src/workflows/nodes/actions/notification.ts +85 -0
  209. package/src/workflows/nodes/actions/run-tool.ts +55 -0
  210. package/src/workflows/nodes/actions/send-message.ts +82 -0
  211. package/src/workflows/nodes/actions/shell-command.ts +76 -0
  212. package/src/workflows/nodes/actions/telegram.ts +60 -0
  213. package/src/workflows/nodes/builtin.ts +119 -0
  214. package/src/workflows/nodes/error/error-handler.ts +37 -0
  215. package/src/workflows/nodes/error/fallback.ts +47 -0
  216. package/src/workflows/nodes/error/retry.ts +82 -0
  217. package/src/workflows/nodes/logic/delay.ts +42 -0
  218. package/src/workflows/nodes/logic/if-else.ts +41 -0
  219. package/src/workflows/nodes/logic/loop.ts +90 -0
  220. package/src/workflows/nodes/logic/merge.ts +38 -0
  221. package/src/workflows/nodes/logic/race.ts +40 -0
  222. package/src/workflows/nodes/logic/switch.ts +59 -0
  223. package/src/workflows/nodes/logic/template-render.ts +53 -0
  224. package/src/workflows/nodes/logic/variable-get.ts +37 -0
  225. package/src/workflows/nodes/logic/variable-set.ts +59 -0
  226. package/src/workflows/nodes/registry.ts +99 -0
  227. package/src/workflows/nodes/transform/aggregate.ts +99 -0
  228. package/src/workflows/nodes/transform/csv-parse.ts +70 -0
  229. package/src/workflows/nodes/transform/json-parse.ts +63 -0
  230. package/src/workflows/nodes/transform/map-filter.ts +84 -0
  231. package/src/workflows/nodes/transform/regex-match.ts +89 -0
  232. package/src/workflows/nodes/triggers/calendar.ts +33 -0
  233. package/src/workflows/nodes/triggers/clipboard.ts +32 -0
  234. package/src/workflows/nodes/triggers/cron.ts +40 -0
  235. package/src/workflows/nodes/triggers/email.ts +40 -0
  236. package/src/workflows/nodes/triggers/file-change.ts +45 -0
  237. package/src/workflows/nodes/triggers/git.ts +46 -0
  238. package/src/workflows/nodes/triggers/manual.ts +23 -0
  239. package/src/workflows/nodes/triggers/poll.ts +81 -0
  240. package/src/workflows/nodes/triggers/process.ts +44 -0
  241. package/src/workflows/nodes/triggers/screen-event.ts +37 -0
  242. package/src/workflows/nodes/triggers/webhook.ts +39 -0
  243. package/src/workflows/safe-eval.ts +139 -0
  244. package/src/workflows/template.ts +118 -0
  245. package/src/workflows/triggers/cron.ts +311 -0
  246. package/src/workflows/triggers/manager.ts +285 -0
  247. package/src/workflows/triggers/observer-bridge.ts +172 -0
  248. package/src/workflows/triggers/poller.ts +201 -0
  249. package/src/workflows/triggers/screen-condition.ts +218 -0
  250. package/src/workflows/triggers/triggers.test.ts +740 -0
  251. package/src/workflows/triggers/webhook.ts +191 -0
  252. package/src/workflows/types.ts +133 -0
  253. package/src/workflows/variables.ts +72 -0
  254. package/src/workflows/workflows.test.ts +383 -0
  255. package/src/workflows/yaml.ts +104 -0
  256. package/ui/dist/index-j75njzc1.css +1199 -0
  257. package/ui/dist/index-p2zh407q.js +80603 -0
  258. package/ui/dist/index.html +13 -0
  259. package/ui/public/openwakeword/models/embedding_model.onnx +0 -0
  260. package/ui/public/openwakeword/models/hey_jarvis_v0.1.onnx +0 -0
  261. package/ui/public/openwakeword/models/melspectrogram.onnx +0 -0
  262. package/ui/public/openwakeword/models/silero_vad.onnx +0 -0
  263. package/ui/public/ort/ort-wasm-simd-threaded.jsep.mjs +106 -0
  264. package/ui/public/ort/ort-wasm-simd-threaded.jsep.wasm +0 -0
  265. package/ui/public/ort/ort-wasm-simd-threaded.mjs +59 -0
  266. package/ui/public/ort/ort-wasm-simd-threaded.wasm +0 -0
@@ -0,0 +1,260 @@
1
+ export type HeartbeatConfig = {
2
+ interval_minutes: number;
3
+ active_hours: { start: number; end: number };
4
+ aggressiveness: 'passive' | 'moderate' | 'aggressive';
5
+ };
6
+
7
+ export type GoogleConfig = {
8
+ client_id: string;
9
+ client_secret: string;
10
+ };
11
+
12
+ export type ChannelConfig = {
13
+ telegram?: {
14
+ enabled: boolean;
15
+ bot_token: string;
16
+ allowed_users: number[]; // Telegram user IDs
17
+ };
18
+ discord?: {
19
+ enabled: boolean;
20
+ bot_token: string;
21
+ allowed_users: string[]; // Discord user IDs
22
+ guild_id?: string; // restrict to single guild
23
+ };
24
+ };
25
+
26
+ export type STTConfig = {
27
+ provider: 'openai' | 'groq' | 'local';
28
+ openai?: { api_key: string; model?: string };
29
+ groq?: { api_key: string; model?: string };
30
+ local?: { endpoint: string; model?: string };
31
+ };
32
+
33
+ export type TTSConfig = {
34
+ enabled: boolean;
35
+ provider?: 'edge' | 'elevenlabs'; // default: 'edge'
36
+ voice?: string; // e.g. 'en-US-AriaNeural' (edge)
37
+ rate?: string; // e.g. '+0%', '+10%' (edge)
38
+ volume?: string; // e.g. '+0%' (edge)
39
+ elevenlabs?: {
40
+ api_key: string;
41
+ voice_id?: string;
42
+ model?: string; // 'eleven_flash_v2_5' | 'eleven_multilingual_v2'
43
+ stability?: number; // 0-1
44
+ similarity_boost?: number; // 0-1
45
+ };
46
+ };
47
+
48
+ export type DesktopConfig = {
49
+ enabled: boolean;
50
+ sidecar_port: number;
51
+ sidecar_path?: string;
52
+ auto_launch: boolean;
53
+ tree_depth: number;
54
+ snapshot_max_elements: number;
55
+ };
56
+
57
+ export type AwarenessConfig = {
58
+ enabled: boolean;
59
+ capture_interval_ms: number;
60
+ min_change_threshold: number; // 0.0-1.0 pixel diff percentage
61
+ cloud_vision_enabled: boolean;
62
+ cloud_vision_cooldown_ms: number;
63
+ stuck_threshold_ms: number;
64
+ struggle_grace_ms: number; // min time before struggle fires
65
+ struggle_cooldown_ms: number; // min gap between struggle detections
66
+ suggestion_rate_limit_ms: number;
67
+ overlay_autolaunch: boolean; // auto-open floating overlay widget on start
68
+ retention: {
69
+ full_hours: number;
70
+ key_moment_hours: number;
71
+ };
72
+ capture_dir: string;
73
+ };
74
+
75
+ export type PerActionOverride = {
76
+ action: string; // ActionCategory
77
+ role_id?: string;
78
+ allowed: boolean;
79
+ requires_approval?: boolean;
80
+ };
81
+
82
+ export type ContextRule = {
83
+ id: string;
84
+ action: string; // ActionCategory
85
+ condition: 'time_range' | 'tool_name' | 'always';
86
+ params: Record<string, unknown>;
87
+ effect: 'allow' | 'deny' | 'require_approval';
88
+ description: string;
89
+ };
90
+
91
+ export type AuthorityConfig = {
92
+ default_level: number;
93
+ governed_categories: string[]; // ActionCategory[]
94
+ overrides: PerActionOverride[];
95
+ context_rules: ContextRule[];
96
+ learning: {
97
+ enabled: boolean;
98
+ suggest_threshold: number;
99
+ };
100
+ emergency_state: 'normal' | 'paused' | 'killed';
101
+ };
102
+
103
+ export type WorkflowConfig = {
104
+ enabled: boolean;
105
+ maxConcurrentExecutions: number;
106
+ defaultRetries: number;
107
+ defaultTimeoutMs: number;
108
+ selfHealEnabled: boolean;
109
+ autoSuggestEnabled: boolean;
110
+ };
111
+
112
+ export type GoalConfig = {
113
+ enabled: boolean;
114
+ morning_window: { start: number; end: number };
115
+ evening_window: { start: number; end: number };
116
+ accountability_style: 'drill_sergeant' | 'supportive' | 'balanced';
117
+ escalation_weeks: { pressure: number; root_cause: number; suggest_kill: number };
118
+ auto_decompose: boolean;
119
+ calendar_ownership: boolean;
120
+ };
121
+
122
+ export type AuthConfig = {
123
+ /** Shared secret token. If unset, auth is disabled (open access). Env: JARVIS_AUTH_TOKEN */
124
+ token?: string;
125
+ };
126
+
127
+ export type UserConfig = {
128
+ name?: string;
129
+ };
130
+
131
+ export type JarvisConfig = {
132
+ user?: UserConfig;
133
+ daemon: {
134
+ port: number;
135
+ data_dir: string;
136
+ db_path: string;
137
+ /** External domain for the brain (used in sidecar JWT tokens). Env: JARVIS_BRAIN_DOMAIN */
138
+ brain_domain?: string;
139
+ };
140
+ auth?: AuthConfig;
141
+ google?: GoogleConfig;
142
+ channels?: ChannelConfig;
143
+ stt?: STTConfig;
144
+ tts?: TTSConfig;
145
+ desktop?: DesktopConfig;
146
+ awareness?: AwarenessConfig;
147
+ llm: {
148
+ primary: string; // provider name
149
+ fallback: string[];
150
+ anthropic?: { api_key: string; model?: string };
151
+ openai?: { api_key: string; model?: string };
152
+ gemini?: { api_key: string; model?: string };
153
+ ollama?: { base_url?: string; model?: string };
154
+ };
155
+ personality: {
156
+ core_traits: string[];
157
+ assistant_name?: string;
158
+ };
159
+ workflows?: WorkflowConfig;
160
+ goals?: GoalConfig;
161
+ authority: AuthorityConfig;
162
+ heartbeat: HeartbeatConfig;
163
+ active_role: string; // role file name
164
+ };
165
+
166
+ export const DEFAULT_CONFIG: JarvisConfig = {
167
+ user: {
168
+ name: '',
169
+ },
170
+ daemon: {
171
+ port: 3142,
172
+ data_dir: '~/.jarvis',
173
+ db_path: '~/.jarvis/jarvis.db',
174
+ },
175
+ channels: {
176
+ telegram: { enabled: false, bot_token: '', allowed_users: [] },
177
+ discord: { enabled: false, bot_token: '', allowed_users: [] },
178
+ },
179
+ stt: {
180
+ provider: 'openai',
181
+ },
182
+ tts: {
183
+ enabled: false,
184
+ provider: 'edge',
185
+ voice: 'en-US-AriaNeural',
186
+ rate: '+0%',
187
+ volume: '+0%',
188
+ },
189
+ desktop: {
190
+ enabled: true,
191
+ sidecar_port: 9224,
192
+ auto_launch: true,
193
+ tree_depth: 5,
194
+ snapshot_max_elements: 60,
195
+ },
196
+ awareness: {
197
+ enabled: true,
198
+ capture_interval_ms: 7000,
199
+ min_change_threshold: 0.02,
200
+ cloud_vision_enabled: true,
201
+ cloud_vision_cooldown_ms: 30000,
202
+ stuck_threshold_ms: 120000,
203
+ struggle_grace_ms: 45000,
204
+ struggle_cooldown_ms: 90000,
205
+ suggestion_rate_limit_ms: 60000,
206
+ overlay_autolaunch: true,
207
+ retention: {
208
+ full_hours: 1,
209
+ key_moment_hours: 24,
210
+ },
211
+ capture_dir: '~/.jarvis/captures',
212
+ },
213
+ llm: {
214
+ primary: 'anthropic',
215
+ fallback: ['openai', 'ollama'],
216
+ anthropic: {
217
+ api_key: '',
218
+ model: 'claude-sonnet-4-6',
219
+ },
220
+ openai: {
221
+ api_key: '',
222
+ model: 'gpt-5.4',
223
+ },
224
+ gemini: {
225
+ api_key: '',
226
+ model: 'gemini-3-flash-preview',
227
+ },
228
+ ollama: {
229
+ base_url: 'http://localhost:11434',
230
+ model: 'llama3',
231
+ },
232
+ },
233
+ personality: {
234
+ core_traits: [
235
+ 'loyal',
236
+ 'efficient',
237
+ 'proactive',
238
+ 'respectful',
239
+ 'adaptive',
240
+ ],
241
+ assistant_name: 'Jarvis',
242
+ },
243
+ authority: {
244
+ default_level: 3,
245
+ governed_categories: ['send_email', 'send_message', 'make_payment'],
246
+ overrides: [],
247
+ context_rules: [],
248
+ learning: {
249
+ enabled: true,
250
+ suggest_threshold: 5,
251
+ },
252
+ emergency_state: 'normal',
253
+ },
254
+ heartbeat: {
255
+ interval_minutes: 15,
256
+ active_hours: { start: 8, end: 23 },
257
+ aggressiveness: 'aggressive',
258
+ },
259
+ active_role: 'personal-assistant',
260
+ };
@@ -0,0 +1,232 @@
1
+ # J.A.R.V.I.S. Daemon
2
+
3
+ Core daemon infrastructure for the JARVIS system.
4
+
5
+ ## Overview
6
+
7
+ The daemon provides:
8
+ - **Service Registry**: Manages lifecycle of all system services (observers, agents, WebSocket server)
9
+ - **Health Monitoring**: Tracks system health, memory usage, database connectivity
10
+ - **Graceful Shutdown**: Handles SIGINT/SIGTERM signals and stops services cleanly
11
+ - **Structured Logging**: Timestamped logs for debugging and monitoring
12
+
13
+ ## Architecture
14
+
15
+ ```
16
+ src/daemon/
17
+ ├── index.ts # Main entry point and CLI
18
+ ├── services.ts # Service registry and lifecycle management
19
+ └── health.ts # Health monitoring and status reporting
20
+ ```
21
+
22
+ ## Usage
23
+
24
+ ### Running the Daemon
25
+
26
+ ```bash
27
+ # Run with defaults (port 3142, ~/.jarvis data directory)
28
+ bun run src/daemon/index.ts
29
+
30
+ # Run with custom configuration
31
+ bun run src/daemon/index.ts --port 3142 --data-dir ~/my-jarvis-data
32
+
33
+ # See all options
34
+ bun run src/daemon/index.ts --help
35
+ ```
36
+
37
+ ### Programmatic Usage
38
+
39
+ ```typescript
40
+ import { startDaemon } from './src/daemon/index.ts';
41
+
42
+ await startDaemon({
43
+ port: 3142,
44
+ dataDir: '/path/to/data',
45
+ dbPath: '/path/to/jarvis.db',
46
+ healthCheckInterval: 30000, // 30 seconds
47
+ });
48
+ ```
49
+
50
+ ## Service Registry
51
+
52
+ Services implement the `Service` interface:
53
+
54
+ ```typescript
55
+ export interface Service {
56
+ name: string;
57
+ start(): Promise<void>;
58
+ stop(): Promise<void>;
59
+ status(): ServiceStatus;
60
+ }
61
+ ```
62
+
63
+ Register services before starting the daemon:
64
+
65
+ ```typescript
66
+ import { ServiceRegistry } from './src/daemon/services.ts';
67
+
68
+ const registry = new ServiceRegistry();
69
+
70
+ // Register your service
71
+ registry.register({
72
+ name: 'my-service',
73
+ async start() {
74
+ // Start logic
75
+ },
76
+ async stop() {
77
+ // Stop logic
78
+ },
79
+ status() {
80
+ return 'running';
81
+ }
82
+ });
83
+
84
+ // Start all services
85
+ await registry.startAll();
86
+
87
+ // Stop all services (in reverse order)
88
+ await registry.stopAll();
89
+ ```
90
+
91
+ ## Health Monitoring
92
+
93
+ The health monitor tracks:
94
+ - **Uptime**: Total daemon uptime in seconds
95
+ - **Services**: Status of each registered service
96
+ - **Memory**: Heap usage and RSS
97
+ - **Database**: Connection status and file size
98
+
99
+ Access health status:
100
+
101
+ ```typescript
102
+ import { HealthMonitor } from './src/daemon/health.ts';
103
+
104
+ const monitor = new HealthMonitor(registry, dbPath);
105
+ monitor.start(30000); // Check every 30 seconds
106
+
107
+ const health = monitor.getHealth();
108
+ console.log(health);
109
+ // {
110
+ // uptime: 120,
111
+ // services: { core: 'running', observers: 'running' },
112
+ // memory: { heapUsed: 1048576, heapTotal: 2097152, rss: 45678912 },
113
+ // database: { connected: true, size: 4096 },
114
+ // startedAt: 1708644000000
115
+ // }
116
+
117
+ // Get formatted health report
118
+ console.log(monitor.formatHealth());
119
+ ```
120
+
121
+ ## Configuration
122
+
123
+ | Option | Default | Description |
124
+ |--------|---------|-------------|
125
+ | `--port` | 3142 | WebSocket server port |
126
+ | `--data-dir` | `~/.jarvis` | Data directory |
127
+ | `--db-path` | `~/.jarvis/jarvis.db` | Database file path |
128
+ | `--health-interval` | 30000 | Health check interval (ms) |
129
+
130
+ ## Graceful Shutdown
131
+
132
+ The daemon handles:
133
+ - `SIGINT` (Ctrl+C)
134
+ - `SIGTERM` (kill command)
135
+ - Uncaught exceptions
136
+ - Unhandled promise rejections
137
+
138
+ Shutdown sequence:
139
+ 1. Stop health monitor
140
+ 2. Stop all services in reverse order
141
+ 3. Close database connection
142
+ 4. Exit process
143
+
144
+ Press Ctrl+C twice for force shutdown.
145
+
146
+ ## Development
147
+
148
+ ### Adding a New Service
149
+
150
+ 1. Implement the `Service` interface
151
+ 2. Register the service in `src/daemon/index.ts`
152
+ 3. The daemon will handle start/stop lifecycle
153
+
154
+ Example:
155
+
156
+ ```typescript
157
+ // src/observers/file-observer.ts
158
+ import type { Service, ServiceStatus } from '../daemon/services.ts';
159
+
160
+ export class FileObserver implements Service {
161
+ name = 'file-observer';
162
+ private watcher: FSWatcher | null = null;
163
+ private _status: ServiceStatus = 'stopped';
164
+
165
+ async start(): Promise<void> {
166
+ this._status = 'starting';
167
+ // Set up file watching
168
+ this._status = 'running';
169
+ }
170
+
171
+ async stop(): Promise<void> {
172
+ this._status = 'stopping';
173
+ this.watcher?.close();
174
+ this._status = 'stopped';
175
+ }
176
+
177
+ status(): ServiceStatus {
178
+ return this._status;
179
+ }
180
+ }
181
+
182
+ // Register in src/daemon/index.ts
183
+ import { FileObserver } from '../observers/file-observer.ts';
184
+
185
+ registry.register(new FileObserver());
186
+ ```
187
+
188
+ ## Logging
189
+
190
+ All logs include timestamps and component prefixes:
191
+
192
+ ```
193
+ [2026-02-22T22:17:03.230Z] Initializing database at /home/user/.jarvis/jarvis.db
194
+ [ServiceRegistry] Starting core...
195
+ [ServiceRegistry] ✓ core started
196
+ [HealthMonitor] Starting health checks (every 30000ms)
197
+ ```
198
+
199
+ ## Database
200
+
201
+ The daemon uses `bun:sqlite` with:
202
+ - **WAL mode**: Better concurrency
203
+ - **Foreign keys**: Enabled
204
+ - **Location**: `~/.jarvis/jarvis.db` (configurable)
205
+
206
+ Schema is managed by `~/jarvis/src/vault/schema.ts`.
207
+
208
+ ## Testing
209
+
210
+ Run a quick test:
211
+
212
+ ```bash
213
+ # Start daemon and let it run for 3 seconds
214
+ timeout 3 bun run src/daemon/index.ts --data-dir /tmp/test-jarvis
215
+ ```
216
+
217
+ Expected output:
218
+ - ASCII banner
219
+ - Configuration summary
220
+ - Database initialization
221
+ - Service startup
222
+ - Health status
223
+ - Graceful shutdown on timeout
224
+
225
+ ## Next Steps
226
+
227
+ Replace placeholder services with real implementations:
228
+ - Observer services (file, window, process, etc.)
229
+ - Agent services (personality, decision-making)
230
+ - WebSocket server for external communication
231
+ - Commitment scheduler
232
+ - Vector embedding service
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Common interface for agent services that can handle messages.
3
+ * Both the main AgentService (user chat) and BackgroundAgentService
4
+ * (heartbeat/reactions) implement this.
5
+ */
6
+ export interface IAgentService {
7
+ handleMessage(text: string, channel?: string): Promise<string>;
8
+ handleHeartbeat(coalescedEvents?: string): Promise<string | null>;
9
+ }