@cloudcli-ai/cloudcli 1.35.0 → 1.36.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/README.md +12 -7
- package/dist/api-docs.html +8 -2
- package/dist/assets/{index-CtwxqzGG.js → index-S6cIy7hj.js} +271 -260
- package/dist/assets/index-uLUE6Qt1.css +32 -0
- package/dist/index.html +12 -4
- package/dist-server/server/claude-sdk.js +25 -26
- package/dist-server/server/claude-sdk.js.map +1 -1
- package/dist-server/server/index.js +0 -13
- package/dist-server/server/index.js.map +1 -1
- package/dist-server/server/modules/providers/list/claude/claude-models.provider.js +70 -1
- package/dist-server/server/modules/providers/list/claude/claude-models.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/codex/codex-models.provider.js +52 -11
- package/dist-server/server/modules/providers/list/codex/codex-models.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/opencode/opencode-models.provider.js +138 -1
- package/dist-server/server/modules/providers/list/opencode/opencode-models.provider.js.map +1 -1
- package/dist-server/server/modules/providers/services/provider-capabilities.service.js +5 -0
- package/dist-server/server/modules/providers/services/provider-capabilities.service.js.map +1 -1
- package/dist-server/server/modules/providers/services/provider-models.service.js +1 -1
- package/dist-server/server/modules/providers/tests/opencode-models.test.js +58 -1
- package/dist-server/server/modules/providers/tests/opencode-models.test.js.map +1 -1
- package/dist-server/server/modules/websocket/services/websocket-server.service.js +0 -5
- package/dist-server/server/modules/websocket/services/websocket-server.service.js.map +1 -1
- package/dist-server/server/openai-codex.js +9 -8
- package/dist-server/server/openai-codex.js.map +1 -1
- package/dist-server/server/opencode-cli.js +20 -2
- package/dist-server/server/opencode-cli.js.map +1 -1
- package/dist-server/server/routes/agent.js +14 -3
- package/dist-server/server/routes/agent.js.map +1 -1
- package/electron/desktopWindow.js +0 -15
- package/electron/launcher/launcher.js +1 -143
- package/electron/main.js +1 -117
- package/electron/preload.cjs +0 -3
- package/package.json +3 -8
- package/public/api-docs.html +8 -2
- package/scripts/release/prepare-desktop-app.js +0 -6
- package/server/claude-sdk.js +32 -26
- package/server/index.js +0 -14
- package/server/modules/providers/list/claude/claude-models.provider.ts +73 -1
- package/server/modules/providers/list/codex/codex-models.provider.ts +59 -11
- package/server/modules/providers/list/opencode/opencode-models.provider.ts +180 -1
- package/server/modules/providers/services/provider-capabilities.service.ts +7 -0
- package/server/modules/providers/services/provider-models.service.ts +1 -1
- package/server/modules/providers/tests/opencode-models.test.ts +62 -0
- package/server/modules/websocket/services/websocket-server.service.ts +0 -6
- package/server/openai-codex.js +9 -7
- package/server/opencode-cli.js +21 -2
- package/server/routes/agent.js +14 -3
- package/server/shared/types.ts +7 -0
- package/dist/assets/index-DlvtxFyt.css +0 -32
- package/dist-server/server/computer-use-agent.js +0 -242
- package/dist-server/server/computer-use-agent.js.map +0 -1
- package/dist-server/server/computer-use-mcp.js +0 -519
- package/dist-server/server/computer-use-mcp.js.map +0 -1
- package/dist-server/server/modules/computer-use/actions/raw-action-dispatcher.js +0 -55
- package/dist-server/server/modules/computer-use/actions/raw-action-dispatcher.js.map +0 -1
- package/dist-server/server/modules/computer-use/actions/raw-action-types.js +0 -2
- package/dist-server/server/modules/computer-use/actions/raw-action-types.js.map +0 -1
- package/dist-server/server/modules/computer-use/computer-executor.js +0 -212
- package/dist-server/server/modules/computer-use/computer-executor.js.map +0 -1
- package/dist-server/server/modules/computer-use/computer-semantics.service.js +0 -422
- package/dist-server/server/modules/computer-use/computer-semantics.service.js.map +0 -1
- package/dist-server/server/modules/computer-use/computer-use-mcp.routes.js +0 -126
- package/dist-server/server/modules/computer-use/computer-use-mcp.routes.js.map +0 -1
- package/dist-server/server/modules/computer-use/computer-use.routes.js +0 -196
- package/dist-server/server/modules/computer-use/computer-use.routes.js.map +0 -1
- package/dist-server/server/modules/computer-use/computer-use.service.js +0 -759
- package/dist-server/server/modules/computer-use/computer-use.service.js.map +0 -1
- package/dist-server/server/modules/computer-use/desktop-agent-relay.service.js +0 -126
- package/dist-server/server/modules/computer-use/desktop-agent-relay.service.js.map +0 -1
- package/dist-server/server/modules/computer-use/index.js +0 -3
- package/dist-server/server/modules/computer-use/index.js.map +0 -1
- package/dist-server/server/modules/computer-use/semantics/adapters/helper-semantic-adapter.js +0 -59
- package/dist-server/server/modules/computer-use/semantics/adapters/helper-semantic-adapter.js.map +0 -1
- package/dist-server/server/modules/computer-use/semantics/adapters/macos/macos-semantic-adapter.js +0 -5
- package/dist-server/server/modules/computer-use/semantics/adapters/macos/macos-semantic-adapter.js.map +0 -1
- package/dist-server/server/modules/computer-use/semantics/adapters/semantic-adapter.js +0 -2
- package/dist-server/server/modules/computer-use/semantics/adapters/semantic-adapter.js.map +0 -1
- package/dist-server/server/modules/computer-use/semantics/adapters/windows/windows-semantic-adapter.js +0 -5
- package/dist-server/server/modules/computer-use/semantics/adapters/windows/windows-semantic-adapter.js.map +0 -1
- package/dist-server/server/modules/computer-use/semantics/bin/darwin-arm64/CloudCLISemantics +0 -0
- package/dist-server/server/modules/computer-use/semantics/bin/darwin-x64/CloudCLISemantics +0 -0
- package/dist-server/server/modules/computer-use/semantics/bin/win32-arm64/CloudCLISemantics.exe +0 -0
- package/dist-server/server/modules/computer-use/semantics/bin/win32-x64/CloudCLISemantics.exe +0 -0
- package/dist-server/server/modules/computer-use/semantics/helpers/semantic-helper-process.js +0 -106
- package/dist-server/server/modules/computer-use/semantics/helpers/semantic-helper-process.js.map +0 -1
- package/dist-server/server/modules/computer-use/semantics/helpers/semantic-helper-resolver.js +0 -78
- package/dist-server/server/modules/computer-use/semantics/helpers/semantic-helper-resolver.js.map +0 -1
- package/dist-server/server/modules/computer-use/semantics/semantic-session-store.js +0 -68
- package/dist-server/server/modules/computer-use/semantics/semantic-session-store.js.map +0 -1
- package/dist-server/server/modules/computer-use/semantics/semantic-tool-dispatcher.js +0 -16
- package/dist-server/server/modules/computer-use/semantics/semantic-tool-dispatcher.js.map +0 -1
- package/dist-server/server/modules/computer-use/semantics/semantic-types.js +0 -2
- package/dist-server/server/modules/computer-use/semantics/semantic-types.js.map +0 -1
- package/dist-server/server/modules/websocket/services/desktop-agent-websocket.service.js +0 -39
- package/dist-server/server/modules/websocket/services/desktop-agent-websocket.service.js.map +0 -1
- package/electron/computerAgent.js +0 -290
- package/scripts/build-computer-semantics.mjs +0 -133
- package/scripts/copy-computer-semantics-bin.mjs +0 -24
- package/server/computer-use-agent.ts +0 -279
- package/server/computer-use-mcp.ts +0 -574
- package/server/modules/computer-use/actions/raw-action-dispatcher.ts +0 -67
- package/server/modules/computer-use/actions/raw-action-types.ts +0 -28
- package/server/modules/computer-use/computer-executor.ts +0 -242
- package/server/modules/computer-use/computer-semantics.service.ts +0 -460
- package/server/modules/computer-use/computer-use-mcp.routes.ts +0 -141
- package/server/modules/computer-use/computer-use.routes.ts +0 -211
- package/server/modules/computer-use/computer-use.service.ts +0 -920
- package/server/modules/computer-use/desktop-agent-relay.service.ts +0 -158
- package/server/modules/computer-use/index.ts +0 -2
- package/server/modules/computer-use/semantics/adapters/helper-semantic-adapter.ts +0 -82
- package/server/modules/computer-use/semantics/adapters/macos/macos-semantic-adapter.ts +0 -5
- package/server/modules/computer-use/semantics/adapters/semantic-adapter.ts +0 -23
- package/server/modules/computer-use/semantics/adapters/windows/windows-semantic-adapter.ts +0 -5
- package/server/modules/computer-use/semantics/bin/darwin-arm64/CloudCLISemantics +0 -0
- package/server/modules/computer-use/semantics/bin/darwin-x64/CloudCLISemantics +0 -0
- package/server/modules/computer-use/semantics/bin/win32-arm64/CloudCLISemantics.exe +0 -0
- package/server/modules/computer-use/semantics/bin/win32-x64/CloudCLISemantics.exe +0 -0
- package/server/modules/computer-use/semantics/helpers/macos/CloudCLISemantics.swift +0 -467
- package/server/modules/computer-use/semantics/helpers/semantic-helper-process.ts +0 -124
- package/server/modules/computer-use/semantics/helpers/semantic-helper-resolver.ts +0 -97
- package/server/modules/computer-use/semantics/helpers/windows/CloudCLISemantics.csproj +0 -11
- package/server/modules/computer-use/semantics/helpers/windows/Program.cs +0 -534
- package/server/modules/computer-use/semantics/semantic-session-store.ts +0 -87
- package/server/modules/computer-use/semantics/semantic-tool-dispatcher.ts +0 -17
- package/server/modules/computer-use/semantics/semantic-types.ts +0 -58
- package/server/modules/websocket/services/desktop-agent-websocket.service.ts +0 -51
|
@@ -1,279 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* CloudCLI Computer Use — Desktop Agent.
|
|
4
|
-
*
|
|
5
|
-
* Standalone executor for the cloud relay. The Electron desktop app spawns this
|
|
6
|
-
* process (via ELECTRON_RUN_AS_NODE) whenever Computer Use is enabled and the
|
|
7
|
-
* user has running cloud environments. It opens an outbound websocket to each
|
|
8
|
-
* environment's `/desktop-agent` endpoint and executes the `computer_*` actions
|
|
9
|
-
* the hosted server relays, returning a fresh screenshot each time.
|
|
10
|
-
*
|
|
11
|
-
* It is fully self-contained: it reuses the shared nut-js executor module and
|
|
12
|
-
* does NOT depend on the local CloudCLI server. Consent is enforced here (the
|
|
13
|
-
* controlled machine is the authority): in `ask` mode the agent asks the parent
|
|
14
|
-
* Electron process for a per-session decision before the first action runs.
|
|
15
|
-
*/
|
|
16
|
-
import readline from 'node:readline';
|
|
17
|
-
|
|
18
|
-
import { WebSocket } from 'ws';
|
|
19
|
-
|
|
20
|
-
import {
|
|
21
|
-
getRuntimeReadiness,
|
|
22
|
-
type Point,
|
|
23
|
-
type ClickButton,
|
|
24
|
-
type ScrollDirection,
|
|
25
|
-
} from './modules/computer-use/computer-executor.js';
|
|
26
|
-
import { runRawComputerAction } from './modules/computer-use/actions/raw-action-dispatcher.js';
|
|
27
|
-
import type { RawActionTarget, RawComputerAction } from './modules/computer-use/actions/raw-action-types.js';
|
|
28
|
-
import { computerSemanticsService } from './modules/computer-use/computer-semantics.service.js';
|
|
29
|
-
|
|
30
|
-
type ConsentMode = 'ask' | 'auto';
|
|
31
|
-
|
|
32
|
-
type RelayMessage = {
|
|
33
|
-
kind?: string;
|
|
34
|
-
type?: string;
|
|
35
|
-
id?: string;
|
|
36
|
-
params?: Record<string, unknown>;
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
const IPC_PREFIX = '@@CUAGENT@@';
|
|
40
|
-
const RECONNECT_BASE_MS = 2000;
|
|
41
|
-
const RECONNECT_MAX_MS = 30_000;
|
|
42
|
-
|
|
43
|
-
const consentMode: ConsentMode = process.env.CLOUDCLI_COMPUTER_USE_CONSENT_MODE === 'auto' ? 'auto' : 'ask';
|
|
44
|
-
const agentLabel = process.env.CLOUDCLI_DESKTOP_AGENT_LABEL || 'cloudcli-desktop';
|
|
45
|
-
const desktopAgentApiKey = process.env.CLOUDCLI_DESKTOP_AGENT_API_KEY || '';
|
|
46
|
-
|
|
47
|
-
function parseTargets(): string[] {
|
|
48
|
-
const raw =
|
|
49
|
-
process.env.CLOUDCLI_DESKTOP_AGENT_URLS ||
|
|
50
|
-
process.env.CLOUDCLI_DESKTOP_AGENT_URL ||
|
|
51
|
-
'';
|
|
52
|
-
return raw
|
|
53
|
-
.split(',')
|
|
54
|
-
.map((value) => value.trim())
|
|
55
|
-
.filter(Boolean);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
// --- Parent (Electron) IPC over stdout/stdin -------------------------------
|
|
59
|
-
|
|
60
|
-
function emitToParent(message: Record<string, unknown>): void {
|
|
61
|
-
process.stdout.write(`${IPC_PREFIX} ${JSON.stringify(message)}\n`);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/** Per-session consent decisions, and resolvers awaiting a parent reply. */
|
|
65
|
-
const sessionConsent = new Map<string, 'granted' | 'denied'>();
|
|
66
|
-
const pendingConsent = new Map<string, Array<(allow: boolean) => void>>();
|
|
67
|
-
|
|
68
|
-
const stdinReader = readline.createInterface({ input: process.stdin });
|
|
69
|
-
stdinReader.on('line', (line) => {
|
|
70
|
-
const trimmed = line.trim();
|
|
71
|
-
if (!trimmed.startsWith(IPC_PREFIX)) {
|
|
72
|
-
return;
|
|
73
|
-
}
|
|
74
|
-
try {
|
|
75
|
-
const payload = JSON.parse(trimmed.slice(IPC_PREFIX.length).trim()) as Record<string, unknown>;
|
|
76
|
-
if (payload.type === 'consent-response' && typeof payload.sessionId === 'string') {
|
|
77
|
-
const allow = payload.allow === true;
|
|
78
|
-
sessionConsent.set(payload.sessionId, allow ? 'granted' : 'denied');
|
|
79
|
-
const waiters = pendingConsent.get(payload.sessionId) || [];
|
|
80
|
-
pendingConsent.delete(payload.sessionId);
|
|
81
|
-
for (const resolve of waiters) {
|
|
82
|
-
resolve(allow);
|
|
83
|
-
}
|
|
84
|
-
} else if (payload.type === 'revoke-session' && typeof payload.sessionId === 'string') {
|
|
85
|
-
sessionConsent.delete(payload.sessionId);
|
|
86
|
-
}
|
|
87
|
-
} catch {
|
|
88
|
-
// ignore malformed control lines
|
|
89
|
-
}
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
async function ensureConsent(sessionId: string): Promise<boolean> {
|
|
93
|
-
if (consentMode === 'auto') {
|
|
94
|
-
return true;
|
|
95
|
-
}
|
|
96
|
-
const existing = sessionConsent.get(sessionId);
|
|
97
|
-
if (existing === 'granted') return true;
|
|
98
|
-
if (existing === 'denied') return false;
|
|
99
|
-
|
|
100
|
-
// Ask the parent (Electron) to prompt the user, and wait for the decision.
|
|
101
|
-
return new Promise<boolean>((resolve) => {
|
|
102
|
-
const waiters = pendingConsent.get(sessionId) || [];
|
|
103
|
-
waiters.push(resolve);
|
|
104
|
-
pendingConsent.set(sessionId, waiters);
|
|
105
|
-
emitToParent({ type: 'consent-request', sessionId });
|
|
106
|
-
});
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
// --- Action execution ------------------------------------------------------
|
|
110
|
-
|
|
111
|
-
function asPoint(value: unknown): Point | undefined {
|
|
112
|
-
if (value && typeof value === 'object') {
|
|
113
|
-
const point = value as Record<string, unknown>;
|
|
114
|
-
if (typeof point.x === 'number' && typeof point.y === 'number') {
|
|
115
|
-
return { x: point.x, y: point.y };
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
return undefined;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
function rawActionFromRelay(type: string, params: Record<string, unknown>): RawComputerAction {
|
|
122
|
-
const point = asPoint(params.point);
|
|
123
|
-
|
|
124
|
-
switch (type) {
|
|
125
|
-
case 'screenshot':
|
|
126
|
-
return { type: 'screenshot' };
|
|
127
|
-
case 'cursor_position':
|
|
128
|
-
return { type: 'cursor_position' };
|
|
129
|
-
case 'mouse_move':
|
|
130
|
-
if (!point) {
|
|
131
|
-
throw new Error('mouse_move requires a valid point.');
|
|
132
|
-
}
|
|
133
|
-
return { type: 'mouse_move', point };
|
|
134
|
-
case 'click':
|
|
135
|
-
return {
|
|
136
|
-
type: 'click',
|
|
137
|
-
button: (params.button as ClickButton) || 'left',
|
|
138
|
-
point,
|
|
139
|
-
double: params.double === true,
|
|
140
|
-
};
|
|
141
|
-
case 'drag': {
|
|
142
|
-
const from = asPoint(params.from);
|
|
143
|
-
const to = asPoint(params.to);
|
|
144
|
-
if (!from || !to) {
|
|
145
|
-
throw new Error('drag requires valid from and to points.');
|
|
146
|
-
}
|
|
147
|
-
return { type: 'drag', from, to, button: (params.button as ClickButton) || 'left' };
|
|
148
|
-
}
|
|
149
|
-
case 'type':
|
|
150
|
-
return { type: 'type', text: String(params.text ?? '') };
|
|
151
|
-
case 'key':
|
|
152
|
-
return { type: 'key', key: String(params.key ?? '') };
|
|
153
|
-
case 'scroll':
|
|
154
|
-
return {
|
|
155
|
-
type: 'scroll',
|
|
156
|
-
direction: (params.direction as ScrollDirection) || 'down',
|
|
157
|
-
amount: typeof params.amount === 'number' ? params.amount : 3,
|
|
158
|
-
point,
|
|
159
|
-
};
|
|
160
|
-
case 'wait':
|
|
161
|
-
return { type: 'wait', ms: typeof params.ms === 'number' ? params.ms : undefined };
|
|
162
|
-
default:
|
|
163
|
-
throw new Error(`Unsupported computer action: ${type}`);
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
async function runAction(type: string, params: Record<string, unknown>): Promise<Record<string, unknown>> {
|
|
168
|
-
if (type === 'semantic_tool') {
|
|
169
|
-
const toolName = typeof params.toolName === 'string' ? params.toolName : '';
|
|
170
|
-
const args = params.arguments && typeof params.arguments === 'object'
|
|
171
|
-
? params.arguments as Record<string, unknown>
|
|
172
|
-
: {};
|
|
173
|
-
const sessionId = typeof params.sessionId === 'string' ? params.sessionId : 'default';
|
|
174
|
-
if (!toolName) {
|
|
175
|
-
throw new Error('semantic_tool requires toolName.');
|
|
176
|
-
}
|
|
177
|
-
return await computerSemanticsService.callTool(toolName, { ...args, sessionId }) as Record<string, unknown>;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
const readiness = getRuntimeReadiness();
|
|
181
|
-
if (!readiness.nutInstalled || !readiness.screenshotInstalled) {
|
|
182
|
-
throw new Error('Computer Use runtime is not installed on the desktop agent.');
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
const target: RawActionTarget = {
|
|
186
|
-
displaySize: (params.displaySize as RawActionTarget['displaySize']) ?? null,
|
|
187
|
-
};
|
|
188
|
-
return await runRawComputerAction(rawActionFromRelay(type, params), target) as Record<string, unknown>;
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
// --- Relay connection ------------------------------------------------------
|
|
192
|
-
|
|
193
|
-
function connect(url: string): void {
|
|
194
|
-
let reconnectMs = RECONNECT_BASE_MS;
|
|
195
|
-
let socket: WebSocket | null = null;
|
|
196
|
-
|
|
197
|
-
const open = () => {
|
|
198
|
-
socket = new WebSocket(url, {
|
|
199
|
-
headers: desktopAgentApiKey ? { 'X-API-Key': desktopAgentApiKey } : undefined,
|
|
200
|
-
});
|
|
201
|
-
|
|
202
|
-
socket.on('open', () => {
|
|
203
|
-
reconnectMs = RECONNECT_BASE_MS;
|
|
204
|
-
emitToParent({ type: 'connected', url });
|
|
205
|
-
socket?.send(JSON.stringify({ kind: 'register', label: agentLabel, consentMode }));
|
|
206
|
-
});
|
|
207
|
-
|
|
208
|
-
socket.on('message', async (raw) => {
|
|
209
|
-
let message: RelayMessage;
|
|
210
|
-
try {
|
|
211
|
-
message = JSON.parse(String(raw)) as RelayMessage;
|
|
212
|
-
} catch {
|
|
213
|
-
return;
|
|
214
|
-
}
|
|
215
|
-
const kind = message.kind || message.type;
|
|
216
|
-
if (kind !== 'computer_relay' || typeof message.id !== 'string') {
|
|
217
|
-
return;
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
const id = message.id;
|
|
221
|
-
const type = String(message.type || (message.params?.type as string) || '');
|
|
222
|
-
const params = message.params || {};
|
|
223
|
-
const sessionId = typeof params.sessionId === 'string' ? params.sessionId : 'default';
|
|
224
|
-
|
|
225
|
-
if (type === 'stop_session') {
|
|
226
|
-
sessionConsent.delete(sessionId);
|
|
227
|
-
socket?.send(JSON.stringify({ kind: 'computer_relay_result', id, result: { ok: true } }));
|
|
228
|
-
return;
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
try {
|
|
232
|
-
const allowed = await ensureConsent(sessionId);
|
|
233
|
-
if (!allowed) {
|
|
234
|
-
socket?.send(JSON.stringify({ kind: 'computer_relay_result', id, error: 'The user denied desktop control for this session.' }));
|
|
235
|
-
return;
|
|
236
|
-
}
|
|
237
|
-
const result = await runAction(type, params);
|
|
238
|
-
socket?.send(JSON.stringify({ kind: 'computer_relay_result', id, result }));
|
|
239
|
-
} catch (error) {
|
|
240
|
-
socket?.send(JSON.stringify({
|
|
241
|
-
kind: 'computer_relay_result',
|
|
242
|
-
id,
|
|
243
|
-
error: error instanceof Error ? error.message : 'Desktop agent action failed.',
|
|
244
|
-
}));
|
|
245
|
-
}
|
|
246
|
-
});
|
|
247
|
-
|
|
248
|
-
const scheduleReconnect = (code?: number, reason?: Buffer) => {
|
|
249
|
-
const reasonText = reason?.toString() || '';
|
|
250
|
-
emitToParent({ type: 'disconnected', url, code, reason: reasonText });
|
|
251
|
-
if (code === 1008 && /computer use.*disabled/i.test(reasonText)) {
|
|
252
|
-
return;
|
|
253
|
-
}
|
|
254
|
-
setTimeout(open, reconnectMs);
|
|
255
|
-
reconnectMs = Math.min(reconnectMs * 2, RECONNECT_MAX_MS);
|
|
256
|
-
};
|
|
257
|
-
|
|
258
|
-
socket.on('close', scheduleReconnect);
|
|
259
|
-
socket.on('error', () => {
|
|
260
|
-
try { socket?.close(); } catch { /* noop */ }
|
|
261
|
-
});
|
|
262
|
-
};
|
|
263
|
-
|
|
264
|
-
open();
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
function main(): void {
|
|
268
|
-
const targets = parseTargets();
|
|
269
|
-
if (targets.length === 0) {
|
|
270
|
-
emitToParent({ type: 'error', message: 'No desktop-agent target URLs provided.' });
|
|
271
|
-
return;
|
|
272
|
-
}
|
|
273
|
-
emitToParent({ type: 'starting', targets, consentMode });
|
|
274
|
-
for (const url of targets) {
|
|
275
|
-
connect(url);
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
main();
|