@elizaos/plugin-browser 2.0.0-alpha.9 → 2.0.11-beta.7

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 (256) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +98 -83
  3. package/auto-enable.ts +24 -0
  4. package/dist/actions/browser-autofill-login.d.ts +43 -0
  5. package/dist/actions/browser-autofill-login.d.ts.map +1 -0
  6. package/dist/actions/browser-autofill-login.js +278 -0
  7. package/dist/actions/browser-autofill-login.js.map +1 -0
  8. package/dist/actions/browser.d.ts +11 -0
  9. package/dist/actions/browser.d.ts.map +1 -0
  10. package/dist/actions/browser.js +412 -0
  11. package/dist/actions/browser.js.map +1 -0
  12. package/dist/actions/manage-browser-bridge.d.ts +34 -0
  13. package/dist/actions/manage-browser-bridge.d.ts.map +1 -0
  14. package/dist/actions/manage-browser-bridge.js +572 -0
  15. package/dist/actions/manage-browser-bridge.js.map +1 -0
  16. package/dist/bridge-policy.d.ts +10 -0
  17. package/dist/bridge-policy.d.ts.map +1 -0
  18. package/dist/bridge-policy.js +37 -0
  19. package/dist/bridge-policy.js.map +1 -0
  20. package/dist/bridge-readiness.d.ts +16 -0
  21. package/dist/bridge-readiness.d.ts.map +1 -0
  22. package/dist/bridge-readiness.js +82 -0
  23. package/dist/bridge-readiness.js.map +1 -0
  24. package/dist/bridge-records.d.ts +9 -0
  25. package/dist/bridge-records.d.ts.map +1 -0
  26. package/dist/bridge-records.js +37 -0
  27. package/dist/bridge-records.js.map +1 -0
  28. package/dist/browser-capture-hooks.d.ts +9 -0
  29. package/dist/browser-capture-hooks.d.ts.map +1 -0
  30. package/dist/browser-capture-hooks.js +15 -0
  31. package/dist/browser-capture-hooks.js.map +1 -0
  32. package/dist/browser-service.d.ts +103 -0
  33. package/dist/browser-service.d.ts.map +1 -0
  34. package/dist/browser-service.js +186 -0
  35. package/dist/browser-service.js.map +1 -0
  36. package/dist/browser-workspace-hooks.d.ts +14 -0
  37. package/dist/browser-workspace-hooks.d.ts.map +1 -0
  38. package/dist/browser-workspace-hooks.js +15 -0
  39. package/dist/browser-workspace-hooks.js.map +1 -0
  40. package/dist/companion-auth.d.ts +34 -0
  41. package/dist/companion-auth.d.ts.map +1 -0
  42. package/dist/companion-auth.js +98 -0
  43. package/dist/companion-auth.js.map +1 -0
  44. package/dist/contracts.d.ts +284 -0
  45. package/dist/contracts.d.ts.map +1 -0
  46. package/dist/contracts.js +56 -0
  47. package/dist/contracts.js.map +1 -0
  48. package/dist/index.d.ts +30 -16
  49. package/dist/index.d.ts.map +1 -1
  50. package/dist/index.js +76 -90
  51. package/dist/index.js.map +1 -1
  52. package/dist/lifeops-session-contracts.d.ts +46 -0
  53. package/dist/lifeops-session-contracts.d.ts.map +1 -0
  54. package/dist/lifeops-session-contracts.js +1 -0
  55. package/dist/lifeops-session-contracts.js.map +1 -0
  56. package/dist/message-adapter.d.ts +9 -0
  57. package/dist/message-adapter.d.ts.map +1 -0
  58. package/dist/message-adapter.js +104 -0
  59. package/dist/message-adapter.js.map +1 -0
  60. package/dist/packaging.d.ts +27 -0
  61. package/dist/packaging.d.ts.map +1 -0
  62. package/dist/packaging.js +571 -0
  63. package/dist/packaging.js.map +1 -0
  64. package/dist/password-manager-bridge.d.ts +50 -0
  65. package/dist/password-manager-bridge.d.ts.map +1 -0
  66. package/dist/password-manager-bridge.js +437 -0
  67. package/dist/password-manager-bridge.js.map +1 -0
  68. package/dist/plugin.d.ts +10 -0
  69. package/dist/plugin.d.ts.map +1 -0
  70. package/dist/plugin.js +168 -0
  71. package/dist/plugin.js.map +1 -0
  72. package/dist/providers/workspace.d.ts +13 -0
  73. package/dist/providers/workspace.d.ts.map +1 -0
  74. package/dist/providers/workspace.js +64 -0
  75. package/dist/providers/workspace.js.map +1 -0
  76. package/dist/routes/bridge.d.ts +37 -0
  77. package/dist/routes/bridge.d.ts.map +1 -0
  78. package/dist/routes/bridge.js +844 -0
  79. package/dist/routes/bridge.js.map +1 -0
  80. package/dist/routes/workspace-account-gate.d.ts +29 -0
  81. package/dist/routes/workspace-account-gate.d.ts.map +1 -0
  82. package/dist/routes/workspace-account-gate.js +147 -0
  83. package/dist/routes/workspace-account-gate.js.map +1 -0
  84. package/dist/routes/workspace-setup.d.ts +10 -0
  85. package/dist/routes/workspace-setup.d.ts.map +1 -0
  86. package/dist/routes/workspace-setup.js +65 -0
  87. package/dist/routes/workspace-setup.js.map +1 -0
  88. package/dist/routes/workspace.d.ts +20 -0
  89. package/dist/routes/workspace.d.ts.map +1 -0
  90. package/dist/routes/workspace.js +276 -0
  91. package/dist/routes/workspace.js.map +1 -0
  92. package/dist/schema.d.ts +2326 -0
  93. package/dist/schema.d.ts.map +1 -0
  94. package/dist/schema.js +133 -0
  95. package/dist/schema.js.map +1 -0
  96. package/dist/service.d.ts +30 -0
  97. package/dist/service.d.ts.map +1 -0
  98. package/dist/service.js +5 -0
  99. package/dist/service.js.map +1 -0
  100. package/dist/targets/bridge-target.d.ts +31 -0
  101. package/dist/targets/bridge-target.d.ts.map +1 -0
  102. package/dist/targets/bridge-target.js +98 -0
  103. package/dist/targets/bridge-target.js.map +1 -0
  104. package/dist/targets/stagehand-target.d.ts +3 -0
  105. package/dist/targets/stagehand-target.d.ts.map +1 -0
  106. package/dist/targets/stagehand-target.js +187 -0
  107. package/dist/targets/stagehand-target.js.map +1 -0
  108. package/dist/workspace/browser-capture.d.ts +41 -0
  109. package/dist/workspace/browser-capture.d.ts.map +1 -0
  110. package/dist/workspace/browser-capture.js +159 -0
  111. package/dist/workspace/browser-capture.js.map +1 -0
  112. package/dist/workspace/browser-workspace-desktop.d.ts +19 -0
  113. package/dist/workspace/browser-workspace-desktop.d.ts.map +1 -0
  114. package/dist/workspace/browser-workspace-desktop.js +1578 -0
  115. package/dist/workspace/browser-workspace-desktop.js.map +1 -0
  116. package/dist/workspace/browser-workspace-elements.d.ts +42 -0
  117. package/dist/workspace/browser-workspace-elements.d.ts.map +1 -0
  118. package/dist/workspace/browser-workspace-elements.js +547 -0
  119. package/dist/workspace/browser-workspace-elements.js.map +1 -0
  120. package/dist/workspace/browser-workspace-forms.d.ts +19 -0
  121. package/dist/workspace/browser-workspace-forms.d.ts.map +1 -0
  122. package/dist/workspace/browser-workspace-forms.js +277 -0
  123. package/dist/workspace/browser-workspace-forms.js.map +1 -0
  124. package/dist/workspace/browser-workspace-helpers.d.ts +32 -0
  125. package/dist/workspace/browser-workspace-helpers.d.ts.map +1 -0
  126. package/dist/workspace/browser-workspace-helpers.js +232 -0
  127. package/dist/workspace/browser-workspace-helpers.js.map +1 -0
  128. package/dist/workspace/browser-workspace-jsdom.d.ts +16 -0
  129. package/dist/workspace/browser-workspace-jsdom.d.ts.map +1 -0
  130. package/dist/workspace/browser-workspace-jsdom.js +233 -0
  131. package/dist/workspace/browser-workspace-jsdom.js.map +1 -0
  132. package/dist/workspace/browser-workspace-network.d.ts +7 -0
  133. package/dist/workspace/browser-workspace-network.d.ts.map +1 -0
  134. package/dist/workspace/browser-workspace-network.js +145 -0
  135. package/dist/workspace/browser-workspace-network.js.map +1 -0
  136. package/dist/workspace/browser-workspace-snapshots.d.ts +14 -0
  137. package/dist/workspace/browser-workspace-snapshots.d.ts.map +1 -0
  138. package/dist/workspace/browser-workspace-snapshots.js +144 -0
  139. package/dist/workspace/browser-workspace-snapshots.js.map +1 -0
  140. package/dist/workspace/browser-workspace-state.d.ts +24 -0
  141. package/dist/workspace/browser-workspace-state.d.ts.map +1 -0
  142. package/dist/workspace/browser-workspace-state.js +155 -0
  143. package/dist/workspace/browser-workspace-state.js.map +1 -0
  144. package/dist/workspace/browser-workspace-types.d.ts +345 -0
  145. package/dist/workspace/browser-workspace-types.d.ts.map +1 -0
  146. package/dist/workspace/browser-workspace-types.js +11 -0
  147. package/dist/workspace/browser-workspace-types.js.map +1 -0
  148. package/dist/workspace/browser-workspace-web.d.ts +8 -0
  149. package/dist/workspace/browser-workspace-web.d.ts.map +1 -0
  150. package/dist/workspace/browser-workspace-web.js +1342 -0
  151. package/dist/workspace/browser-workspace-web.js.map +1 -0
  152. package/dist/workspace/browser-workspace.d.ts +39 -0
  153. package/dist/workspace/browser-workspace.d.ts.map +1 -0
  154. package/dist/workspace/browser-workspace.js +958 -0
  155. package/dist/workspace/browser-workspace.js.map +1 -0
  156. package/dist/workspace/index.d.ts +26 -0
  157. package/dist/workspace/index.d.ts.map +1 -0
  158. package/dist/workspace/index.js +3 -0
  159. package/dist/workspace/index.js.map +1 -0
  160. package/dist/workspace.d.ts +2 -0
  161. package/dist/workspace.d.ts.map +1 -0
  162. package/dist/workspace.js +2 -0
  163. package/dist/workspace.js.map +1 -0
  164. package/package.json +71 -110
  165. package/dist/actions/click.d.ts +0 -3
  166. package/dist/actions/click.d.ts.map +0 -1
  167. package/dist/actions/click.js +0 -158
  168. package/dist/actions/click.js.map +0 -1
  169. package/dist/actions/extract.d.ts +0 -3
  170. package/dist/actions/extract.d.ts.map +0 -1
  171. package/dist/actions/extract.js +0 -168
  172. package/dist/actions/extract.js.map +0 -1
  173. package/dist/actions/index.d.ts +0 -7
  174. package/dist/actions/index.d.ts.map +0 -1
  175. package/dist/actions/index.js +0 -7
  176. package/dist/actions/index.js.map +0 -1
  177. package/dist/actions/navigate.d.ts +0 -3
  178. package/dist/actions/navigate.d.ts.map +0 -1
  179. package/dist/actions/navigate.js +0 -187
  180. package/dist/actions/navigate.js.map +0 -1
  181. package/dist/actions/screenshot.d.ts +0 -3
  182. package/dist/actions/screenshot.d.ts.map +0 -1
  183. package/dist/actions/screenshot.js +0 -167
  184. package/dist/actions/screenshot.js.map +0 -1
  185. package/dist/actions/select.d.ts +0 -3
  186. package/dist/actions/select.d.ts.map +0 -1
  187. package/dist/actions/select.js +0 -167
  188. package/dist/actions/select.js.map +0 -1
  189. package/dist/actions/type.d.ts +0 -3
  190. package/dist/actions/type.d.ts.map +0 -1
  191. package/dist/actions/type.js +0 -167
  192. package/dist/actions/type.js.map +0 -1
  193. package/dist/cli/index.d.ts +0 -8
  194. package/dist/cli/index.d.ts.map +0 -1
  195. package/dist/cli/index.js +0 -13
  196. package/dist/cli/index.js.map +0 -1
  197. package/dist/cli/register.d.ts +0 -20
  198. package/dist/cli/register.d.ts.map +0 -1
  199. package/dist/cli/register.js +0 -403
  200. package/dist/cli/register.js.map +0 -1
  201. package/dist/providerRelevance.d.ts +0 -4
  202. package/dist/providerRelevance.d.ts.map +0 -1
  203. package/dist/providerRelevance.js +0 -33
  204. package/dist/providerRelevance.js.map +0 -1
  205. package/dist/providers/browser-state.d.ts +0 -3
  206. package/dist/providers/browser-state.d.ts.map +0 -1
  207. package/dist/providers/browser-state.js +0 -72
  208. package/dist/providers/browser-state.js.map +0 -1
  209. package/dist/providers/index.d.ts +0 -2
  210. package/dist/providers/index.d.ts.map +0 -1
  211. package/dist/providers/index.js +0 -2
  212. package/dist/providers/index.js.map +0 -1
  213. package/dist/services/browser-service.d.ts +0 -32
  214. package/dist/services/browser-service.d.ts.map +0 -1
  215. package/dist/services/browser-service.js +0 -213
  216. package/dist/services/browser-service.js.map +0 -1
  217. package/dist/services/index.d.ts +0 -4
  218. package/dist/services/index.d.ts.map +0 -1
  219. package/dist/services/index.js +0 -4
  220. package/dist/services/index.js.map +0 -1
  221. package/dist/services/process-manager.d.ts +0 -24
  222. package/dist/services/process-manager.d.ts.map +0 -1
  223. package/dist/services/process-manager.js +0 -270
  224. package/dist/services/process-manager.js.map +0 -1
  225. package/dist/services/websocket-client.d.ts +0 -35
  226. package/dist/services/websocket-client.d.ts.map +0 -1
  227. package/dist/services/websocket-client.js +0 -221
  228. package/dist/services/websocket-client.js.map +0 -1
  229. package/dist/types.d.ts +0 -101
  230. package/dist/types.d.ts.map +0 -1
  231. package/dist/types.js +0 -2
  232. package/dist/types.js.map +0 -1
  233. package/dist/utils/captcha.d.ts +0 -33
  234. package/dist/utils/captcha.d.ts.map +0 -1
  235. package/dist/utils/captcha.js +0 -219
  236. package/dist/utils/captcha.js.map +0 -1
  237. package/dist/utils/errors.d.ts +0 -37
  238. package/dist/utils/errors.d.ts.map +0 -1
  239. package/dist/utils/errors.js +0 -81
  240. package/dist/utils/errors.js.map +0 -1
  241. package/dist/utils/index.d.ts +0 -5
  242. package/dist/utils/index.d.ts.map +0 -1
  243. package/dist/utils/index.js +0 -5
  244. package/dist/utils/index.js.map +0 -1
  245. package/dist/utils/retry.d.ts +0 -26
  246. package/dist/utils/retry.d.ts.map +0 -1
  247. package/dist/utils/retry.js +0 -55
  248. package/dist/utils/retry.js.map +0 -1
  249. package/dist/utils/security.d.ts +0 -27
  250. package/dist/utils/security.d.ts.map +0 -1
  251. package/dist/utils/security.js +0 -139
  252. package/dist/utils/security.js.map +0 -1
  253. package/dist/utils/url.d.ts +0 -12
  254. package/dist/utils/url.d.ts.map +0 -1
  255. package/dist/utils/url.js +0 -39
  256. package/dist/utils/url.js.map +0 -1
