@phnx-labs/agents-cli 1.22.116 → 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.
Files changed (254) hide show
  1. package/CHANGELOG.md +247 -0
  2. package/dist/bootstrap.js +4 -11
  3. package/dist/commands/browser.d.ts +52 -70
  4. package/dist/commands/browser.js +192 -3562
  5. package/dist/commands/daemon.d.ts +39 -2
  6. package/dist/commands/daemon.js +72 -73
  7. package/dist/commands/events.js +1 -1
  8. package/dist/commands/exec.d.ts +18 -0
  9. package/dist/commands/exec.js +104 -12
  10. package/dist/commands/repo.js +13 -49
  11. package/dist/commands/route.js +5 -5
  12. package/dist/commands/routines.js +39 -12
  13. package/dist/commands/sessions-render.d.ts +1 -1
  14. package/dist/commands/sessions-render.js +0 -1
  15. package/dist/commands/sessions.test-fixture.d.ts +0 -1
  16. package/dist/commands/sessions.test-fixture.js +0 -37
  17. package/dist/commands/setup-browser.d.ts +17 -12
  18. package/dist/commands/setup-browser.js +52 -87
  19. package/dist/commands/setup-preferences.d.ts +0 -17
  20. package/dist/commands/setup-preferences.js +18 -49
  21. package/dist/commands/setup-term.d.ts +4 -3
  22. package/dist/commands/setup-term.js +5 -4
  23. package/dist/commands/setup.js +11 -11
  24. package/dist/commands/ssh.js +10 -1
  25. package/dist/commands/sync.js +6 -44
  26. package/dist/commands/teams.js +0 -1
  27. package/dist/commands/update.d.ts +19 -0
  28. package/dist/commands/update.js +34 -6
  29. package/dist/commands/view.d.ts +12 -1
  30. package/dist/commands/view.js +47 -2
  31. package/dist/index.js +107 -26
  32. package/dist/lib/account-capabilities.js +0 -2
  33. package/dist/lib/account-catalog.d.ts +38 -0
  34. package/dist/lib/account-catalog.js +110 -26
  35. package/dist/lib/account-provider-registry.js +1 -1
  36. package/dist/lib/account-registry.d.ts +1 -1
  37. package/dist/lib/account-registry.js +36 -2
  38. package/dist/lib/accounting/rotate.js +22 -8
  39. package/dist/lib/accounting/usage-ingest.d.ts +6 -1
  40. package/dist/lib/accounting/usage-ingest.js +115 -45
  41. package/dist/lib/accounting/usage-sync.d.ts +134 -31
  42. package/dist/lib/accounting/usage-sync.js +227 -66
  43. package/dist/lib/accounting/usage.d.ts +16 -3
  44. package/dist/lib/accounting/usage.js +26 -8
  45. package/dist/lib/accounts/slots.d.ts +8 -0
  46. package/dist/lib/accounts/slots.js +17 -0
  47. package/dist/lib/add-dir.js +0 -1
  48. package/dist/lib/agent-cli-commands.js +0 -1
  49. package/dist/lib/agent-spec/agents.d.ts +6 -7
  50. package/dist/lib/agent-spec/agents.js +6 -60
  51. package/dist/lib/auth-health.d.ts +69 -1
  52. package/dist/lib/auth-health.js +133 -4
  53. package/dist/lib/browser/context.d.ts +82 -0
  54. package/dist/lib/browser/context.js +88 -0
  55. package/dist/lib/browser/paths.d.ts +25 -0
  56. package/dist/lib/browser/paths.js +51 -0
  57. package/dist/lib/browser/record.d.ts +38 -0
  58. package/dist/lib/browser/record.js +57 -0
  59. package/dist/lib/browser/sessions-list.js +1 -2
  60. package/dist/lib/browser-client.d.ts +158 -0
  61. package/dist/lib/browser-client.js +234 -0
  62. package/dist/lib/channels/owner-sink.d.ts +1 -18
  63. package/dist/lib/channels/owner-sink.js +29 -82
  64. package/dist/lib/channels/providers/rush.d.ts +7 -7
  65. package/dist/lib/channels/providers/rush.js +127 -57
  66. package/dist/lib/claude-statusline.d.ts +1 -1
  67. package/dist/lib/claude-statusline.js +15 -3
  68. package/dist/lib/commands.js +1 -1
  69. package/dist/lib/crabbox/lease.js +1 -1
  70. package/dist/lib/crabbox/runtimes.js +1 -3
  71. package/dist/lib/daemon/account-state-daemon-service.js +1 -0
  72. package/dist/lib/daemon/auth-sync-service.d.ts +21 -18
  73. package/dist/lib/daemon/auth-sync-service.js +37 -43
  74. package/dist/lib/daemon/daemon.d.ts +25 -14
  75. package/dist/lib/daemon/daemon.js +92 -154
  76. package/dist/lib/daemon/runner.d.ts +2 -2
  77. package/dist/lib/daemon/runner.js +32 -9
  78. package/dist/lib/daemon/self-update-service.d.ts +35 -34
  79. package/dist/lib/daemon/self-update-service.js +40 -36
  80. package/dist/lib/daemon/service.d.ts +12 -8
  81. package/dist/lib/daemon/supervisor.d.ts +65 -54
  82. package/dist/lib/daemon/supervisor.js +136 -171
  83. package/dist/lib/daemon/testdata/process-view-start.js +5 -2
  84. package/dist/lib/daemon/usage-sync-service.d.ts +21 -30
  85. package/dist/lib/daemon/usage-sync-service.js +46 -78
  86. package/dist/lib/daemon-health.d.ts +22 -5
  87. package/dist/lib/daemon-health.js +47 -3
  88. package/dist/lib/daemon-services.d.ts +1 -1
  89. package/dist/lib/daemon-services.js +0 -10
  90. package/dist/lib/daemon-ticks.js +4 -2
  91. package/dist/lib/devices/doctor-findings.js +8 -11
  92. package/dist/lib/devices/harness-inventory.js +14 -5
  93. package/dist/lib/exec-account-home.js +5 -0
  94. package/dist/lib/exec.js +0 -11
  95. package/dist/lib/feed/events.js +0 -1
  96. package/dist/lib/feed/tool-activity.js +5 -2
  97. package/dist/lib/fleet-shared-state.d.ts +45 -0
  98. package/dist/lib/fleet-shared-state.js +78 -9
  99. package/dist/lib/fs-atomic.js +25 -0
  100. package/dist/lib/harness-auth-capabilities.js +0 -1
  101. package/dist/lib/helper-versions.js +1 -1
  102. package/dist/lib/hooks/cache.d.ts +7 -0
  103. package/dist/lib/hooks/cache.js +27 -2
  104. package/dist/lib/hooks/install.js +7 -1
  105. package/dist/lib/hosts/ready.d.ts +38 -8
  106. package/dist/lib/hosts/ready.js +62 -14
  107. package/dist/lib/hosts/remote-cmd.js +1 -0
  108. package/dist/lib/installations/active-check.d.ts +27 -0
  109. package/dist/lib/installations/active-check.js +61 -0
  110. package/dist/lib/installations/migrate.js +6 -3
  111. package/dist/lib/installations/shims.js +9 -7
  112. package/dist/lib/installations/update.js +21 -15
  113. package/dist/lib/installations/versions.js +12 -1
  114. package/dist/lib/manifest.js +1 -1
  115. package/dist/lib/models.js +0 -2
  116. package/dist/lib/open-url.js +28 -54
  117. package/dist/lib/placement.d.ts +2 -0
  118. package/dist/lib/placement.js +5 -0
  119. package/dist/lib/profiles.js +0 -2
  120. package/dist/lib/refresh.js +1 -1
  121. package/dist/lib/routine-readiness.d.ts +35 -0
  122. package/dist/lib/routine-readiness.js +74 -16
  123. package/dist/lib/rules/compile.js +6 -0
  124. package/dist/lib/sandbox.js +0 -2
  125. package/dist/lib/secrets-policy.d.ts +89 -11
  126. package/dist/lib/secrets-policy.js +175 -28
  127. package/dist/lib/session/db.d.ts +1 -1
  128. package/dist/lib/session/db.js +65 -18
  129. package/dist/lib/session/discover.js +1 -283
  130. package/dist/lib/session/mirror.d.ts +4 -3
  131. package/dist/lib/session/mirror.js +4 -3
  132. package/dist/lib/session/parse.d.ts +0 -2
  133. package/dist/lib/session/parse.js +1 -138
  134. package/dist/lib/session/throughput.d.ts +1 -3
  135. package/dist/lib/session/throughput.js +0 -20
  136. package/dist/lib/session/types.d.ts +2 -2
  137. package/dist/lib/session/types.js +2 -2
  138. package/dist/lib/sessions-client.d.ts +60 -1
  139. package/dist/lib/sessions-client.js +227 -4
  140. package/dist/lib/setup-tool-status.js +8 -12
  141. package/dist/lib/signin-badge.d.ts +3 -2
  142. package/dist/lib/signin-badge.js +6 -3
  143. package/dist/lib/smart-launch.js +4 -1
  144. package/dist/lib/staleness/detectors/commands.d.ts +1 -1
  145. package/dist/lib/staleness/detectors/hooks.d.ts +1 -1
  146. package/dist/lib/staleness/detectors/mcp.d.ts +1 -1
  147. package/dist/lib/staleness/detectors/permissions.d.ts +1 -1
  148. package/dist/lib/staleness/detectors/plugins.d.ts +1 -1
  149. package/dist/lib/staleness/detectors/rules.d.ts +1 -1
  150. package/dist/lib/staleness/detectors/skills.d.ts +1 -1
  151. package/dist/lib/staleness/detectors/subagents.d.ts +1 -1
  152. package/dist/lib/staleness/detectors/workflows.d.ts +1 -1
  153. package/dist/lib/staleness/writers/commands.d.ts +1 -1
  154. package/dist/lib/staleness/writers/hooks.d.ts +1 -1
  155. package/dist/lib/staleness/writers/mcp.d.ts +1 -1
  156. package/dist/lib/staleness/writers/permissions.d.ts +1 -1
  157. package/dist/lib/staleness/writers/plugins.d.ts +1 -1
  158. package/dist/lib/staleness/writers/rules.d.ts +1 -1
  159. package/dist/lib/staleness/writers/skills.d.ts +1 -1
  160. package/dist/lib/staleness/writers/sources.js +5 -0
  161. package/dist/lib/staleness/writers/subagents.d.ts +1 -1
  162. package/dist/lib/staleness/writers/workflows.d.ts +1 -1
  163. package/dist/lib/state.d.ts +6 -4
  164. package/dist/lib/state.js +7 -17
  165. package/dist/lib/teams/parsers.d.ts +1 -1
  166. package/dist/lib/teams/parsers.js +1 -136
  167. package/dist/lib/teams/placement-probe.js +50 -15
  168. package/dist/lib/teams/scheduler.d.ts +7 -0
  169. package/dist/lib/types.d.ts +10 -1
  170. package/dist/lib/types.js +1 -1
  171. package/dist/lib/view-types.d.ts +32 -0
  172. package/dist/lib/watchdog/read.js +0 -1
  173. package/dist/lib/watchdog/rotate.js +1 -2
  174. package/dist/lib/watchdog/runner.js +2 -2
  175. package/dist/lib/watchdog/watchdog.d.ts +1 -1
  176. package/dist/lib/watchdog/watchdogTail.js +0 -31
  177. package/package.json +1 -1
  178. package/scripts/postinstall.js +8 -8
  179. package/dist/browser.d.ts +0 -2
  180. package/dist/browser.js +0 -17
  181. package/dist/commands/browser-picker.d.ts +0 -18
  182. package/dist/commands/browser-picker.js +0 -97
  183. package/dist/lib/browser/arc-discovery.d.ts +0 -52
  184. package/dist/lib/browser/arc-discovery.js +0 -197
  185. package/dist/lib/browser/arc-dom.d.ts +0 -14
  186. package/dist/lib/browser/arc-dom.js +0 -121
  187. package/dist/lib/browser/caller-identity.d.ts +0 -40
  188. package/dist/lib/browser/caller-identity.js +0 -175
  189. package/dist/lib/browser/cdp.d.ts +0 -51
  190. package/dist/lib/browser/cdp.js +0 -254
  191. package/dist/lib/browser/chrome.d.ts +0 -141
  192. package/dist/lib/browser/chrome.js +0 -704
  193. package/dist/lib/browser/chromium-discovery.d.ts +0 -28
  194. package/dist/lib/browser/chromium-discovery.js +0 -96
  195. package/dist/lib/browser/devices.d.ts +0 -34
  196. package/dist/lib/browser/devices.js +0 -61
  197. package/dist/lib/browser/domain-skills.d.ts +0 -71
  198. package/dist/lib/browser/domain-skills.js +0 -195
  199. package/dist/lib/browser/drivers/arc.d.ts +0 -40
  200. package/dist/lib/browser/drivers/arc.js +0 -276
  201. package/dist/lib/browser/drivers/firefox.d.ts +0 -99
  202. package/dist/lib/browser/drivers/firefox.js +0 -377
  203. package/dist/lib/browser/drivers/local.d.ts +0 -55
  204. package/dist/lib/browser/drivers/local.js +0 -266
  205. package/dist/lib/browser/drivers/ssh.d.ts +0 -120
  206. package/dist/lib/browser/drivers/ssh.js +0 -467
  207. package/dist/lib/browser/editor.d.ts +0 -3
  208. package/dist/lib/browser/editor.js +0 -50
  209. package/dist/lib/browser/ffmpeg.d.ts +0 -12
  210. package/dist/lib/browser/ffmpeg.js +0 -184
  211. package/dist/lib/browser/firefox-discovery.d.ts +0 -69
  212. package/dist/lib/browser/firefox-discovery.js +0 -162
  213. package/dist/lib/browser/har.d.ts +0 -85
  214. package/dist/lib/browser/har.js +0 -77
  215. package/dist/lib/browser/hygiene.d.ts +0 -97
  216. package/dist/lib/browser/hygiene.js +0 -153
  217. package/dist/lib/browser/index.d.ts +0 -5
  218. package/dist/lib/browser/index.js +0 -5
  219. package/dist/lib/browser/input.d.ts +0 -7
  220. package/dist/lib/browser/input.js +0 -92
  221. package/dist/lib/browser/ipc.d.ts +0 -204
  222. package/dist/lib/browser/ipc.js +0 -1453
  223. package/dist/lib/browser/login-detection.d.ts +0 -87
  224. package/dist/lib/browser/login-detection.js +0 -274
  225. package/dist/lib/browser/profiles.d.ts +0 -422
  226. package/dist/lib/browser/profiles.js +0 -1157
  227. package/dist/lib/browser/refs.d.ts +0 -89
  228. package/dist/lib/browser/refs.js +0 -191
  229. package/dist/lib/browser/registry.d.ts +0 -70
  230. package/dist/lib/browser/registry.js +0 -252
  231. package/dist/lib/browser/remote-control.d.ts +0 -59
  232. package/dist/lib/browser/remote-control.js +0 -85
  233. package/dist/lib/browser/resolve-target.d.ts +0 -66
  234. package/dist/lib/browser/resolve-target.js +0 -264
  235. package/dist/lib/browser/runtime-state.d.ts +0 -291
  236. package/dist/lib/browser/runtime-state.js +0 -584
  237. package/dist/lib/browser/secret-ref.d.ts +0 -10
  238. package/dist/lib/browser/secret-ref.js +0 -14
  239. package/dist/lib/browser/service.d.ts +0 -812
  240. package/dist/lib/browser/service.js +0 -4693
  241. package/dist/lib/browser/stream.d.ts +0 -17
  242. package/dist/lib/browser/stream.js +0 -72
  243. package/dist/lib/browser/task-index.d.ts +0 -78
  244. package/dist/lib/browser/task-index.js +0 -199
  245. package/dist/lib/browser/types.d.ts +0 -647
  246. package/dist/lib/browser/types.js +0 -61
  247. package/dist/lib/browser/upload.d.ts +0 -29
  248. package/dist/lib/browser/upload.js +0 -298
  249. package/dist/lib/daemon/browser-ipc-service.d.ts +0 -20
  250. package/dist/lib/daemon/browser-ipc-service.js +0 -46
  251. package/dist/lib/daemon/browser-task-reap-service.d.ts +0 -14
  252. package/dist/lib/daemon/browser-task-reap-service.js +0 -26
  253. package/dist/lib/fleet-shared-repo-sync.d.ts +0 -55
  254. 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 {};