@web-auto/camo 0.1.26 → 0.2.1
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 +21 -21
- package/README.md +586 -586
- package/bin/browser-service.mjs +11 -11
- package/bin/camo.mjs +22 -22
- package/package.json +48 -48
- package/scripts/build.mjs +19 -19
- package/scripts/bump-version.mjs +34 -34
- package/scripts/check-file-size.mjs +80 -80
- package/scripts/file-size-policy.json +12 -2
- package/scripts/install.mjs +76 -76
- package/scripts/release.sh +54 -54
- package/src/autoscript/action-providers/index.mjs +6 -6
- package/src/autoscript/impact-engine.mjs +78 -78
- package/src/autoscript/runtime.mjs +1017 -1017
- package/src/autoscript/schema.mjs +376 -376
- package/src/cli.mjs +405 -405
- package/src/commands/attach.mjs +141 -141
- package/src/commands/autoscript.mjs +1011 -1011
- package/src/commands/browser.mjs +1255 -1257
- package/src/commands/container.mjs +401 -401
- package/src/commands/cookies.mjs +69 -69
- package/src/commands/create.mjs +98 -98
- package/src/commands/devtools.mjs +349 -349
- package/src/commands/events.mjs +152 -152
- package/src/commands/highlight-mode.mjs +24 -24
- package/src/commands/init.mjs +68 -68
- package/src/commands/lifecycle.mjs +275 -275
- package/src/commands/mouse.mjs +45 -45
- package/src/commands/profile.mjs +46 -46
- package/src/commands/record.mjs +115 -115
- package/src/commands/system.mjs +14 -14
- package/src/commands/window.mjs +123 -123
- package/src/container/change-notifier.mjs +362 -362
- package/src/container/element-filter.mjs +143 -143
- package/src/container/index.mjs +3 -3
- package/src/container/runtime-core/checkpoint.mjs +209 -209
- package/src/container/runtime-core/index.mjs +21 -21
- package/src/container/runtime-core/operations/index.mjs +774 -774
- package/src/container/runtime-core/operations/selector-scripts.mjs +277 -277
- package/src/container/runtime-core/operations/tab-pool.mjs +746 -746
- package/src/container/runtime-core/operations/viewport.mjs +189 -189
- package/src/container/runtime-core/search.mjs +190 -190
- package/src/container/runtime-core/subscription.mjs +224 -224
- package/src/container/runtime-core/utils.mjs +94 -94
- package/src/container/runtime-core/validation.mjs +127 -184
- package/src/container/runtime-core.mjs +1 -1
- package/src/container/subscription-registry.mjs +459 -459
- package/src/core/actions.mjs +561 -561
- package/src/core/browser.mjs +266 -266
- package/src/core/index.mjs +52 -52
- package/src/core/utils.mjs +91 -91
- package/src/events/daemon-entry.mjs +33 -33
- package/src/events/daemon.mjs +80 -80
- package/src/events/progress-log.mjs +109 -109
- package/src/events/ws-server.mjs +239 -239
- package/src/lib/client.mjs +200 -200
- package/src/lifecycle/cleanup.mjs +83 -83
- package/src/lifecycle/lock.mjs +126 -126
- package/src/lifecycle/session-registry.mjs +279 -279
- package/src/lifecycle/session-view.mjs +76 -76
- package/src/lifecycle/session-watchdog.mjs +281 -281
- package/src/services/browser-service/index.js +671 -674
- package/src/services/browser-service/internal/BrowserSession.input.test.js +389 -389
- package/src/services/browser-service/internal/BrowserSession.js +325 -336
- package/src/services/browser-service/internal/ElementRegistry.js +60 -60
- package/src/services/browser-service/internal/ProfileLock.js +84 -84
- package/src/services/browser-service/internal/SessionManager.js +184 -184
- package/src/services/browser-service/internal/SessionManager.test.js +39 -39
- package/src/services/browser-service/internal/browser-session/cookies.js +144 -144
- package/src/services/browser-service/internal/browser-session/input-ops.js +222 -219
- package/src/services/browser-service/internal/browser-session/input-pipeline.js +144 -144
- package/src/services/browser-service/internal/browser-session/logging.js +46 -46
- package/src/services/browser-service/internal/browser-session/navigation.js +38 -38
- package/src/services/browser-service/internal/browser-session/page-hooks.js +442 -442
- package/src/services/browser-service/internal/browser-session/page-management.js +302 -336
- package/src/services/browser-service/internal/browser-session/page-management.test.js +148 -148
- package/src/services/browser-service/internal/browser-session/recording.js +198 -198
- package/src/services/browser-service/internal/browser-session/runtime-events.js +61 -61
- package/src/services/browser-service/internal/browser-session/session-core.js +84 -84
- package/src/services/browser-service/internal/browser-session/session-state.js +38 -38
- package/src/services/browser-service/internal/browser-session/types.js +14 -14
- package/src/services/browser-service/internal/browser-session/utils.js +95 -95
- package/src/services/browser-service/internal/browser-session/viewport-manager.js +46 -46
- package/src/services/browser-service/internal/browser-session/viewport.js +215 -215
- package/src/services/browser-service/internal/container-matcher.js +851 -851
- package/src/services/browser-service/internal/container-registry.js +182 -182
- package/src/services/browser-service/internal/engine-manager.js +259 -259
- package/src/services/browser-service/internal/fingerprint.js +203 -203
- package/src/services/browser-service/internal/heartbeat.js +137 -137
- package/src/services/browser-service/internal/logging.js +46 -46
- package/src/services/browser-service/internal/page-runtime/runtime.js +1317 -1317
- package/src/services/browser-service/internal/pageRuntime.js +28 -28
- package/src/services/browser-service/internal/runtimeInjector.js +31 -31
- package/src/services/browser-service/internal/service-process-logger.js +140 -140
- package/src/services/browser-service/internal/state-bus.js +45 -45
- package/src/services/browser-service/internal/storage-paths.js +42 -42
- package/src/services/browser-service/internal/ws-server.js +1194 -1194
- package/src/services/browser-service/internal/ws-server.test.js +58 -58
- package/src/services/browser-service/server.mjs +6 -6
- package/src/services/controller/cli-bridge.js +93 -93
- package/src/services/controller/container-index.js +50 -50
- package/src/services/controller/container-storage.js +36 -36
- package/src/services/controller/controller-actions.js +207 -207
- package/src/services/controller/controller.js +1138 -1138
- package/src/services/controller/selectors.js +54 -54
- package/src/services/controller/transport.js +125 -125
- package/src/utils/args.mjs +26 -26
- package/src/utils/browser-service.mjs +544 -544
- package/src/utils/command-log.mjs +64 -64
- package/src/utils/config.mjs +214 -214
- package/src/utils/fingerprint.mjs +181 -181
- package/src/utils/help.mjs +216 -216
- package/src/utils/js-policy.mjs +13 -13
- package/src/utils/ws-client.mjs +30 -30
- package/src/container/runtime-core/operations/tab-pool.mjs.bak +0 -762
- package/src/container/runtime-core/operations/tab-pool.mjs.syntax-error +0 -762
- package/src/services/browser-service/index.js.bak +0 -671
package/src/cli.mjs
CHANGED
|
@@ -1,405 +1,405 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import { fileURLToPath } from 'node:url';
|
|
3
|
-
import path from 'node:path';
|
|
4
|
-
import { readFileSync } from 'node:fs';
|
|
5
|
-
import { listProfiles, getDefaultProfile, loadConfig, setRepoRoot } from './utils/config.mjs';
|
|
6
|
-
import { printHelp, printProfilesAndHint } from './utils/help.mjs';
|
|
7
|
-
import { handleProfileCommand } from './commands/profile.mjs';
|
|
8
|
-
import { handleInitCommand } from './commands/init.mjs';
|
|
9
|
-
import { handleCreateCommand } from './commands/create.mjs';
|
|
10
|
-
import { handleCookiesCommand } from './commands/cookies.mjs';
|
|
11
|
-
import { handleWindowCommand } from './commands/window.mjs';
|
|
12
|
-
import { handleMouseCommand } from './commands/mouse.mjs';
|
|
13
|
-
import { handleSystemCommand } from './commands/system.mjs';
|
|
14
|
-
import { handleContainerCommand } from './commands/container.mjs';
|
|
15
|
-
import { handleAutoscriptCommand } from './commands/autoscript.mjs';
|
|
16
|
-
import { handleEventsCommand } from './commands/events.mjs';
|
|
17
|
-
import { handleDevtoolsCommand } from './commands/devtools.mjs';
|
|
18
|
-
import { handleRecordCommand } from './commands/record.mjs';
|
|
19
|
-
import { handleHighlightModeCommand } from './commands/highlight-mode.mjs';
|
|
20
|
-
import { handleAttachCommand } from './commands/attach.mjs';
|
|
21
|
-
import {
|
|
22
|
-
handleStartCommand, handleStopCommand, handleStatusCommand,
|
|
23
|
-
handleGotoCommand, handleBackCommand, handleScreenshotCommand,
|
|
24
|
-
handleScrollCommand, handleClickCommand, handleTypeCommand,
|
|
25
|
-
handleHighlightCommand, handleClearHighlightCommand, handleViewportCommand,
|
|
26
|
-
handleNewPageCommand, handleClosePageCommand, handleSwitchPageCommand,
|
|
27
|
-
handleListPagesCommand, handleShutdownCommand
|
|
28
|
-
} from './commands/browser.mjs';
|
|
29
|
-
import {
|
|
30
|
-
handleCleanupCommand, handleForceStopCommand, handleLockCommand,
|
|
31
|
-
handleUnlockCommand, handleSessionsCommand, handleInstancesCommand
|
|
32
|
-
} from './commands/lifecycle.mjs';
|
|
33
|
-
import { handleSessionWatchdogCommand } from './lifecycle/session-watchdog.mjs';
|
|
34
|
-
import { safeAppendProgressEvent } from './events/progress-log.mjs';
|
|
35
|
-
import { ensureProgressEventDaemon } from './events/daemon.mjs';
|
|
36
|
-
import { appendCommandLog, buildCommandSenderMeta } from './utils/command-log.mjs';
|
|
37
|
-
|
|
38
|
-
const CURRENT_DIR = path.dirname(fileURLToPath(import.meta.url));
|
|
39
|
-
const PACKAGE_JSON_PATH = path.resolve(CURRENT_DIR, '..', 'package.json');
|
|
40
|
-
|
|
41
|
-
function readCliVersion() {
|
|
42
|
-
try {
|
|
43
|
-
const raw = JSON.parse(readFileSync(PACKAGE_JSON_PATH, 'utf8'));
|
|
44
|
-
const version = String(raw?.version || '').trim();
|
|
45
|
-
return version || '0.0.0';
|
|
46
|
-
} catch {
|
|
47
|
-
return '0.0.0';
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
const CLI_VERSION = readCliVersion();
|
|
52
|
-
|
|
53
|
-
function readFlagValue(args, names) {
|
|
54
|
-
for (let i = 0; i < args.length; i += 1) {
|
|
55
|
-
if (!names.includes(args[i])) continue;
|
|
56
|
-
const value = args[i + 1];
|
|
57
|
-
if (!value || String(value).startsWith('-')) return null;
|
|
58
|
-
return value;
|
|
59
|
-
}
|
|
60
|
-
return null;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
function inferProfileId(cmd, args) {
|
|
64
|
-
const explicitProfile = readFlagValue(args, ['--profile', '-p']);
|
|
65
|
-
if (explicitProfile) return explicitProfile;
|
|
66
|
-
const positionals = args.slice(1).filter((item) => item && !String(item).startsWith('-'));
|
|
67
|
-
if (positionals.length === 0) return null;
|
|
68
|
-
|
|
69
|
-
if ([
|
|
70
|
-
'start', 'stop', 'status', 'list', 'goto', 'navigate', 'back', 'screenshot',
|
|
71
|
-
'scroll', 'click', 'type', 'highlight', 'clear-highlight', 'viewport',
|
|
72
|
-
'new-page', 'close-page', 'switch-page', 'list-pages',
|
|
73
|
-
'cleanup', 'force-stop', 'lock', 'unlock', 'sessions',
|
|
74
|
-
].includes(cmd)) {
|
|
75
|
-
if ((cmd === 'stop' || cmd === 'close') && (args.includes('--id') || args.includes('--alias'))) {
|
|
76
|
-
return null;
|
|
77
|
-
}
|
|
78
|
-
const first = positionals[0] || null;
|
|
79
|
-
if ((cmd === 'stop' || cmd === 'close') && (first === 'all' || first === 'idle')) {
|
|
80
|
-
return null;
|
|
81
|
-
}
|
|
82
|
-
return positionals[0] || null;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
if (cmd === 'devtools') {
|
|
86
|
-
const sub = positionals[0] || null;
|
|
87
|
-
if (sub === 'eval' || sub === 'logs' || sub === 'clear') {
|
|
88
|
-
return positionals[1] || null;
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
if (cmd === 'record') {
|
|
93
|
-
const explicit = readFlagValue(args, ['--profile', '-p']);
|
|
94
|
-
if (explicit) return explicit;
|
|
95
|
-
const sub = positionals[0] || null;
|
|
96
|
-
const values = [];
|
|
97
|
-
for (let i = 2; i < args.length; i += 1) {
|
|
98
|
-
const token = args[i];
|
|
99
|
-
if (!token || String(token).startsWith('-')) continue;
|
|
100
|
-
const prev = args[i - 1];
|
|
101
|
-
if (prev && ['--name', '--output', '--reason'].includes(prev)) continue;
|
|
102
|
-
values.push(String(token));
|
|
103
|
-
}
|
|
104
|
-
if (sub === 'start' || sub === 'stop' || sub === 'status') {
|
|
105
|
-
return values[0] || null;
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
if (cmd === 'autoscript' && positionals[0] === 'run') {
|
|
110
|
-
return explicitProfile || null;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
if (cmd === 'container' && ['watch', 'filter', 'list', 'targets', 'register'].includes(positionals[0])) {
|
|
114
|
-
return positionals[1] || null;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
return null;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
async function runTrackedCommand(cmd, args, fn) {
|
|
121
|
-
const startedAt = Date.now();
|
|
122
|
-
const profileId = inferProfileId(cmd, args);
|
|
123
|
-
appendCommandLog({
|
|
124
|
-
action: cmd,
|
|
125
|
-
command: cmd,
|
|
126
|
-
profileId,
|
|
127
|
-
args: args.slice(1),
|
|
128
|
-
payload: { mode: 'cli' },
|
|
129
|
-
meta: buildCommandSenderMeta({ source: 'cli', cwd: process.cwd(), argv: process.argv.slice() }),
|
|
130
|
-
});
|
|
131
|
-
safeAppendProgressEvent({
|
|
132
|
-
source: 'cli.command',
|
|
133
|
-
mode: cmd === 'autoscript' ? 'autoscript' : 'normal',
|
|
134
|
-
profileId,
|
|
135
|
-
event: 'cli.command_start',
|
|
136
|
-
payload: { cmd, args: args.slice(1), startedAt },
|
|
137
|
-
});
|
|
138
|
-
try {
|
|
139
|
-
const result = await fn();
|
|
140
|
-
safeAppendProgressEvent({
|
|
141
|
-
source: 'cli.command',
|
|
142
|
-
mode: cmd === 'autoscript' ? 'autoscript' : 'normal',
|
|
143
|
-
profileId,
|
|
144
|
-
event: 'cli.command_done',
|
|
145
|
-
payload: { cmd, args: args.slice(1), startedAt, endedAt: Date.now(), durationMs: Date.now() - startedAt },
|
|
146
|
-
});
|
|
147
|
-
return result;
|
|
148
|
-
} catch (err) {
|
|
149
|
-
safeAppendProgressEvent({
|
|
150
|
-
source: 'cli.command',
|
|
151
|
-
mode: cmd === 'autoscript' ? 'autoscript' : 'normal',
|
|
152
|
-
profileId,
|
|
153
|
-
event: 'cli.command_error',
|
|
154
|
-
payload: {
|
|
155
|
-
cmd,
|
|
156
|
-
args: args.slice(1),
|
|
157
|
-
startedAt,
|
|
158
|
-
endedAt: Date.now(),
|
|
159
|
-
durationMs: Date.now() - startedAt,
|
|
160
|
-
error: err?.message || String(err),
|
|
161
|
-
},
|
|
162
|
-
});
|
|
163
|
-
throw err;
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
async function handleConfigCommand(args) {
|
|
168
|
-
const sub = args[1];
|
|
169
|
-
if (sub !== 'repo-root') {
|
|
170
|
-
throw new Error('Usage: camo config repo-root [path]');
|
|
171
|
-
}
|
|
172
|
-
const repoRoot = args[2];
|
|
173
|
-
if (!repoRoot) {
|
|
174
|
-
console.log(JSON.stringify({ ok: true, repoRoot: loadConfig().repoRoot }, null, 2));
|
|
175
|
-
return;
|
|
176
|
-
}
|
|
177
|
-
// Accept any path; camo does not require camo-specific structure
|
|
178
|
-
const resolved = path.resolve(repoRoot);
|
|
179
|
-
setRepoRoot(resolved);
|
|
180
|
-
console.log(JSON.stringify({ ok: true, repoRoot: resolved }, null, 2));
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
async function main() {
|
|
184
|
-
const rawArgs = process.argv.slice(2);
|
|
185
|
-
const jsEnabled = rawArgs.includes('--js');
|
|
186
|
-
if (jsEnabled) process.env.CAMO_ALLOW_JS = '1';
|
|
187
|
-
else delete process.env.CAMO_ALLOW_JS;
|
|
188
|
-
const args = rawArgs.filter((arg) => arg !== '--js');
|
|
189
|
-
const cmd = args[0];
|
|
190
|
-
|
|
191
|
-
if (!cmd) {
|
|
192
|
-
printProfilesAndHint(listProfiles, getDefaultProfile);
|
|
193
|
-
return;
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
if (cmd === 'help' || cmd === '--help' || cmd === '-h') {
|
|
197
|
-
printHelp();
|
|
198
|
-
return;
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
if (cmd === 'version' || cmd === '--version' || cmd === '-v') {
|
|
202
|
-
console.log(CLI_VERSION);
|
|
203
|
-
return;
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
if (cmd === '__session-watchdog') {
|
|
207
|
-
await handleSessionWatchdogCommand(args);
|
|
208
|
-
return;
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
const skipProgressAutoStart = new Set(['help', '--help', '-h', 'profiles', 'events', '__session-watchdog']);
|
|
212
|
-
if (!skipProgressAutoStart.has(cmd)) {
|
|
213
|
-
try {
|
|
214
|
-
await ensureProgressEventDaemon();
|
|
215
|
-
} catch {
|
|
216
|
-
// Progress daemon auto-start is best-effort and must not block command execution.
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
if (cmd === 'profiles') {
|
|
221
|
-
const profiles = listProfiles();
|
|
222
|
-
const defaultProfile = getDefaultProfile();
|
|
223
|
-
console.log(JSON.stringify({ ok: true, profiles, defaultProfile, count: profiles.length }, null, 2));
|
|
224
|
-
return;
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
if (cmd === 'profile') {
|
|
228
|
-
await runTrackedCommand(cmd, args, () => handleProfileCommand(args));
|
|
229
|
-
return;
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
if (cmd === 'config') {
|
|
233
|
-
await runTrackedCommand(cmd, args, () => handleConfigCommand(args));
|
|
234
|
-
return;
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
if (cmd === 'init') {
|
|
238
|
-
await runTrackedCommand(cmd, args, () => handleInitCommand(args));
|
|
239
|
-
return;
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
if (cmd === 'create') {
|
|
243
|
-
await runTrackedCommand(cmd, args, () => handleCreateCommand(args));
|
|
244
|
-
return;
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
if (cmd === 'events') {
|
|
248
|
-
await runTrackedCommand(cmd, args, () => handleEventsCommand(args));
|
|
249
|
-
return;
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
if (cmd === 'attach') {
|
|
253
|
-
await runTrackedCommand(cmd, args, () => handleAttachCommand(args));
|
|
254
|
-
return;
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
if (cmd === 'devtools') {
|
|
258
|
-
await runTrackedCommand(cmd, args, () => handleDevtoolsCommand(args));
|
|
259
|
-
return;
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
if (cmd === 'record') {
|
|
263
|
-
await runTrackedCommand(cmd, args, () => handleRecordCommand(args));
|
|
264
|
-
return;
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
if (cmd === 'highlight-mode') {
|
|
268
|
-
await runTrackedCommand(cmd, args, () => handleHighlightModeCommand(args));
|
|
269
|
-
return;
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
// Lifecycle commands
|
|
273
|
-
if (cmd === 'cleanup') {
|
|
274
|
-
await runTrackedCommand(cmd, args, () => handleCleanupCommand(args));
|
|
275
|
-
return;
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
if (cmd === 'force-stop') {
|
|
279
|
-
await runTrackedCommand(cmd, args, () => handleForceStopCommand(args));
|
|
280
|
-
return;
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
if (cmd === 'lock') {
|
|
284
|
-
await runTrackedCommand(cmd, args, () => handleLockCommand(args));
|
|
285
|
-
return;
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
if (cmd === 'unlock') {
|
|
289
|
-
await runTrackedCommand(cmd, args, () => handleUnlockCommand(args));
|
|
290
|
-
return;
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
if (cmd === 'sessions') {
|
|
294
|
-
await runTrackedCommand(cmd, args, () => handleSessionsCommand(args));
|
|
295
|
-
return;
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
if (cmd === 'instances') {
|
|
299
|
-
await runTrackedCommand(cmd, args, () => handleInstancesCommand(args));
|
|
300
|
-
return;
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
if (cmd === 'container') {
|
|
304
|
-
await runTrackedCommand(cmd, args, () => handleContainerCommand(args));
|
|
305
|
-
return;
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
if (cmd === 'autoscript') {
|
|
309
|
-
await runTrackedCommand(cmd, args, () => handleAutoscriptCommand(args));
|
|
310
|
-
return;
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
const serviceCommands = new Set([
|
|
314
|
-
'start', 'stop', 'close', 'status', 'list', 'goto', 'navigate', 'back', 'screenshot',
|
|
315
|
-
'new-page', 'close-page', 'switch-page', 'list-pages', 'shutdown',
|
|
316
|
-
'scroll', 'click', 'type', 'highlight', 'clear-highlight', 'viewport',
|
|
317
|
-
'cookies', 'window', 'mouse', 'system', 'container', 'autoscript', 'events', 'devtools', 'record', 'highlight-mode',
|
|
318
|
-
]);
|
|
319
|
-
|
|
320
|
-
if (!serviceCommands.has(cmd)) {
|
|
321
|
-
throw new Error(`Unknown command: ${cmd}`);
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
await runTrackedCommand(cmd, args, async () => {
|
|
325
|
-
switch (cmd) {
|
|
326
|
-
case 'start':
|
|
327
|
-
await handleStartCommand(args);
|
|
328
|
-
break;
|
|
329
|
-
case 'stop':
|
|
330
|
-
case 'close':
|
|
331
|
-
await handleStopCommand(args);
|
|
332
|
-
break;
|
|
333
|
-
case 'status':
|
|
334
|
-
case 'list':
|
|
335
|
-
await handleStatusCommand(args);
|
|
336
|
-
break;
|
|
337
|
-
case 'goto':
|
|
338
|
-
case 'navigate':
|
|
339
|
-
await handleGotoCommand(args);
|
|
340
|
-
break;
|
|
341
|
-
case 'back':
|
|
342
|
-
await handleBackCommand(args);
|
|
343
|
-
break;
|
|
344
|
-
case 'screenshot':
|
|
345
|
-
await handleScreenshotCommand(args);
|
|
346
|
-
break;
|
|
347
|
-
case 'scroll':
|
|
348
|
-
await handleScrollCommand(args);
|
|
349
|
-
break;
|
|
350
|
-
case 'click':
|
|
351
|
-
await handleClickCommand(args);
|
|
352
|
-
break;
|
|
353
|
-
case 'type':
|
|
354
|
-
await handleTypeCommand(args);
|
|
355
|
-
break;
|
|
356
|
-
case 'highlight':
|
|
357
|
-
await handleHighlightCommand(args);
|
|
358
|
-
break;
|
|
359
|
-
case 'clear-highlight':
|
|
360
|
-
await handleClearHighlightCommand(args);
|
|
361
|
-
break;
|
|
362
|
-
case 'viewport':
|
|
363
|
-
await handleViewportCommand(args);
|
|
364
|
-
break;
|
|
365
|
-
case 'new-page':
|
|
366
|
-
await handleNewPageCommand(args);
|
|
367
|
-
break;
|
|
368
|
-
case 'close-page':
|
|
369
|
-
await handleClosePageCommand(args);
|
|
370
|
-
break;
|
|
371
|
-
case 'switch-page':
|
|
372
|
-
await handleSwitchPageCommand(args);
|
|
373
|
-
break;
|
|
374
|
-
case 'list-pages':
|
|
375
|
-
await handleListPagesCommand(args);
|
|
376
|
-
break;
|
|
377
|
-
case 'shutdown':
|
|
378
|
-
await handleShutdownCommand();
|
|
379
|
-
break;
|
|
380
|
-
case 'cookies':
|
|
381
|
-
await handleCookiesCommand(args);
|
|
382
|
-
break;
|
|
383
|
-
case 'window':
|
|
384
|
-
await handleWindowCommand(args);
|
|
385
|
-
break;
|
|
386
|
-
case 'mouse':
|
|
387
|
-
await handleMouseCommand(args);
|
|
388
|
-
break;
|
|
389
|
-
case 'system':
|
|
390
|
-
await handleSystemCommand(args);
|
|
391
|
-
break;
|
|
392
|
-
case 'record':
|
|
393
|
-
await handleRecordCommand(args);
|
|
394
|
-
break;
|
|
395
|
-
case 'highlight-mode':
|
|
396
|
-
await handleHighlightModeCommand(args);
|
|
397
|
-
break;
|
|
398
|
-
}
|
|
399
|
-
});
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
main().catch((err) => {
|
|
403
|
-
console.error(`Error: ${err?.message || String(err)}`);
|
|
404
|
-
process.exit(1);
|
|
405
|
-
});
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { fileURLToPath } from 'node:url';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { readFileSync } from 'node:fs';
|
|
5
|
+
import { listProfiles, getDefaultProfile, loadConfig, setRepoRoot } from './utils/config.mjs';
|
|
6
|
+
import { printHelp, printProfilesAndHint } from './utils/help.mjs';
|
|
7
|
+
import { handleProfileCommand } from './commands/profile.mjs';
|
|
8
|
+
import { handleInitCommand } from './commands/init.mjs';
|
|
9
|
+
import { handleCreateCommand } from './commands/create.mjs';
|
|
10
|
+
import { handleCookiesCommand } from './commands/cookies.mjs';
|
|
11
|
+
import { handleWindowCommand } from './commands/window.mjs';
|
|
12
|
+
import { handleMouseCommand } from './commands/mouse.mjs';
|
|
13
|
+
import { handleSystemCommand } from './commands/system.mjs';
|
|
14
|
+
import { handleContainerCommand } from './commands/container.mjs';
|
|
15
|
+
import { handleAutoscriptCommand } from './commands/autoscript.mjs';
|
|
16
|
+
import { handleEventsCommand } from './commands/events.mjs';
|
|
17
|
+
import { handleDevtoolsCommand } from './commands/devtools.mjs';
|
|
18
|
+
import { handleRecordCommand } from './commands/record.mjs';
|
|
19
|
+
import { handleHighlightModeCommand } from './commands/highlight-mode.mjs';
|
|
20
|
+
import { handleAttachCommand } from './commands/attach.mjs';
|
|
21
|
+
import {
|
|
22
|
+
handleStartCommand, handleStopCommand, handleStatusCommand,
|
|
23
|
+
handleGotoCommand, handleBackCommand, handleScreenshotCommand,
|
|
24
|
+
handleScrollCommand, handleClickCommand, handleTypeCommand,
|
|
25
|
+
handleHighlightCommand, handleClearHighlightCommand, handleViewportCommand,
|
|
26
|
+
handleNewPageCommand, handleClosePageCommand, handleSwitchPageCommand,
|
|
27
|
+
handleListPagesCommand, handleShutdownCommand
|
|
28
|
+
} from './commands/browser.mjs';
|
|
29
|
+
import {
|
|
30
|
+
handleCleanupCommand, handleForceStopCommand, handleLockCommand,
|
|
31
|
+
handleUnlockCommand, handleSessionsCommand, handleInstancesCommand
|
|
32
|
+
} from './commands/lifecycle.mjs';
|
|
33
|
+
import { handleSessionWatchdogCommand } from './lifecycle/session-watchdog.mjs';
|
|
34
|
+
import { safeAppendProgressEvent } from './events/progress-log.mjs';
|
|
35
|
+
import { ensureProgressEventDaemon } from './events/daemon.mjs';
|
|
36
|
+
import { appendCommandLog, buildCommandSenderMeta } from './utils/command-log.mjs';
|
|
37
|
+
|
|
38
|
+
const CURRENT_DIR = path.dirname(fileURLToPath(import.meta.url));
|
|
39
|
+
const PACKAGE_JSON_PATH = path.resolve(CURRENT_DIR, '..', 'package.json');
|
|
40
|
+
|
|
41
|
+
function readCliVersion() {
|
|
42
|
+
try {
|
|
43
|
+
const raw = JSON.parse(readFileSync(PACKAGE_JSON_PATH, 'utf8'));
|
|
44
|
+
const version = String(raw?.version || '').trim();
|
|
45
|
+
return version || '0.0.0';
|
|
46
|
+
} catch {
|
|
47
|
+
return '0.0.0';
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const CLI_VERSION = readCliVersion();
|
|
52
|
+
|
|
53
|
+
function readFlagValue(args, names) {
|
|
54
|
+
for (let i = 0; i < args.length; i += 1) {
|
|
55
|
+
if (!names.includes(args[i])) continue;
|
|
56
|
+
const value = args[i + 1];
|
|
57
|
+
if (!value || String(value).startsWith('-')) return null;
|
|
58
|
+
return value;
|
|
59
|
+
}
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function inferProfileId(cmd, args) {
|
|
64
|
+
const explicitProfile = readFlagValue(args, ['--profile', '-p']);
|
|
65
|
+
if (explicitProfile) return explicitProfile;
|
|
66
|
+
const positionals = args.slice(1).filter((item) => item && !String(item).startsWith('-'));
|
|
67
|
+
if (positionals.length === 0) return null;
|
|
68
|
+
|
|
69
|
+
if ([
|
|
70
|
+
'start', 'stop', 'status', 'list', 'goto', 'navigate', 'back', 'screenshot',
|
|
71
|
+
'scroll', 'click', 'type', 'highlight', 'clear-highlight', 'viewport',
|
|
72
|
+
'new-page', 'close-page', 'switch-page', 'list-pages',
|
|
73
|
+
'cleanup', 'force-stop', 'lock', 'unlock', 'sessions',
|
|
74
|
+
].includes(cmd)) {
|
|
75
|
+
if ((cmd === 'stop' || cmd === 'close') && (args.includes('--id') || args.includes('--alias'))) {
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
const first = positionals[0] || null;
|
|
79
|
+
if ((cmd === 'stop' || cmd === 'close') && (first === 'all' || first === 'idle')) {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
return positionals[0] || null;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (cmd === 'devtools') {
|
|
86
|
+
const sub = positionals[0] || null;
|
|
87
|
+
if (sub === 'eval' || sub === 'logs' || sub === 'clear') {
|
|
88
|
+
return positionals[1] || null;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (cmd === 'record') {
|
|
93
|
+
const explicit = readFlagValue(args, ['--profile', '-p']);
|
|
94
|
+
if (explicit) return explicit;
|
|
95
|
+
const sub = positionals[0] || null;
|
|
96
|
+
const values = [];
|
|
97
|
+
for (let i = 2; i < args.length; i += 1) {
|
|
98
|
+
const token = args[i];
|
|
99
|
+
if (!token || String(token).startsWith('-')) continue;
|
|
100
|
+
const prev = args[i - 1];
|
|
101
|
+
if (prev && ['--name', '--output', '--reason'].includes(prev)) continue;
|
|
102
|
+
values.push(String(token));
|
|
103
|
+
}
|
|
104
|
+
if (sub === 'start' || sub === 'stop' || sub === 'status') {
|
|
105
|
+
return values[0] || null;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (cmd === 'autoscript' && positionals[0] === 'run') {
|
|
110
|
+
return explicitProfile || null;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (cmd === 'container' && ['watch', 'filter', 'list', 'targets', 'register'].includes(positionals[0])) {
|
|
114
|
+
return positionals[1] || null;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
async function runTrackedCommand(cmd, args, fn) {
|
|
121
|
+
const startedAt = Date.now();
|
|
122
|
+
const profileId = inferProfileId(cmd, args);
|
|
123
|
+
appendCommandLog({
|
|
124
|
+
action: cmd,
|
|
125
|
+
command: cmd,
|
|
126
|
+
profileId,
|
|
127
|
+
args: args.slice(1),
|
|
128
|
+
payload: { mode: 'cli' },
|
|
129
|
+
meta: buildCommandSenderMeta({ source: 'cli', cwd: process.cwd(), argv: process.argv.slice() }),
|
|
130
|
+
});
|
|
131
|
+
safeAppendProgressEvent({
|
|
132
|
+
source: 'cli.command',
|
|
133
|
+
mode: cmd === 'autoscript' ? 'autoscript' : 'normal',
|
|
134
|
+
profileId,
|
|
135
|
+
event: 'cli.command_start',
|
|
136
|
+
payload: { cmd, args: args.slice(1), startedAt },
|
|
137
|
+
});
|
|
138
|
+
try {
|
|
139
|
+
const result = await fn();
|
|
140
|
+
safeAppendProgressEvent({
|
|
141
|
+
source: 'cli.command',
|
|
142
|
+
mode: cmd === 'autoscript' ? 'autoscript' : 'normal',
|
|
143
|
+
profileId,
|
|
144
|
+
event: 'cli.command_done',
|
|
145
|
+
payload: { cmd, args: args.slice(1), startedAt, endedAt: Date.now(), durationMs: Date.now() - startedAt },
|
|
146
|
+
});
|
|
147
|
+
return result;
|
|
148
|
+
} catch (err) {
|
|
149
|
+
safeAppendProgressEvent({
|
|
150
|
+
source: 'cli.command',
|
|
151
|
+
mode: cmd === 'autoscript' ? 'autoscript' : 'normal',
|
|
152
|
+
profileId,
|
|
153
|
+
event: 'cli.command_error',
|
|
154
|
+
payload: {
|
|
155
|
+
cmd,
|
|
156
|
+
args: args.slice(1),
|
|
157
|
+
startedAt,
|
|
158
|
+
endedAt: Date.now(),
|
|
159
|
+
durationMs: Date.now() - startedAt,
|
|
160
|
+
error: err?.message || String(err),
|
|
161
|
+
},
|
|
162
|
+
});
|
|
163
|
+
throw err;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
async function handleConfigCommand(args) {
|
|
168
|
+
const sub = args[1];
|
|
169
|
+
if (sub !== 'repo-root') {
|
|
170
|
+
throw new Error('Usage: camo config repo-root [path]');
|
|
171
|
+
}
|
|
172
|
+
const repoRoot = args[2];
|
|
173
|
+
if (!repoRoot) {
|
|
174
|
+
console.log(JSON.stringify({ ok: true, repoRoot: loadConfig().repoRoot }, null, 2));
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
// Accept any path; camo does not require camo-specific structure
|
|
178
|
+
const resolved = path.resolve(repoRoot);
|
|
179
|
+
setRepoRoot(resolved);
|
|
180
|
+
console.log(JSON.stringify({ ok: true, repoRoot: resolved }, null, 2));
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
async function main() {
|
|
184
|
+
const rawArgs = process.argv.slice(2);
|
|
185
|
+
const jsEnabled = rawArgs.includes('--js');
|
|
186
|
+
if (jsEnabled) process.env.CAMO_ALLOW_JS = '1';
|
|
187
|
+
else delete process.env.CAMO_ALLOW_JS;
|
|
188
|
+
const args = rawArgs.filter((arg) => arg !== '--js');
|
|
189
|
+
const cmd = args[0];
|
|
190
|
+
|
|
191
|
+
if (!cmd) {
|
|
192
|
+
printProfilesAndHint(listProfiles, getDefaultProfile);
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
if (cmd === 'help' || cmd === '--help' || cmd === '-h') {
|
|
197
|
+
printHelp();
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
if (cmd === 'version' || cmd === '--version' || cmd === '-v') {
|
|
202
|
+
console.log(CLI_VERSION);
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
if (cmd === '__session-watchdog') {
|
|
207
|
+
await handleSessionWatchdogCommand(args);
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
const skipProgressAutoStart = new Set(['help', '--help', '-h', 'profiles', 'events', '__session-watchdog']);
|
|
212
|
+
if (!skipProgressAutoStart.has(cmd)) {
|
|
213
|
+
try {
|
|
214
|
+
await ensureProgressEventDaemon();
|
|
215
|
+
} catch {
|
|
216
|
+
// Progress daemon auto-start is best-effort and must not block command execution.
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
if (cmd === 'profiles') {
|
|
221
|
+
const profiles = listProfiles();
|
|
222
|
+
const defaultProfile = getDefaultProfile();
|
|
223
|
+
console.log(JSON.stringify({ ok: true, profiles, defaultProfile, count: profiles.length }, null, 2));
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
if (cmd === 'profile') {
|
|
228
|
+
await runTrackedCommand(cmd, args, () => handleProfileCommand(args));
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
if (cmd === 'config') {
|
|
233
|
+
await runTrackedCommand(cmd, args, () => handleConfigCommand(args));
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
if (cmd === 'init') {
|
|
238
|
+
await runTrackedCommand(cmd, args, () => handleInitCommand(args));
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
if (cmd === 'create') {
|
|
243
|
+
await runTrackedCommand(cmd, args, () => handleCreateCommand(args));
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
if (cmd === 'events') {
|
|
248
|
+
await runTrackedCommand(cmd, args, () => handleEventsCommand(args));
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
if (cmd === 'attach') {
|
|
253
|
+
await runTrackedCommand(cmd, args, () => handleAttachCommand(args));
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
if (cmd === 'devtools') {
|
|
258
|
+
await runTrackedCommand(cmd, args, () => handleDevtoolsCommand(args));
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
if (cmd === 'record') {
|
|
263
|
+
await runTrackedCommand(cmd, args, () => handleRecordCommand(args));
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
if (cmd === 'highlight-mode') {
|
|
268
|
+
await runTrackedCommand(cmd, args, () => handleHighlightModeCommand(args));
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// Lifecycle commands
|
|
273
|
+
if (cmd === 'cleanup') {
|
|
274
|
+
await runTrackedCommand(cmd, args, () => handleCleanupCommand(args));
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
if (cmd === 'force-stop') {
|
|
279
|
+
await runTrackedCommand(cmd, args, () => handleForceStopCommand(args));
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
if (cmd === 'lock') {
|
|
284
|
+
await runTrackedCommand(cmd, args, () => handleLockCommand(args));
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
if (cmd === 'unlock') {
|
|
289
|
+
await runTrackedCommand(cmd, args, () => handleUnlockCommand(args));
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
if (cmd === 'sessions') {
|
|
294
|
+
await runTrackedCommand(cmd, args, () => handleSessionsCommand(args));
|
|
295
|
+
return;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
if (cmd === 'instances') {
|
|
299
|
+
await runTrackedCommand(cmd, args, () => handleInstancesCommand(args));
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
if (cmd === 'container') {
|
|
304
|
+
await runTrackedCommand(cmd, args, () => handleContainerCommand(args));
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
if (cmd === 'autoscript') {
|
|
309
|
+
await runTrackedCommand(cmd, args, () => handleAutoscriptCommand(args));
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
const serviceCommands = new Set([
|
|
314
|
+
'start', 'stop', 'close', 'status', 'list', 'goto', 'navigate', 'back', 'screenshot',
|
|
315
|
+
'new-page', 'close-page', 'switch-page', 'list-pages', 'shutdown',
|
|
316
|
+
'scroll', 'click', 'type', 'highlight', 'clear-highlight', 'viewport',
|
|
317
|
+
'cookies', 'window', 'mouse', 'system', 'container', 'autoscript', 'events', 'devtools', 'record', 'highlight-mode',
|
|
318
|
+
]);
|
|
319
|
+
|
|
320
|
+
if (!serviceCommands.has(cmd)) {
|
|
321
|
+
throw new Error(`Unknown command: ${cmd}`);
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
await runTrackedCommand(cmd, args, async () => {
|
|
325
|
+
switch (cmd) {
|
|
326
|
+
case 'start':
|
|
327
|
+
await handleStartCommand(args);
|
|
328
|
+
break;
|
|
329
|
+
case 'stop':
|
|
330
|
+
case 'close':
|
|
331
|
+
await handleStopCommand(args);
|
|
332
|
+
break;
|
|
333
|
+
case 'status':
|
|
334
|
+
case 'list':
|
|
335
|
+
await handleStatusCommand(args);
|
|
336
|
+
break;
|
|
337
|
+
case 'goto':
|
|
338
|
+
case 'navigate':
|
|
339
|
+
await handleGotoCommand(args);
|
|
340
|
+
break;
|
|
341
|
+
case 'back':
|
|
342
|
+
await handleBackCommand(args);
|
|
343
|
+
break;
|
|
344
|
+
case 'screenshot':
|
|
345
|
+
await handleScreenshotCommand(args);
|
|
346
|
+
break;
|
|
347
|
+
case 'scroll':
|
|
348
|
+
await handleScrollCommand(args);
|
|
349
|
+
break;
|
|
350
|
+
case 'click':
|
|
351
|
+
await handleClickCommand(args);
|
|
352
|
+
break;
|
|
353
|
+
case 'type':
|
|
354
|
+
await handleTypeCommand(args);
|
|
355
|
+
break;
|
|
356
|
+
case 'highlight':
|
|
357
|
+
await handleHighlightCommand(args);
|
|
358
|
+
break;
|
|
359
|
+
case 'clear-highlight':
|
|
360
|
+
await handleClearHighlightCommand(args);
|
|
361
|
+
break;
|
|
362
|
+
case 'viewport':
|
|
363
|
+
await handleViewportCommand(args);
|
|
364
|
+
break;
|
|
365
|
+
case 'new-page':
|
|
366
|
+
await handleNewPageCommand(args);
|
|
367
|
+
break;
|
|
368
|
+
case 'close-page':
|
|
369
|
+
await handleClosePageCommand(args);
|
|
370
|
+
break;
|
|
371
|
+
case 'switch-page':
|
|
372
|
+
await handleSwitchPageCommand(args);
|
|
373
|
+
break;
|
|
374
|
+
case 'list-pages':
|
|
375
|
+
await handleListPagesCommand(args);
|
|
376
|
+
break;
|
|
377
|
+
case 'shutdown':
|
|
378
|
+
await handleShutdownCommand();
|
|
379
|
+
break;
|
|
380
|
+
case 'cookies':
|
|
381
|
+
await handleCookiesCommand(args);
|
|
382
|
+
break;
|
|
383
|
+
case 'window':
|
|
384
|
+
await handleWindowCommand(args);
|
|
385
|
+
break;
|
|
386
|
+
case 'mouse':
|
|
387
|
+
await handleMouseCommand(args);
|
|
388
|
+
break;
|
|
389
|
+
case 'system':
|
|
390
|
+
await handleSystemCommand(args);
|
|
391
|
+
break;
|
|
392
|
+
case 'record':
|
|
393
|
+
await handleRecordCommand(args);
|
|
394
|
+
break;
|
|
395
|
+
case 'highlight-mode':
|
|
396
|
+
await handleHighlightModeCommand(args);
|
|
397
|
+
break;
|
|
398
|
+
}
|
|
399
|
+
});
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
main().catch((err) => {
|
|
403
|
+
console.error(`Error: ${err?.message || String(err)}`);
|
|
404
|
+
process.exit(1);
|
|
405
|
+
});
|