@elizaos/plugin-browser 2.0.0-alpha.9 → 2.0.3-beta.2

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,1342 @@
1
+ import * as fsp from "node:fs/promises";
2
+ import * as path from "node:path";
3
+ import {
4
+ browserWorkspaceTextMatches,
5
+ buildBrowserWorkspaceElementSelector,
6
+ collectBrowserWorkspaceInspectElements,
7
+ createBrowserWorkspaceElementSummary,
8
+ findClosestBrowserWorkspaceForm,
9
+ getBrowserWorkspaceElementBox,
10
+ getBrowserWorkspaceElementStyles,
11
+ getBrowserWorkspaceElementValue,
12
+ isBrowserWorkspaceElementVisible,
13
+ mergeBrowserWorkspaceSelectorCommand,
14
+ queryAllBrowserWorkspaceSelector,
15
+ resolveBrowserWorkspaceElement,
16
+ resolveBrowserWorkspaceFindElement,
17
+ resolveWebBrowserWorkspaceCommandDocument
18
+ } from "./browser-workspace-elements.js";
19
+ import {
20
+ activateWebBrowserWorkspaceElement,
21
+ clearWebBrowserWorkspaceTabElementRefs,
22
+ cloneWebBrowserWorkspaceTabState,
23
+ ensureBrowserWorkspaceCheckboxElement,
24
+ ensureBrowserWorkspaceFormControlElement,
25
+ ensureLoadedWebBrowserWorkspaceTabDocument,
26
+ scrollWebBrowserWorkspaceTarget,
27
+ setBrowserWorkspaceControlValue,
28
+ submitWebBrowserWorkspaceForm
29
+ } from "./browser-workspace-forms.js";
30
+ import {
31
+ assertBrowserWorkspaceConnectorSecretsNotExported,
32
+ createBrowserWorkspaceJsdomScriptExecutionError,
33
+ assertBrowserWorkspaceJsdomScriptNotRequested,
34
+ createBrowserWorkspaceCommandTargetError,
35
+ createBrowserWorkspaceNotFoundError,
36
+ DEFAULT_TIMEOUT_MS,
37
+ DEFAULT_WAIT_INTERVAL_MS,
38
+ normalizeBrowserWorkspaceText,
39
+ resolveBrowserWorkspaceCommandElementRefs,
40
+ sleep,
41
+ writeBrowserWorkspaceFile
42
+ } from "./browser-workspace-helpers.js";
43
+ import {
44
+ applyBrowserWorkspaceDomSettings,
45
+ ensureBrowserWorkspaceDom
46
+ } from "./browser-workspace-jsdom.js";
47
+ import {
48
+ fetchBrowserWorkspaceTrackedResponse,
49
+ normalizeBrowserWorkspaceHeaders
50
+ } from "./browser-workspace-network.js";
51
+ import {
52
+ applyBrowserWorkspaceStateToWebDocument,
53
+ buildBrowserWorkspaceDocumentSnapshotText,
54
+ createBrowserWorkspacePdfBuffer,
55
+ createBrowserWorkspaceSnapshotRecord,
56
+ createBrowserWorkspaceSyntheticScreenshotData,
57
+ diffBrowserWorkspaceSnapshots,
58
+ readBrowserWorkspaceCookies,
59
+ readBrowserWorkspaceStorage
60
+ } from "./browser-workspace-snapshots.js";
61
+ import {
62
+ browserWorkspaceClipboardText,
63
+ getBrowserWorkspaceRuntimeState,
64
+ getBrowserWorkspaceTimestamp,
65
+ registerBrowserWorkspaceElementRefs,
66
+ setBrowserWorkspaceClipboardText,
67
+ webWorkspaceState,
68
+ withWebStateLock
69
+ } from "./browser-workspace-state.js";
70
+ function getWebBrowserWorkspaceTabIndex(tabId) {
71
+ return webWorkspaceState.tabs.findIndex((tab) => tab.id === tabId);
72
+ }
73
+ function getWebBrowserWorkspaceTabState(tabId) {
74
+ const tab = webWorkspaceState.tabs.find((entry) => entry.id === tabId);
75
+ if (!tab) {
76
+ throw createBrowserWorkspaceNotFoundError(tabId);
77
+ }
78
+ return tab;
79
+ }
80
+ function getCurrentWebBrowserWorkspaceTabState() {
81
+ if (webWorkspaceState.tabs.length === 0) {
82
+ return null;
83
+ }
84
+ return webWorkspaceState.tabs.find((tab) => tab.visible) ?? [...webWorkspaceState.tabs].sort((left, right) => {
85
+ const leftTime = left.lastFocusedAt ?? left.updatedAt ?? "";
86
+ const rightTime = right.lastFocusedAt ?? right.updatedAt ?? "";
87
+ return rightTime.localeCompare(leftTime) || left.id.localeCompare(right.id);
88
+ })[0] ?? null;
89
+ }
90
+ function findWebBrowserWorkspaceTargetTabId(command) {
91
+ if (command.id?.trim()) {
92
+ return command.id.trim();
93
+ }
94
+ const current = getCurrentWebBrowserWorkspaceTabState();
95
+ if (!current) {
96
+ throw createBrowserWorkspaceCommandTargetError(command.subaction);
97
+ }
98
+ return current.id;
99
+ }
100
+ async function executeWebBrowserWorkspaceUtilityCommand(command) {
101
+ return withWebStateLock(async () => {
102
+ if (![
103
+ "clipboard",
104
+ "console",
105
+ "cookies",
106
+ "diff",
107
+ "dialog",
108
+ "drag",
109
+ "errors",
110
+ "eval",
111
+ "frame",
112
+ "highlight",
113
+ "mouse",
114
+ "network",
115
+ "pdf",
116
+ "screenshot",
117
+ "set",
118
+ "state",
119
+ "storage",
120
+ "trace",
121
+ "profiler",
122
+ "upload"
123
+ ].includes(command.subaction)) {
124
+ return null;
125
+ }
126
+ const id = findWebBrowserWorkspaceTargetTabId(command);
127
+ const tab = getWebBrowserWorkspaceTabState(id);
128
+ const dom = await ensureLoadedWebBrowserWorkspaceTabDocument(tab);
129
+ const runtime = getBrowserWorkspaceRuntimeState("web", id);
130
+ const frameContext = resolveWebBrowserWorkspaceCommandDocument(
131
+ tab,
132
+ dom,
133
+ runtime
134
+ );
135
+ const document = frameContext.document;
136
+ const resolveTarget = () => resolveBrowserWorkspaceElement(
137
+ document,
138
+ command.selector,
139
+ command.text,
140
+ command
141
+ );
142
+ switch (command.subaction) {
143
+ case "eval": {
144
+ if (!command.script?.trim()) {
145
+ throw new Error("Eliza browser workspace eval requires script.");
146
+ }
147
+ throw createBrowserWorkspaceJsdomScriptExecutionError("eval");
148
+ }
149
+ case "screenshot": {
150
+ const data = createBrowserWorkspaceSyntheticScreenshotData(
151
+ tab.title,
152
+ tab.url,
153
+ buildBrowserWorkspaceDocumentSnapshotText(document),
154
+ runtime.settings.viewport ?? void 0
155
+ );
156
+ runtime.lastScreenshotData = data;
157
+ if (command.filePath?.trim() || command.outputPath?.trim()) {
158
+ const targetPath = command.filePath?.trim() || command.outputPath?.trim() || "";
159
+ await writeBrowserWorkspaceFile(
160
+ targetPath,
161
+ Buffer.from(data, "base64")
162
+ );
163
+ return {
164
+ mode: "web",
165
+ subaction: command.subaction,
166
+ snapshot: { data },
167
+ value: { path: path.resolve(targetPath) }
168
+ };
169
+ }
170
+ return {
171
+ mode: "web",
172
+ subaction: command.subaction,
173
+ snapshot: { data }
174
+ };
175
+ }
176
+ case "clipboard": {
177
+ const action = command.clipboardAction ?? "read";
178
+ if (action === "read") {
179
+ return {
180
+ mode: "web",
181
+ subaction: command.subaction,
182
+ value: browserWorkspaceClipboardText
183
+ };
184
+ }
185
+ if (action === "write") {
186
+ setBrowserWorkspaceClipboardText(command.value ?? command.text ?? "");
187
+ return {
188
+ mode: "web",
189
+ subaction: command.subaction,
190
+ value: browserWorkspaceClipboardText
191
+ };
192
+ }
193
+ if (action === "copy") {
194
+ const target2 = resolveTarget();
195
+ setBrowserWorkspaceClipboardText(
196
+ target2 && "value" in target2 ? String(target2.value ?? "") : normalizeBrowserWorkspaceText(
197
+ target2?.textContent ?? document.body?.textContent
198
+ )
199
+ );
200
+ return {
201
+ mode: "web",
202
+ subaction: command.subaction,
203
+ value: browserWorkspaceClipboardText
204
+ };
205
+ }
206
+ const target = resolveTarget() ?? document.activeElement;
207
+ if (target && (target.tagName === "INPUT" || target.tagName === "TEXTAREA" || target.tagName === "SELECT")) {
208
+ const control = ensureBrowserWorkspaceFormControlElement(
209
+ target,
210
+ "clipboard"
211
+ );
212
+ setBrowserWorkspaceControlValue(
213
+ control,
214
+ `${control.value ?? ""}${browserWorkspaceClipboardText}`
215
+ );
216
+ return {
217
+ mode: "web",
218
+ subaction: command.subaction,
219
+ value: {
220
+ selector: buildBrowserWorkspaceElementSelector(control),
221
+ value: control.value
222
+ }
223
+ };
224
+ }
225
+ return {
226
+ mode: "web",
227
+ subaction: command.subaction,
228
+ value: browserWorkspaceClipboardText
229
+ };
230
+ }
231
+ case "mouse": {
232
+ const action = command.mouseAction ?? "move";
233
+ if (action === "move") {
234
+ runtime.mouse.x = command.x ?? runtime.mouse.x;
235
+ runtime.mouse.y = command.y ?? runtime.mouse.y;
236
+ } else if (action === "down") {
237
+ const button = command.button ?? "left";
238
+ runtime.mouse.buttons = Array.from(
239
+ /* @__PURE__ */ new Set([...runtime.mouse.buttons, button])
240
+ );
241
+ } else if (action === "up") {
242
+ const button = command.button ?? "left";
243
+ runtime.mouse.buttons = runtime.mouse.buttons.filter(
244
+ (entry) => entry !== button
245
+ );
246
+ } else {
247
+ return {
248
+ mode: "web",
249
+ subaction: command.subaction,
250
+ value: scrollWebBrowserWorkspaceTarget(
251
+ dom,
252
+ resolveTarget(),
253
+ (command.deltaY ?? 0) < 0 ? "up" : "down",
254
+ Math.abs(command.deltaY ?? command.pixels ?? 240)
255
+ )
256
+ };
257
+ }
258
+ return {
259
+ mode: "web",
260
+ subaction: command.subaction,
261
+ value: runtime.mouse
262
+ };
263
+ }
264
+ case "drag": {
265
+ const source = resolveTarget();
266
+ const target = command.value ? resolveBrowserWorkspaceElement(document, command.value) : null;
267
+ if (!source || !target) {
268
+ throw new Error(
269
+ "Eliza browser workspace drag requires source selector and target selector in value."
270
+ );
271
+ }
272
+ source.setAttribute("data-eliza-dragging", "true");
273
+ target.setAttribute("data-eliza-drop-target", "true");
274
+ return {
275
+ mode: "web",
276
+ subaction: command.subaction,
277
+ value: {
278
+ source: buildBrowserWorkspaceElementSelector(source),
279
+ target: buildBrowserWorkspaceElementSelector(target)
280
+ }
281
+ };
282
+ }
283
+ case "upload": {
284
+ const target = resolveTarget();
285
+ if (!target || target.tagName !== "INPUT") {
286
+ throw new Error(
287
+ "Eliza browser workspace upload requires a file input target."
288
+ );
289
+ }
290
+ const files = (command.files ?? []).map(
291
+ (entry) => path.basename(entry)
292
+ );
293
+ target.setAttribute("data-eliza-uploaded-files", files.join(","));
294
+ return {
295
+ mode: "web",
296
+ subaction: command.subaction,
297
+ value: {
298
+ files,
299
+ selector: buildBrowserWorkspaceElementSelector(target)
300
+ }
301
+ };
302
+ }
303
+ case "set": {
304
+ const action = command.setAction ?? "viewport";
305
+ if (action === "credentials" || action === "headers") {
306
+ assertBrowserWorkspaceConnectorSecretsNotExported(
307
+ tab.partition,
308
+ `set:${action}`
309
+ );
310
+ }
311
+ if (action === "viewport") {
312
+ runtime.settings.viewport = {
313
+ height: Math.max(1, Math.round(command.height ?? 720)),
314
+ scale: Math.max(1, Number(command.scale ?? 1)),
315
+ width: Math.max(1, Math.round(command.width ?? 1280))
316
+ };
317
+ } else if (action === "device") {
318
+ runtime.settings.device = command.device ?? null;
319
+ } else if (action === "geo") {
320
+ runtime.settings.geo = typeof command.latitude === "number" && typeof command.longitude === "number" ? { latitude: command.latitude, longitude: command.longitude } : null;
321
+ } else if (action === "offline") {
322
+ runtime.settings.offline = Boolean(command.offline);
323
+ } else if (action === "headers") {
324
+ runtime.settings.headers = normalizeBrowserWorkspaceHeaders(
325
+ command.headers
326
+ );
327
+ } else if (action === "credentials") {
328
+ runtime.settings.credentials = command.username || command.password ? {
329
+ password: command.password ?? "",
330
+ username: command.username ?? ""
331
+ } : null;
332
+ } else if (action === "media") {
333
+ runtime.settings.media = command.media ?? null;
334
+ }
335
+ applyBrowserWorkspaceDomSettings(dom, runtime);
336
+ return {
337
+ mode: "web",
338
+ subaction: command.subaction,
339
+ value: runtime.settings
340
+ };
341
+ }
342
+ case "cookies": {
343
+ assertBrowserWorkspaceConnectorSecretsNotExported(
344
+ tab.partition,
345
+ "cookies"
346
+ );
347
+ const action = command.cookieAction ?? "get";
348
+ if (action === "clear") {
349
+ for (const key of Object.keys(
350
+ readBrowserWorkspaceCookies(document)
351
+ )) {
352
+ document.cookie = `${key}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/`;
353
+ }
354
+ return {
355
+ mode: "web",
356
+ subaction: command.subaction,
357
+ value: { cleared: true }
358
+ };
359
+ }
360
+ if (action === "set") {
361
+ const cookieName = command.name?.trim() || command.entryKey?.trim();
362
+ if (!cookieName) {
363
+ throw new Error(
364
+ "Eliza browser workspace cookies set requires name."
365
+ );
366
+ }
367
+ document.cookie = `${cookieName}=${command.value ?? ""}; path=/`;
368
+ }
369
+ return {
370
+ mode: "web",
371
+ subaction: command.subaction,
372
+ value: readBrowserWorkspaceCookies(document)
373
+ };
374
+ }
375
+ case "storage": {
376
+ assertBrowserWorkspaceConnectorSecretsNotExported(
377
+ tab.partition,
378
+ "storage"
379
+ );
380
+ const area = command.storageArea === "session" ? dom.window.sessionStorage : dom.window.localStorage;
381
+ const action = command.storageAction ?? "get";
382
+ if (action === "clear") {
383
+ area.clear();
384
+ return {
385
+ mode: "web",
386
+ subaction: command.subaction,
387
+ value: { cleared: true }
388
+ };
389
+ }
390
+ if (action === "set") {
391
+ const key = command.entryKey?.trim() || command.name?.trim();
392
+ if (!key) {
393
+ throw new Error(
394
+ "Eliza browser workspace storage set requires entryKey."
395
+ );
396
+ }
397
+ area.setItem(key, command.value ?? "");
398
+ }
399
+ if (command.entryKey?.trim() || command.name?.trim()) {
400
+ const key = command.entryKey?.trim() || command.name?.trim() || "";
401
+ return {
402
+ mode: "web",
403
+ subaction: command.subaction,
404
+ value: area.getItem(key)
405
+ };
406
+ }
407
+ return {
408
+ mode: "web",
409
+ subaction: command.subaction,
410
+ value: readBrowserWorkspaceStorage(area)
411
+ };
412
+ }
413
+ case "network": {
414
+ const action = command.networkAction ?? "requests";
415
+ if (action === "route") {
416
+ const pattern = command.url?.trim();
417
+ if (!pattern) {
418
+ throw new Error(
419
+ "Eliza browser workspace network route requires url pattern."
420
+ );
421
+ }
422
+ runtime.networkRoutes.push({
423
+ abort: Boolean(command.offline),
424
+ body: command.responseBody ?? null,
425
+ headers: normalizeBrowserWorkspaceHeaders(command.responseHeaders),
426
+ pattern,
427
+ status: typeof command.responseStatus === "number" ? command.responseStatus : null
428
+ });
429
+ return {
430
+ mode: "web",
431
+ subaction: command.subaction,
432
+ value: runtime.networkRoutes
433
+ };
434
+ }
435
+ if (action === "unroute") {
436
+ runtime.networkRoutes = command.url?.trim() ? runtime.networkRoutes.filter(
437
+ (route) => route.pattern !== command.url?.trim()
438
+ ) : [];
439
+ return {
440
+ mode: "web",
441
+ subaction: command.subaction,
442
+ value: runtime.networkRoutes
443
+ };
444
+ }
445
+ if (action === "request") {
446
+ const request = runtime.networkRequests.find(
447
+ (entry) => entry.id === command.requestId
448
+ );
449
+ return {
450
+ mode: "web",
451
+ subaction: command.subaction,
452
+ value: request ?? null
453
+ };
454
+ }
455
+ if (action === "harstart") {
456
+ runtime.networkHar = {
457
+ active: true,
458
+ entries: [],
459
+ startedAt: getBrowserWorkspaceTimestamp()
460
+ };
461
+ return {
462
+ mode: "web",
463
+ subaction: command.subaction,
464
+ value: runtime.networkHar
465
+ };
466
+ }
467
+ if (action === "harstop") {
468
+ runtime.networkHar.active = false;
469
+ const har = {
470
+ log: {
471
+ entries: runtime.networkHar.entries,
472
+ startedAt: runtime.networkHar.startedAt
473
+ }
474
+ };
475
+ if (command.filePath?.trim() || command.outputPath?.trim()) {
476
+ const targetPath = command.filePath?.trim() || command.outputPath?.trim() || "";
477
+ await writeBrowserWorkspaceFile(
478
+ targetPath,
479
+ JSON.stringify(har, null, 2)
480
+ );
481
+ return {
482
+ mode: "web",
483
+ subaction: command.subaction,
484
+ value: { path: path.resolve(targetPath), ...har }
485
+ };
486
+ }
487
+ return { mode: "web", subaction: command.subaction, value: har };
488
+ }
489
+ let requests = [...runtime.networkRequests];
490
+ if (command.filter?.trim()) {
491
+ requests = requests.filter(
492
+ (entry) => entry.url.includes(command.filter ?? "")
493
+ );
494
+ }
495
+ if (command.method?.trim()) {
496
+ requests = requests.filter(
497
+ (entry) => entry.method.toUpperCase() === command.method?.trim().toUpperCase()
498
+ );
499
+ }
500
+ if (command.status?.trim()) {
501
+ const statusFilter = command.status.trim();
502
+ requests = requests.filter((entry) => {
503
+ if (entry.status === null) {
504
+ return false;
505
+ }
506
+ if (/^\dxx$/i.test(statusFilter)) {
507
+ return String(entry.status).startsWith(statusFilter[0] ?? "");
508
+ }
509
+ return String(entry.status) === statusFilter;
510
+ });
511
+ }
512
+ return { mode: "web", subaction: command.subaction, value: requests };
513
+ }
514
+ case "dialog": {
515
+ const action = command.dialogAction ?? "status";
516
+ if (action === "status") {
517
+ return {
518
+ mode: "web",
519
+ subaction: command.subaction,
520
+ value: runtime.dialog
521
+ };
522
+ }
523
+ if (runtime.dialog) {
524
+ runtime.dialog.open = false;
525
+ }
526
+ const result = action === "accept" ? {
527
+ accepted: true,
528
+ dialog: runtime.dialog,
529
+ promptText: command.promptText ?? command.value ?? null
530
+ } : { accepted: false, dialog: runtime.dialog };
531
+ runtime.dialog = null;
532
+ return { mode: "web", subaction: command.subaction, value: result };
533
+ }
534
+ case "console": {
535
+ if (command.consoleAction === "clear") {
536
+ runtime.consoleEntries = [];
537
+ }
538
+ return {
539
+ mode: "web",
540
+ subaction: command.subaction,
541
+ value: runtime.consoleEntries
542
+ };
543
+ }
544
+ case "errors": {
545
+ if (command.consoleAction === "clear") {
546
+ runtime.errors = [];
547
+ }
548
+ return {
549
+ mode: "web",
550
+ subaction: command.subaction,
551
+ value: runtime.errors
552
+ };
553
+ }
554
+ case "highlight": {
555
+ const target = resolveTarget();
556
+ if (!target) {
557
+ throw new Error("Target element was not found.");
558
+ }
559
+ target.setAttribute("data-eliza-highlight", "true");
560
+ runtime.highlightedSelector = buildBrowserWorkspaceElementSelector(target);
561
+ return {
562
+ mode: "web",
563
+ subaction: command.subaction,
564
+ value: { selector: runtime.highlightedSelector }
565
+ };
566
+ }
567
+ case "frame": {
568
+ const action = command.frameAction ?? "select";
569
+ if (action === "main") {
570
+ runtime.currentFrame = null;
571
+ return {
572
+ mode: "web",
573
+ subaction: command.subaction,
574
+ value: { frame: null }
575
+ };
576
+ }
577
+ const frame = resolveBrowserWorkspaceElement(
578
+ dom.window.document,
579
+ command.selector
580
+ );
581
+ if (!frame || frame.tagName !== "IFRAME") {
582
+ throw new Error(
583
+ "Eliza browser workspace frame select requires an iframe selector."
584
+ );
585
+ }
586
+ runtime.currentFrame = buildBrowserWorkspaceElementSelector(frame);
587
+ return {
588
+ mode: "web",
589
+ subaction: command.subaction,
590
+ value: { frame: runtime.currentFrame }
591
+ };
592
+ }
593
+ case "diff": {
594
+ const snapshot = createBrowserWorkspaceSnapshotRecord(
595
+ tab.title,
596
+ tab.url,
597
+ buildBrowserWorkspaceDocumentSnapshotText(document)
598
+ );
599
+ if (command.diffAction === "url") {
600
+ const leftUrl = command.url?.trim() || tab.url;
601
+ const rightUrl = command.secondaryUrl?.trim();
602
+ if (!rightUrl) {
603
+ throw new Error(
604
+ "Eliza browser workspace diff url requires secondaryUrl."
605
+ );
606
+ }
607
+ const left = await fetchBrowserWorkspaceTrackedResponse(
608
+ runtime,
609
+ leftUrl,
610
+ {},
611
+ "document"
612
+ );
613
+ const right = await fetchBrowserWorkspaceTrackedResponse(
614
+ runtime,
615
+ rightUrl,
616
+ {},
617
+ "document"
618
+ );
619
+ const leftSnapshot = createBrowserWorkspaceSnapshotRecord(
620
+ leftUrl,
621
+ left.url || leftUrl,
622
+ await left.text()
623
+ );
624
+ const rightSnapshot = createBrowserWorkspaceSnapshotRecord(
625
+ rightUrl,
626
+ right.url || rightUrl,
627
+ await right.text()
628
+ );
629
+ return {
630
+ mode: "web",
631
+ subaction: command.subaction,
632
+ value: diffBrowserWorkspaceSnapshots(leftSnapshot, rightSnapshot)
633
+ };
634
+ }
635
+ if (command.diffAction === "screenshot") {
636
+ const currentData = runtime.lastScreenshotData ?? createBrowserWorkspaceSyntheticScreenshotData(
637
+ tab.title,
638
+ tab.url,
639
+ buildBrowserWorkspaceDocumentSnapshotText(document),
640
+ runtime.settings.viewport ?? void 0
641
+ );
642
+ const baseline2 = command.baselinePath?.trim() ? await fsp.readFile(
643
+ path.resolve(command.baselinePath.trim()),
644
+ "base64"
645
+ ) : runtime.lastScreenshotData;
646
+ runtime.lastScreenshotData = currentData;
647
+ return {
648
+ mode: "web",
649
+ subaction: command.subaction,
650
+ value: {
651
+ baselineLength: baseline2?.length ?? 0,
652
+ changed: baseline2 !== currentData,
653
+ currentLength: currentData.length
654
+ }
655
+ };
656
+ }
657
+ const baseline = command.baselinePath?.trim() ? JSON.parse(
658
+ await fsp.readFile(
659
+ path.resolve(command.baselinePath.trim()),
660
+ "utf8"
661
+ )
662
+ ) : runtime.lastSnapshot;
663
+ const diff = diffBrowserWorkspaceSnapshots(baseline, snapshot);
664
+ runtime.lastSnapshot = snapshot;
665
+ return { mode: "web", subaction: command.subaction, value: diff };
666
+ }
667
+ case "trace": {
668
+ if (command.traceAction === "stop") {
669
+ runtime.trace.active = false;
670
+ const traceValue = { entries: runtime.trace.entries };
671
+ if (command.filePath?.trim() || command.outputPath?.trim()) {
672
+ const targetPath = command.filePath?.trim() || command.outputPath?.trim() || "";
673
+ await writeBrowserWorkspaceFile(
674
+ targetPath,
675
+ JSON.stringify(traceValue, null, 2)
676
+ );
677
+ return {
678
+ mode: "web",
679
+ subaction: command.subaction,
680
+ value: { path: path.resolve(targetPath), ...traceValue }
681
+ };
682
+ }
683
+ return {
684
+ mode: "web",
685
+ subaction: command.subaction,
686
+ value: traceValue
687
+ };
688
+ }
689
+ runtime.trace = { active: true, entries: [] };
690
+ runtime.trace.entries.push({
691
+ command: "trace:start",
692
+ timestamp: getBrowserWorkspaceTimestamp()
693
+ });
694
+ return {
695
+ mode: "web",
696
+ subaction: command.subaction,
697
+ value: { active: true }
698
+ };
699
+ }
700
+ case "profiler": {
701
+ if (command.profilerAction === "stop") {
702
+ runtime.profiler.active = false;
703
+ const profileValue = { entries: runtime.profiler.entries };
704
+ if (command.filePath?.trim() || command.outputPath?.trim()) {
705
+ const targetPath = command.filePath?.trim() || command.outputPath?.trim() || "";
706
+ await writeBrowserWorkspaceFile(
707
+ targetPath,
708
+ JSON.stringify(profileValue, null, 2)
709
+ );
710
+ return {
711
+ mode: "web",
712
+ subaction: command.subaction,
713
+ value: { path: path.resolve(targetPath), ...profileValue }
714
+ };
715
+ }
716
+ return {
717
+ mode: "web",
718
+ subaction: command.subaction,
719
+ value: profileValue
720
+ };
721
+ }
722
+ runtime.profiler = {
723
+ active: true,
724
+ entries: [
725
+ {
726
+ command: "profiler:start",
727
+ timestamp: getBrowserWorkspaceTimestamp()
728
+ }
729
+ ]
730
+ };
731
+ return {
732
+ mode: "web",
733
+ subaction: command.subaction,
734
+ value: { active: true }
735
+ };
736
+ }
737
+ case "state": {
738
+ assertBrowserWorkspaceConnectorSecretsNotExported(
739
+ tab.partition,
740
+ "state"
741
+ );
742
+ if (command.stateAction === "load") {
743
+ const filePath2 = command.filePath?.trim() || command.outputPath?.trim();
744
+ if (!filePath2) {
745
+ throw new Error(
746
+ "Eliza browser workspace state load requires filePath."
747
+ );
748
+ }
749
+ const payload2 = JSON.parse(
750
+ await fsp.readFile(path.resolve(filePath2), "utf8")
751
+ );
752
+ applyBrowserWorkspaceStateToWebDocument(document, payload2);
753
+ if (payload2.settings && typeof payload2.settings === "object") {
754
+ runtime.settings = {
755
+ ...runtime.settings,
756
+ ...payload2.settings
757
+ };
758
+ applyBrowserWorkspaceDomSettings(dom, runtime);
759
+ }
760
+ setBrowserWorkspaceClipboardText(
761
+ typeof payload2.clipboard === "string" ? payload2.clipboard : browserWorkspaceClipboardText
762
+ );
763
+ return {
764
+ mode: "web",
765
+ subaction: command.subaction,
766
+ value: { loaded: true }
767
+ };
768
+ }
769
+ const payload = {
770
+ clipboard: browserWorkspaceClipboardText,
771
+ cookies: readBrowserWorkspaceCookies(document),
772
+ localStorage: readBrowserWorkspaceStorage(dom.window.localStorage),
773
+ sessionStorage: readBrowserWorkspaceStorage(
774
+ dom.window.sessionStorage
775
+ ),
776
+ settings: runtime.settings,
777
+ url: tab.url
778
+ };
779
+ const filePath = command.filePath?.trim() || command.outputPath?.trim();
780
+ if (filePath) {
781
+ await writeBrowserWorkspaceFile(
782
+ filePath,
783
+ JSON.stringify(payload, null, 2)
784
+ );
785
+ return {
786
+ mode: "web",
787
+ subaction: command.subaction,
788
+ value: { path: path.resolve(filePath), ...payload }
789
+ };
790
+ }
791
+ return { mode: "web", subaction: command.subaction, value: payload };
792
+ }
793
+ case "pdf": {
794
+ const filePath = command.filePath?.trim() || command.outputPath?.trim();
795
+ if (!filePath) {
796
+ throw new Error("Eliza browser workspace pdf requires filePath.");
797
+ }
798
+ const pdf = createBrowserWorkspacePdfBuffer(
799
+ tab.title,
800
+ normalizeBrowserWorkspaceText(document.body?.textContent)
801
+ );
802
+ const resolved = await writeBrowserWorkspaceFile(filePath, pdf);
803
+ return {
804
+ mode: "web",
805
+ subaction: command.subaction,
806
+ value: { path: resolved, size: pdf.byteLength }
807
+ };
808
+ }
809
+ default:
810
+ return null;
811
+ }
812
+ });
813
+ }
814
+ async function executeWebBrowserWorkspaceDomCommand(command) {
815
+ return withWebStateLock(async () => {
816
+ const id = findWebBrowserWorkspaceTargetTabId(command);
817
+ command = resolveBrowserWorkspaceCommandElementRefs(command, "web", id);
818
+ const tab = getWebBrowserWorkspaceTabState(id);
819
+ const dom = await ensureLoadedWebBrowserWorkspaceTabDocument(tab);
820
+ const runtime = getBrowserWorkspaceRuntimeState("web", id);
821
+ const frameContext = resolveWebBrowserWorkspaceCommandDocument(
822
+ tab,
823
+ dom,
824
+ runtime
825
+ );
826
+ const document = frameContext.document;
827
+ const resolveTarget = () => resolveBrowserWorkspaceElement(
828
+ document,
829
+ command.selector,
830
+ command.text,
831
+ command
832
+ );
833
+ switch (command.subaction) {
834
+ case "inspect":
835
+ clearWebBrowserWorkspaceTabElementRefs(tab.id);
836
+ return {
837
+ mode: "web",
838
+ subaction: command.subaction,
839
+ elements: registerBrowserWorkspaceElementRefs(
840
+ "web",
841
+ tab.id,
842
+ collectBrowserWorkspaceInspectElements(document)
843
+ ),
844
+ value: {
845
+ title: tab.title,
846
+ url: tab.url
847
+ }
848
+ };
849
+ case "snapshot":
850
+ clearWebBrowserWorkspaceTabElementRefs(tab.id);
851
+ return {
852
+ mode: "web",
853
+ subaction: command.subaction,
854
+ elements: registerBrowserWorkspaceElementRefs(
855
+ "web",
856
+ tab.id,
857
+ collectBrowserWorkspaceInspectElements(document)
858
+ ),
859
+ value: {
860
+ bodyText: buildBrowserWorkspaceDocumentSnapshotText(document).slice(
861
+ 0,
862
+ 800
863
+ ),
864
+ title: tab.title,
865
+ url: tab.url
866
+ }
867
+ };
868
+ case "get": {
869
+ if (command.getMode === "title") {
870
+ return {
871
+ mode: "web",
872
+ subaction: command.subaction,
873
+ value: tab.title
874
+ };
875
+ }
876
+ if (command.getMode === "url") {
877
+ return { mode: "web", subaction: command.subaction, value: tab.url };
878
+ }
879
+ if (command.getMode === "count") {
880
+ if (!command.selector?.trim()) {
881
+ throw new Error(
882
+ "Eliza browser workspace get count requires selector."
883
+ );
884
+ }
885
+ const semanticCommand = mergeBrowserWorkspaceSelectorCommand(
886
+ command,
887
+ command.selector
888
+ );
889
+ return {
890
+ mode: "web",
891
+ subaction: command.subaction,
892
+ value: semanticCommand ? Number(
893
+ Boolean(
894
+ resolveBrowserWorkspaceFindElement(
895
+ document,
896
+ semanticCommand
897
+ )
898
+ )
899
+ ) : queryAllBrowserWorkspaceSelector(document, command.selector).length
900
+ };
901
+ }
902
+ const element = resolveTarget();
903
+ if (!element) {
904
+ throw new Error("Target element was not found.");
905
+ }
906
+ let value;
907
+ switch (command.getMode) {
908
+ case "attr":
909
+ if (!command.attribute?.trim()) {
910
+ throw new Error(
911
+ "Eliza browser workspace attr lookups require attribute."
912
+ );
913
+ }
914
+ value = element.getAttribute(command.attribute);
915
+ break;
916
+ case "box":
917
+ value = getBrowserWorkspaceElementBox(element);
918
+ break;
919
+ case "checked":
920
+ value = element.tagName === "INPUT" ? Boolean(element.checked) : element.tagName === "OPTION" ? Boolean(element.selected) : false;
921
+ break;
922
+ case "enabled":
923
+ value = "disabled" in element ? !element.disabled : true;
924
+ break;
925
+ case "html":
926
+ value = element.innerHTML;
927
+ break;
928
+ case "styles":
929
+ value = getBrowserWorkspaceElementStyles(element, dom.window);
930
+ break;
931
+ case "value":
932
+ value = getBrowserWorkspaceElementValue(element);
933
+ break;
934
+ case "visible":
935
+ value = isBrowserWorkspaceElementVisible(element);
936
+ break;
937
+ default:
938
+ value = normalizeBrowserWorkspaceText(element.textContent);
939
+ break;
940
+ }
941
+ return { mode: "web", subaction: command.subaction, value };
942
+ }
943
+ case "find": {
944
+ const element = resolveTarget();
945
+ if (!element) {
946
+ throw new Error("Target element was not found.");
947
+ }
948
+ switch (command.action) {
949
+ case "check": {
950
+ const input = ensureBrowserWorkspaceCheckboxElement(
951
+ element,
952
+ "check"
953
+ );
954
+ input.checked = true;
955
+ return {
956
+ mode: "web",
957
+ subaction: command.subaction,
958
+ value: {
959
+ checked: input.checked,
960
+ selector: buildBrowserWorkspaceElementSelector(input)
961
+ }
962
+ };
963
+ }
964
+ case "click":
965
+ return {
966
+ ...await activateWebBrowserWorkspaceElement(
967
+ tab,
968
+ element,
969
+ "click"
970
+ ),
971
+ subaction: command.subaction
972
+ };
973
+ case "fill": {
974
+ const control = ensureBrowserWorkspaceFormControlElement(
975
+ element,
976
+ "fill"
977
+ );
978
+ setBrowserWorkspaceControlValue(control, command.value ?? "");
979
+ return {
980
+ mode: "web",
981
+ subaction: command.subaction,
982
+ value: {
983
+ selector: buildBrowserWorkspaceElementSelector(control),
984
+ value: control.value
985
+ }
986
+ };
987
+ }
988
+ case "focus":
989
+ if (typeof element.focus === "function") {
990
+ element.focus();
991
+ }
992
+ return {
993
+ mode: "web",
994
+ subaction: command.subaction,
995
+ value: {
996
+ focused: document.activeElement === element,
997
+ selector: buildBrowserWorkspaceElementSelector(element)
998
+ }
999
+ };
1000
+ case "hover":
1001
+ element.setAttribute("data-eliza-hover", "true");
1002
+ return {
1003
+ mode: "web",
1004
+ subaction: command.subaction,
1005
+ value: {
1006
+ hovered: true,
1007
+ selector: buildBrowserWorkspaceElementSelector(element)
1008
+ }
1009
+ };
1010
+ case "type": {
1011
+ const control = ensureBrowserWorkspaceFormControlElement(
1012
+ element,
1013
+ "type"
1014
+ );
1015
+ setBrowserWorkspaceControlValue(
1016
+ control,
1017
+ `${control.value ?? ""}${command.value ?? ""}`
1018
+ );
1019
+ return {
1020
+ mode: "web",
1021
+ subaction: command.subaction,
1022
+ value: {
1023
+ selector: buildBrowserWorkspaceElementSelector(control),
1024
+ value: control.value
1025
+ }
1026
+ };
1027
+ }
1028
+ case "uncheck": {
1029
+ const input = ensureBrowserWorkspaceCheckboxElement(
1030
+ element,
1031
+ "uncheck"
1032
+ );
1033
+ input.checked = false;
1034
+ return {
1035
+ mode: "web",
1036
+ subaction: command.subaction,
1037
+ value: {
1038
+ checked: input.checked,
1039
+ selector: buildBrowserWorkspaceElementSelector(input)
1040
+ }
1041
+ };
1042
+ }
1043
+ case "text":
1044
+ case void 0:
1045
+ return {
1046
+ mode: "web",
1047
+ subaction: command.subaction,
1048
+ value: {
1049
+ element: createBrowserWorkspaceElementSummary(element),
1050
+ text: normalizeBrowserWorkspaceText(element.textContent)
1051
+ }
1052
+ };
1053
+ default:
1054
+ throw new Error(
1055
+ `Unsupported browser workspace find action: ${command.action}`
1056
+ );
1057
+ }
1058
+ }
1059
+ case "check": {
1060
+ const element = resolveTarget();
1061
+ if (!element) {
1062
+ throw new Error("Target element was not found.");
1063
+ }
1064
+ const input = ensureBrowserWorkspaceCheckboxElement(element, "check");
1065
+ input.checked = true;
1066
+ return {
1067
+ mode: "web",
1068
+ subaction: command.subaction,
1069
+ value: {
1070
+ checked: input.checked,
1071
+ selector: buildBrowserWorkspaceElementSelector(input)
1072
+ }
1073
+ };
1074
+ }
1075
+ case "fill":
1076
+ case "type": {
1077
+ const element = resolveTarget();
1078
+ if (!element) {
1079
+ throw new Error("Target element was not found.");
1080
+ }
1081
+ const control = ensureBrowserWorkspaceFormControlElement(
1082
+ element,
1083
+ command.subaction
1084
+ );
1085
+ const nextValue = command.subaction === "type" ? `${control.value ?? ""}${command.value ?? ""}` : command.value ?? "";
1086
+ setBrowserWorkspaceControlValue(control, nextValue);
1087
+ return {
1088
+ mode: "web",
1089
+ subaction: command.subaction,
1090
+ value: {
1091
+ selector: buildBrowserWorkspaceElementSelector(control),
1092
+ value: nextValue
1093
+ }
1094
+ };
1095
+ }
1096
+ case "focus": {
1097
+ const element = resolveTarget();
1098
+ if (!element) {
1099
+ throw new Error("Target element was not found.");
1100
+ }
1101
+ if (typeof element.focus === "function") {
1102
+ element.focus();
1103
+ }
1104
+ return {
1105
+ mode: "web",
1106
+ subaction: command.subaction,
1107
+ value: {
1108
+ focused: document.activeElement === element,
1109
+ selector: buildBrowserWorkspaceElementSelector(element)
1110
+ }
1111
+ };
1112
+ }
1113
+ case "hover": {
1114
+ const element = resolveTarget();
1115
+ if (!element) {
1116
+ throw new Error("Target element was not found.");
1117
+ }
1118
+ element.setAttribute("data-eliza-hover", "true");
1119
+ return {
1120
+ mode: "web",
1121
+ subaction: command.subaction,
1122
+ value: {
1123
+ hovered: true,
1124
+ selector: buildBrowserWorkspaceElementSelector(element)
1125
+ }
1126
+ };
1127
+ }
1128
+ case "keyboardinserttext":
1129
+ case "keyboardtype": {
1130
+ const active = document.activeElement;
1131
+ if (!active || !(active.tagName === "INPUT" || active.tagName === "TEXTAREA" || active.tagName === "SELECT")) {
1132
+ throw new Error(
1133
+ "Eliza browser workspace keyboard text input requires a focused input target."
1134
+ );
1135
+ }
1136
+ const control = ensureBrowserWorkspaceFormControlElement(
1137
+ active,
1138
+ command.subaction === "keyboardtype" ? "type" : "keyboardinserttext"
1139
+ );
1140
+ const nextValue = command.subaction === "keyboardtype" ? `${control.value ?? ""}${command.value ?? ""}` : command.value ?? "";
1141
+ setBrowserWorkspaceControlValue(control, nextValue);
1142
+ return {
1143
+ mode: "web",
1144
+ subaction: command.subaction,
1145
+ value: {
1146
+ selector: buildBrowserWorkspaceElementSelector(control),
1147
+ value: control.value
1148
+ }
1149
+ };
1150
+ }
1151
+ case "keydown":
1152
+ case "keyup":
1153
+ return {
1154
+ mode: "web",
1155
+ subaction: command.subaction,
1156
+ value: {
1157
+ key: command.key?.trim() || "Enter",
1158
+ selector: document.activeElement && document.activeElement instanceof Element ? buildBrowserWorkspaceElementSelector(document.activeElement) : null
1159
+ }
1160
+ };
1161
+ case "click": {
1162
+ const element = resolveTarget();
1163
+ if (!element) {
1164
+ throw new Error("Target element was not found.");
1165
+ }
1166
+ return activateWebBrowserWorkspaceElement(tab, element, "click");
1167
+ }
1168
+ case "dblclick": {
1169
+ const element = resolveTarget();
1170
+ if (!element) {
1171
+ throw new Error("Target element was not found.");
1172
+ }
1173
+ return activateWebBrowserWorkspaceElement(tab, element, "dblclick");
1174
+ }
1175
+ case "press": {
1176
+ const key = command.key?.trim() || "Enter";
1177
+ const element = resolveTarget();
1178
+ const form = findClosestBrowserWorkspaceForm(element);
1179
+ if (key === "Enter" && form) {
1180
+ await submitWebBrowserWorkspaceForm(tab, form);
1181
+ return {
1182
+ mode: "web",
1183
+ subaction: command.subaction,
1184
+ tab: cloneWebBrowserWorkspaceTabState(tab),
1185
+ value: { key, url: tab.url }
1186
+ };
1187
+ }
1188
+ return { mode: "web", subaction: command.subaction, value: { key } };
1189
+ }
1190
+ case "scroll": {
1191
+ return {
1192
+ mode: "web",
1193
+ subaction: command.subaction,
1194
+ value: scrollWebBrowserWorkspaceTarget(
1195
+ dom,
1196
+ resolveTarget(),
1197
+ command.direction ?? "down",
1198
+ command.pixels ?? 240
1199
+ )
1200
+ };
1201
+ }
1202
+ case "scrollinto": {
1203
+ const element = resolveTarget();
1204
+ if (!element) {
1205
+ throw new Error("Target element was not found.");
1206
+ }
1207
+ if (typeof element.focus === "function") {
1208
+ element.focus();
1209
+ }
1210
+ return {
1211
+ mode: "web",
1212
+ subaction: command.subaction,
1213
+ value: {
1214
+ scrolled: true,
1215
+ selector: buildBrowserWorkspaceElementSelector(element)
1216
+ }
1217
+ };
1218
+ }
1219
+ case "select": {
1220
+ const element = resolveTarget();
1221
+ if (!element) {
1222
+ throw new Error("Target element was not found.");
1223
+ }
1224
+ if (element.tagName !== "SELECT") {
1225
+ throw new Error(
1226
+ "Eliza browser workspace select requires a select target."
1227
+ );
1228
+ }
1229
+ const select = ensureBrowserWorkspaceFormControlElement(
1230
+ element,
1231
+ "select"
1232
+ );
1233
+ const option = Array.from(select.options).find(
1234
+ (entry) => entry.value === (command.value ?? "") || browserWorkspaceTextMatches(
1235
+ entry.textContent ?? "",
1236
+ command.value ?? "",
1237
+ true
1238
+ )
1239
+ );
1240
+ if (!option) {
1241
+ throw new Error("Select option was not found.");
1242
+ }
1243
+ select.value = option.value;
1244
+ option.selected = true;
1245
+ return {
1246
+ mode: "web",
1247
+ subaction: command.subaction,
1248
+ value: {
1249
+ selector: buildBrowserWorkspaceElementSelector(select),
1250
+ value: select.value
1251
+ }
1252
+ };
1253
+ }
1254
+ case "uncheck": {
1255
+ const element = resolveTarget();
1256
+ if (!element) {
1257
+ throw new Error("Target element was not found.");
1258
+ }
1259
+ const input = ensureBrowserWorkspaceCheckboxElement(element, "uncheck");
1260
+ input.checked = false;
1261
+ return {
1262
+ mode: "web",
1263
+ subaction: command.subaction,
1264
+ value: {
1265
+ checked: input.checked,
1266
+ selector: buildBrowserWorkspaceElementSelector(input)
1267
+ }
1268
+ };
1269
+ }
1270
+ case "wait": {
1271
+ assertBrowserWorkspaceJsdomScriptNotRequested(command.script, "wait");
1272
+ if (!command.selector && !command.findBy && !command.text && !command.url && !command.script && typeof command.timeoutMs === "number" && Number.isFinite(command.timeoutMs)) {
1273
+ const waitedMs = Math.max(0, command.timeoutMs);
1274
+ await sleep(waitedMs);
1275
+ return {
1276
+ mode: "web",
1277
+ subaction: command.subaction,
1278
+ value: { waitedMs }
1279
+ };
1280
+ }
1281
+ const timeoutMs = typeof command.timeoutMs === "number" && Number.isFinite(command.timeoutMs) ? Math.max(100, command.timeoutMs) : DEFAULT_TIMEOUT_MS;
1282
+ const deadline = Date.now() + timeoutMs;
1283
+ while (Date.now() <= deadline) {
1284
+ await ensureLoadedWebBrowserWorkspaceTabDocument(tab);
1285
+ const currentDom = ensureBrowserWorkspaceDom(tab);
1286
+ const currentDocument = currentDom.window.document;
1287
+ const matchesSelector = command.selector?.trim() ? (() => {
1288
+ const found = resolveBrowserWorkspaceElement(
1289
+ currentDocument,
1290
+ command.selector,
1291
+ void 0,
1292
+ command
1293
+ );
1294
+ if (command.state === "hidden") {
1295
+ return !found || !isBrowserWorkspaceElementVisible(found);
1296
+ }
1297
+ return found ? isBrowserWorkspaceElementVisible(found) : false;
1298
+ })() : false;
1299
+ const matchesFind = command.findBy ? (() => {
1300
+ const found = resolveBrowserWorkspaceFindElement(
1301
+ currentDocument,
1302
+ command
1303
+ );
1304
+ return command.state === "hidden" ? !found : Boolean(found);
1305
+ })() : false;
1306
+ const matchesText = command.text?.trim() ? normalizeBrowserWorkspaceText(
1307
+ currentDocument.body?.textContent
1308
+ ).includes(command.text.trim()) : false;
1309
+ const matchesUrl = command.url?.trim() ? tab.url.includes(command.url.trim()) : false;
1310
+ if (matchesSelector || matchesFind || matchesText || matchesUrl || !command.selector && !command.findBy && !command.text && !command.url) {
1311
+ return {
1312
+ mode: "web",
1313
+ subaction: command.subaction,
1314
+ value: {
1315
+ findBy: command.findBy ?? null,
1316
+ selector: command.selector ?? null,
1317
+ state: command.state ?? null,
1318
+ text: command.text ?? null,
1319
+ url: tab.url
1320
+ }
1321
+ };
1322
+ }
1323
+ await sleep(DEFAULT_WAIT_INTERVAL_MS);
1324
+ }
1325
+ throw new Error("Timed out waiting for browser workspace condition.");
1326
+ }
1327
+ default:
1328
+ throw new Error(
1329
+ `Unsupported web browser workspace subaction: ${command.subaction}`
1330
+ );
1331
+ }
1332
+ });
1333
+ }
1334
+ export {
1335
+ executeWebBrowserWorkspaceDomCommand,
1336
+ executeWebBrowserWorkspaceUtilityCommand,
1337
+ findWebBrowserWorkspaceTargetTabId,
1338
+ getCurrentWebBrowserWorkspaceTabState,
1339
+ getWebBrowserWorkspaceTabIndex,
1340
+ getWebBrowserWorkspaceTabState
1341
+ };
1342
+ //# sourceMappingURL=browser-workspace-web.js.map