@shykaruu/jarvis-brain 0.4.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 (330) hide show
  1. package/LICENSE +153 -0
  2. package/README.md +428 -0
  3. package/bin/jarvis.ts +449 -0
  4. package/package.json +79 -0
  5. package/roles/activity-observer.yaml +60 -0
  6. package/roles/ceo-founder.yaml +144 -0
  7. package/roles/chief-of-staff.yaml +158 -0
  8. package/roles/dev-lead.yaml +182 -0
  9. package/roles/executive-assistant.yaml +77 -0
  10. package/roles/marketing-director.yaml +168 -0
  11. package/roles/personal-assistant.yaml +266 -0
  12. package/roles/research-specialist.yaml +60 -0
  13. package/roles/specialists/content-writer.yaml +53 -0
  14. package/roles/specialists/customer-support.yaml +57 -0
  15. package/roles/specialists/data-analyst.yaml +57 -0
  16. package/roles/specialists/financial-analyst.yaml +56 -0
  17. package/roles/specialists/hr-specialist.yaml +55 -0
  18. package/roles/specialists/legal-advisor.yaml +58 -0
  19. package/roles/specialists/marketing-strategist.yaml +56 -0
  20. package/roles/specialists/project-coordinator.yaml +55 -0
  21. package/roles/specialists/research-analyst.yaml +58 -0
  22. package/roles/specialists/software-engineer.yaml +57 -0
  23. package/roles/specialists/system-administrator.yaml +57 -0
  24. package/roles/system-admin.yaml +76 -0
  25. package/scripts/ensure-bun.cjs +16 -0
  26. package/src/actions/README.md +421 -0
  27. package/src/actions/app-control/desktop-controller.test.ts +26 -0
  28. package/src/actions/app-control/desktop-controller.ts +438 -0
  29. package/src/actions/app-control/interface.ts +64 -0
  30. package/src/actions/app-control/linux.ts +273 -0
  31. package/src/actions/app-control/macos.ts +54 -0
  32. package/src/actions/app-control/sidecar-launcher.test.ts +23 -0
  33. package/src/actions/app-control/sidecar-launcher.ts +286 -0
  34. package/src/actions/app-control/windows.ts +44 -0
  35. package/src/actions/browser/cdp.ts +138 -0
  36. package/src/actions/browser/chrome-launcher.ts +261 -0
  37. package/src/actions/browser/session.ts +506 -0
  38. package/src/actions/browser/stealth.ts +49 -0
  39. package/src/actions/index.ts +20 -0
  40. package/src/actions/terminal/executor.ts +157 -0
  41. package/src/actions/terminal/wsl-bridge.ts +126 -0
  42. package/src/actions/test.ts +93 -0
  43. package/src/actions/tools/agents.ts +363 -0
  44. package/src/actions/tools/builtin.ts +950 -0
  45. package/src/actions/tools/commitments.ts +192 -0
  46. package/src/actions/tools/content.ts +217 -0
  47. package/src/actions/tools/delegate.ts +147 -0
  48. package/src/actions/tools/desktop.test.ts +55 -0
  49. package/src/actions/tools/desktop.ts +305 -0
  50. package/src/actions/tools/documents.ts +169 -0
  51. package/src/actions/tools/goals.ts +376 -0
  52. package/src/actions/tools/local-tools-guard.ts +31 -0
  53. package/src/actions/tools/registry.ts +173 -0
  54. package/src/actions/tools/research.ts +111 -0
  55. package/src/actions/tools/sidecar-list.ts +57 -0
  56. package/src/actions/tools/sidecar-route.ts +105 -0
  57. package/src/actions/tools/workflows.ts +216 -0
  58. package/src/agents/agent.ts +132 -0
  59. package/src/agents/delegation.ts +107 -0
  60. package/src/agents/hierarchy.ts +113 -0
  61. package/src/agents/index.ts +19 -0
  62. package/src/agents/messaging.ts +125 -0
  63. package/src/agents/orchestrator.ts +592 -0
  64. package/src/agents/role-discovery.ts +61 -0
  65. package/src/agents/sub-agent-runner.ts +309 -0
  66. package/src/agents/task-manager.ts +151 -0
  67. package/src/authority/approval-delivery.ts +59 -0
  68. package/src/authority/approval.ts +196 -0
  69. package/src/authority/audit.ts +158 -0
  70. package/src/authority/authority.test.ts +519 -0
  71. package/src/authority/deferred-executor.ts +103 -0
  72. package/src/authority/emergency.ts +66 -0
  73. package/src/authority/engine.ts +301 -0
  74. package/src/authority/index.ts +12 -0
  75. package/src/authority/learning.ts +111 -0
  76. package/src/authority/tool-action-map.ts +74 -0
  77. package/src/awareness/analytics.ts +466 -0
  78. package/src/awareness/awareness.test.ts +332 -0
  79. package/src/awareness/capture-engine.ts +305 -0
  80. package/src/awareness/context-graph.ts +130 -0
  81. package/src/awareness/context-tracker.ts +349 -0
  82. package/src/awareness/index.ts +25 -0
  83. package/src/awareness/intelligence.ts +321 -0
  84. package/src/awareness/ocr-engine.ts +88 -0
  85. package/src/awareness/service.ts +528 -0
  86. package/src/awareness/struggle-detector.ts +342 -0
  87. package/src/awareness/suggestion-engine.ts +476 -0
  88. package/src/awareness/types.ts +201 -0
  89. package/src/cli/autostart.ts +417 -0
  90. package/src/cli/deps.ts +449 -0
  91. package/src/cli/doctor.ts +238 -0
  92. package/src/cli/helpers.ts +401 -0
  93. package/src/cli/onboard.ts +827 -0
  94. package/src/cli/uninstall.test.ts +37 -0
  95. package/src/cli/uninstall.ts +202 -0
  96. package/src/comms/README.md +329 -0
  97. package/src/comms/auth-error.html +48 -0
  98. package/src/comms/channels/discord.ts +228 -0
  99. package/src/comms/channels/signal.ts +56 -0
  100. package/src/comms/channels/telegram.ts +316 -0
  101. package/src/comms/channels/whatsapp.ts +60 -0
  102. package/src/comms/channels.test.ts +173 -0
  103. package/src/comms/dashboard-auth.ts +75 -0
  104. package/src/comms/desktop-notify.ts +114 -0
  105. package/src/comms/example.ts +129 -0
  106. package/src/comms/index.ts +129 -0
  107. package/src/comms/streaming.ts +149 -0
  108. package/src/comms/voice.test.ts +504 -0
  109. package/src/comms/voice.ts +341 -0
  110. package/src/comms/websocket.test.ts +409 -0
  111. package/src/comms/websocket.ts +669 -0
  112. package/src/config/README.md +389 -0
  113. package/src/config/index.ts +6 -0
  114. package/src/config/loader.test.ts +183 -0
  115. package/src/config/loader.ts +148 -0
  116. package/src/config/types.ts +293 -0
  117. package/src/daemon/README.md +232 -0
  118. package/src/daemon/agent-service-interface.ts +9 -0
  119. package/src/daemon/agent-service.ts +667 -0
  120. package/src/daemon/api-routes.ts +3067 -0
  121. package/src/daemon/background-agent-service.ts +396 -0
  122. package/src/daemon/background-agent.test.ts +78 -0
  123. package/src/daemon/channel-service.ts +201 -0
  124. package/src/daemon/commitment-executor.ts +297 -0
  125. package/src/daemon/dashboard-auth.test.ts +170 -0
  126. package/src/daemon/event-classifier.ts +239 -0
  127. package/src/daemon/event-coalescer.ts +123 -0
  128. package/src/daemon/event-reactor.ts +214 -0
  129. package/src/daemon/flock.c +7 -0
  130. package/src/daemon/health.ts +220 -0
  131. package/src/daemon/index.ts +1070 -0
  132. package/src/daemon/llm-settings.test.ts +78 -0
  133. package/src/daemon/llm-settings.ts +450 -0
  134. package/src/daemon/observer-service.ts +150 -0
  135. package/src/daemon/pid.test.ts +283 -0
  136. package/src/daemon/pid.ts +224 -0
  137. package/src/daemon/research-queue.ts +155 -0
  138. package/src/daemon/services.ts +175 -0
  139. package/src/daemon/ws-service.ts +926 -0
  140. package/src/global.d.ts +4 -0
  141. package/src/goals/accountability.ts +240 -0
  142. package/src/goals/awareness-bridge.ts +185 -0
  143. package/src/goals/estimator.ts +185 -0
  144. package/src/goals/events.ts +28 -0
  145. package/src/goals/goals.test.ts +400 -0
  146. package/src/goals/integration.test.ts +329 -0
  147. package/src/goals/nl-builder.test.ts +220 -0
  148. package/src/goals/nl-builder.ts +256 -0
  149. package/src/goals/rhythm.test.ts +177 -0
  150. package/src/goals/rhythm.ts +275 -0
  151. package/src/goals/service.test.ts +135 -0
  152. package/src/goals/service.ts +407 -0
  153. package/src/goals/types.ts +106 -0
  154. package/src/goals/workflow-bridge.ts +96 -0
  155. package/src/integrations/google-api.ts +134 -0
  156. package/src/integrations/google-auth.ts +175 -0
  157. package/src/llm/README.md +291 -0
  158. package/src/llm/anthropic.ts +400 -0
  159. package/src/llm/gemini.ts +380 -0
  160. package/src/llm/groq.ts +406 -0
  161. package/src/llm/history.ts +147 -0
  162. package/src/llm/index.ts +21 -0
  163. package/src/llm/manager.ts +226 -0
  164. package/src/llm/ollama.ts +316 -0
  165. package/src/llm/openai.ts +411 -0
  166. package/src/llm/openrouter.ts +390 -0
  167. package/src/llm/provider.test.ts +487 -0
  168. package/src/llm/provider.ts +61 -0
  169. package/src/llm/test.ts +88 -0
  170. package/src/observers/README.md +278 -0
  171. package/src/observers/calendar.ts +113 -0
  172. package/src/observers/clipboard.ts +136 -0
  173. package/src/observers/email.ts +109 -0
  174. package/src/observers/example.ts +58 -0
  175. package/src/observers/file-watcher.ts +124 -0
  176. package/src/observers/index.ts +159 -0
  177. package/src/observers/notifications.ts +197 -0
  178. package/src/observers/observers.test.ts +203 -0
  179. package/src/observers/processes.ts +225 -0
  180. package/src/personality/README.md +61 -0
  181. package/src/personality/adapter.ts +196 -0
  182. package/src/personality/index.ts +20 -0
  183. package/src/personality/learner.ts +209 -0
  184. package/src/personality/model.ts +132 -0
  185. package/src/personality/personality.test.ts +236 -0
  186. package/src/roles/README.md +252 -0
  187. package/src/roles/authority.ts +120 -0
  188. package/src/roles/example-usage.ts +198 -0
  189. package/src/roles/index.ts +42 -0
  190. package/src/roles/loader.ts +143 -0
  191. package/src/roles/prompt-builder.ts +218 -0
  192. package/src/roles/test-multi.ts +102 -0
  193. package/src/roles/test-role.yaml +77 -0
  194. package/src/roles/test-utils.ts +93 -0
  195. package/src/roles/test.ts +106 -0
  196. package/src/roles/tool-guide.ts +195 -0
  197. package/src/roles/types.ts +36 -0
  198. package/src/roles/utils.ts +200 -0
  199. package/src/scripts/google-setup.ts +168 -0
  200. package/src/sidecar/connection.ts +179 -0
  201. package/src/sidecar/index.ts +6 -0
  202. package/src/sidecar/manager.ts +542 -0
  203. package/src/sidecar/protocol.ts +85 -0
  204. package/src/sidecar/rpc.ts +161 -0
  205. package/src/sidecar/scheduler.ts +136 -0
  206. package/src/sidecar/types.ts +112 -0
  207. package/src/sidecar/validator.ts +144 -0
  208. package/src/sites/builder-tools.ts +215 -0
  209. package/src/sites/dev-server-manager.ts +286 -0
  210. package/src/sites/fixtures/security-test-site/.jarvis-project.json +6 -0
  211. package/src/sites/fixtures/security-test-site/Makefile +15 -0
  212. package/src/sites/fixtures/security-test-site/README.md +18 -0
  213. package/src/sites/fixtures/security-test-site/index.html +12 -0
  214. package/src/sites/fixtures/security-test-site/index.ts +16 -0
  215. package/src/sites/fixtures/security-test-site/package.json +13 -0
  216. package/src/sites/fixtures/security-test-site/src/app.tsx +780 -0
  217. package/src/sites/fixtures/security-test-site/tsconfig.json +10 -0
  218. package/src/sites/git-manager.ts +240 -0
  219. package/src/sites/github-manager.ts +355 -0
  220. package/src/sites/index.ts +25 -0
  221. package/src/sites/project-manager.ts +389 -0
  222. package/src/sites/proxy.ts +133 -0
  223. package/src/sites/service.ts +136 -0
  224. package/src/sites/templates.ts +169 -0
  225. package/src/sites/types.ts +89 -0
  226. package/src/user/profile-followup.test.ts +84 -0
  227. package/src/user/profile-followup.ts +185 -0
  228. package/src/user/profile.ts +224 -0
  229. package/src/vault/README.md +110 -0
  230. package/src/vault/awareness.ts +341 -0
  231. package/src/vault/commitments.ts +299 -0
  232. package/src/vault/content-pipeline.ts +270 -0
  233. package/src/vault/conversations.ts +173 -0
  234. package/src/vault/dashboard-sessions.ts +44 -0
  235. package/src/vault/documents.ts +130 -0
  236. package/src/vault/entities.ts +185 -0
  237. package/src/vault/extractor.test.ts +356 -0
  238. package/src/vault/extractor.ts +345 -0
  239. package/src/vault/facts.ts +190 -0
  240. package/src/vault/goals.ts +477 -0
  241. package/src/vault/index.ts +87 -0
  242. package/src/vault/keychain.ts +99 -0
  243. package/src/vault/observations.ts +115 -0
  244. package/src/vault/relationships.ts +178 -0
  245. package/src/vault/retrieval.test.ts +139 -0
  246. package/src/vault/retrieval.ts +258 -0
  247. package/src/vault/schema.ts +709 -0
  248. package/src/vault/settings.ts +38 -0
  249. package/src/vault/user-profile.test.ts +113 -0
  250. package/src/vault/user-profile.ts +176 -0
  251. package/src/vault/vectors.ts +92 -0
  252. package/src/vault/webapp-template-seeds.ts +116 -0
  253. package/src/vault/webapp-templates.ts +244 -0
  254. package/src/vault/workflows.ts +403 -0
  255. package/src/workflows/auto-suggest.ts +290 -0
  256. package/src/workflows/engine.ts +366 -0
  257. package/src/workflows/events.ts +24 -0
  258. package/src/workflows/executor.ts +207 -0
  259. package/src/workflows/nl-builder.ts +198 -0
  260. package/src/workflows/nodes/actions/agent-task.ts +73 -0
  261. package/src/workflows/nodes/actions/calendar-action.ts +85 -0
  262. package/src/workflows/nodes/actions/code-execution.ts +73 -0
  263. package/src/workflows/nodes/actions/discord.ts +77 -0
  264. package/src/workflows/nodes/actions/file-write.ts +73 -0
  265. package/src/workflows/nodes/actions/gmail.ts +69 -0
  266. package/src/workflows/nodes/actions/http-request.ts +117 -0
  267. package/src/workflows/nodes/actions/notification.ts +85 -0
  268. package/src/workflows/nodes/actions/run-tool.ts +55 -0
  269. package/src/workflows/nodes/actions/send-message.ts +82 -0
  270. package/src/workflows/nodes/actions/shell-command.ts +76 -0
  271. package/src/workflows/nodes/actions/telegram.ts +60 -0
  272. package/src/workflows/nodes/builtin.ts +119 -0
  273. package/src/workflows/nodes/error/error-handler.ts +37 -0
  274. package/src/workflows/nodes/error/fallback.ts +47 -0
  275. package/src/workflows/nodes/error/retry.ts +82 -0
  276. package/src/workflows/nodes/logic/delay.ts +42 -0
  277. package/src/workflows/nodes/logic/if-else.ts +41 -0
  278. package/src/workflows/nodes/logic/loop.ts +90 -0
  279. package/src/workflows/nodes/logic/merge.ts +38 -0
  280. package/src/workflows/nodes/logic/race.ts +40 -0
  281. package/src/workflows/nodes/logic/switch.ts +59 -0
  282. package/src/workflows/nodes/logic/template-render.ts +53 -0
  283. package/src/workflows/nodes/logic/variable-get.ts +37 -0
  284. package/src/workflows/nodes/logic/variable-set.ts +59 -0
  285. package/src/workflows/nodes/registry.ts +99 -0
  286. package/src/workflows/nodes/transform/aggregate.ts +99 -0
  287. package/src/workflows/nodes/transform/csv-parse.ts +70 -0
  288. package/src/workflows/nodes/transform/json-parse.ts +63 -0
  289. package/src/workflows/nodes/transform/map-filter.ts +84 -0
  290. package/src/workflows/nodes/transform/regex-match.ts +89 -0
  291. package/src/workflows/nodes/triggers/calendar.ts +33 -0
  292. package/src/workflows/nodes/triggers/clipboard.ts +32 -0
  293. package/src/workflows/nodes/triggers/cron.ts +40 -0
  294. package/src/workflows/nodes/triggers/email.ts +40 -0
  295. package/src/workflows/nodes/triggers/file-change.ts +45 -0
  296. package/src/workflows/nodes/triggers/git.ts +46 -0
  297. package/src/workflows/nodes/triggers/manual.ts +23 -0
  298. package/src/workflows/nodes/triggers/poll.ts +81 -0
  299. package/src/workflows/nodes/triggers/process.ts +44 -0
  300. package/src/workflows/nodes/triggers/screen-event.ts +37 -0
  301. package/src/workflows/nodes/triggers/webhook.ts +39 -0
  302. package/src/workflows/safe-eval.ts +139 -0
  303. package/src/workflows/template.ts +118 -0
  304. package/src/workflows/triggers/cron.ts +311 -0
  305. package/src/workflows/triggers/manager.ts +285 -0
  306. package/src/workflows/triggers/observer-bridge.ts +172 -0
  307. package/src/workflows/triggers/poller.ts +201 -0
  308. package/src/workflows/triggers/screen-condition.ts +218 -0
  309. package/src/workflows/triggers/triggers.test.ts +740 -0
  310. package/src/workflows/triggers/webhook.ts +191 -0
  311. package/src/workflows/types.ts +133 -0
  312. package/src/workflows/variables.ts +72 -0
  313. package/src/workflows/workflows.test.ts +383 -0
  314. package/src/workflows/yaml.ts +104 -0
  315. package/ui/dist/index-3gr23jt9.js +112614 -0
  316. package/ui/dist/index-9vmj8127.css +14239 -0
  317. package/ui/dist/index-hy9pc1gm.js +112873 -0
  318. package/ui/dist/index-j2ep5d1w.js +112374 -0
  319. package/ui/dist/index-jt00vjqs.js +112858 -0
  320. package/ui/dist/index-k9ymx5qb.js +112374 -0
  321. package/ui/dist/index.html +16 -0
  322. package/ui/public/audio/pcm-capture-processor.js +11 -0
  323. package/ui/public/openwakeword/models/embedding_model.onnx +0 -0
  324. package/ui/public/openwakeword/models/hey_jarvis_v0.1.onnx +0 -0
  325. package/ui/public/openwakeword/models/melspectrogram.onnx +0 -0
  326. package/ui/public/openwakeword/models/silero_vad.onnx +0 -0
  327. package/ui/public/ort/ort-wasm-simd-threaded.jsep.mjs +106 -0
  328. package/ui/public/ort/ort-wasm-simd-threaded.jsep.wasm +0 -0
  329. package/ui/public/ort/ort-wasm-simd-threaded.mjs +59 -0
  330. package/ui/public/ort/ort-wasm-simd-threaded.wasm +0 -0
