@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
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { spawn, type Subprocess } from 'bun';
|
|
2
|
+
|
|
3
|
+
export type CommandResult = {
|
|
4
|
+
stdout: string;
|
|
5
|
+
stderr: string;
|
|
6
|
+
exitCode: number;
|
|
7
|
+
duration: number;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export type ExecuteOptions = {
|
|
11
|
+
cwd?: string;
|
|
12
|
+
env?: Record<string, string>;
|
|
13
|
+
timeout?: number;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export class TerminalExecutor {
|
|
17
|
+
private shell: string;
|
|
18
|
+
private defaultTimeout: number;
|
|
19
|
+
|
|
20
|
+
constructor(opts?: { shell?: string; timeout?: number }) {
|
|
21
|
+
this.shell = opts?.shell ?? TerminalExecutor.detectShell();
|
|
22
|
+
this.defaultTimeout = opts?.timeout ?? 30000;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
async execute(command: string, opts?: ExecuteOptions): Promise<CommandResult> {
|
|
26
|
+
const startTime = Date.now();
|
|
27
|
+
const timeout = opts?.timeout ?? this.defaultTimeout;
|
|
28
|
+
|
|
29
|
+
try {
|
|
30
|
+
const proc = spawn({
|
|
31
|
+
cmd: [this.shell, '-c', command],
|
|
32
|
+
cwd: opts?.cwd,
|
|
33
|
+
env: { ...process.env, ...opts?.env },
|
|
34
|
+
stdout: 'pipe',
|
|
35
|
+
stderr: 'pipe',
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
const timeoutId = setTimeout(() => {
|
|
39
|
+
proc.kill();
|
|
40
|
+
}, timeout);
|
|
41
|
+
|
|
42
|
+
const [stdout, stderr, exitCode] = await Promise.all([
|
|
43
|
+
this.readStream(proc.stdout),
|
|
44
|
+
this.readStream(proc.stderr),
|
|
45
|
+
proc.exited,
|
|
46
|
+
]);
|
|
47
|
+
|
|
48
|
+
clearTimeout(timeoutId);
|
|
49
|
+
|
|
50
|
+
const duration = Date.now() - startTime;
|
|
51
|
+
|
|
52
|
+
return {
|
|
53
|
+
stdout: stdout.toString('utf-8'),
|
|
54
|
+
stderr: stderr.toString('utf-8'),
|
|
55
|
+
exitCode: exitCode ?? 0,
|
|
56
|
+
duration,
|
|
57
|
+
};
|
|
58
|
+
} catch (error) {
|
|
59
|
+
const duration = Date.now() - startTime;
|
|
60
|
+
|
|
61
|
+
if (duration >= timeout) {
|
|
62
|
+
throw new Error(`Command timed out after ${timeout}ms: ${command}`);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
throw new Error(`Command execution failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
async *stream(command: string, opts?: { cwd?: string; env?: Record<string, string> }): AsyncIterable<string> {
|
|
70
|
+
const proc = spawn({
|
|
71
|
+
cmd: [this.shell, '-c', command],
|
|
72
|
+
cwd: opts?.cwd,
|
|
73
|
+
env: { ...process.env, ...opts?.env },
|
|
74
|
+
stdout: 'pipe',
|
|
75
|
+
stderr: 'pipe',
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
const decoder = new TextDecoder();
|
|
79
|
+
|
|
80
|
+
if (!proc.stdout) {
|
|
81
|
+
throw new Error('Failed to get stdout stream');
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const reader = proc.stdout.getReader();
|
|
85
|
+
|
|
86
|
+
try {
|
|
87
|
+
while (true) {
|
|
88
|
+
const { done, value } = await reader.read();
|
|
89
|
+
|
|
90
|
+
if (done) {
|
|
91
|
+
break;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (value) {
|
|
95
|
+
yield decoder.decode(value, { stream: true });
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
} finally {
|
|
99
|
+
reader.releaseLock();
|
|
100
|
+
proc.kill();
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
static detectShell(): string {
|
|
105
|
+
const platform = process.platform;
|
|
106
|
+
|
|
107
|
+
if (platform === 'win32') {
|
|
108
|
+
return process.env.COMSPEC ?? 'powershell.exe';
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (process.env.SHELL) {
|
|
112
|
+
return process.env.SHELL;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return '/bin/bash';
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
getShell(): string {
|
|
119
|
+
return this.shell;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
private async readStream(stream: ReadableStream<Uint8Array> | null): Promise<Buffer> {
|
|
123
|
+
if (!stream) {
|
|
124
|
+
return Buffer.from('');
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const reader = stream.getReader();
|
|
128
|
+
const chunks: Uint8Array[] = [];
|
|
129
|
+
|
|
130
|
+
try {
|
|
131
|
+
while (true) {
|
|
132
|
+
const { done, value } = await reader.read();
|
|
133
|
+
|
|
134
|
+
if (done) {
|
|
135
|
+
break;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if (value) {
|
|
139
|
+
chunks.push(value);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
} finally {
|
|
143
|
+
reader.releaseLock();
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
const totalLength = chunks.reduce((sum, chunk) => sum + chunk.length, 0);
|
|
147
|
+
const result = new Uint8Array(totalLength);
|
|
148
|
+
|
|
149
|
+
let offset = 0;
|
|
150
|
+
for (const chunk of chunks) {
|
|
151
|
+
result.set(chunk, offset);
|
|
152
|
+
offset += chunk.length;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
return Buffer.from(result);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { TerminalExecutor, type CommandResult } from './executor.ts';
|
|
2
|
+
import { readFileSync, existsSync } from 'node:fs';
|
|
3
|
+
|
|
4
|
+
export class WSLBridge {
|
|
5
|
+
private executor: TerminalExecutor;
|
|
6
|
+
private windowsHome: string | null = null;
|
|
7
|
+
|
|
8
|
+
constructor() {
|
|
9
|
+
this.executor = new TerminalExecutor();
|
|
10
|
+
|
|
11
|
+
if (WSLBridge.isWSL()) {
|
|
12
|
+
this.detectWindowsHome();
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
static isWSL(): boolean {
|
|
17
|
+
try {
|
|
18
|
+
if (process.platform !== 'linux') {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (existsSync('/proc/version')) {
|
|
23
|
+
const version = readFileSync('/proc/version', 'utf-8').toLowerCase();
|
|
24
|
+
return version.includes('microsoft') || version.includes('wsl');
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (process.env.WSL_DISTRO_NAME || process.env.WSL_INTEROP) {
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return false;
|
|
32
|
+
} catch {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
async runWindowsCommand(command: string): Promise<CommandResult> {
|
|
38
|
+
if (!WSLBridge.isWSL()) {
|
|
39
|
+
throw new Error('Not running in WSL environment');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
try {
|
|
43
|
+
return await this.executor.execute(`cmd.exe /C "${command.replace(/"/g, '\\"')}"`);
|
|
44
|
+
} catch (error) {
|
|
45
|
+
throw new Error(`Failed to run Windows command: ${error instanceof Error ? error.message : String(error)}`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
async runPowerShell(script: string): Promise<CommandResult> {
|
|
50
|
+
if (!WSLBridge.isWSL()) {
|
|
51
|
+
throw new Error('Not running in WSL environment');
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
try {
|
|
55
|
+
const escapedScript = script
|
|
56
|
+
.replace(/\\/g, '\\\\')
|
|
57
|
+
.replace(/"/g, '\\"')
|
|
58
|
+
.replace(/\$/g, '\\$')
|
|
59
|
+
.replace(/`/g, '\\`');
|
|
60
|
+
|
|
61
|
+
return await this.executor.execute(`powershell.exe -Command "${escapedScript}"`);
|
|
62
|
+
} catch (error) {
|
|
63
|
+
throw new Error(`Failed to run PowerShell script: ${error instanceof Error ? error.message : String(error)}`);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
getWindowsHome(): string | null {
|
|
68
|
+
return this.windowsHome;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
private detectWindowsHome(): void {
|
|
72
|
+
try {
|
|
73
|
+
const result = this.executor.execute('cmd.exe /C "echo %USERPROFILE%"');
|
|
74
|
+
result.then(res => {
|
|
75
|
+
const path = res.stdout.trim();
|
|
76
|
+
|
|
77
|
+
if (path && !path.includes('%')) {
|
|
78
|
+
this.windowsHome = this.convertWindowsPath(path);
|
|
79
|
+
}
|
|
80
|
+
}).catch(() => {
|
|
81
|
+
this.windowsHome = null;
|
|
82
|
+
});
|
|
83
|
+
} catch {
|
|
84
|
+
this.windowsHome = null;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
private convertWindowsPath(windowsPath: string): string {
|
|
89
|
+
const normalized = windowsPath.replace(/\\/g, '/');
|
|
90
|
+
|
|
91
|
+
const driveMatch = normalized.match(/^([A-Z]):/i);
|
|
92
|
+
if (driveMatch) {
|
|
93
|
+
const drive = driveMatch[1]?.toLowerCase();
|
|
94
|
+
const rest = normalized.slice(2);
|
|
95
|
+
return `/mnt/${drive}${rest}`;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return normalized;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
async convertToWindowsPath(wslPath: string): Promise<string> {
|
|
102
|
+
if (!WSLBridge.isWSL()) {
|
|
103
|
+
throw new Error('Not running in WSL environment');
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
try {
|
|
107
|
+
const result = await this.executor.execute(`wslpath -w "${wslPath}"`);
|
|
108
|
+
return result.stdout.trim();
|
|
109
|
+
} catch (error) {
|
|
110
|
+
throw new Error(`Failed to convert WSL path: ${error instanceof Error ? error.message : String(error)}`);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
async convertToWSLPath(windowsPath: string): Promise<string> {
|
|
115
|
+
if (!WSLBridge.isWSL()) {
|
|
116
|
+
throw new Error('Not running in WSL environment');
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
try {
|
|
120
|
+
const result = await this.executor.execute(`wslpath -u "${windowsPath}"`);
|
|
121
|
+
return result.stdout.trim();
|
|
122
|
+
} catch (error) {
|
|
123
|
+
throw new Error(`Failed to convert Windows path: ${error instanceof Error ? error.message : String(error)}`);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
getAppController,
|
|
5
|
+
TerminalExecutor,
|
|
6
|
+
WSLBridge,
|
|
7
|
+
BrowserSession,
|
|
8
|
+
CDPBrowser,
|
|
9
|
+
ToolRegistry,
|
|
10
|
+
type ToolDefinition,
|
|
11
|
+
} from './index.ts';
|
|
12
|
+
|
|
13
|
+
async function testActionLayer() {
|
|
14
|
+
console.log('Testing J.A.R.V.I.S. Action Layer\n');
|
|
15
|
+
|
|
16
|
+
console.log('1. App Controller');
|
|
17
|
+
console.log(` Platform: ${process.platform}`);
|
|
18
|
+
try {
|
|
19
|
+
const appController = getAppController();
|
|
20
|
+
console.log(` ✓ App controller initialized for ${process.platform}`);
|
|
21
|
+
} catch (error) {
|
|
22
|
+
console.log(` ⚠ App controller not available: ${error instanceof Error ? error.message.split('\n')[0] : String(error)}`);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
console.log('\n2. Terminal Executor');
|
|
26
|
+
const executor = new TerminalExecutor();
|
|
27
|
+
console.log(` Detected shell: ${executor.getShell()}`);
|
|
28
|
+
try {
|
|
29
|
+
const result = await executor.execute('echo "Hello from JARVIS"');
|
|
30
|
+
console.log(` ✓ Command executed: ${result.stdout.trim()}`);
|
|
31
|
+
console.log(` Duration: ${result.duration}ms`);
|
|
32
|
+
} catch (error) {
|
|
33
|
+
console.log(` ✗ Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
console.log('\n3. WSL Bridge');
|
|
37
|
+
const isWSL = WSLBridge.isWSL();
|
|
38
|
+
console.log(` Running in WSL: ${isWSL}`);
|
|
39
|
+
if (isWSL) {
|
|
40
|
+
const bridge = new WSLBridge();
|
|
41
|
+
console.log(` Windows home: ${bridge.getWindowsHome() ?? 'Not detected'}`);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
console.log('\n4. Browser Session');
|
|
45
|
+
const browserSession = new BrowserSession(9222);
|
|
46
|
+
const isAvailable = await browserSession.isAvailable();
|
|
47
|
+
console.log(` Chrome DevTools available: ${isAvailable}`);
|
|
48
|
+
if (isAvailable) {
|
|
49
|
+
try {
|
|
50
|
+
await (browserSession as any).ensureConnected();
|
|
51
|
+
const browser = (browserSession as any).getBrowser();
|
|
52
|
+
const tabs = await browser.listTabs();
|
|
53
|
+
console.log(` ✓ Found ${tabs.length} browser tab(s)`);
|
|
54
|
+
await browserSession.disconnect();
|
|
55
|
+
} catch (error) {
|
|
56
|
+
console.log(` ⚠ Could not connect: ${error instanceof Error ? error.message.split('\n')[0] : String(error)}`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
console.log('\n5. Tool Registry');
|
|
61
|
+
const registry = new ToolRegistry();
|
|
62
|
+
|
|
63
|
+
const exampleTool: ToolDefinition = {
|
|
64
|
+
name: 'echo',
|
|
65
|
+
description: 'Echo a message',
|
|
66
|
+
category: 'utility',
|
|
67
|
+
parameters: {
|
|
68
|
+
message: {
|
|
69
|
+
type: 'string',
|
|
70
|
+
description: 'Message to echo',
|
|
71
|
+
required: true,
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
execute: async (params) => {
|
|
75
|
+
return `Echo: ${params.message}`;
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
registry.register(exampleTool);
|
|
80
|
+
console.log(` Registered tools: ${registry.count()}`);
|
|
81
|
+
console.log(` Categories: ${registry.getCategories().join(', ')}`);
|
|
82
|
+
|
|
83
|
+
try {
|
|
84
|
+
const result = await registry.execute('echo', { message: 'Hello JARVIS!' });
|
|
85
|
+
console.log(` ✓ Tool execution: ${result}`);
|
|
86
|
+
} catch (error) {
|
|
87
|
+
console.log(` ✗ Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
console.log('\n✓ Action Layer test complete!\n');
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
testActionLayer().catch(console.error);
|