@@ -0,0 +1,958 @@
1
+ import * as fsp from "node:fs/promises";
2
+ import * as path from "node:path";
3
+ import { BROWSER_WORKSPACE_CONNECTOR_AUTH_STATES } from "./browser-workspace-types.js";
4
+ import { __resetBrowserWorkspaceStateForTests } from "./browser-workspace-state.js";
5
+ import {
6
+ evaluateBrowserWorkspaceTab as evaluateBrowserWorkspaceTabDesktop,
7
+ executeDesktopBrowserWorkspaceDomCommand,
8
+ executeDesktopBrowserWorkspaceUtilityCommand,
9
+ getBrowserWorkspaceUnavailableMessage,
10
+ getDesktopBrowserWorkspaceSessionState,
11
+ getDesktopBrowserWorkspaceSnapshotRecord,
12
+ isBrowserWorkspaceBridgeConfigured,
13
+ loadDesktopBrowserWorkspaceSessionState,
14
+ requestBrowserWorkspace,
15
+ resolveBrowserWorkspaceBridgeConfig,
16
+ resolveDesktopBrowserWorkspaceTargetTabId,
17
+ snapshotBrowserWorkspaceTab as snapshotBrowserWorkspaceTabDesktop
18
+ } from "./browser-workspace-desktop.js";
19
+ import {
20
+ assertBrowserWorkspaceConnectorSecretsNotExported,
21
+ assertBrowserWorkspaceUrl,
22
+ assertBrowserWorkspaceUserScriptAllowed,
23
+ createBrowserWorkspaceNotFoundError,
24
+ DEFAULT_WEB_PARTITION,
25
+ inferBrowserWorkspaceTitle,
26
+ normalizeBrowserWorkspaceCommand,
27
+ resolveBrowserWorkspaceCommandPartition,
28
+ resolveConnectorBrowserWorkspacePartition,
29
+ sleep,
30
+ writeBrowserWorkspaceFile
31
+ } from "./browser-workspace-helpers.js";
32
+ import {
33
+ clearWebBrowserWorkspaceTabElementRefs,
34
+ cloneWebBrowserWorkspaceTabState,
35
+ loadWebBrowserWorkspaceTabDocument,
36
+ pushWebBrowserWorkspaceHistory
37
+ } from "./browser-workspace-forms.js";
38
+ import { browserWorkspacePageFetch } from "./browser-workspace-helpers.js";
39
+ import {
40
+ createEmptyWebBrowserWorkspaceDom,
41
+ installBrowserWorkspaceWebRuntime
42
+ } from "./browser-workspace-jsdom.js";
43
+ import {
44
+ createBrowserWorkspacePdfBuffer,
45
+ createBrowserWorkspaceSnapshotRecord,
46
+ diffBrowserWorkspaceSnapshots
47
+ } from "./browser-workspace-snapshots.js";
48
+ import {
49
+ clearBrowserWorkspaceElementRefs,
50
+ clearBrowserWorkspaceRuntimeState,
51
+ getBrowserWorkspaceRuntimeState,
52
+ getBrowserWorkspaceTimestamp,
53
+ resetBrowserWorkspaceRuntimeNavigationState,
54
+ webWorkspaceState,
55
+ withWebStateLock
56
+ } from "./browser-workspace-state.js";
57
+ import {
58
+ executeWebBrowserWorkspaceDomCommand,
59
+ executeWebBrowserWorkspaceUtilityCommand,
60
+ findWebBrowserWorkspaceTargetTabId,
61
+ getWebBrowserWorkspaceTabIndex,
62
+ getWebBrowserWorkspaceTabState
63
+ } from "./browser-workspace-web.js";
64
+ const AGENT_BROWSER_WORKSPACE_PARTITION = "persist:eliza-browser-agent";
65
+ const CONNECTOR_MANUAL_STATES = /* @__PURE__ */ new Set([
66
+ "auth_pending",
67
+ "needs_reauth",
68
+ "manual_handoff"
69
+ ]);
70
+ function getBrowserWorkspaceMode(env = process.env) {
71
+ return isBrowserWorkspaceBridgeConfigured(env) ? "desktop" : "web";
72
+ }
73
+ function resolveBrowserWorkspaceConnectorPartition(provider, accountId) {
74
+ return resolveConnectorBrowserWorkspacePartition(provider, accountId);
75
+ }
76
+ function normalizeConnectorAuthState(value, fallback) {
77
+ switch (value) {
78
+ case "unknown":
79
+ case "ready":
80
+ case "auth_pending":
81
+ case "needs_reauth":
82
+ case "manual_handoff":
83
+ return value;
84
+ default:
85
+ return fallback;
86
+ }
87
+ }
88
+ function connectorSessionRequiresManualHandoff(state) {
89
+ return CONNECTOR_MANUAL_STATES.has(state);
90
+ }
91
+ function createConnectorSessionRef(ref) {
92
+ return {
93
+ kind: ref.kind,
94
+ handleId: ref.handleId,
95
+ partition: ref.partition,
96
+ tabId: ref.tabId,
97
+ browser: ref.browser,
98
+ companionId: ref.companionId,
99
+ profileId: ref.profileId,
100
+ profileLabel: ref.profileLabel
101
+ };
102
+ }
103
+ function createConnectorSessionHandle(args) {
104
+ const sessionRef = createConnectorSessionRef(args.ref);
105
+ return {
106
+ provider: args.provider,
107
+ accountId: args.accountId,
108
+ authState: args.authState,
109
+ requiresManualHandoff: connectorSessionRequiresManualHandoff(
110
+ args.authState
111
+ ),
112
+ sessionRef,
113
+ partition: sessionRef.partition,
114
+ tabId: sessionRef.tabId,
115
+ companionId: sessionRef.companionId,
116
+ browser: sessionRef.browser,
117
+ profileId: sessionRef.profileId,
118
+ profileLabel: sessionRef.profileLabel,
119
+ created: args.created,
120
+ message: args.message ?? null
121
+ };
122
+ }
123
+ function createBrowserBridgeConnectorSessionHandle(args) {
124
+ const browser = args.companion.browser?.trim() || null;
125
+ const companionId = args.companion.companionId?.trim() || null;
126
+ const profileId = args.companion.profileId?.trim() || null;
127
+ const profileLabel = args.companion.profileLabel?.trim() || null;
128
+ return createConnectorSessionHandle({
129
+ provider: args.provider,
130
+ accountId: args.accountId,
131
+ authState: args.authState,
132
+ created: false,
133
+ message: args.message,
134
+ ref: {
135
+ kind: "browser-bridge-companion",
136
+ handleId: [
137
+ "browser-bridge",
138
+ browser ?? "browser",
139
+ companionId ?? profileId ?? "profile",
140
+ args.provider,
141
+ args.accountId
142
+ ].join(":"),
143
+ partition: null,
144
+ tabId: null,
145
+ browser,
146
+ companionId,
147
+ profileId,
148
+ profileLabel
149
+ }
150
+ });
151
+ }
152
+ async function assertDesktopBrowserWorkspaceCanAccessProfileSecrets(command, env, operation) {
153
+ const id = await resolveDesktopBrowserWorkspaceTargetTabId(command, env);
154
+ const tabs = await listBrowserWorkspaceTabs(env);
155
+ const tab = tabs.find((entry) => entry.id === id) ?? null;
156
+ assertBrowserWorkspaceConnectorSecretsNotExported(tab?.partition, operation);
157
+ }
158
+ async function acquireBrowserWorkspaceConnectorSession(request, env = process.env) {
159
+ const provider = request.provider.trim();
160
+ const accountId = request.accountId.trim();
161
+ if (!provider) {
162
+ throw new Error("Eliza browser connector session requires provider.");
163
+ }
164
+ if (!accountId) {
165
+ throw new Error("Eliza browser connector session requires accountId.");
166
+ }
167
+ const companion = request.companion ?? null;
168
+ if (companion?.profileId || companion?.companionId) {
169
+ const authState2 = normalizeConnectorAuthState(
170
+ request.authState,
171
+ "manual_handoff"
172
+ );
173
+ return createBrowserBridgeConnectorSessionHandle({
174
+ provider,
175
+ accountId,
176
+ companion,
177
+ authState: authState2,
178
+ message: request.manualHandoffReason ?? "Use the paired browser companion profile to finish login, MFA, or CAPTCHA if required."
179
+ });
180
+ }
181
+ if (isBrowserWorkspaceBridgeConfigured(env)) {
182
+ const payload = await requestBrowserWorkspace(
183
+ "/sessions/acquire",
184
+ {
185
+ method: "POST",
186
+ body: JSON.stringify({
187
+ accountId,
188
+ authState: request.authState,
189
+ manualHandoffReason: request.manualHandoffReason,
190
+ provider,
191
+ reuse: request.reuse,
192
+ show: request.show,
193
+ title: request.title,
194
+ url: request.url
195
+ })
196
+ },
197
+ env
198
+ );
199
+ return payload.session;
200
+ }
201
+ const partition = resolveBrowserWorkspaceConnectorPartition(
202
+ provider,
203
+ accountId
204
+ );
205
+ const reuse = request.reuse !== false;
206
+ const tabs = reuse ? await listBrowserWorkspaceTabs(env) : [];
207
+ const existing = tabs.find((tab2) => tab2.partition === partition) ?? null;
208
+ let tab = existing;
209
+ let created = false;
210
+ if (!tab) {
211
+ tab = await openBrowserWorkspaceTab(
212
+ {
213
+ kind: "internal",
214
+ partition,
215
+ show: request.show ?? true,
216
+ title: request.title,
217
+ url: request.url
218
+ },
219
+ env
220
+ );
221
+ created = true;
222
+ } else if (request.show === true) {
223
+ tab = await showBrowserWorkspaceTab(tab.id, env);
224
+ }
225
+ const authState = normalizeConnectorAuthState(
226
+ request.authState,
227
+ created ? "auth_pending" : "ready"
228
+ );
229
+ return createConnectorSessionHandle({
230
+ provider,
231
+ accountId,
232
+ authState,
233
+ created,
234
+ message: request.manualHandoffReason ?? (connectorSessionRequiresManualHandoff(authState) ? "Manual login, MFA, or CAPTCHA may be required in this isolated connector browser session." : null),
235
+ ref: {
236
+ kind: "internal-browser",
237
+ handleId: `internal-browser:${partition}`,
238
+ partition,
239
+ tabId: tab.id,
240
+ browser: null,
241
+ companionId: null,
242
+ profileId: null,
243
+ profileLabel: null
244
+ }
245
+ });
246
+ }
247
+ async function getBrowserWorkspaceSnapshot(env = process.env) {
248
+ return {
249
+ mode: getBrowserWorkspaceMode(env),
250
+ tabs: await listBrowserWorkspaceTabs(env)
251
+ };
252
+ }
253
+ async function listBrowserWorkspaceTabs(env = process.env) {
254
+ if (!isBrowserWorkspaceBridgeConfigured(env)) {
255
+ return webWorkspaceState.tabs.map((tab) => ({
256
+ id: tab.id,
257
+ title: tab.title,
258
+ url: tab.url,
259
+ partition: tab.partition,
260
+ kind: tab.kind,
261
+ visible: tab.visible,
262
+ createdAt: tab.createdAt,
263
+ updatedAt: tab.updatedAt,
264
+ lastFocusedAt: tab.lastFocusedAt
265
+ }));
266
+ }
267
+ const payload = await requestBrowserWorkspace("/tabs", void 0, env);
268
+ return Array.isArray(payload.tabs) ? payload.tabs : [];
269
+ }
270
+ async function openBrowserWorkspaceTab(request, env = process.env) {
271
+ if (!isBrowserWorkspaceBridgeConfigured(env)) {
272
+ return withWebStateLock(() => {
273
+ const kind = request.kind === "internal" ? "internal" : "standard";
274
+ const now = getBrowserWorkspaceTimestamp();
275
+ const url = assertBrowserWorkspaceUrl(
276
+ request.url?.trim() || "about:blank"
277
+ );
278
+ const visible = request.show === true;
279
+ const id = `btab_${webWorkspaceState.nextId++}`;
280
+ const dom = url === "about:blank" ? createEmptyWebBrowserWorkspaceDom(url) : null;
281
+ const tab = {
282
+ id,
283
+ title: request.title?.trim() || inferBrowserWorkspaceTitle(url),
284
+ url,
285
+ partition: request.partition?.trim() || DEFAULT_WEB_PARTITION,
286
+ kind,
287
+ visible,
288
+ createdAt: now,
289
+ updatedAt: now,
290
+ lastFocusedAt: visible ? now : null,
291
+ dom,
292
+ history: [url],
293
+ historyIndex: 0,
294
+ loadedUrl: url === "about:blank" ? url : null
295
+ };
296
+ if (dom) {
297
+ installBrowserWorkspaceWebRuntime(tab, dom);
298
+ }
299
+ getBrowserWorkspaceRuntimeState("web", tab.id);
300
+ clearWebBrowserWorkspaceTabElementRefs(tab.id);
301
+ if (tab.visible) {
302
+ webWorkspaceState.tabs = webWorkspaceState.tabs.map((entry) => ({
303
+ ...entry,
304
+ visible: false
305
+ }));
306
+ }
307
+ webWorkspaceState.tabs = [...webWorkspaceState.tabs, tab];
308
+ return cloneWebBrowserWorkspaceTabState(tab);
309
+ });
310
+ }
311
+ const payload = await requestBrowserWorkspace(
312
+ "/tabs",
313
+ {
314
+ method: "POST",
315
+ body: JSON.stringify(request)
316
+ },
317
+ env
318
+ );
319
+ return payload.tab;
320
+ }
321
+ async function navigateBrowserWorkspaceTab(request, env = process.env) {
322
+ const nextUrl = assertBrowserWorkspaceUrl(request.url);
323
+ if (!isBrowserWorkspaceBridgeConfigured(env)) {
324
+ return withWebStateLock(() => {
325
+ const index = getWebBrowserWorkspaceTabIndex(request.id);
326
+ if (index < 0) {
327
+ throw createBrowserWorkspaceNotFoundError(request.id);
328
+ }
329
+ const existing = webWorkspaceState.tabs[index];
330
+ const updatedAt = getBrowserWorkspaceTimestamp();
331
+ const state = getBrowserWorkspaceRuntimeState("web", existing.id);
332
+ clearWebBrowserWorkspaceTabElementRefs(existing.id);
333
+ pushWebBrowserWorkspaceHistory(existing, nextUrl);
334
+ const nextDom = nextUrl === "about:blank" ? createEmptyWebBrowserWorkspaceDom(nextUrl) : null;
335
+ const nextTab = {
336
+ ...existing,
337
+ title: inferBrowserWorkspaceTitle(nextUrl),
338
+ url: nextUrl,
339
+ updatedAt,
340
+ dom: nextDom,
341
+ loadedUrl: nextUrl === "about:blank" ? nextUrl : null
342
+ };
343
+ if (nextDom) {
344
+ installBrowserWorkspaceWebRuntime(nextTab, nextDom);
345
+ }
346
+ resetBrowserWorkspaceRuntimeNavigationState(state);
347
+ webWorkspaceState.tabs[index] = nextTab;
348
+ return cloneWebBrowserWorkspaceTabState(nextTab);
349
+ });
350
+ }
351
+ const navigateBody = { url: nextUrl };
352
+ if (request.partition !== void 0) {
353
+ navigateBody.partition = request.partition;
354
+ }
355
+ const payload = await requestBrowserWorkspace(
356
+ `/tabs/${encodeURIComponent(request.id)}/navigate`,
357
+ {
358
+ method: "POST",
359
+ body: JSON.stringify(navigateBody)
360
+ },
361
+ env
362
+ );
363
+ return payload.tab;
364
+ }
365
+ async function showBrowserWorkspaceTab(id, env = process.env) {
366
+ if (!isBrowserWorkspaceBridgeConfigured(env)) {
367
+ return withWebStateLock(() => {
368
+ getWebBrowserWorkspaceTabState(id);
369
+ const lastFocusedAt = getBrowserWorkspaceTimestamp();
370
+ webWorkspaceState.tabs = webWorkspaceState.tabs.map((tab) => ({
371
+ ...tab,
372
+ visible: tab.id === id,
373
+ lastFocusedAt: tab.id === id ? lastFocusedAt : tab.lastFocusedAt,
374
+ updatedAt: tab.id === id ? lastFocusedAt : tab.updatedAt
375
+ }));
376
+ return cloneWebBrowserWorkspaceTabState(
377
+ getWebBrowserWorkspaceTabState(id)
378
+ );
379
+ });
380
+ }
381
+ const payload = await requestBrowserWorkspace(
382
+ `/tabs/${encodeURIComponent(id)}/show`,
383
+ { method: "POST" },
384
+ env
385
+ );
386
+ return payload.tab;
387
+ }
388
+ async function hideBrowserWorkspaceTab(id, env = process.env) {
389
+ if (!isBrowserWorkspaceBridgeConfigured(env)) {
390
+ return withWebStateLock(() => {
391
+ const index = getWebBrowserWorkspaceTabIndex(id);
392
+ if (index < 0) {
393
+ throw createBrowserWorkspaceNotFoundError(id);
394
+ }
395
+ const updatedAt = getBrowserWorkspaceTimestamp();
396
+ const nextTab = {
397
+ ...webWorkspaceState.tabs[index],
398
+ visible: false,
399
+ updatedAt
400
+ };
401
+ webWorkspaceState.tabs[index] = nextTab;
402
+ return cloneWebBrowserWorkspaceTabState(nextTab);
403
+ });
404
+ }
405
+ const payload = await requestBrowserWorkspace(
406
+ `/tabs/${encodeURIComponent(id)}/hide`,
407
+ { method: "POST" },
408
+ env
409
+ );
410
+ return payload.tab;
411
+ }
412
+ async function closeBrowserWorkspaceTab(id, env = process.env) {
413
+ if (!isBrowserWorkspaceBridgeConfigured(env)) {
414
+ return withWebStateLock(() => {
415
+ const initialLength = webWorkspaceState.tabs.length;
416
+ clearWebBrowserWorkspaceTabElementRefs(id);
417
+ clearBrowserWorkspaceRuntimeState("web", id);
418
+ webWorkspaceState.tabs = webWorkspaceState.tabs.filter(
419
+ (tab) => tab.id !== id
420
+ );
421
+ return webWorkspaceState.tabs.length !== initialLength;
422
+ });
423
+ }
424
+ const payload = await requestBrowserWorkspace(
425
+ `/tabs/${encodeURIComponent(id)}`,
426
+ { method: "DELETE" },
427
+ env
428
+ );
429
+ return payload.closed === true;
430
+ }
431
+ async function evaluateBrowserWorkspaceTab(request, env = process.env) {
432
+ return evaluateBrowserWorkspaceTabDesktop(request, env);
433
+ }
434
+ async function snapshotBrowserWorkspaceTab(id, env = process.env) {
435
+ return snapshotBrowserWorkspaceTabDesktop(id, env);
436
+ }
437
+ async function executeBrowserWorkspaceCommand(command, env = process.env) {
438
+ command = normalizeBrowserWorkspaceCommand(command);
439
+ switch (command.subaction) {
440
+ case "batch": {
441
+ const steps = Array.isArray(command.steps) ? command.steps : [];
442
+ if (steps.length === 0) {
443
+ throw new Error(
444
+ "Eliza browser workspace batch requires at least one step."
445
+ );
446
+ }
447
+ const results = [];
448
+ for (const step of steps) {
449
+ results.push(await executeBrowserWorkspaceCommand(step, env));
450
+ }
451
+ return {
452
+ mode: getBrowserWorkspaceMode(env),
453
+ subaction: command.subaction,
454
+ steps: results,
455
+ value: results.at(-1)?.value
456
+ };
457
+ }
458
+ case "list":
459
+ return {
460
+ mode: getBrowserWorkspaceMode(env),
461
+ subaction: command.subaction,
462
+ tabs: await listBrowserWorkspaceTabs(env)
463
+ };
464
+ case "open": {
465
+ const tab = await openBrowserWorkspaceTab(
466
+ {
467
+ partition: resolveBrowserWorkspaceCommandPartition(
468
+ command,
469
+ AGENT_BROWSER_WORKSPACE_PARTITION
470
+ ),
471
+ show: command.show,
472
+ title: command.title,
473
+ url: command.url
474
+ },
475
+ env
476
+ );
477
+ clearBrowserWorkspaceElementRefs(getBrowserWorkspaceMode(env), tab.id);
478
+ return {
479
+ mode: getBrowserWorkspaceMode(env),
480
+ subaction: command.subaction,
481
+ tab
482
+ };
483
+ }
484
+ case "navigate": {
485
+ const id = isBrowserWorkspaceBridgeConfigured(env) ? await resolveDesktopBrowserWorkspaceTargetTabId(command, env) : findWebBrowserWorkspaceTargetTabId(command);
486
+ clearBrowserWorkspaceElementRefs(getBrowserWorkspaceMode(env), id);
487
+ return {
488
+ mode: getBrowserWorkspaceMode(env),
489
+ subaction: command.subaction,
490
+ tab: await navigateBrowserWorkspaceTab(
491
+ {
492
+ id,
493
+ url: command.url ?? ""
494
+ },
495
+ env
496
+ )
497
+ };
498
+ }
499
+ case "show": {
500
+ const id = isBrowserWorkspaceBridgeConfigured(env) ? await resolveDesktopBrowserWorkspaceTargetTabId(command, env) : findWebBrowserWorkspaceTargetTabId(command);
501
+ return {
502
+ mode: getBrowserWorkspaceMode(env),
503
+ subaction: command.subaction,
504
+ tab: await showBrowserWorkspaceTab(id, env)
505
+ };
506
+ }
507
+ case "hide": {
508
+ const id = isBrowserWorkspaceBridgeConfigured(env) ? await resolveDesktopBrowserWorkspaceTargetTabId(command, env) : findWebBrowserWorkspaceTargetTabId(command);
509
+ return {
510
+ mode: getBrowserWorkspaceMode(env),
511
+ subaction: command.subaction,
512
+ tab: await hideBrowserWorkspaceTab(id, env)
513
+ };
514
+ }
515
+ case "close": {
516
+ const id = isBrowserWorkspaceBridgeConfigured(env) ? await resolveDesktopBrowserWorkspaceTargetTabId(command, env) : findWebBrowserWorkspaceTargetTabId(command);
517
+ clearBrowserWorkspaceElementRefs(getBrowserWorkspaceMode(env), id);
518
+ clearBrowserWorkspaceRuntimeState(getBrowserWorkspaceMode(env), id);
519
+ return {
520
+ mode: getBrowserWorkspaceMode(env),
521
+ subaction: command.subaction,
522
+ closed: await closeBrowserWorkspaceTab(id, env)
523
+ };
524
+ }
525
+ case "eval": {
526
+ if (!isBrowserWorkspaceBridgeConfigured(env)) {
527
+ return await executeWebBrowserWorkspaceUtilityCommand(
528
+ command
529
+ );
530
+ }
531
+ assertBrowserWorkspaceUserScriptAllowed(
532
+ command.script,
533
+ "eval",
534
+ "desktop",
535
+ env
536
+ );
537
+ const id = await resolveDesktopBrowserWorkspaceTargetTabId(command, env);
538
+ return {
539
+ mode: "desktop",
540
+ subaction: command.subaction,
541
+ value: await evaluateBrowserWorkspaceTab(
542
+ {
543
+ id,
544
+ script: command.script ?? ""
545
+ },
546
+ env
547
+ )
548
+ };
549
+ }
550
+ case "screenshot": {
551
+ if (!isBrowserWorkspaceBridgeConfigured(env)) {
552
+ return await executeWebBrowserWorkspaceUtilityCommand(
553
+ command
554
+ );
555
+ }
556
+ const id = await resolveDesktopBrowserWorkspaceTargetTabId(command, env);
557
+ return {
558
+ mode: "desktop",
559
+ subaction: command.subaction,
560
+ snapshot: await snapshotBrowserWorkspaceTab(id, env)
561
+ };
562
+ }
563
+ case "clipboard":
564
+ case "console":
565
+ case "cookies":
566
+ case "dialog":
567
+ case "drag":
568
+ case "errors":
569
+ case "frame":
570
+ case "highlight":
571
+ case "mouse":
572
+ case "network":
573
+ case "set":
574
+ case "storage":
575
+ case "upload": {
576
+ if (!isBrowserWorkspaceBridgeConfigured(env)) {
577
+ return await executeWebBrowserWorkspaceUtilityCommand(
578
+ command
579
+ );
580
+ }
581
+ return executeDesktopBrowserWorkspaceUtilityCommand(command, env);
582
+ }
583
+ case "diff": {
584
+ if (!isBrowserWorkspaceBridgeConfigured(env)) {
585
+ return await executeWebBrowserWorkspaceUtilityCommand(
586
+ command
587
+ );
588
+ }
589
+ const id = await resolveDesktopBrowserWorkspaceTargetTabId(command, env);
590
+ const runtime = getBrowserWorkspaceRuntimeState("desktop", id);
591
+ const snapshot = await getDesktopBrowserWorkspaceSnapshotRecord(
592
+ command,
593
+ env
594
+ );
595
+ if (command.diffAction === "screenshot") {
596
+ const screenshot = await snapshotBrowserWorkspaceTab(id, env);
597
+ const currentData = screenshot.data;
598
+ const baseline2 = command.baselinePath?.trim() ? await fsp.readFile(
599
+ path.resolve(command.baselinePath.trim()),
600
+ "base64"
601
+ ) : runtime.lastScreenshotData;
602
+ runtime.lastScreenshotData = currentData;
603
+ return {
604
+ mode: "desktop",
605
+ subaction: command.subaction,
606
+ value: {
607
+ baselineLength: baseline2?.length ?? 0,
608
+ changed: baseline2 !== currentData,
609
+ currentLength: currentData.length
610
+ }
611
+ };
612
+ }
613
+ if (command.diffAction === "url") {
614
+ const leftUrl = command.url?.trim() || snapshot.url;
615
+ const rightUrl = command.secondaryUrl?.trim();
616
+ if (!rightUrl) {
617
+ throw new Error(
618
+ "Eliza browser workspace diff url requires secondaryUrl."
619
+ );
620
+ }
621
+ const left = await browserWorkspacePageFetch(leftUrl);
622
+ const right = await browserWorkspacePageFetch(rightUrl);
623
+ return {
624
+ mode: "desktop",
625
+ subaction: command.subaction,
626
+ value: diffBrowserWorkspaceSnapshots(
627
+ createBrowserWorkspaceSnapshotRecord(
628
+ leftUrl,
629
+ left.url || leftUrl,
630
+ await left.text()
631
+ ),
632
+ createBrowserWorkspaceSnapshotRecord(
633
+ rightUrl,
634
+ right.url || rightUrl,
635
+ await right.text()
636
+ )
637
+ )
638
+ };
639
+ }
640
+ const baseline = command.baselinePath?.trim() ? JSON.parse(
641
+ await fsp.readFile(
642
+ path.resolve(command.baselinePath.trim()),
643
+ "utf8"
644
+ )
645
+ ) : runtime.lastSnapshot;
646
+ const diff = diffBrowserWorkspaceSnapshots(baseline, snapshot);
647
+ runtime.lastSnapshot = snapshot;
648
+ return { mode: "desktop", subaction: command.subaction, value: diff };
649
+ }
650
+ case "trace":
651
+ case "profiler": {
652
+ if (!isBrowserWorkspaceBridgeConfigured(env)) {
653
+ return await executeWebBrowserWorkspaceUtilityCommand(
654
+ command
655
+ );
656
+ }
657
+ const id = await resolveDesktopBrowserWorkspaceTargetTabId(command, env);
658
+ const runtime = getBrowserWorkspaceRuntimeState("desktop", id);
659
+ const target = command.subaction === "trace" ? runtime.trace : runtime.profiler;
660
+ const stop = command.subaction === "trace" ? command.traceAction === "stop" : command.profilerAction === "stop";
661
+ if (stop) {
662
+ target.active = false;
663
+ const payload = { entries: target.entries };
664
+ const filePath = command.filePath?.trim() || command.outputPath?.trim();
665
+ if (filePath) {
666
+ await writeBrowserWorkspaceFile(
667
+ filePath,
668
+ JSON.stringify(payload, null, 2)
669
+ );
670
+ return {
671
+ mode: "desktop",
672
+ subaction: command.subaction,
673
+ value: { path: path.resolve(filePath), ...payload }
674
+ };
675
+ }
676
+ return {
677
+ mode: "desktop",
678
+ subaction: command.subaction,
679
+ value: payload
680
+ };
681
+ }
682
+ target.active = true;
683
+ target.entries = [
684
+ {
685
+ command: `${command.subaction}:start`,
686
+ timestamp: getBrowserWorkspaceTimestamp()
687
+ }
688
+ ];
689
+ return {
690
+ mode: "desktop",
691
+ subaction: command.subaction,
692
+ value: { active: true }
693
+ };
694
+ }
695
+ case "state": {
696
+ if (!isBrowserWorkspaceBridgeConfigured(env)) {
697
+ return await executeWebBrowserWorkspaceUtilityCommand(
698
+ command
699
+ );
700
+ }
701
+ await assertDesktopBrowserWorkspaceCanAccessProfileSecrets(
702
+ command,
703
+ env,
704
+ "state"
705
+ );
706
+ if (command.stateAction === "load") {
707
+ const filePath2 = command.filePath?.trim() || command.outputPath?.trim();
708
+ if (!filePath2) {
709
+ throw new Error(
710
+ "Eliza browser workspace state load requires filePath."
711
+ );
712
+ }
713
+ const payload2 = JSON.parse(
714
+ await fsp.readFile(path.resolve(filePath2), "utf8")
715
+ );
716
+ await loadDesktopBrowserWorkspaceSessionState(command, payload2, env);
717
+ return {
718
+ mode: "desktop",
719
+ subaction: command.subaction,
720
+ value: { loaded: true }
721
+ };
722
+ }
723
+ const payload = await getDesktopBrowserWorkspaceSessionState(
724
+ command,
725
+ env
726
+ );
727
+ const filePath = command.filePath?.trim() || command.outputPath?.trim();
728
+ if (filePath) {
729
+ await writeBrowserWorkspaceFile(
730
+ filePath,
731
+ JSON.stringify(payload, null, 2)
732
+ );
733
+ return {
734
+ mode: "desktop",
735
+ subaction: command.subaction,
736
+ value: { path: path.resolve(filePath), ...payload }
737
+ };
738
+ }
739
+ return { mode: "desktop", subaction: command.subaction, value: payload };
740
+ }
741
+ case "pdf": {
742
+ if (!isBrowserWorkspaceBridgeConfigured(env)) {
743
+ return await executeWebBrowserWorkspaceUtilityCommand(
744
+ command
745
+ );
746
+ }
747
+ const filePath = command.filePath?.trim() || command.outputPath?.trim();
748
+ if (!filePath) {
749
+ throw new Error("Eliza browser workspace pdf requires filePath.");
750
+ }
751
+ const snapshot = await getDesktopBrowserWorkspaceSnapshotRecord(
752
+ command,
753
+ env
754
+ );
755
+ const pdf = createBrowserWorkspacePdfBuffer(
756
+ snapshot.title,
757
+ snapshot.bodyText
758
+ );
759
+ const resolved = await writeBrowserWorkspaceFile(filePath, pdf);
760
+ return {
761
+ mode: "desktop",
762
+ subaction: command.subaction,
763
+ value: { path: resolved, size: pdf.byteLength }
764
+ };
765
+ }
766
+ case "tab": {
767
+ const action = command.tabAction ?? "list";
768
+ if (action === "list") {
769
+ return {
770
+ mode: getBrowserWorkspaceMode(env),
771
+ subaction: command.subaction,
772
+ tabs: await listBrowserWorkspaceTabs(env)
773
+ };
774
+ }
775
+ if (action === "new") {
776
+ return {
777
+ mode: getBrowserWorkspaceMode(env),
778
+ subaction: command.subaction,
779
+ tab: await openBrowserWorkspaceTab(
780
+ {
781
+ partition: resolveBrowserWorkspaceCommandPartition(
782
+ command,
783
+ AGENT_BROWSER_WORKSPACE_PARTITION
784
+ ),
785
+ show: command.show ?? true,
786
+ title: command.title,
787
+ url: command.url,
788
+ width: command.width,
789
+ height: command.height
790
+ },
791
+ env
792
+ )
793
+ };
794
+ }
795
+ if (action === "switch") {
796
+ const tabs = await listBrowserWorkspaceTabs(env);
797
+ const target = command.id?.trim() ? tabs.find((tab) => tab.id === command.id?.trim()) : typeof command.index === "number" ? tabs[command.index] ?? null : null;
798
+ if (!target) {
799
+ throw new Error(
800
+ "Eliza browser workspace tab switch requires a valid id or index."
801
+ );
802
+ }
803
+ return {
804
+ mode: getBrowserWorkspaceMode(env),
805
+ subaction: command.subaction,
806
+ tab: await showBrowserWorkspaceTab(target.id, env)
807
+ };
808
+ }
809
+ const targetId = command.id?.trim() || (await listBrowserWorkspaceTabs(env))[command.index ?? -1]?.id;
810
+ if (!targetId) {
811
+ throw new Error(
812
+ "Eliza browser workspace tab close requires a valid id or index."
813
+ );
814
+ }
815
+ return {
816
+ mode: getBrowserWorkspaceMode(env),
817
+ subaction: command.subaction,
818
+ closed: await closeBrowserWorkspaceTab(targetId, env)
819
+ };
820
+ }
821
+ case "window":
822
+ return {
823
+ mode: getBrowserWorkspaceMode(env),
824
+ subaction: command.subaction,
825
+ tab: await openBrowserWorkspaceTab(
826
+ {
827
+ partition: resolveBrowserWorkspaceCommandPartition(
828
+ command,
829
+ AGENT_BROWSER_WORKSPACE_PARTITION
830
+ ),
831
+ show: true,
832
+ title: command.title,
833
+ url: command.url,
834
+ width: command.width,
835
+ height: command.height
836
+ },
837
+ env
838
+ )
839
+ };
840
+ case "back":
841
+ case "forward":
842
+ case "reload": {
843
+ if (isBrowserWorkspaceBridgeConfigured(env)) {
844
+ const id = await resolveDesktopBrowserWorkspaceTargetTabId(
845
+ command,
846
+ env
847
+ );
848
+ clearBrowserWorkspaceElementRefs("desktop", id);
849
+ return executeDesktopBrowserWorkspaceDomCommand(command, env);
850
+ }
851
+ return withWebStateLock(async () => {
852
+ const id = findWebBrowserWorkspaceTargetTabId(command);
853
+ const tab = getWebBrowserWorkspaceTabState(id);
854
+ if (command.subaction === "reload") {
855
+ clearWebBrowserWorkspaceTabElementRefs(tab.id);
856
+ tab.dom = null;
857
+ tab.loadedUrl = null;
858
+ await loadWebBrowserWorkspaceTabDocument(tab);
859
+ return {
860
+ mode: "web",
861
+ subaction: command.subaction,
862
+ tab: cloneWebBrowserWorkspaceTabState(tab),
863
+ value: { url: tab.url, title: tab.title }
864
+ };
865
+ }
866
+ const delta = command.subaction === "back" ? -1 : 1;
867
+ const nextIndex = tab.historyIndex + delta;
868
+ if (nextIndex < 0 || nextIndex >= tab.history.length) {
869
+ return {
870
+ mode: "web",
871
+ subaction: command.subaction,
872
+ tab: cloneWebBrowserWorkspaceTabState(tab),
873
+ value: { url: tab.url, title: tab.title, changed: false }
874
+ };
875
+ }
876
+ tab.historyIndex = nextIndex;
877
+ tab.url = tab.history[nextIndex] ?? tab.url;
878
+ tab.title = inferBrowserWorkspaceTitle(tab.url);
879
+ clearWebBrowserWorkspaceTabElementRefs(tab.id);
880
+ tab.dom = null;
881
+ tab.loadedUrl = null;
882
+ await loadWebBrowserWorkspaceTabDocument(tab);
883
+ return {
884
+ mode: "web",
885
+ subaction: command.subaction,
886
+ tab: cloneWebBrowserWorkspaceTabState(tab),
887
+ value: { url: tab.url, title: tab.title, changed: true }
888
+ };
889
+ });
890
+ }
891
+ case "inspect":
892
+ case "snapshot":
893
+ case "check":
894
+ case "click":
895
+ case "dblclick":
896
+ case "find":
897
+ case "fill":
898
+ case "focus":
899
+ case "get":
900
+ case "hover":
901
+ case "keydown":
902
+ case "keyup":
903
+ case "keyboardinserttext":
904
+ case "keyboardtype":
905
+ case "press":
906
+ case "scroll":
907
+ case "scrollinto":
908
+ case "select":
909
+ case "type":
910
+ case "uncheck":
911
+ case "wait":
912
+ case "realistic-click":
913
+ case "realistic-fill":
914
+ case "realistic-type":
915
+ case "realistic-press":
916
+ case "realistic-upload":
917
+ case "cursor-move":
918
+ case "cursor-hide":
919
+ if (command.subaction === "wait" && !command.selector && !command.findBy && !command.text && !command.url && !command.script && typeof command.timeoutMs === "number" && Number.isFinite(command.timeoutMs)) {
920
+ const waitedMs = Math.max(0, command.timeoutMs);
921
+ await sleep(waitedMs);
922
+ return {
923
+ mode: getBrowserWorkspaceMode(env),
924
+ subaction: command.subaction,
925
+ value: { waitedMs }
926
+ };
927
+ }
928
+ if (isBrowserWorkspaceBridgeConfigured(env)) {
929
+ return executeDesktopBrowserWorkspaceDomCommand(command, env);
930
+ }
931
+ return executeWebBrowserWorkspaceDomCommand(command);
932
+ default: {
933
+ const exhaustive = command.subaction;
934
+ throw new Error(`Unsupported browser workspace subaction: ${exhaustive}`);
935
+ }
936
+ }
937
+ }
938
+ export {
939
+ BROWSER_WORKSPACE_CONNECTOR_AUTH_STATES,
940
+ __resetBrowserWorkspaceStateForTests,
941
+ acquireBrowserWorkspaceConnectorSession,
942
+ closeBrowserWorkspaceTab,
943
+ evaluateBrowserWorkspaceTab,
944
+ executeBrowserWorkspaceCommand,
945
+ getBrowserWorkspaceMode,
946
+ getBrowserWorkspaceSnapshot,
947
+ getBrowserWorkspaceUnavailableMessage,
948
+ hideBrowserWorkspaceTab,
949
+ isBrowserWorkspaceBridgeConfigured,
950
+ listBrowserWorkspaceTabs,
951
+ navigateBrowserWorkspaceTab,
952
+ openBrowserWorkspaceTab,
953
+ resolveBrowserWorkspaceBridgeConfig,
954
+ resolveBrowserWorkspaceConnectorPartition,
955
+ showBrowserWorkspaceTab,
956
+ snapshotBrowserWorkspaceTab
957
+ };
958
+ //# sourceMappingURL=browser-workspace.js.map