package/bin/jarvis.ts ADDED
@@ -0,0 +1,449 @@
1
+ #!/usr/bin/env bun
2
+ /**
3
+ * J.A.R.V.I.S. CLI Entry Point
4
+ *
5
+ * Usage:
6
+ * jarvis start [--port N] [-d|--detach] Start the daemon
7
+ * jarvis stop Stop the running daemon
8
+ * jarvis status Show daemon status
9
+ * jarvis onboard Interactive setup wizard
10
+ * jarvis uninstall Remove JARVIS from this machine
11
+ * jarvis doctor Check environment & connectivity
12
+ * jarvis version Print version
13
+ * jarvis help Show this help
14
+ */
15
+
16
+ import { join } from 'node:path';
17
+ import { readFileSync, existsSync, openSync } from 'node:fs';
18
+ import { spawn } from 'node:child_process';
19
+ import { acquireLock, releaseLock, isLocked, getLogPath } from '../src/daemon/pid.ts';
20
+ import { c } from '../src/cli/helpers.ts';
21
+
22
+ const PACKAGE_ROOT = join(import.meta.dir, '..');
23
+
24
+ function getVersion(): string {
25
+ try {
26
+ const pkg = JSON.parse(readFileSync(join(PACKAGE_ROOT, 'package.json'), 'utf-8'));
27
+ return pkg.version || '0.0.0';
28
+ } catch {
29
+ return '0.0.0';
30
+ }
31
+ }
32
+
33
+ function printHelp(): void {
34
+ console.log(`
35
+ ${c.cyan('J.A.R.V.I.S.')} ${c.dim(`v${getVersion()}`)}
36
+ Just A Rather Very Intelligent System
37
+
38
+ ${c.bold('Usage:')}
39
+ jarvis <command> [options]
40
+
41
+ ${c.bold('Commands:')}
42
+ ${c.cyan('start')} Start the JARVIS daemon
43
+ ${c.cyan('stop')} Stop the running daemon
44
+ ${c.cyan('restart')} Restart the daemon (stop + start)
45
+ ${c.cyan('status')} Show daemon status
46
+ ${c.cyan('logs')} Tail the daemon log file
47
+ ${c.cyan('update')} Update JARVIS to the latest version
48
+ ${c.cyan('onboard')} Interactive first-time setup wizard
49
+ ${c.cyan('uninstall')} Remove JARVIS and local data from this machine
50
+ ${c.cyan('doctor')} Check environment and connectivity
51
+ ${c.cyan('version')} Print version number
52
+ ${c.cyan('help')} Show this help message
53
+
54
+ ${c.bold('Start options:')}
55
+ --port <N> Override daemon port (default: 3142)
56
+ -d, --detach Run as background daemon
57
+ --no-open Don't auto-open dashboard in browser
58
+ --data-dir <path> Override data directory (default: ~/.jarvis)
59
+ --no-local-tools Disable local tool execution (Docker/headless mode)
60
+
61
+ ${c.bold('Logs options:')}
62
+ -f, --follow Follow log output (like tail -f)
63
+ -n, --lines <N> Number of lines to show (default: 50)
64
+
65
+ ${c.bold('Examples:')}
66
+ jarvis start Start in foreground
67
+ jarvis start -d Start as background daemon
68
+ jarvis start --port 8080 Start on custom port
69
+ jarvis restart Restart with same settings
70
+ jarvis logs -f Follow live log output
71
+ jarvis update Update to latest version
72
+ jarvis onboard Run the setup wizard
73
+ jarvis uninstall Remove JARVIS from this machine
74
+ jarvis doctor Check if everything is working
75
+ `);
76
+ }
77
+
78
+ function assertSupportedPlatform(): void {
79
+ if (process.platform !== 'win32') return;
80
+ console.error(c.red('Native Windows installs are not supported for the JARVIS daemon.'));
81
+ console.error(c.dim('Use WSL2 for the Bun install, or run JARVIS with Docker on Windows.'));
82
+ console.error(c.dim('The Windows sidecar is still supported separately.'));
83
+ process.exit(1);
84
+ }
85
+
86
+ async function cmdStart(args: string[]): Promise<void> {
87
+ const detach = args.includes('--detach') || args.includes('-d');
88
+ const noOpen = args.includes('--no-open');
89
+ const noLocalTools = args.includes('--no-local-tools');
90
+
91
+ // Parse --port
92
+ let port: number | undefined;
93
+ const portIdx = args.indexOf('--port');
94
+ if (portIdx !== -1 && args[portIdx + 1]) {
95
+ port = parseInt(args[portIdx + 1]!, 10);
96
+ if (isNaN(port) || port < 1 || port > 65535) {
97
+ console.error(c.red('Error: --port requires a number between 1 and 65535'));
98
+ process.exit(1);
99
+ }
100
+ }
101
+
102
+ // Parse --data-dir
103
+ let dataDir: string | undefined;
104
+ const dataDirIdx = args.indexOf('--data-dir');
105
+ if (dataDirIdx !== -1 && args[dataDirIdx + 1]) {
106
+ dataDir = args[dataDirIdx + 1]!;
107
+ }
108
+
109
+ if (!detach) {
110
+ // Run in foreground — acquire lock atomically (checks + locks in one step)
111
+ if (!acquireLock(process.pid)) {
112
+ console.log(c.yellow('JARVIS is already running'));
113
+ console.log(c.dim(' Stop it first with: jarvis stop'));
114
+ process.exit(1);
115
+ }
116
+ process.on('exit', () => releaseLock());
117
+ process.on('SIGINT', () => { releaseLock(); process.exit(0); });
118
+ process.on('SIGTERM', () => { releaseLock(); process.exit(0); });
119
+
120
+ const { startDaemon } = await import('../src/daemon/index.ts');
121
+ await startDaemon({ port, dataDir, noLocalTools });
122
+
123
+ if (!noOpen) {
124
+ openDashboard(port ?? 3142);
125
+ }
126
+ } else {
127
+ // Check if already running before spawning detached child
128
+ const existingPid = isLocked();
129
+ if (existingPid) {
130
+ console.log(c.yellow(`JARVIS is already running (PID ${existingPid})`));
131
+ console.log(c.dim(' Stop it first with: jarvis stop'));
132
+ process.exit(1);
133
+ }
134
+
135
+ // Run in background — spawn a detached child process with log file
136
+ console.log(c.cyan('Starting J.A.R.V.I.S. daemon...'));
137
+
138
+ const logPath = getLogPath();
139
+ const logFile = Bun.file(logPath);
140
+
141
+ const daemonArgs = [join(PACKAGE_ROOT, 'bin/jarvis.ts'), 'start', '--no-open'];
142
+ if (port) daemonArgs.push('--port', String(port));
143
+
144
+ const logFd = openSync(logPath, 'a');
145
+ const child = spawn('bun', daemonArgs, {
146
+ detached: true,
147
+ stdio: ['ignore', logFd, logFd],
148
+ env: { ...process.env },
149
+ });
150
+ child.unref();
151
+
152
+ // Poll for the daemon to acquire its lock (up to 10s)
153
+ let runningPid: number | null = null;
154
+ for (let i = 0; i < 20; i++) {
155
+ await new Promise(resolve => setTimeout(resolve, 500));
156
+ runningPid = isLocked();
157
+ if (runningPid) break;
158
+ }
159
+
160
+ if (runningPid) {
161
+ console.log(c.green(`✓ JARVIS daemon started (PID ${runningPid})`));
162
+ console.log(c.dim(` Dashboard: http://localhost:${port ?? 3142}`));
163
+ console.log(c.dim(` Logs: ${logPath}`));
164
+ console.log(c.dim(` Stop with: jarvis stop`));
165
+
166
+ if (!noOpen) {
167
+ openDashboard(port ?? 3142);
168
+ }
169
+ } else {
170
+ console.log(c.red('✗ Failed to start daemon. Check logs:'));
171
+ console.log(c.dim(` ${logPath}`));
172
+ process.exit(1);
173
+ }
174
+ }
175
+ }
176
+
177
+ async function cmdStop(): Promise<void> {
178
+ const pid = isLocked();
179
+ if (!pid) {
180
+ console.log(c.yellow('JARVIS is not running.'));
181
+ return;
182
+ }
183
+
184
+ console.log(c.cyan(`Stopping JARVIS daemon (PID ${pid})...`));
185
+ try {
186
+ process.kill(pid, 'SIGTERM');
187
+
188
+ // Wait up to 5s for graceful shutdown, then SIGKILL
189
+ let alive = true;
190
+ for (let i = 0; i < 10; i++) {
191
+ await new Promise(resolve => setTimeout(resolve, 500));
192
+ try { process.kill(pid, 0); } catch { alive = false; break; }
193
+ }
194
+
195
+ if (alive) {
196
+ console.log(c.dim(' Process still alive, sending SIGKILL...'));
197
+ try { process.kill(pid, 'SIGKILL'); } catch { /* already gone */ }
198
+ }
199
+
200
+ releaseLock();
201
+ console.log(c.green('✓ JARVIS daemon stopped.'));
202
+ } catch (err) {
203
+ console.error(c.red(`Failed to stop process ${pid}: ${err}`));
204
+ releaseLock();
205
+ }
206
+ }
207
+
208
+ function cmdStatus(): void {
209
+ const pid = isLocked();
210
+ if (pid) {
211
+ console.log(`${c.green('●')} JARVIS is ${c.green('running')} (PID ${pid})`);
212
+
213
+ // Try to read the port from config
214
+ try {
215
+ const { homedir } = require('node:os');
216
+ const configPath = join(homedir(), '.jarvis', 'config.yaml');
217
+ const YAML = require('yaml');
218
+ const text = readFileSync(configPath, 'utf-8');
219
+ const cfg = YAML.parse(text);
220
+ const port = cfg?.daemon?.port ?? 3142;
221
+ console.log(c.dim(` Dashboard: http://localhost:${port}`));
222
+ } catch {
223
+ console.log(c.dim(` Dashboard: http://localhost:3142`));
224
+ }
225
+
226
+ console.log(c.dim(` Stop with: jarvis stop`));
227
+ } else {
228
+ console.log(`${c.red('●')} JARVIS is ${c.red('stopped')}`);
229
+ console.log(c.dim(` Start with: jarvis start`));
230
+ }
231
+ }
232
+
233
+ async function cmdOnboard(): Promise<void> {
234
+ const { runOnboard } = await import('../src/cli/onboard.ts');
235
+ await runOnboard();
236
+ }
237
+
238
+ async function cmdDoctor(): Promise<void> {
239
+ const { runDoctor } = await import('../src/cli/doctor.ts');
240
+ await runDoctor();
241
+ }
242
+
243
+ async function cmdUninstall(): Promise<void> {
244
+ const { runUninstallWizard } = await import('../src/cli/uninstall.ts');
245
+ await runUninstallWizard(PACKAGE_ROOT);
246
+ }
247
+
248
+ async function cmdRestart(args: string[]): Promise<void> {
249
+ const pid = isLocked();
250
+ if (pid) {
251
+ await cmdStop();
252
+ }
253
+
254
+ console.log('');
255
+ await cmdStart(args);
256
+ }
257
+
258
+ function cmdLogs(args: string[]): void {
259
+ const logPath = getLogPath();
260
+
261
+ if (!existsSync(logPath)) {
262
+ console.log(c.yellow('No log file found. Start the daemon first: jarvis start'));
263
+ return;
264
+ }
265
+
266
+ const follow = args.includes('-f') || args.includes('--follow');
267
+
268
+ // Parse --lines / -n
269
+ let lines = 50;
270
+ const nIdx = args.indexOf('-n') !== -1 ? args.indexOf('-n') : args.indexOf('--lines');
271
+ if (nIdx !== -1 && args[nIdx + 1]) {
272
+ const n = parseInt(args[nIdx + 1], 10);
273
+ if (!isNaN(n) && n > 0) lines = n;
274
+ }
275
+
276
+ console.log(c.dim(`Log file: ${logPath}\n`));
277
+
278
+ if (follow) {
279
+ // tail -f equivalent
280
+ const tailProc = Bun.spawn(['tail', '-f', '-n', String(lines), logPath], {
281
+ stdio: ['ignore', 'inherit', 'inherit'],
282
+ });
283
+
284
+ process.on('SIGINT', () => {
285
+ tailProc.kill();
286
+ process.exit(0);
287
+ });
288
+ } else {
289
+ // Just show last N lines
290
+ const tailProc = Bun.spawnSync(['tail', '-n', String(lines), logPath]);
291
+ process.stdout.write(tailProc.stdout);
292
+ }
293
+ }
294
+
295
+ async function cmdUpdate(): Promise<void> {
296
+ console.log(c.cyan('Checking for updates...\n'));
297
+
298
+ // Get current version
299
+ const currentVersion = getVersion();
300
+ console.log(` Current version: ${c.bold(currentVersion)}`);
301
+
302
+ // Check if daemon is running (we'll restart it after update)
303
+ const wasRunning = isLocked();
304
+
305
+ // Stop daemon if running
306
+ if (wasRunning) {
307
+ console.log(c.dim(' Stopping daemon before update...'));
308
+ try {
309
+ process.kill(wasRunning, 'SIGTERM');
310
+ releaseLock();
311
+ await new Promise(resolve => setTimeout(resolve, 1000));
312
+ } catch {
313
+ releaseLock();
314
+ }
315
+ }
316
+
317
+ // Update via git pull + bun install (not npm — package is not published)
318
+ console.log('');
319
+ const gitPull = Bun.spawnSync(['git', 'pull', '--ff-only'], {
320
+ cwd: PACKAGE_ROOT,
321
+ stdio: ['ignore', 'pipe', 'pipe'],
322
+ env: { ...process.env },
323
+ });
324
+
325
+ if (gitPull.exitCode !== 0) {
326
+ const stderr = gitPull.stderr.toString();
327
+ // If not a git repo, try the install dir
328
+ const installDir = join(require('node:os').homedir(), '.jarvis', 'daemon');
329
+ const gitPull2 = Bun.spawnSync(['git', 'pull', '--ff-only'], {
330
+ cwd: installDir,
331
+ stdio: ['ignore', 'pipe', 'pipe'],
332
+ env: { ...process.env },
333
+ });
334
+
335
+ if (gitPull2.exitCode !== 0) {
336
+ console.log(c.red('✗ Update failed (git pull):'));
337
+ console.log(c.dim(` ${gitPull2.stderr.toString().trim() || stderr.trim()}`));
338
+ if (wasRunning) {
339
+ console.log(c.dim('\n Restarting daemon...'));
340
+ await cmdStart(['--no-open']);
341
+ }
342
+ process.exit(1);
343
+ }
344
+ }
345
+
346
+ // Reinstall dependencies
347
+ const bunInstall = Bun.spawnSync(['bun', 'install'], {
348
+ cwd: PACKAGE_ROOT,
349
+ stdio: ['ignore', 'pipe', 'pipe'],
350
+ env: { ...process.env },
351
+ });
352
+
353
+ if (bunInstall.exitCode !== 0) {
354
+ console.log(c.yellow('! Dependencies may need manual refresh: bun install'));
355
+ }
356
+
357
+ // Get new version
358
+ const newVersion = getVersion();
359
+ if (newVersion === currentVersion) {
360
+ console.log(c.green(`✓ Already on the latest version (${currentVersion})`));
361
+ } else {
362
+ console.log(c.green(`✓ Updated: ${currentVersion} → ${newVersion}`));
363
+ }
364
+
365
+ // Restart daemon if it was running
366
+ if (wasRunning) {
367
+ console.log(c.dim('\nRestarting daemon...'));
368
+ await cmdStart(['--no-open']);
369
+ }
370
+ }
371
+
372
+ function openDashboard(port: number): void {
373
+ const url = `http://localhost:${port}`;
374
+ try {
375
+ const platform = process.platform;
376
+ if (platform === 'darwin') {
377
+ Bun.spawn(['open', url], { stdio: ['ignore', 'ignore', 'ignore'] });
378
+ } else {
379
+ // Check WSL first
380
+ const { readFileSync } = require('node:fs');
381
+ try {
382
+ const version = readFileSync('/proc/version', 'utf-8');
383
+ if (version.toLowerCase().includes('microsoft')) {
384
+ Bun.spawn(['wslview', url], { stdio: ['ignore', 'ignore', 'ignore'] });
385
+ return;
386
+ }
387
+ } catch {}
388
+ // Regular Linux
389
+ Bun.spawn(['xdg-open', url], { stdio: ['ignore', 'ignore', 'ignore'] });
390
+ }
391
+ } catch {
392
+ // Silently fail — user can open manually
393
+ }
394
+ }
395
+
396
+ // ── Main ─────────────────────────────────────────────────────────────
397
+
398
+ assertSupportedPlatform();
399
+
400
+ const args = process.argv.slice(2);
401
+ const command = args[0] || 'help';
402
+ const commandArgs = args.slice(1);
403
+
404
+ switch (command) {
405
+ case 'start':
406
+ await cmdStart(commandArgs);
407
+ break;
408
+ case 'stop':
409
+ await cmdStop();
410
+ break;
411
+ case 'restart':
412
+ await cmdRestart(commandArgs);
413
+ break;
414
+ case 'status':
415
+ cmdStatus();
416
+ break;
417
+ case 'logs':
418
+ case 'log':
419
+ cmdLogs(commandArgs);
420
+ break;
421
+ case 'update':
422
+ case 'upgrade':
423
+ await cmdUpdate();
424
+ break;
425
+ case 'onboard':
426
+ await cmdOnboard();
427
+ break;
428
+ case 'doctor':
429
+ await cmdDoctor();
430
+ break;
431
+ case 'uninstall':
432
+ case 'remove':
433
+ await cmdUninstall();
434
+ break;
435
+ case 'version':
436
+ case '-v':
437
+ case '--version':
438
+ console.log(getVersion());
439
+ break;
440
+ case 'help':
441
+ case '-h':
442
+ case '--help':
443
+ printHelp();
444
+ break;
445
+ default:
446
+ console.error(c.red(`Unknown command: ${command}`));
447
+ console.log(c.dim('Run "jarvis help" for usage information.'));
448
+ process.exit(1);
449
+ }
package/package.json ADDED
@@ -0,0 +1,79 @@
1
+ {
2
+ "name": "@shykaruu/jarvis-brain",
3
+ "version": "0.4.0",
4
+ "description": "J.A.R.V.I.S. — Just A Rather Very Intelligent System. An always-on autonomous AI daemon.",
5
+ "module": "src/daemon/index.ts",
6
+ "type": "module",
7
+ "bin": {
8
+ "jarvis": "bin/jarvis.ts"
9
+ },
10
+ "engines": {
11
+ "bun": ">=1.0.0"
12
+ },
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "git+https://github.com/vierisid/jarvis.git"
16
+ },
17
+ "license": "SEE LICENSE IN LICENSE",
18
+ "keywords": ["jarvis", "ai", "daemon", "assistant", "cli"],
19
+ "files": [
20
+ "bin/",
21
+ "src/",
22
+ "roles/",
23
+ "ui/dist/",
24
+ "ui/public/",
25
+ "scripts/ensure-bun.cjs",
26
+ "README.md"
27
+ ],
28
+ "scripts": {
29
+ "start": "bun run src/daemon/index.ts",
30
+ "dev": "bun --hot run src/daemon/index.ts",
31
+ "copy:models": "mkdir -p ui/public/openwakeword/models ui/public/ort && cp node_modules/openwakeword-wasm-browser/models/melspectrogram.onnx node_modules/openwakeword-wasm-browser/models/embedding_model.onnx node_modules/openwakeword-wasm-browser/models/silero_vad.onnx node_modules/openwakeword-wasm-browser/models/hey_jarvis_v0.1.onnx ui/public/openwakeword/models/ && cp node_modules/onnxruntime-web/dist/ort-wasm-simd-threaded.jsep.wasm node_modules/onnxruntime-web/dist/ort-wasm-simd-threaded.wasm node_modules/onnxruntime-web/dist/ort-wasm-simd-threaded.jsep.mjs node_modules/onnxruntime-web/dist/ort-wasm-simd-threaded.mjs ui/public/ort/",
32
+ "prebuild:ui": "bun run copy:models",
33
+ "build:ui": "bun build ui/index.html --outdir ui/dist",
34
+ "test": "bun test",
35
+ "db:init": "bun run src/vault/schema.ts",
36
+ "setup": "bun run scripts/setup-config.ts",
37
+ "test:llm": "bun run src/llm/test.ts",
38
+ "examples": "bun run examples/llm-integration.ts",
39
+ "setup:google": "bun run src/scripts/google-setup.ts",
40
+ "postinstall": "node scripts/ensure-bun.cjs && (bun run copy:models 2>/dev/null || true)",
41
+ "prepare": "git config core.hooksPath .githooks 2>/dev/null || true",
42
+ "prepublishOnly": "bun run copy:models && bun run build:ui"
43
+ },
44
+ "dependencies": {
45
+ "@codemirror/lang-css": "^6.3.1",
46
+ "@codemirror/lang-html": "^6.4.11",
47
+ "@codemirror/lang-javascript": "^6.2.5",
48
+ "@codemirror/lang-json": "^6.0.2",
49
+ "@codemirror/lang-markdown": "^6.5.0",
50
+ "@codemirror/lang-python": "^6.2.1",
51
+ "@codemirror/state": "^6.6.0",
52
+ "@codemirror/theme-one-dark": "^6.1.3",
53
+ "@codemirror/view": "^6.40.0",
54
+ "@types/react": "^19.2.14",
55
+ "@types/react-dom": "^19.2.3",
56
+ "@xyflow/react": "^12.10.1",
57
+ "codemirror": "^6.0.2",
58
+ "discord.js": "^14.25.1",
59
+ "edge-tts-universal": "^1.4.0",
60
+ "highlight.js": "^11.11.1",
61
+ "jose": "^6.2.0",
62
+ "openwakeword-wasm-browser": "^0.1.1",
63
+ "react": "^19.2.4",
64
+ "react-dom": "^19.2.4",
65
+ "react-markdown": "^10.1.0",
66
+ "rehype-highlight": "^7.0.2",
67
+ "remark-gfm": "^4.0.1",
68
+ "sharp": "^0.34.5",
69
+ "tailwindcss": "^4.2.1",
70
+ "tesseract.js": "^7.0.0",
71
+ "yaml": "^2.7.0"
72
+ },
73
+ "devDependencies": {
74
+ "@types/bun": "latest"
75
+ },
76
+ "peerDependencies": {
77
+ "typescript": "^5"
78
+ }
79
+ }
@@ -0,0 +1,60 @@
1
+ id: activity_observer
2
+ name: Activity Observer
3
+ description: A passive monitoring agent that watches user activity, learns patterns, and provides insights without taking actions.
4
+
5
+ responsibilities:
6
+ - Monitor user's work patterns and habits
7
+ - Track application usage and context switches
8
+ - Identify productivity patterns and bottlenecks
9
+ - Generate insights about work efficiency
10
+ - Build a model of user preferences and routines
11
+
12
+ autonomous_actions:
13
+ - Log observed activities to the vault
14
+ - Update user preference models
15
+ - Generate daily activity summaries
16
+
17
+ approval_required:
18
+ - Share observations with other agents
19
+ - Send notifications or suggestions to the user
20
+ - Modify any system settings
21
+ - Access sensitive data sources
22
+
23
+ kpis:
24
+ - name: Observation Accuracy
25
+ metric: Percentage of correctly identified activities
26
+ target: "> 90%"
27
+ check_interval: weekly
28
+ - name: Insight Quality
29
+ metric: User rating of generated insights
30
+ target: "> 4.0/5"
31
+ check_interval: weekly
32
+ - name: Pattern Detection
33
+ metric: Number of useful patterns identified
34
+ target: "> 3 per week"
35
+ check_interval: weekly
36
+
37
+ communication_style:
38
+ tone: Observant and analytical, non-intrusive
39
+ verbosity: concise
40
+ formality: casual
41
+
42
+ heartbeat_instructions: |
43
+ Every 30 minutes, passively check:
44
+ 1. Active applications and windows
45
+ 2. User's current context (working, browsing, break)
46
+ 3. Time spent on different tasks
47
+ 4. Interruptions and context switches
48
+
49
+ Do NOT interrupt the user. Only log observations.
50
+ At the end of each day, generate a summary of patterns noticed.
51
+
52
+ sub_roles: []
53
+
54
+ tools:
55
+ - window_observer
56
+ - activity_logger
57
+ - pattern_analyzer
58
+ - data_visualizer
59
+
60
+ authority_level: 2