@phnx-labs/agents-cli 1.22.117 → 1.22.118
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/CHANGELOG.md +235 -0
- package/dist/bootstrap.js +4 -11
- package/dist/commands/browser.d.ts +52 -70
- package/dist/commands/browser.js +192 -3562
- package/dist/commands/daemon.d.ts +39 -2
- package/dist/commands/daemon.js +72 -73
- package/dist/commands/events.js +1 -1
- package/dist/commands/exec.js +53 -1
- package/dist/commands/repo.js +13 -49
- package/dist/commands/route.js +5 -5
- package/dist/commands/routines.js +39 -12
- package/dist/commands/sessions-render.d.ts +1 -1
- package/dist/commands/sessions-render.js +0 -1
- package/dist/commands/sessions.test-fixture.d.ts +0 -1
- package/dist/commands/sessions.test-fixture.js +0 -37
- package/dist/commands/setup-browser.d.ts +17 -12
- package/dist/commands/setup-browser.js +52 -87
- package/dist/commands/setup-preferences.d.ts +0 -17
- package/dist/commands/setup-preferences.js +18 -49
- package/dist/commands/setup.js +9 -9
- package/dist/commands/ssh.js +10 -1
- package/dist/commands/sync.js +6 -44
- package/dist/commands/teams.js +0 -1
- package/dist/commands/update.d.ts +19 -0
- package/dist/commands/update.js +34 -6
- package/dist/commands/view.d.ts +12 -1
- package/dist/commands/view.js +47 -2
- package/dist/index.js +107 -26
- package/dist/lib/account-capabilities.js +0 -2
- package/dist/lib/account-catalog.d.ts +38 -0
- package/dist/lib/account-catalog.js +110 -26
- package/dist/lib/account-provider-registry.js +1 -1
- package/dist/lib/account-registry.d.ts +1 -1
- package/dist/lib/account-registry.js +36 -2
- package/dist/lib/accounting/rotate.js +22 -8
- package/dist/lib/accounting/usage-ingest.d.ts +6 -1
- package/dist/lib/accounting/usage-ingest.js +115 -45
- package/dist/lib/accounting/usage-sync.d.ts +134 -31
- package/dist/lib/accounting/usage-sync.js +227 -66
- package/dist/lib/accounting/usage.d.ts +16 -3
- package/dist/lib/accounting/usage.js +26 -8
- package/dist/lib/accounts/slots.d.ts +8 -0
- package/dist/lib/accounts/slots.js +17 -0
- package/dist/lib/add-dir.js +0 -1
- package/dist/lib/agent-cli-commands.js +0 -1
- package/dist/lib/agent-spec/agents.d.ts +6 -7
- package/dist/lib/agent-spec/agents.js +6 -60
- package/dist/lib/auth-health.d.ts +69 -1
- package/dist/lib/auth-health.js +133 -4
- package/dist/lib/browser/context.d.ts +82 -0
- package/dist/lib/browser/context.js +88 -0
- package/dist/lib/browser/paths.d.ts +25 -0
- package/dist/lib/browser/paths.js +51 -0
- package/dist/lib/browser/record.d.ts +38 -0
- package/dist/lib/browser/record.js +57 -0
- package/dist/lib/browser/sessions-list.js +1 -2
- package/dist/lib/browser-client.d.ts +158 -0
- package/dist/lib/browser-client.js +234 -0
- package/dist/lib/channels/owner-sink.d.ts +1 -18
- package/dist/lib/channels/owner-sink.js +29 -82
- package/dist/lib/channels/providers/rush.d.ts +7 -7
- package/dist/lib/channels/providers/rush.js +127 -57
- package/dist/lib/claude-statusline.d.ts +1 -1
- package/dist/lib/claude-statusline.js +15 -3
- package/dist/lib/commands.js +1 -1
- package/dist/lib/crabbox/lease.js +1 -1
- package/dist/lib/crabbox/runtimes.js +1 -3
- package/dist/lib/daemon/account-state-daemon-service.js +1 -0
- package/dist/lib/daemon/auth-sync-service.d.ts +21 -18
- package/dist/lib/daemon/auth-sync-service.js +37 -43
- package/dist/lib/daemon/daemon.d.ts +25 -14
- package/dist/lib/daemon/daemon.js +92 -154
- package/dist/lib/daemon/runner.d.ts +2 -2
- package/dist/lib/daemon/runner.js +32 -9
- package/dist/lib/daemon/self-update-service.d.ts +35 -34
- package/dist/lib/daemon/self-update-service.js +40 -36
- package/dist/lib/daemon/service.d.ts +12 -8
- package/dist/lib/daemon/supervisor.d.ts +65 -54
- package/dist/lib/daemon/supervisor.js +136 -171
- package/dist/lib/daemon/testdata/process-view-start.js +5 -2
- package/dist/lib/daemon/usage-sync-service.d.ts +21 -30
- package/dist/lib/daemon/usage-sync-service.js +46 -78
- package/dist/lib/daemon-health.d.ts +22 -5
- package/dist/lib/daemon-health.js +47 -3
- package/dist/lib/daemon-services.d.ts +1 -1
- package/dist/lib/daemon-services.js +0 -10
- package/dist/lib/daemon-ticks.js +4 -2
- package/dist/lib/devices/doctor-findings.js +8 -11
- package/dist/lib/devices/harness-inventory.js +14 -5
- package/dist/lib/exec-account-home.js +5 -0
- package/dist/lib/exec.js +0 -11
- package/dist/lib/feed/events.js +0 -1
- package/dist/lib/feed/tool-activity.js +5 -2
- package/dist/lib/fleet-shared-state.d.ts +45 -0
- package/dist/lib/fleet-shared-state.js +78 -9
- package/dist/lib/fs-atomic.js +25 -0
- package/dist/lib/harness-auth-capabilities.js +0 -1
- package/dist/lib/helper-versions.js +1 -1
- package/dist/lib/hooks/cache.d.ts +7 -0
- package/dist/lib/hooks/cache.js +27 -2
- package/dist/lib/hooks/install.js +7 -1
- package/dist/lib/hosts/ready.d.ts +38 -8
- package/dist/lib/hosts/ready.js +62 -14
- package/dist/lib/installations/active-check.d.ts +27 -0
- package/dist/lib/installations/active-check.js +61 -0
- package/dist/lib/installations/migrate.js +6 -3
- package/dist/lib/installations/shims.js +9 -7
- package/dist/lib/installations/update.js +21 -15
- package/dist/lib/installations/versions.js +12 -1
- package/dist/lib/manifest.js +1 -1
- package/dist/lib/models.js +0 -2
- package/dist/lib/open-url.js +28 -54
- package/dist/lib/profiles.js +0 -2
- package/dist/lib/refresh.js +1 -1
- package/dist/lib/routine-readiness.d.ts +35 -0
- package/dist/lib/routine-readiness.js +74 -16
- package/dist/lib/rules/compile.js +6 -0
- package/dist/lib/sandbox.js +0 -2
- package/dist/lib/secrets-policy.d.ts +89 -11
- package/dist/lib/secrets-policy.js +175 -28
- package/dist/lib/session/db.d.ts +1 -1
- package/dist/lib/session/db.js +65 -18
- package/dist/lib/session/discover.js +1 -283
- package/dist/lib/session/mirror.d.ts +4 -3
- package/dist/lib/session/mirror.js +4 -3
- package/dist/lib/session/parse.d.ts +0 -2
- package/dist/lib/session/parse.js +1 -138
- package/dist/lib/session/throughput.d.ts +1 -3
- package/dist/lib/session/throughput.js +0 -20
- package/dist/lib/session/types.d.ts +2 -2
- package/dist/lib/session/types.js +2 -2
- package/dist/lib/sessions-client.d.ts +60 -1
- package/dist/lib/sessions-client.js +227 -4
- package/dist/lib/setup-tool-status.js +5 -10
- package/dist/lib/signin-badge.d.ts +3 -2
- package/dist/lib/signin-badge.js +6 -3
- package/dist/lib/smart-launch.js +4 -1
- package/dist/lib/staleness/detectors/commands.d.ts +1 -1
- package/dist/lib/staleness/detectors/hooks.d.ts +1 -1
- package/dist/lib/staleness/detectors/mcp.d.ts +1 -1
- package/dist/lib/staleness/detectors/permissions.d.ts +1 -1
- package/dist/lib/staleness/detectors/plugins.d.ts +1 -1
- package/dist/lib/staleness/detectors/rules.d.ts +1 -1
- package/dist/lib/staleness/detectors/skills.d.ts +1 -1
- package/dist/lib/staleness/detectors/subagents.d.ts +1 -1
- package/dist/lib/staleness/detectors/workflows.d.ts +1 -1
- package/dist/lib/staleness/writers/commands.d.ts +1 -1
- package/dist/lib/staleness/writers/hooks.d.ts +1 -1
- package/dist/lib/staleness/writers/mcp.d.ts +1 -1
- package/dist/lib/staleness/writers/permissions.d.ts +1 -1
- package/dist/lib/staleness/writers/plugins.d.ts +1 -1
- package/dist/lib/staleness/writers/rules.d.ts +1 -1
- package/dist/lib/staleness/writers/skills.d.ts +1 -1
- package/dist/lib/staleness/writers/sources.js +5 -0
- package/dist/lib/staleness/writers/subagents.d.ts +1 -1
- package/dist/lib/staleness/writers/workflows.d.ts +1 -1
- package/dist/lib/state.d.ts +6 -4
- package/dist/lib/state.js +7 -17
- package/dist/lib/teams/parsers.d.ts +1 -1
- package/dist/lib/teams/parsers.js +1 -136
- package/dist/lib/teams/placement-probe.js +50 -15
- package/dist/lib/teams/scheduler.d.ts +7 -0
- package/dist/lib/types.d.ts +10 -1
- package/dist/lib/types.js +1 -1
- package/dist/lib/view-types.d.ts +32 -0
- package/dist/lib/watchdog/read.js +0 -1
- package/dist/lib/watchdog/rotate.js +1 -2
- package/dist/lib/watchdog/runner.js +2 -2
- package/dist/lib/watchdog/watchdog.d.ts +1 -1
- package/dist/lib/watchdog/watchdogTail.js +0 -31
- package/package.json +1 -1
- package/scripts/postinstall.js +8 -8
- package/dist/browser.d.ts +0 -2
- package/dist/browser.js +0 -17
- package/dist/commands/browser-picker.d.ts +0 -18
- package/dist/commands/browser-picker.js +0 -97
- package/dist/lib/browser/arc-discovery.d.ts +0 -52
- package/dist/lib/browser/arc-discovery.js +0 -197
- package/dist/lib/browser/arc-dom.d.ts +0 -14
- package/dist/lib/browser/arc-dom.js +0 -121
- package/dist/lib/browser/caller-identity.d.ts +0 -40
- package/dist/lib/browser/caller-identity.js +0 -175
- package/dist/lib/browser/cdp.d.ts +0 -51
- package/dist/lib/browser/cdp.js +0 -254
- package/dist/lib/browser/chrome.d.ts +0 -141
- package/dist/lib/browser/chrome.js +0 -704
- package/dist/lib/browser/chromium-discovery.d.ts +0 -28
- package/dist/lib/browser/chromium-discovery.js +0 -96
- package/dist/lib/browser/devices.d.ts +0 -34
- package/dist/lib/browser/devices.js +0 -61
- package/dist/lib/browser/domain-skills.d.ts +0 -71
- package/dist/lib/browser/domain-skills.js +0 -195
- package/dist/lib/browser/drivers/arc.d.ts +0 -40
- package/dist/lib/browser/drivers/arc.js +0 -276
- package/dist/lib/browser/drivers/firefox.d.ts +0 -99
- package/dist/lib/browser/drivers/firefox.js +0 -377
- package/dist/lib/browser/drivers/local.d.ts +0 -55
- package/dist/lib/browser/drivers/local.js +0 -266
- package/dist/lib/browser/drivers/ssh.d.ts +0 -120
- package/dist/lib/browser/drivers/ssh.js +0 -467
- package/dist/lib/browser/editor.d.ts +0 -3
- package/dist/lib/browser/editor.js +0 -50
- package/dist/lib/browser/ffmpeg.d.ts +0 -12
- package/dist/lib/browser/ffmpeg.js +0 -184
- package/dist/lib/browser/firefox-discovery.d.ts +0 -69
- package/dist/lib/browser/firefox-discovery.js +0 -162
- package/dist/lib/browser/har.d.ts +0 -85
- package/dist/lib/browser/har.js +0 -77
- package/dist/lib/browser/hygiene.d.ts +0 -97
- package/dist/lib/browser/hygiene.js +0 -153
- package/dist/lib/browser/index.d.ts +0 -5
- package/dist/lib/browser/index.js +0 -5
- package/dist/lib/browser/input.d.ts +0 -7
- package/dist/lib/browser/input.js +0 -92
- package/dist/lib/browser/ipc.d.ts +0 -204
- package/dist/lib/browser/ipc.js +0 -1453
- package/dist/lib/browser/login-detection.d.ts +0 -87
- package/dist/lib/browser/login-detection.js +0 -274
- package/dist/lib/browser/profiles.d.ts +0 -422
- package/dist/lib/browser/profiles.js +0 -1157
- package/dist/lib/browser/refs.d.ts +0 -89
- package/dist/lib/browser/refs.js +0 -191
- package/dist/lib/browser/registry.d.ts +0 -70
- package/dist/lib/browser/registry.js +0 -252
- package/dist/lib/browser/remote-control.d.ts +0 -59
- package/dist/lib/browser/remote-control.js +0 -85
- package/dist/lib/browser/resolve-target.d.ts +0 -66
- package/dist/lib/browser/resolve-target.js +0 -264
- package/dist/lib/browser/runtime-state.d.ts +0 -291
- package/dist/lib/browser/runtime-state.js +0 -584
- package/dist/lib/browser/secret-ref.d.ts +0 -10
- package/dist/lib/browser/secret-ref.js +0 -14
- package/dist/lib/browser/service.d.ts +0 -812
- package/dist/lib/browser/service.js +0 -4693
- package/dist/lib/browser/stream.d.ts +0 -17
- package/dist/lib/browser/stream.js +0 -72
- package/dist/lib/browser/task-index.d.ts +0 -78
- package/dist/lib/browser/task-index.js +0 -199
- package/dist/lib/browser/types.d.ts +0 -647
- package/dist/lib/browser/types.js +0 -61
- package/dist/lib/browser/upload.d.ts +0 -29
- package/dist/lib/browser/upload.js +0 -298
- package/dist/lib/daemon/browser-ipc-service.d.ts +0 -20
- package/dist/lib/daemon/browser-ipc-service.js +0 -46
- package/dist/lib/daemon/browser-task-reap-service.d.ts +0 -14
- package/dist/lib/daemon/browser-task-reap-service.js +0 -26
- package/dist/lib/fleet-shared-repo-sync.d.ts +0 -55
- package/dist/lib/fleet-shared-repo-sync.js +0 -490
|
@@ -1,276 +0,0 @@
|
|
|
1
|
-
/** Native Apple Events transport. Never uses CDP or launches an Arc process. */
|
|
2
|
-
import { spawn } from 'node:child_process';
|
|
3
|
-
export class ArcNativeCapabilityError extends Error {
|
|
4
|
-
capability;
|
|
5
|
-
constructor(capability, message) {
|
|
6
|
-
super(message ?? `Native Arc does not support ${capability}. Use a configured browser with that capability.`);
|
|
7
|
-
this.capability = capability;
|
|
8
|
-
this.name = 'ArcNativeCapabilityError';
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
const TIMEOUT_MS = 15_000;
|
|
12
|
-
const MAX_OUTPUT_BYTES = 4 * 1024 * 1024;
|
|
13
|
-
const APP_ID = 'company.thebrowser.Browser';
|
|
14
|
-
let operationQueue = Promise.resolve();
|
|
15
|
-
/** Serialize native operations in this service, including failures. */
|
|
16
|
-
function serialized(operation) {
|
|
17
|
-
const result = operationQueue.then(operation, operation);
|
|
18
|
-
operationQueue = result.catch(() => undefined);
|
|
19
|
-
return result;
|
|
20
|
-
}
|
|
21
|
-
/** AppleScript strings do not implement JSON's \uXXXX escape syntax. */
|
|
22
|
-
function escapeAppleScriptString(value) {
|
|
23
|
-
const parts = value.split(/([\u0000-\u001f])/u).filter(Boolean);
|
|
24
|
-
if (parts.length === 0)
|
|
25
|
-
return '""';
|
|
26
|
-
return '(' + parts.map(part => part.length === 1 && part.charCodeAt(0) < 32
|
|
27
|
-
? `(character id ${part.charCodeAt(0)})`
|
|
28
|
-
: `"${part.replace(/\\/g, '\\\\').replace(/"/g, '\\"')}"`).join(' & ') + ')';
|
|
29
|
-
}
|
|
30
|
-
/** No shell, bounded output and lifetime, and no blocking of the shared daemon. */
|
|
31
|
-
function execAppleScript(source, timeoutMs = TIMEOUT_MS) {
|
|
32
|
-
if (process.platform !== 'darwin')
|
|
33
|
-
return Promise.reject(new Error('Native Arc requires macOS.'));
|
|
34
|
-
if (!Number.isFinite(timeoutMs) || timeoutMs <= 0)
|
|
35
|
-
return Promise.reject(new Error('Invalid Apple Events timeout.'));
|
|
36
|
-
return new Promise((resolve, reject) => {
|
|
37
|
-
const child = spawn('/usr/bin/osascript', [], { stdio: ['pipe', 'pipe', 'pipe'] });
|
|
38
|
-
const chunks = [];
|
|
39
|
-
const errors = [];
|
|
40
|
-
let bytes = 0;
|
|
41
|
-
let failure;
|
|
42
|
-
const abort = (error) => {
|
|
43
|
-
failure ??= error;
|
|
44
|
-
child.kill('SIGKILL');
|
|
45
|
-
};
|
|
46
|
-
const timer = setTimeout(() => abort(new Error(`Arc Apple Event timed out after ${timeoutMs}ms.`)), timeoutMs);
|
|
47
|
-
for (const [stream, target] of [[child.stdout, chunks], [child.stderr, errors]]) {
|
|
48
|
-
stream.on('data', (chunk) => {
|
|
49
|
-
bytes += chunk.length;
|
|
50
|
-
if (bytes > MAX_OUTPUT_BYTES)
|
|
51
|
-
abort(new Error('Arc Apple Event output exceeded the safety limit.'));
|
|
52
|
-
else
|
|
53
|
-
target.push(chunk);
|
|
54
|
-
});
|
|
55
|
-
}
|
|
56
|
-
child.stdin.on('error', error => abort(error));
|
|
57
|
-
child.once('error', error => { clearTimeout(timer); reject(error); });
|
|
58
|
-
child.once('close', (code, signal) => {
|
|
59
|
-
clearTimeout(timer);
|
|
60
|
-
if (failure) {
|
|
61
|
-
reject(failure);
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
if (code !== 0) {
|
|
65
|
-
reject(new Error(`Arc Apple Event failed (${signal ?? code}): ${Buffer.concat(errors).toString('utf8').trim()}`));
|
|
66
|
-
return;
|
|
67
|
-
}
|
|
68
|
-
resolve(Buffer.concat(chunks).toString('utf8').trim());
|
|
69
|
-
});
|
|
70
|
-
child.stdin.end(source);
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
// Foundation serializes arbitrary titles/URLs, including tabs, newlines and Unicode.
|
|
74
|
-
// Delimiter splitting is not a safe wire format for browser-controlled strings.
|
|
75
|
-
const PRELUDE = `use framework "Foundation"
|
|
76
|
-
use scripting additions
|
|
77
|
-
on jsonString(rawValue)
|
|
78
|
-
if rawValue is missing value then set rawValue to ""
|
|
79
|
-
set wrapped to {current application's NSString's stringWithString:(rawValue as text)}
|
|
80
|
-
set jsonData to current application's NSJSONSerialization's dataWithJSONObject:wrapped options:0 |error|:(missing value)
|
|
81
|
-
set jsonText to (current application's NSString's alloc()'s initWithData:jsonData encoding:(current application's NSUTF8StringEncoding)) as text
|
|
82
|
-
return text 2 thru -2 of jsonText
|
|
83
|
-
end jsonString
|
|
84
|
-
`;
|
|
85
|
-
function script(body) {
|
|
86
|
-
return `${PRELUDE}\nif application id "${APP_ID}" is not running then error "Arc is not running. Open it before starting a native task."
|
|
87
|
-
tell application id "${APP_ID}"
|
|
88
|
-
${body}
|
|
89
|
-
end tell`;
|
|
90
|
-
}
|
|
91
|
-
function identity(value, kind) {
|
|
92
|
-
if (typeof value !== 'string' || value.length === 0 || value.length > 256)
|
|
93
|
-
throw new Error(`Missing or invalid native ${kind} ID.`);
|
|
94
|
-
return escapeAppleScriptString(value);
|
|
95
|
-
}
|
|
96
|
-
/**
|
|
97
|
-
* Resolve all ordinals afresh INSIDE the operation; never persist an index.
|
|
98
|
-
*
|
|
99
|
-
* Every `X of every Y` below is ONE Apple Event returning a list. The naive
|
|
100
|
-
* form (`id of tab ti of targetSpace` inside a repeat) costs one round trip per
|
|
101
|
-
* tab — on a 30-tab Space that alone took the create path past the 15 s budget
|
|
102
|
-
* from inside the shared daemon, whose loop also serves everything else.
|
|
103
|
-
*/
|
|
104
|
-
function lookup(ref, missing = 'error "Native Arc target is no longer in its original window and Space."') {
|
|
105
|
-
return `set targetWindowIndex to 0
|
|
106
|
-
set windowIds to id of every window
|
|
107
|
-
set windowVisible to visible of every window
|
|
108
|
-
repeat with wi from 1 to count of windowIds
|
|
109
|
-
if (item wi of windowIds as text) is ${identity(ref.windowId, 'window')} and (item wi of windowVisible) then set targetWindowIndex to wi as integer
|
|
110
|
-
end repeat
|
|
111
|
-
if targetWindowIndex is 0 then
|
|
112
|
-
${missing}
|
|
113
|
-
end if
|
|
114
|
-
set targetSpaceIndex to 0
|
|
115
|
-
set spaceIds to id of every space of window targetWindowIndex
|
|
116
|
-
repeat with si from 1 to count of spaceIds
|
|
117
|
-
if (item si of spaceIds as text) is ${identity(ref.spaceId, 'Space')} then set targetSpaceIndex to si as integer
|
|
118
|
-
end repeat
|
|
119
|
-
if targetSpaceIndex is 0 then
|
|
120
|
-
${missing}
|
|
121
|
-
end if
|
|
122
|
-
set targetSpace to a reference to space targetSpaceIndex of window targetWindowIndex
|
|
123
|
-
${ref.tabId === undefined ? '' : `set targetTabIndex to 0
|
|
124
|
-
set tabIds to id of every tab of targetSpace
|
|
125
|
-
repeat with ti from 1 to count of tabIds
|
|
126
|
-
if (item ti of tabIds as text) is ${identity(ref.tabId, 'tab')} then set targetTabIndex to ti as integer
|
|
127
|
-
end repeat
|
|
128
|
-
if targetTabIndex is 0 then
|
|
129
|
-
${missing}
|
|
130
|
-
end if
|
|
131
|
-
set targetTab to a reference to tab targetTabIndex of targetSpace`}`;
|
|
132
|
-
}
|
|
133
|
-
const TAB_JSON = `"{\\"windowId\\":" & my jsonString(id of window targetWindowIndex) & ",\\"spaceId\\":" & my jsonString(id of targetSpace) & ",\\"tabId\\":" & my jsonString(id of targetTab) & ",\\"url\\":" & my jsonString(URL of targetTab) & ",\\"title\\":" & my jsonString(title of targetTab) & "}"`;
|
|
134
|
-
function parse(raw) {
|
|
135
|
-
try {
|
|
136
|
-
return JSON.parse(raw);
|
|
137
|
-
}
|
|
138
|
-
catch {
|
|
139
|
-
throw new Error('Arc returned an invalid native response; no target was adopted.');
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
export function isArcRunning() {
|
|
143
|
-
if (process.platform !== 'darwin')
|
|
144
|
-
return Promise.resolve(false);
|
|
145
|
-
return serialized(async () => (await execAppleScript(`return application id "${APP_ID}" is running`)) === 'true');
|
|
146
|
-
}
|
|
147
|
-
export function enumerateArcSpaces() {
|
|
148
|
-
return serialized(async () => parse(await execAppleScript(script(`set resultText to "["
|
|
149
|
-
set separator to ""
|
|
150
|
-
set windowIds to id of every window
|
|
151
|
-
set windowVisible to visible of every window
|
|
152
|
-
repeat with wi from 1 to count of windowIds
|
|
153
|
-
if item wi of windowVisible then
|
|
154
|
-
set targetWindowIndex to wi as integer
|
|
155
|
-
set windowIdText to my jsonString(item wi of windowIds)
|
|
156
|
-
set activeId to ""
|
|
157
|
-
try
|
|
158
|
-
set activeId to id of active tab of window targetWindowIndex as text
|
|
159
|
-
end try
|
|
160
|
-
set spaceIds to id of every space of window targetWindowIndex
|
|
161
|
-
set spaceTitles to title of every space of window targetWindowIndex
|
|
162
|
-
repeat with si from 1 to count of spaceIds
|
|
163
|
-
set targetSpace to a reference to space si of window targetWindowIndex
|
|
164
|
-
set resultText to resultText & separator & "{\\"windowId\\":" & windowIdText & ",\\"spaceId\\":" & my jsonString(item si of spaceIds) & ",\\"spaceTitle\\":" & my jsonString(item si of spaceTitles) & ",\\"activeTabId\\":" & my jsonString(activeId) & ",\\"tabs\\":["
|
|
165
|
-
set tabIds to id of every tab of targetSpace
|
|
166
|
-
set tabUrls to URL of every tab of targetSpace
|
|
167
|
-
set tabTitles to title of every tab of targetSpace
|
|
168
|
-
set tabSeparator to ""
|
|
169
|
-
repeat with ti from 1 to count of tabIds
|
|
170
|
-
set resultText to resultText & tabSeparator & "{\\"windowId\\":" & windowIdText & ",\\"spaceId\\":" & my jsonString(item si of spaceIds) & ",\\"tabId\\":" & my jsonString(item ti of tabIds) & ",\\"url\\":" & my jsonString(item ti of tabUrls) & ",\\"title\\":" & my jsonString(item ti of tabTitles) & "}"
|
|
171
|
-
set tabSeparator to ","
|
|
172
|
-
end repeat
|
|
173
|
-
set resultText to resultText & "]}"
|
|
174
|
-
set separator to ","
|
|
175
|
-
end repeat
|
|
176
|
-
end if
|
|
177
|
-
end repeat
|
|
178
|
-
return resultText & "]"`))));
|
|
179
|
-
}
|
|
180
|
-
/** Caller durably records marker intent before calling; never use a real page URL as ownership. */
|
|
181
|
-
export function createArcTab(target, markerUrl) {
|
|
182
|
-
if (!markerUrl || markerUrl.length > 16_384)
|
|
183
|
-
return Promise.reject(new Error('A bounded unique tab creation marker URL is required.'));
|
|
184
|
-
return serialized(async () => parse(await execAppleScript(script(`${lookup(target)}
|
|
185
|
-
set existingUrls to URL of every tab of targetSpace
|
|
186
|
-
repeat with ti from 1 to count of existingUrls
|
|
187
|
-
if (item ti of existingUrls as text) is ${escapeAppleScriptString(markerUrl)} then error "Creation marker already exists; reconcile the saved intent instead of creating another tab."
|
|
188
|
-
end repeat
|
|
189
|
-
tell targetSpace
|
|
190
|
-
make new tab with properties {URL:${escapeAppleScriptString(markerUrl)}}
|
|
191
|
-
end tell
|
|
192
|
-
set matchCount to 0
|
|
193
|
-
set targetTabIndex to 0
|
|
194
|
-
-- Arc commits the new tab's URL asynchronously: read back immediately it is
|
|
195
|
-
-- still empty. Poll briefly (bounded) until the marker shows up.
|
|
196
|
-
repeat with attempt from 1 to 30
|
|
197
|
-
set matchCount to 0
|
|
198
|
-
set createdUrls to URL of every tab of targetSpace
|
|
199
|
-
repeat with ti from 1 to count of createdUrls
|
|
200
|
-
if (item ti of createdUrls as text) is ${escapeAppleScriptString(markerUrl)} then
|
|
201
|
-
set matchCount to matchCount + 1
|
|
202
|
-
set targetTabIndex to ti as integer
|
|
203
|
-
end if
|
|
204
|
-
end repeat
|
|
205
|
-
if matchCount is not 0 then exit repeat
|
|
206
|
-
delay 0.1
|
|
207
|
-
end repeat
|
|
208
|
-
if matchCount is not 1 then error "Creation marker did not resolve exactly one tab; preserve the creation intent for recovery."
|
|
209
|
-
set targetTab to a reference to tab targetTabIndex of targetSpace
|
|
210
|
-
return ${TAB_JSON}`))));
|
|
211
|
-
}
|
|
212
|
-
export function resolveArcTab(ref) {
|
|
213
|
-
return serialized(async () => parse(await execAppleScript(script(`${lookup(ref, 'return "null"')}\nreturn ${TAB_JSON}`))));
|
|
214
|
-
}
|
|
215
|
-
export function navigateArcTab(ref, url) {
|
|
216
|
-
return serialized(async () => {
|
|
217
|
-
await execAppleScript(script(`${lookup(ref)}\nset URL of targetTab to ${escapeAppleScriptString(url)}\nreturn "navigated"`));
|
|
218
|
-
});
|
|
219
|
-
}
|
|
220
|
-
/** Arc serializes a returned object once. JSON.stringify at the top level would double-encode. */
|
|
221
|
-
export function executeJavaScript(ref, expression) {
|
|
222
|
-
const wrapper = `(()=>{try{const value=(0,eval)(${JSON.stringify(expression)});if(value!=null&&typeof value.then==='function')return {ok:false,error:'Native Arc does not support asynchronous evaluation.'};return {ok:true,hasValue:value!==undefined,value:value===undefined?null:JSON.parse(JSON.stringify(value))}}catch(error){return {ok:false,error:String(error)}}})()`;
|
|
223
|
-
return serialized(async () => {
|
|
224
|
-
const result = parse(await execAppleScript(script(`${lookup(ref)}\nreturn execute targetTab javascript ${escapeAppleScriptString(wrapper)}`)));
|
|
225
|
-
if (!result || result.ok !== true)
|
|
226
|
-
throw new Error(result?.error ?? 'Native Arc JavaScript returned no result.');
|
|
227
|
-
return result.hasValue ? result.value : undefined;
|
|
228
|
-
});
|
|
229
|
-
}
|
|
230
|
-
export function closeArcTab(ref) {
|
|
231
|
-
return serialized(async () => {
|
|
232
|
-
const result = await execAppleScript(script(`${lookup(ref, 'return "missing"')}\nclose targetTab\nreturn "closed"`));
|
|
233
|
-
if (result !== 'closed' && result !== 'missing')
|
|
234
|
-
throw new Error('Arc did not confirm tab cleanup.');
|
|
235
|
-
return result;
|
|
236
|
-
});
|
|
237
|
-
}
|
|
238
|
-
/** Explicit user-facing focus only. Evaluation and cleanup never invoke this. */
|
|
239
|
-
export function selectArcTab(ref) {
|
|
240
|
-
return serialized(async () => { await execAppleScript(script(`${lookup(ref)}\nselect targetTab\nreturn "selected"`)); });
|
|
241
|
-
}
|
|
242
|
-
/** AppleScript that selects `tabId` in whatever Space of window `targetWindowIndex` holds it; returns "true"/"false". */
|
|
243
|
-
function selectTabInWindowScript(tabId) {
|
|
244
|
-
return `set spaceCount to count of spaces of window targetWindowIndex
|
|
245
|
-
repeat with si from 1 to spaceCount
|
|
246
|
-
set candidateIds to id of every tab of space si of window targetWindowIndex
|
|
247
|
-
repeat with ti from 1 to count of candidateIds
|
|
248
|
-
if (item ti of candidateIds as text) is ${identity(tabId, 'tab')} then
|
|
249
|
-
select tab ti of space si of window targetWindowIndex
|
|
250
|
-
return "true"
|
|
251
|
-
end if
|
|
252
|
-
end repeat
|
|
253
|
-
end repeat
|
|
254
|
-
return "false"`;
|
|
255
|
-
}
|
|
256
|
-
/**
|
|
257
|
-
* Select `tabId` wherever it lives in window `windowId` (any Space). Used to put
|
|
258
|
-
* the owner back on their tab after a creation that failed mid-way, when there is
|
|
259
|
-
* no owned tab to check against. Returns false when the tab is gone.
|
|
260
|
-
*/
|
|
261
|
-
export function selectWindowTab(windowId, tabId) {
|
|
262
|
-
return serialized(async () => (await execAppleScript(script(`set targetWindowIndex to 0
|
|
263
|
-
set windowIds to id of every window
|
|
264
|
-
set windowVisible to visible of every window
|
|
265
|
-
repeat with wi from 1 to count of windowIds
|
|
266
|
-
if (item wi of windowIds as text) is ${identity(windowId, 'window')} and (item wi of windowVisible) then set targetWindowIndex to wi as integer
|
|
267
|
-
end repeat
|
|
268
|
-
if targetWindowIndex is 0 then return "false"
|
|
269
|
-
${selectTabInWindowScript(tabId)}`))) === 'true');
|
|
270
|
-
}
|
|
271
|
-
/** Restore only while the task's new tab is still selected; preserve a later human choice. */
|
|
272
|
-
export function restoreArcSelection(owned, previousTabId) {
|
|
273
|
-
return serialized(async () => (await execAppleScript(script(`${lookup(owned, 'return "false"')}
|
|
274
|
-
if (id of active tab of window targetWindowIndex as text) is not ${identity(owned.tabId, 'tab')} then return "false"
|
|
275
|
-
${selectTabInWindowScript(previousTabId)}`))) === 'true');
|
|
276
|
-
}
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
import type { BrowserProfile, ConnectionKey } from '../types.js';
|
|
2
|
-
/** How agents obtain a live Firefox — matches the CDP driver's launch/attach split. */
|
|
3
|
-
export interface FirefoxConnection {
|
|
4
|
-
bidi: FirefoxBiDiClient;
|
|
5
|
-
port: number;
|
|
6
|
-
/** The Firefox process pid we launched, or 0 when we attached to a running one. */
|
|
7
|
-
pid: number;
|
|
8
|
-
/** The BiDi session id from `session.new`. */
|
|
9
|
-
sessionId: string;
|
|
10
|
-
}
|
|
11
|
-
/**
|
|
12
|
-
* A verb Firefox-over-BiDi cannot serve (network capture, upload, pdf, trusted
|
|
13
|
-
* key input, …). Mirrors `ArcNativeCapabilityError`: the service throws it in
|
|
14
|
-
* the one place the capability is missing, and the message steers the caller to
|
|
15
|
-
* a Chromium-family profile that has it.
|
|
16
|
-
*/
|
|
17
|
-
export declare class FirefoxCapabilityError extends Error {
|
|
18
|
-
readonly capability: string;
|
|
19
|
-
constructor(capability: string, message?: string);
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Minimal WebDriver BiDi client: request/response keyed by the `id` field, with
|
|
23
|
-
* events drained and ignored. Deliberately shaped like `CDPClient` so the
|
|
24
|
-
* service treats a Firefox connection the same way it treats a CDP one. The
|
|
25
|
-
* large `maxPayload` matches CDPClient's, so a base64 screenshot of a
|
|
26
|
-
* content-rich page never trips the socket's decompressed-size cap.
|
|
27
|
-
*/
|
|
28
|
-
export declare class FirefoxBiDiClient {
|
|
29
|
-
private ws;
|
|
30
|
-
private nextId;
|
|
31
|
-
private pending;
|
|
32
|
-
private closed;
|
|
33
|
-
get isOpen(): boolean;
|
|
34
|
-
connect(url: string): Promise<void>;
|
|
35
|
-
private handleMessage;
|
|
36
|
-
private handleClose;
|
|
37
|
-
send<T = Record<string, unknown>>(method: string, params?: Record<string, unknown>): Promise<T>;
|
|
38
|
-
close(): void;
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* The loud error raised when a Firefox already holds this profile but exposes no
|
|
42
|
-
* BiDi port, so agents cannot attach and must not launch a rival (Firefox is
|
|
43
|
-
* single-instance per profile dir). Mirrors `attachOnlyRequiredError` in
|
|
44
|
-
* `drivers/local.ts`: name the exact relaunch that makes the running instance
|
|
45
|
-
* attachable. Exported so the contract is unit-testable without a real Firefox.
|
|
46
|
-
*/
|
|
47
|
-
export declare function firefoxAttachRequiredError(profile: Pick<BrowserProfile, 'name'> & {
|
|
48
|
-
firefox?: {
|
|
49
|
-
profileName: string;
|
|
50
|
-
};
|
|
51
|
-
}, port: number, profileDir: string): Error;
|
|
52
|
-
/**
|
|
53
|
-
* Connect a Firefox profile over BiDi: attach if the port is already served,
|
|
54
|
-
* otherwise launch Firefox and wait for it. Fails loud when a Firefox holds the
|
|
55
|
-
* profile without a port.
|
|
56
|
-
*/
|
|
57
|
-
export declare function connectFirefox(profile: BrowserProfile, key: ConnectionKey, port: number, opts?: {
|
|
58
|
-
profileDir: string;
|
|
59
|
-
headless?: boolean;
|
|
60
|
-
}): Promise<FirefoxConnection>;
|
|
61
|
-
export declare function deserializeBidi(remote: unknown): unknown;
|
|
62
|
-
/** One top-level browsing context (a tab), flattened from `browsingContext.getTree`. */
|
|
63
|
-
interface BiDiContext {
|
|
64
|
-
context: string;
|
|
65
|
-
url: string;
|
|
66
|
-
}
|
|
67
|
-
/** Every top-level tab currently open in this Firefox. */
|
|
68
|
-
export declare function bidiTopLevelContexts(bidi: FirefoxBiDiClient): Promise<BiDiContext[]>;
|
|
69
|
-
/** Open a fresh tab and return its context id. */
|
|
70
|
-
export declare function bidiCreateTab(bidi: FirefoxBiDiClient): Promise<string>;
|
|
71
|
-
/** Navigate a context and wait for the document to finish loading. */
|
|
72
|
-
export declare function bidiNavigate(bidi: FirefoxBiDiClient, context: string, url: string): Promise<void>;
|
|
73
|
-
/** Reload a context in place, waiting for load. */
|
|
74
|
-
export declare function bidiReload(bidi: FirefoxBiDiClient, context: string): Promise<void>;
|
|
75
|
-
/** Close a tab. */
|
|
76
|
-
export declare function bidiCloseTab(bidi: FirefoxBiDiClient, context: string): Promise<void>;
|
|
77
|
-
/** Bring a tab to the foreground (explicit focus only). */
|
|
78
|
-
export declare function bidiActivate(bidi: FirefoxBiDiClient, context: string): Promise<void>;
|
|
79
|
-
/**
|
|
80
|
-
* Evaluate an expression in a context and return the deserialized value.
|
|
81
|
-
* `awaitPromise` mirrors the CDP evaluate contract; a thrown/rejected value
|
|
82
|
-
* surfaces as an Error rather than a silent undefined.
|
|
83
|
-
*/
|
|
84
|
-
export declare function bidiEvaluate(bidi: FirefoxBiDiClient, context: string, expression: string): Promise<unknown>;
|
|
85
|
-
/** Capture a screenshot of the viewport as raw bytes. `quality` is 0–1 for JPEG. */
|
|
86
|
-
export declare function bidiScreenshot(bidi: FirefoxBiDiClient, context: string, format: {
|
|
87
|
-
type: 'image/png';
|
|
88
|
-
} | {
|
|
89
|
-
type: 'image/jpeg';
|
|
90
|
-
quality: number;
|
|
91
|
-
}): Promise<Buffer>;
|
|
92
|
-
/**
|
|
93
|
-
* A real, trusted left click at viewport coordinates via `input.performActions`
|
|
94
|
-
* — the pointer path CDP `Input.dispatchMouseEvent` gives Chromium, which Arc
|
|
95
|
-
* (Apple Events) never had. The service resolves a ref to (x, y) first, exactly
|
|
96
|
-
* as the CDP click path does.
|
|
97
|
-
*/
|
|
98
|
-
export declare function bidiClickAt(bidi: FirefoxBiDiClient, context: string, x: number, y: number): Promise<void>;
|
|
99
|
-
export {};
|