@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.
- package/LICENSE +153 -0
- package/README.md +428 -0
- package/bin/jarvis.ts +449 -0
- package/package.json +79 -0
- package/roles/activity-observer.yaml +60 -0
- package/roles/ceo-founder.yaml +144 -0
- package/roles/chief-of-staff.yaml +158 -0
- package/roles/dev-lead.yaml +182 -0
- package/roles/executive-assistant.yaml +77 -0
- package/roles/marketing-director.yaml +168 -0
- package/roles/personal-assistant.yaml +266 -0
- package/roles/research-specialist.yaml +60 -0
- package/roles/specialists/content-writer.yaml +53 -0
- package/roles/specialists/customer-support.yaml +57 -0
- package/roles/specialists/data-analyst.yaml +57 -0
- package/roles/specialists/financial-analyst.yaml +56 -0
- package/roles/specialists/hr-specialist.yaml +55 -0
- package/roles/specialists/legal-advisor.yaml +58 -0
- package/roles/specialists/marketing-strategist.yaml +56 -0
- package/roles/specialists/project-coordinator.yaml +55 -0
- package/roles/specialists/research-analyst.yaml +58 -0
- package/roles/specialists/software-engineer.yaml +57 -0
- package/roles/specialists/system-administrator.yaml +57 -0
- package/roles/system-admin.yaml +76 -0
- package/scripts/ensure-bun.cjs +16 -0
- package/src/actions/README.md +421 -0
- package/src/actions/app-control/desktop-controller.test.ts +26 -0
- package/src/actions/app-control/desktop-controller.ts +438 -0
- package/src/actions/app-control/interface.ts +64 -0
- package/src/actions/app-control/linux.ts +273 -0
- package/src/actions/app-control/macos.ts +54 -0
- package/src/actions/app-control/sidecar-launcher.test.ts +23 -0
- package/src/actions/app-control/sidecar-launcher.ts +286 -0
- package/src/actions/app-control/windows.ts +44 -0
- package/src/actions/browser/cdp.ts +138 -0
- package/src/actions/browser/chrome-launcher.ts +261 -0
- package/src/actions/browser/session.ts +506 -0
- package/src/actions/browser/stealth.ts +49 -0
- package/src/actions/index.ts +20 -0
- package/src/actions/terminal/executor.ts +157 -0
- package/src/actions/terminal/wsl-bridge.ts +126 -0
- package/src/actions/test.ts +93 -0
- package/src/actions/tools/agents.ts +363 -0
- package/src/actions/tools/builtin.ts +950 -0
- package/src/actions/tools/commitments.ts +192 -0
- package/src/actions/tools/content.ts +217 -0
- package/src/actions/tools/delegate.ts +147 -0
- package/src/actions/tools/desktop.test.ts +55 -0
- package/src/actions/tools/desktop.ts +305 -0
- package/src/actions/tools/documents.ts +169 -0
- package/src/actions/tools/goals.ts +376 -0
- package/src/actions/tools/local-tools-guard.ts +31 -0
- package/src/actions/tools/registry.ts +173 -0
- package/src/actions/tools/research.ts +111 -0
- package/src/actions/tools/sidecar-list.ts +57 -0
- package/src/actions/tools/sidecar-route.ts +105 -0
- package/src/actions/tools/workflows.ts +216 -0
- package/src/agents/agent.ts +132 -0
- package/src/agents/delegation.ts +107 -0
- package/src/agents/hierarchy.ts +113 -0
- package/src/agents/index.ts +19 -0
- package/src/agents/messaging.ts +125 -0
- package/src/agents/orchestrator.ts +592 -0
- package/src/agents/role-discovery.ts +61 -0
- package/src/agents/sub-agent-runner.ts +309 -0
- package/src/agents/task-manager.ts +151 -0
- package/src/authority/approval-delivery.ts +59 -0
- package/src/authority/approval.ts +196 -0
- package/src/authority/audit.ts +158 -0
- package/src/authority/authority.test.ts +519 -0
- package/src/authority/deferred-executor.ts +103 -0
- package/src/authority/emergency.ts +66 -0
- package/src/authority/engine.ts +301 -0
- package/src/authority/index.ts +12 -0
- package/src/authority/learning.ts +111 -0
- package/src/authority/tool-action-map.ts +74 -0
- package/src/awareness/analytics.ts +466 -0
- package/src/awareness/awareness.test.ts +332 -0
- package/src/awareness/capture-engine.ts +305 -0
- package/src/awareness/context-graph.ts +130 -0
- package/src/awareness/context-tracker.ts +349 -0
- package/src/awareness/index.ts +25 -0
- package/src/awareness/intelligence.ts +321 -0
- package/src/awareness/ocr-engine.ts +88 -0
- package/src/awareness/service.ts +528 -0
- package/src/awareness/struggle-detector.ts +342 -0
- package/src/awareness/suggestion-engine.ts +476 -0
- package/src/awareness/types.ts +201 -0
- package/src/cli/autostart.ts +417 -0
- package/src/cli/deps.ts +449 -0
- package/src/cli/doctor.ts +238 -0
- package/src/cli/helpers.ts +401 -0
- package/src/cli/onboard.ts +827 -0
- package/src/cli/uninstall.test.ts +37 -0
- package/src/cli/uninstall.ts +202 -0
- package/src/comms/README.md +329 -0
- package/src/comms/auth-error.html +48 -0
- package/src/comms/channels/discord.ts +228 -0
- package/src/comms/channels/signal.ts +56 -0
- package/src/comms/channels/telegram.ts +316 -0
- package/src/comms/channels/whatsapp.ts +60 -0
- package/src/comms/channels.test.ts +173 -0
- package/src/comms/dashboard-auth.ts +75 -0
- package/src/comms/desktop-notify.ts +114 -0
- package/src/comms/example.ts +129 -0
- package/src/comms/index.ts +129 -0
- package/src/comms/streaming.ts +149 -0
- package/src/comms/voice.test.ts +504 -0
- package/src/comms/voice.ts +341 -0
- package/src/comms/websocket.test.ts +409 -0
- package/src/comms/websocket.ts +669 -0
- package/src/config/README.md +389 -0
- package/src/config/index.ts +6 -0
- package/src/config/loader.test.ts +183 -0
- package/src/config/loader.ts +148 -0
- package/src/config/types.ts +293 -0
- package/src/daemon/README.md +232 -0
- package/src/daemon/agent-service-interface.ts +9 -0
- package/src/daemon/agent-service.ts +667 -0
- package/src/daemon/api-routes.ts +3067 -0
- package/src/daemon/background-agent-service.ts +396 -0
- package/src/daemon/background-agent.test.ts +78 -0
- package/src/daemon/channel-service.ts +201 -0
- package/src/daemon/commitment-executor.ts +297 -0
- package/src/daemon/dashboard-auth.test.ts +170 -0
- package/src/daemon/event-classifier.ts +239 -0
- package/src/daemon/event-coalescer.ts +123 -0
- package/src/daemon/event-reactor.ts +214 -0
- package/src/daemon/flock.c +7 -0
- package/src/daemon/health.ts +220 -0
- package/src/daemon/index.ts +1070 -0
- package/src/daemon/llm-settings.test.ts +78 -0
- package/src/daemon/llm-settings.ts +450 -0
- package/src/daemon/observer-service.ts +150 -0
- package/src/daemon/pid.test.ts +283 -0
- package/src/daemon/pid.ts +224 -0
- package/src/daemon/research-queue.ts +155 -0
- package/src/daemon/services.ts +175 -0
- package/src/daemon/ws-service.ts +926 -0
- package/src/global.d.ts +4 -0
- package/src/goals/accountability.ts +240 -0
- package/src/goals/awareness-bridge.ts +185 -0
- package/src/goals/estimator.ts +185 -0
- package/src/goals/events.ts +28 -0
- package/src/goals/goals.test.ts +400 -0
- package/src/goals/integration.test.ts +329 -0
- package/src/goals/nl-builder.test.ts +220 -0
- package/src/goals/nl-builder.ts +256 -0
- package/src/goals/rhythm.test.ts +177 -0
- package/src/goals/rhythm.ts +275 -0
- package/src/goals/service.test.ts +135 -0
- package/src/goals/service.ts +407 -0
- package/src/goals/types.ts +106 -0
- package/src/goals/workflow-bridge.ts +96 -0
- package/src/integrations/google-api.ts +134 -0
- package/src/integrations/google-auth.ts +175 -0
- package/src/llm/README.md +291 -0
- package/src/llm/anthropic.ts +400 -0
- package/src/llm/gemini.ts +380 -0
- package/src/llm/groq.ts +406 -0
- package/src/llm/history.ts +147 -0
- package/src/llm/index.ts +21 -0
- package/src/llm/manager.ts +226 -0
- package/src/llm/ollama.ts +316 -0
- package/src/llm/openai.ts +411 -0
- package/src/llm/openrouter.ts +390 -0
- package/src/llm/provider.test.ts +487 -0
- package/src/llm/provider.ts +61 -0
- package/src/llm/test.ts +88 -0
- package/src/observers/README.md +278 -0
- package/src/observers/calendar.ts +113 -0
- package/src/observers/clipboard.ts +136 -0
- package/src/observers/email.ts +109 -0
- package/src/observers/example.ts +58 -0
- package/src/observers/file-watcher.ts +124 -0
- package/src/observers/index.ts +159 -0
- package/src/observers/notifications.ts +197 -0
- package/src/observers/observers.test.ts +203 -0
- package/src/observers/processes.ts +225 -0
- package/src/personality/README.md +61 -0
- package/src/personality/adapter.ts +196 -0
- package/src/personality/index.ts +20 -0
- package/src/personality/learner.ts +209 -0
- package/src/personality/model.ts +132 -0
- package/src/personality/personality.test.ts +236 -0
- package/src/roles/README.md +252 -0
- package/src/roles/authority.ts +120 -0
- package/src/roles/example-usage.ts +198 -0
- package/src/roles/index.ts +42 -0
- package/src/roles/loader.ts +143 -0
- package/src/roles/prompt-builder.ts +218 -0
- package/src/roles/test-multi.ts +102 -0
- package/src/roles/test-role.yaml +77 -0
- package/src/roles/test-utils.ts +93 -0
- package/src/roles/test.ts +106 -0
- package/src/roles/tool-guide.ts +195 -0
- package/src/roles/types.ts +36 -0
- package/src/roles/utils.ts +200 -0
- package/src/scripts/google-setup.ts +168 -0
- package/src/sidecar/connection.ts +179 -0
- package/src/sidecar/index.ts +6 -0
- package/src/sidecar/manager.ts +542 -0
- package/src/sidecar/protocol.ts +85 -0
- package/src/sidecar/rpc.ts +161 -0
- package/src/sidecar/scheduler.ts +136 -0
- package/src/sidecar/types.ts +112 -0
- package/src/sidecar/validator.ts +144 -0
- package/src/sites/builder-tools.ts +215 -0
- package/src/sites/dev-server-manager.ts +286 -0
- package/src/sites/fixtures/security-test-site/.jarvis-project.json +6 -0
- package/src/sites/fixtures/security-test-site/Makefile +15 -0
- package/src/sites/fixtures/security-test-site/README.md +18 -0
- package/src/sites/fixtures/security-test-site/index.html +12 -0
- package/src/sites/fixtures/security-test-site/index.ts +16 -0
- package/src/sites/fixtures/security-test-site/package.json +13 -0
- package/src/sites/fixtures/security-test-site/src/app.tsx +780 -0
- package/src/sites/fixtures/security-test-site/tsconfig.json +10 -0
- package/src/sites/git-manager.ts +240 -0
- package/src/sites/github-manager.ts +355 -0
- package/src/sites/index.ts +25 -0
- package/src/sites/project-manager.ts +389 -0
- package/src/sites/proxy.ts +133 -0
- package/src/sites/service.ts +136 -0
- package/src/sites/templates.ts +169 -0
- package/src/sites/types.ts +89 -0
- package/src/user/profile-followup.test.ts +84 -0
- package/src/user/profile-followup.ts +185 -0
- package/src/user/profile.ts +224 -0
- package/src/vault/README.md +110 -0
- package/src/vault/awareness.ts +341 -0
- package/src/vault/commitments.ts +299 -0
- package/src/vault/content-pipeline.ts +270 -0
- package/src/vault/conversations.ts +173 -0
- package/src/vault/dashboard-sessions.ts +44 -0
- package/src/vault/documents.ts +130 -0
- package/src/vault/entities.ts +185 -0
- package/src/vault/extractor.test.ts +356 -0
- package/src/vault/extractor.ts +345 -0
- package/src/vault/facts.ts +190 -0
- package/src/vault/goals.ts +477 -0
- package/src/vault/index.ts +87 -0
- package/src/vault/keychain.ts +99 -0
- package/src/vault/observations.ts +115 -0
- package/src/vault/relationships.ts +178 -0
- package/src/vault/retrieval.test.ts +139 -0
- package/src/vault/retrieval.ts +258 -0
- package/src/vault/schema.ts +709 -0
- package/src/vault/settings.ts +38 -0
- package/src/vault/user-profile.test.ts +113 -0
- package/src/vault/user-profile.ts +176 -0
- package/src/vault/vectors.ts +92 -0
- package/src/vault/webapp-template-seeds.ts +116 -0
- package/src/vault/webapp-templates.ts +244 -0
- package/src/vault/workflows.ts +403 -0
- package/src/workflows/auto-suggest.ts +290 -0
- package/src/workflows/engine.ts +366 -0
- package/src/workflows/events.ts +24 -0
- package/src/workflows/executor.ts +207 -0
- package/src/workflows/nl-builder.ts +198 -0
- package/src/workflows/nodes/actions/agent-task.ts +73 -0
- package/src/workflows/nodes/actions/calendar-action.ts +85 -0
- package/src/workflows/nodes/actions/code-execution.ts +73 -0
- package/src/workflows/nodes/actions/discord.ts +77 -0
- package/src/workflows/nodes/actions/file-write.ts +73 -0
- package/src/workflows/nodes/actions/gmail.ts +69 -0
- package/src/workflows/nodes/actions/http-request.ts +117 -0
- package/src/workflows/nodes/actions/notification.ts +85 -0
- package/src/workflows/nodes/actions/run-tool.ts +55 -0
- package/src/workflows/nodes/actions/send-message.ts +82 -0
- package/src/workflows/nodes/actions/shell-command.ts +76 -0
- package/src/workflows/nodes/actions/telegram.ts +60 -0
- package/src/workflows/nodes/builtin.ts +119 -0
- package/src/workflows/nodes/error/error-handler.ts +37 -0
- package/src/workflows/nodes/error/fallback.ts +47 -0
- package/src/workflows/nodes/error/retry.ts +82 -0
- package/src/workflows/nodes/logic/delay.ts +42 -0
- package/src/workflows/nodes/logic/if-else.ts +41 -0
- package/src/workflows/nodes/logic/loop.ts +90 -0
- package/src/workflows/nodes/logic/merge.ts +38 -0
- package/src/workflows/nodes/logic/race.ts +40 -0
- package/src/workflows/nodes/logic/switch.ts +59 -0
- package/src/workflows/nodes/logic/template-render.ts +53 -0
- package/src/workflows/nodes/logic/variable-get.ts +37 -0
- package/src/workflows/nodes/logic/variable-set.ts +59 -0
- package/src/workflows/nodes/registry.ts +99 -0
- package/src/workflows/nodes/transform/aggregate.ts +99 -0
- package/src/workflows/nodes/transform/csv-parse.ts +70 -0
- package/src/workflows/nodes/transform/json-parse.ts +63 -0
- package/src/workflows/nodes/transform/map-filter.ts +84 -0
- package/src/workflows/nodes/transform/regex-match.ts +89 -0
- package/src/workflows/nodes/triggers/calendar.ts +33 -0
- package/src/workflows/nodes/triggers/clipboard.ts +32 -0
- package/src/workflows/nodes/triggers/cron.ts +40 -0
- package/src/workflows/nodes/triggers/email.ts +40 -0
- package/src/workflows/nodes/triggers/file-change.ts +45 -0
- package/src/workflows/nodes/triggers/git.ts +46 -0
- package/src/workflows/nodes/triggers/manual.ts +23 -0
- package/src/workflows/nodes/triggers/poll.ts +81 -0
- package/src/workflows/nodes/triggers/process.ts +44 -0
- package/src/workflows/nodes/triggers/screen-event.ts +37 -0
- package/src/workflows/nodes/triggers/webhook.ts +39 -0
- package/src/workflows/safe-eval.ts +139 -0
- package/src/workflows/template.ts +118 -0
- package/src/workflows/triggers/cron.ts +311 -0
- package/src/workflows/triggers/manager.ts +285 -0
- package/src/workflows/triggers/observer-bridge.ts +172 -0
- package/src/workflows/triggers/poller.ts +201 -0
- package/src/workflows/triggers/screen-condition.ts +218 -0
- package/src/workflows/triggers/triggers.test.ts +740 -0
- package/src/workflows/triggers/webhook.ts +191 -0
- package/src/workflows/types.ts +133 -0
- package/src/workflows/variables.ts +72 -0
- package/src/workflows/workflows.test.ts +383 -0
- package/src/workflows/yaml.ts +104 -0
- package/ui/dist/index-3gr23jt9.js +112614 -0
- package/ui/dist/index-9vmj8127.css +14239 -0
- package/ui/dist/index-hy9pc1gm.js +112873 -0
- package/ui/dist/index-j2ep5d1w.js +112374 -0
- package/ui/dist/index-jt00vjqs.js +112858 -0
- package/ui/dist/index-k9ymx5qb.js +112374 -0
- package/ui/dist/index.html +16 -0
- package/ui/public/audio/pcm-capture-processor.js +11 -0
- package/ui/public/openwakeword/models/embedding_model.onnx +0 -0
- package/ui/public/openwakeword/models/hey_jarvis_v0.1.onnx +0 -0
- package/ui/public/openwakeword/models/melspectrogram.onnx +0 -0
- package/ui/public/openwakeword/models/silero_vad.onnx +0 -0
- package/ui/public/ort/ort-wasm-simd-threaded.jsep.mjs +106 -0
- package/ui/public/ort/ort-wasm-simd-threaded.jsep.wasm +0 -0
- package/ui/public/ort/ort-wasm-simd-threaded.mjs +59 -0
- 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
|