@elizaos/plugin-browser 2.0.0-beta.1 → 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 (169) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +106 -64
  3. package/dist/actions/browser-autofill-login.d.ts.map +1 -1
  4. package/dist/actions/browser-autofill-login.js.map +1 -1
  5. package/dist/actions/browser.d.ts +5 -6
  6. package/dist/actions/browser.d.ts.map +1 -1
  7. package/dist/actions/browser.js +54 -59
  8. package/dist/actions/browser.js.map +1 -1
  9. package/dist/actions/manage-browser-bridge.d.ts.map +1 -1
  10. package/dist/actions/manage-browser-bridge.js +10 -14
  11. package/dist/actions/manage-browser-bridge.js.map +1 -1
  12. package/dist/bridge-policy.d.ts +10 -0
  13. package/dist/bridge-policy.d.ts.map +1 -0
  14. package/dist/bridge-policy.js +37 -0
  15. package/dist/bridge-policy.js.map +1 -0
  16. package/dist/bridge-readiness.d.ts +16 -0
  17. package/dist/bridge-readiness.d.ts.map +1 -0
  18. package/dist/bridge-readiness.js +82 -0
  19. package/dist/bridge-readiness.js.map +1 -0
  20. package/dist/bridge-records.d.ts +9 -0
  21. package/dist/bridge-records.d.ts.map +1 -0
  22. package/dist/bridge-records.js +37 -0
  23. package/dist/bridge-records.js.map +1 -0
  24. package/dist/browser-capture-hooks.d.ts +9 -0
  25. package/dist/browser-capture-hooks.d.ts.map +1 -0
  26. package/dist/browser-capture-hooks.js +15 -0
  27. package/dist/browser-capture-hooks.js.map +1 -0
  28. package/dist/browser-service.d.ts +22 -4
  29. package/dist/browser-service.d.ts.map +1 -1
  30. package/dist/browser-service.js +63 -15
  31. package/dist/browser-service.js.map +1 -1
  32. package/dist/browser-workspace-hooks.d.ts +14 -0
  33. package/dist/browser-workspace-hooks.d.ts.map +1 -0
  34. package/dist/browser-workspace-hooks.js +15 -0
  35. package/dist/browser-workspace-hooks.js.map +1 -0
  36. package/dist/companion-auth.d.ts +34 -0
  37. package/dist/companion-auth.d.ts.map +1 -0
  38. package/dist/companion-auth.js +98 -0
  39. package/dist/companion-auth.js.map +1 -0
  40. package/dist/index.d.ts +9 -3
  41. package/dist/index.d.ts.map +1 -1
  42. package/dist/index.js +46 -11
  43. package/dist/index.js.map +1 -1
  44. package/dist/message-adapter.d.ts +9 -0
  45. package/dist/message-adapter.d.ts.map +1 -0
  46. package/dist/message-adapter.js +104 -0
  47. package/dist/message-adapter.js.map +1 -0
  48. package/dist/packaging.d.ts.map +1 -1
  49. package/dist/packaging.js +2 -0
  50. package/dist/packaging.js.map +1 -1
  51. package/dist/password-manager-bridge.d.ts +50 -0
  52. package/dist/password-manager-bridge.d.ts.map +1 -0
  53. package/dist/password-manager-bridge.js +437 -0
  54. package/dist/password-manager-bridge.js.map +1 -0
  55. package/dist/plugin.d.ts.map +1 -1
  56. package/dist/plugin.js +8 -4
  57. package/dist/plugin.js.map +1 -1
  58. package/dist/providers/workspace.d.ts +1 -1
  59. package/dist/providers/workspace.js.map +1 -1
  60. package/dist/routes/bridge.d.ts.map +1 -1
  61. package/dist/routes/bridge.js +63 -14
  62. package/dist/routes/bridge.js.map +1 -1
  63. package/dist/routes/workspace-setup.d.ts.map +1 -1
  64. package/dist/routes/workspace-setup.js +1 -1
  65. package/dist/routes/workspace-setup.js.map +1 -1
  66. package/dist/routes/workspace.d.ts +1 -2
  67. package/dist/routes/workspace.d.ts.map +1 -1
  68. package/dist/routes/workspace.js +63 -3
  69. package/dist/routes/workspace.js.map +1 -1
  70. package/dist/schema.d.ts +2 -2
  71. package/dist/schema.js.map +1 -1
  72. package/dist/service.d.ts +1 -1
  73. package/dist/service.d.ts.map +1 -1
  74. package/dist/service.js.map +1 -1
  75. package/dist/targets/bridge-target.d.ts +1 -1
  76. package/dist/targets/bridge-target.d.ts.map +1 -1
  77. package/dist/targets/bridge-target.js.map +1 -1
  78. package/dist/targets/stagehand-target.d.ts +3 -0
  79. package/dist/targets/stagehand-target.d.ts.map +1 -0
  80. package/dist/targets/stagehand-target.js +187 -0
  81. package/dist/targets/stagehand-target.js.map +1 -0
  82. package/dist/workspace/browser-capture.d.ts +1 -1
  83. package/dist/workspace/browser-capture.js.map +1 -1
  84. package/dist/workspace/browser-workspace-desktop.d.ts +1 -1
  85. package/dist/workspace/browser-workspace-desktop.d.ts.map +1 -1
  86. package/dist/workspace/browser-workspace-desktop.js +47 -25
  87. package/dist/workspace/browser-workspace-desktop.js.map +1 -1
  88. package/dist/workspace/browser-workspace-forms.d.ts.map +1 -1
  89. package/dist/workspace/browser-workspace-forms.js +1 -1
  90. package/dist/workspace/browser-workspace-forms.js.map +1 -1
  91. package/dist/workspace/browser-workspace-helpers.d.ts +7 -0
  92. package/dist/workspace/browser-workspace-helpers.d.ts.map +1 -1
  93. package/dist/workspace/browser-workspace-helpers.js +37 -0
  94. package/dist/workspace/browser-workspace-helpers.js.map +1 -1
  95. package/dist/workspace/browser-workspace-network.d.ts +1 -1
  96. package/dist/workspace/browser-workspace-network.d.ts.map +1 -1
  97. package/dist/workspace/browser-workspace-types.d.ts +15 -0
  98. package/dist/workspace/browser-workspace-types.d.ts.map +1 -1
  99. package/dist/workspace/browser-workspace-types.js.map +1 -1
  100. package/dist/workspace/browser-workspace-web.d.ts.map +1 -1
  101. package/dist/workspace/browser-workspace-web.js +15 -88
  102. package/dist/workspace/browser-workspace-web.js.map +1 -1
  103. package/dist/workspace/browser-workspace.d.ts +1 -1
  104. package/dist/workspace/browser-workspace.d.ts.map +1 -1
  105. package/dist/workspace/browser-workspace.js +9 -4
  106. package/dist/workspace/browser-workspace.js.map +1 -1
  107. package/package.json +28 -7
  108. package/dist/actions/browser-autofill-login.d.js +0 -1
  109. package/dist/actions/browser-autofill-login.d.js.map +0 -1
  110. package/dist/actions/browser.d.js +0 -1
  111. package/dist/actions/browser.d.js.map +0 -1
  112. package/dist/actions/manage-browser-bridge.d.js +0 -1
  113. package/dist/actions/manage-browser-bridge.d.js.map +0 -1
  114. package/dist/ambient-jsdom.d.js +0 -1
  115. package/dist/ambient-jsdom.d.js.map +0 -1
  116. package/dist/browser-service.d.js +0 -1
  117. package/dist/browser-service.d.js.map +0 -1
  118. package/dist/contracts.d.js +0 -1
  119. package/dist/contracts.d.js.map +0 -1
  120. package/dist/index.d.js +0 -21
  121. package/dist/index.d.js.map +0 -1
  122. package/dist/lifeops-session-contracts.d.js +0 -1
  123. package/dist/lifeops-session-contracts.d.js.map +0 -1
  124. package/dist/packaging.d.js +0 -1
  125. package/dist/packaging.d.js.map +0 -1
  126. package/dist/plugin.d.js +0 -1
  127. package/dist/plugin.d.js.map +0 -1
  128. package/dist/providers/workspace.d.js +0 -1
  129. package/dist/providers/workspace.d.js.map +0 -1
  130. package/dist/routes/bridge.d.js +0 -1
  131. package/dist/routes/bridge.d.js.map +0 -1
  132. package/dist/routes/workspace-account-gate.d.js +0 -1
  133. package/dist/routes/workspace-account-gate.d.js.map +0 -1
  134. package/dist/routes/workspace-setup.d.js +0 -1
  135. package/dist/routes/workspace-setup.d.js.map +0 -1
  136. package/dist/routes/workspace.d.js +0 -1
  137. package/dist/routes/workspace.d.js.map +0 -1
  138. package/dist/schema.d.js +0 -1
  139. package/dist/schema.d.js.map +0 -1
  140. package/dist/service.d.js +0 -1
  141. package/dist/service.d.js.map +0 -1
  142. package/dist/targets/bridge-target.d.js +0 -1
  143. package/dist/targets/bridge-target.d.js.map +0 -1
  144. package/dist/workspace/browser-capture.d.js +0 -1
  145. package/dist/workspace/browser-capture.d.js.map +0 -1
  146. package/dist/workspace/browser-workspace-desktop.d.js +0 -1
  147. package/dist/workspace/browser-workspace-desktop.d.js.map +0 -1
  148. package/dist/workspace/browser-workspace-elements.d.js +0 -1
  149. package/dist/workspace/browser-workspace-elements.d.js.map +0 -1
  150. package/dist/workspace/browser-workspace-forms.d.js +0 -1
  151. package/dist/workspace/browser-workspace-forms.d.js.map +0 -1
  152. package/dist/workspace/browser-workspace-helpers.d.js +0 -1
  153. package/dist/workspace/browser-workspace-helpers.d.js.map +0 -1
  154. package/dist/workspace/browser-workspace-jsdom.d.js +0 -1
  155. package/dist/workspace/browser-workspace-jsdom.d.js.map +0 -1
  156. package/dist/workspace/browser-workspace-network.d.js +0 -1
  157. package/dist/workspace/browser-workspace-network.d.js.map +0 -1
  158. package/dist/workspace/browser-workspace-snapshots.d.js +0 -1
  159. package/dist/workspace/browser-workspace-snapshots.d.js.map +0 -1
  160. package/dist/workspace/browser-workspace-state.d.js +0 -1
  161. package/dist/workspace/browser-workspace-state.d.js.map +0 -1
  162. package/dist/workspace/browser-workspace-types.d.js +0 -1
  163. package/dist/workspace/browser-workspace-types.d.js.map +0 -1
  164. package/dist/workspace/browser-workspace-web.d.js +0 -1
  165. package/dist/workspace/browser-workspace-web.d.js.map +0 -1
  166. package/dist/workspace/browser-workspace.d.js +0 -11
  167. package/dist/workspace/browser-workspace.d.js.map +0 -1
  168. package/dist/workspace/index.d.js +0 -3
  169. package/dist/workspace/index.d.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/workspace/browser-workspace.ts"],"sourcesContent":["/**\n * Browser workspace — public API surface.\n *\n * Implementation is split across sibling modules:\n * browser-workspace-types.ts — all exported types and interfaces\n * browser-workspace-state.ts — global mutable state and CRUD helpers\n * browser-workspace-helpers.ts — small utilities, error factories, command normalization\n * browser-workspace-jsdom.ts — JSDOM loading, DOM creation, runtime setup\n * browser-workspace-elements.ts — element finding, selector parsing, inspection\n * browser-workspace-network.ts — network interception, HAR, tracked fetch\n * browser-workspace-forms.ts — form control interaction, activation, scrolling\n * browser-workspace-snapshots.ts — document snapshots, diff, PDF/screenshot\n * browser-workspace-desktop.ts — desktop bridge HTTP client and script generators\n * browser-workspace-web.ts — web-mode command execution\n *\n * This file re-exports every public symbol so external consumers are unaffected.\n */\n\nimport * as fsp from \"node:fs/promises\";\nimport * as path from \"node:path\";\n\n// ── Re-export types ──────────────────────────────────────────────────\nexport { BROWSER_WORKSPACE_CONNECTOR_AUTH_STATES } from \"./browser-workspace-types.js\";\nexport type {\n AcquireBrowserWorkspaceConnectorSessionRequest,\n BrowserWorkspaceBridgeConfig,\n BrowserWorkspaceClipboardAction,\n BrowserWorkspaceCommand,\n BrowserWorkspaceCommandResult,\n BrowserWorkspaceConnectorAuthState,\n BrowserWorkspaceConnectorCompanionRef,\n BrowserWorkspaceConnectorSessionHandle,\n BrowserWorkspaceConnectorSessionKind,\n BrowserWorkspaceConnectorSessionRef,\n BrowserWorkspaceConsoleAction,\n BrowserWorkspaceCookieAction,\n BrowserWorkspaceDialogAction,\n BrowserWorkspaceDiffAction,\n BrowserWorkspaceDomElementSummary,\n BrowserWorkspaceFindAction,\n BrowserWorkspaceFindBy,\n BrowserWorkspaceFrameAction,\n BrowserWorkspaceGetMode,\n BrowserWorkspaceMode,\n BrowserWorkspaceMouseAction,\n BrowserWorkspaceMouseButton,\n BrowserWorkspaceNetworkAction,\n BrowserWorkspaceOperation,\n BrowserWorkspaceProfilerAction,\n BrowserWorkspaceScrollDirection,\n BrowserWorkspaceSetAction,\n BrowserWorkspaceSnapshot,\n BrowserWorkspaceStateAction,\n BrowserWorkspaceStorageAction,\n BrowserWorkspaceStorageArea,\n BrowserWorkspaceSubaction,\n BrowserWorkspaceTab,\n BrowserWorkspaceTabAction,\n BrowserWorkspaceTabKind,\n BrowserWorkspaceTraceAction,\n BrowserWorkspaceWaitState,\n BrowserWorkspaceWindowAction,\n EvaluateBrowserWorkspaceTabRequest,\n NavigateBrowserWorkspaceTabRequest,\n OpenBrowserWorkspaceTabRequest,\n} from \"./browser-workspace-types.js\";\n\nimport type {\n AcquireBrowserWorkspaceConnectorSessionRequest,\n BrowserWorkspaceCommand,\n BrowserWorkspaceCommandResult,\n BrowserWorkspaceConnectorAuthState,\n BrowserWorkspaceConnectorCompanionRef,\n BrowserWorkspaceConnectorSessionHandle,\n BrowserWorkspaceConnectorSessionRef,\n BrowserWorkspaceMode,\n BrowserWorkspaceSnapshot,\n BrowserWorkspaceTab,\n BrowserWorkspaceTabKind,\n EvaluateBrowserWorkspaceTabRequest,\n NavigateBrowserWorkspaceTabRequest,\n OpenBrowserWorkspaceTabRequest,\n} from \"./browser-workspace-types.js\";\n\n// ── Re-export state ──────────────────────────────────────────────────\nexport { __resetBrowserWorkspaceStateForTests } from \"./browser-workspace-state.js\";\n\n// ── Re-export desktop bridge ─────────────────────────────────────────\nimport {\n evaluateBrowserWorkspaceTab as evaluateBrowserWorkspaceTabDesktop,\n executeDesktopBrowserWorkspaceDomCommand,\n executeDesktopBrowserWorkspaceUtilityCommand,\n getBrowserWorkspaceUnavailableMessage,\n getDesktopBrowserWorkspaceSessionState,\n getDesktopBrowserWorkspaceSnapshotRecord,\n isBrowserWorkspaceBridgeConfigured,\n loadDesktopBrowserWorkspaceSessionState,\n requestBrowserWorkspace,\n resolveBrowserWorkspaceBridgeConfig,\n resolveDesktopBrowserWorkspaceTargetTabId,\n snapshotBrowserWorkspaceTab as snapshotBrowserWorkspaceTabDesktop,\n} from \"./browser-workspace-desktop.js\";\n// ── Re-export helpers ────────────────────────────────────────────────\nimport {\n assertBrowserWorkspaceConnectorSecretsNotExported,\n assertBrowserWorkspaceUrl,\n createBrowserWorkspaceNotFoundError,\n DEFAULT_WEB_PARTITION,\n inferBrowserWorkspaceTitle,\n normalizeBrowserWorkspaceCommand,\n resolveBrowserWorkspaceCommandPartition,\n resolveConnectorBrowserWorkspacePartition,\n sleep,\n} from \"./browser-workspace-helpers.js\";\n\nexport {\n getBrowserWorkspaceUnavailableMessage,\n isBrowserWorkspaceBridgeConfigured,\n resolveBrowserWorkspaceBridgeConfig,\n};\n\n// ── Re-export forms ─────────────────────────────────────────────────\nimport {\n clearWebBrowserWorkspaceTabElementRefs,\n cloneWebBrowserWorkspaceTabState,\n loadWebBrowserWorkspaceTabDocument,\n pushWebBrowserWorkspaceHistory,\n} from \"./browser-workspace-forms.js\";\n// ── Re-export network ────────────────────────────────────────────────\nimport { browserWorkspacePageFetch } from \"./browser-workspace-helpers.js\";\n// ── Re-export jsdom ──────────────────────────────────────────────────\nimport {\n createEmptyWebBrowserWorkspaceDom,\n installBrowserWorkspaceWebRuntime,\n} from \"./browser-workspace-jsdom.js\";\n// ── Re-export snapshots ──────────────────────────────────────────────\nimport {\n createBrowserWorkspacePdfBuffer,\n createBrowserWorkspaceSnapshotRecord,\n diffBrowserWorkspaceSnapshots,\n} from \"./browser-workspace-snapshots.js\";\n// ── Imports for state ────────────────────────────────────────────────\nimport {\n clearBrowserWorkspaceElementRefs,\n clearBrowserWorkspaceRuntimeState,\n getBrowserWorkspaceRuntimeState,\n getBrowserWorkspaceTimestamp,\n resetBrowserWorkspaceRuntimeNavigationState,\n webWorkspaceState,\n withWebStateLock,\n} from \"./browser-workspace-state.js\";\n// ── Re-export web ────────────────────────────────────────────────────\nimport {\n executeWebBrowserWorkspaceDomCommand,\n executeWebBrowserWorkspaceUtilityCommand,\n findWebBrowserWorkspaceTargetTabId,\n getWebBrowserWorkspaceTabIndex,\n getWebBrowserWorkspaceTabState,\n} from \"./browser-workspace-web.js\";\n\nconst AGENT_BROWSER_WORKSPACE_PARTITION = \"persist:eliza-browser-agent\";\nconst CONNECTOR_MANUAL_STATES = new Set<BrowserWorkspaceConnectorAuthState>([\n \"auth_pending\",\n \"needs_reauth\",\n \"manual_handoff\",\n]);\n\n// ────────────────────────────────────────────────────────────────────\n// Public API functions\n// ────────────────────────────────────────────────────────────────────\n\nexport function getBrowserWorkspaceMode(\n env: NodeJS.ProcessEnv = process.env,\n): BrowserWorkspaceMode {\n return isBrowserWorkspaceBridgeConfigured(env) ? \"desktop\" : \"web\";\n}\n\nexport function resolveBrowserWorkspaceConnectorPartition(\n provider: string,\n accountId: string,\n): string {\n return resolveConnectorBrowserWorkspacePartition(provider, accountId);\n}\n\nfunction normalizeConnectorAuthState(\n value: BrowserWorkspaceConnectorAuthState | undefined,\n fallback: BrowserWorkspaceConnectorAuthState,\n): BrowserWorkspaceConnectorAuthState {\n switch (value) {\n case \"unknown\":\n case \"ready\":\n case \"auth_pending\":\n case \"needs_reauth\":\n case \"manual_handoff\":\n return value;\n default:\n return fallback;\n }\n}\n\nfunction connectorSessionRequiresManualHandoff(\n state: BrowserWorkspaceConnectorAuthState,\n): boolean {\n return CONNECTOR_MANUAL_STATES.has(state);\n}\n\nfunction createConnectorSessionRef(\n ref: BrowserWorkspaceConnectorSessionRef,\n): BrowserWorkspaceConnectorSessionRef {\n return {\n kind: ref.kind,\n handleId: ref.handleId,\n partition: ref.partition,\n tabId: ref.tabId,\n browser: ref.browser,\n companionId: ref.companionId,\n profileId: ref.profileId,\n profileLabel: ref.profileLabel,\n };\n}\n\nfunction createConnectorSessionHandle(args: {\n provider: string;\n accountId: string;\n authState: BrowserWorkspaceConnectorAuthState;\n ref: BrowserWorkspaceConnectorSessionRef;\n created: boolean;\n message?: string | null;\n}): BrowserWorkspaceConnectorSessionHandle {\n const sessionRef = createConnectorSessionRef(args.ref);\n return {\n provider: args.provider,\n accountId: args.accountId,\n authState: args.authState,\n requiresManualHandoff: connectorSessionRequiresManualHandoff(\n args.authState,\n ),\n sessionRef,\n partition: sessionRef.partition,\n tabId: sessionRef.tabId,\n companionId: sessionRef.companionId,\n browser: sessionRef.browser,\n profileId: sessionRef.profileId,\n profileLabel: sessionRef.profileLabel,\n created: args.created,\n message: args.message ?? null,\n };\n}\n\nfunction createBrowserBridgeConnectorSessionHandle(args: {\n provider: string;\n accountId: string;\n companion: BrowserWorkspaceConnectorCompanionRef;\n authState: BrowserWorkspaceConnectorAuthState;\n message?: string | null;\n}): BrowserWorkspaceConnectorSessionHandle {\n const browser = args.companion.browser?.trim() || null;\n const companionId = args.companion.companionId?.trim() || null;\n const profileId = args.companion.profileId?.trim() || null;\n const profileLabel = args.companion.profileLabel?.trim() || null;\n return createConnectorSessionHandle({\n provider: args.provider,\n accountId: args.accountId,\n authState: args.authState,\n created: false,\n message: args.message,\n ref: {\n kind: \"browser-bridge-companion\",\n handleId: [\n \"browser-bridge\",\n browser ?? \"browser\",\n companionId ?? profileId ?? \"profile\",\n args.provider,\n args.accountId,\n ].join(\":\"),\n partition: null,\n tabId: null,\n browser,\n companionId,\n profileId,\n profileLabel,\n },\n });\n}\n\nasync function assertDesktopBrowserWorkspaceCanAccessProfileSecrets(\n command: BrowserWorkspaceCommand,\n env: NodeJS.ProcessEnv,\n operation: string,\n): Promise<void> {\n const id = await resolveDesktopBrowserWorkspaceTargetTabId(command, env);\n const tabs = await listBrowserWorkspaceTabs(env);\n const tab = tabs.find((entry) => entry.id === id) ?? null;\n assertBrowserWorkspaceConnectorSecretsNotExported(tab?.partition, operation);\n}\n\nexport async function acquireBrowserWorkspaceConnectorSession(\n request: AcquireBrowserWorkspaceConnectorSessionRequest,\n env: NodeJS.ProcessEnv = process.env,\n): Promise<BrowserWorkspaceConnectorSessionHandle> {\n const provider = request.provider.trim();\n const accountId = request.accountId.trim();\n if (!provider) {\n throw new Error(\"Eliza browser connector session requires provider.\");\n }\n if (!accountId) {\n throw new Error(\"Eliza browser connector session requires accountId.\");\n }\n\n const companion = request.companion ?? null;\n if (companion?.profileId || companion?.companionId) {\n const authState = normalizeConnectorAuthState(\n request.authState,\n \"manual_handoff\",\n );\n return createBrowserBridgeConnectorSessionHandle({\n provider,\n accountId,\n companion,\n authState,\n message:\n request.manualHandoffReason ??\n \"Use the paired browser companion profile to finish login, MFA, or CAPTCHA if required.\",\n });\n }\n\n if (isBrowserWorkspaceBridgeConfigured(env)) {\n const payload = await requestBrowserWorkspace<{\n session: BrowserWorkspaceConnectorSessionHandle;\n }>(\n \"/sessions/acquire\",\n {\n method: \"POST\",\n body: JSON.stringify({\n accountId,\n authState: request.authState,\n manualHandoffReason: request.manualHandoffReason,\n provider,\n reuse: request.reuse,\n show: request.show,\n title: request.title,\n url: request.url,\n }),\n },\n env,\n );\n return payload.session;\n }\n\n const partition = resolveBrowserWorkspaceConnectorPartition(\n provider,\n accountId,\n );\n const reuse = request.reuse !== false;\n const tabs = reuse ? await listBrowserWorkspaceTabs(env) : [];\n const existing = tabs.find((tab) => tab.partition === partition) ?? null;\n let tab = existing;\n let created = false;\n\n if (!tab) {\n tab = await openBrowserWorkspaceTab(\n {\n kind: \"internal\",\n partition,\n show: request.show ?? true,\n title: request.title,\n url: request.url,\n },\n env,\n );\n created = true;\n } else if (request.show === true) {\n tab = await showBrowserWorkspaceTab(tab.id, env);\n }\n\n const authState = normalizeConnectorAuthState(\n request.authState,\n created ? \"auth_pending\" : \"ready\",\n );\n return createConnectorSessionHandle({\n provider,\n accountId,\n authState,\n created,\n message:\n request.manualHandoffReason ??\n (connectorSessionRequiresManualHandoff(authState)\n ? \"Manual login, MFA, or CAPTCHA may be required in this isolated connector browser session.\"\n : null),\n ref: {\n kind: \"internal-browser\",\n handleId: `internal-browser:${partition}`,\n partition,\n tabId: tab.id,\n browser: null,\n companionId: null,\n profileId: null,\n profileLabel: null,\n },\n });\n}\n\nexport async function getBrowserWorkspaceSnapshot(\n env: NodeJS.ProcessEnv = process.env,\n): Promise<BrowserWorkspaceSnapshot> {\n return {\n mode: getBrowserWorkspaceMode(env),\n tabs: await listBrowserWorkspaceTabs(env),\n };\n}\n\nexport async function listBrowserWorkspaceTabs(\n env: NodeJS.ProcessEnv = process.env,\n): Promise<BrowserWorkspaceTab[]> {\n if (!isBrowserWorkspaceBridgeConfigured(env)) {\n return webWorkspaceState.tabs.map((tab) => ({\n id: tab.id,\n title: tab.title,\n url: tab.url,\n partition: tab.partition,\n kind: tab.kind,\n visible: tab.visible,\n createdAt: tab.createdAt,\n updatedAt: tab.updatedAt,\n lastFocusedAt: tab.lastFocusedAt,\n }));\n }\n\n const payload = await requestBrowserWorkspace<{\n tabs?: BrowserWorkspaceTab[];\n }>(\"/tabs\", undefined, env);\n return Array.isArray(payload.tabs) ? payload.tabs : [];\n}\n\nexport async function openBrowserWorkspaceTab(\n request: OpenBrowserWorkspaceTabRequest,\n env: NodeJS.ProcessEnv = process.env,\n): Promise<BrowserWorkspaceTab> {\n if (!isBrowserWorkspaceBridgeConfigured(env)) {\n return withWebStateLock(() => {\n const kind: BrowserWorkspaceTabKind =\n request.kind === \"internal\" ? \"internal\" : \"standard\";\n const now = getBrowserWorkspaceTimestamp();\n const url = assertBrowserWorkspaceUrl(\n request.url?.trim() || \"about:blank\",\n );\n const visible = request.show === true;\n const id = `btab_${webWorkspaceState.nextId++}`;\n const dom =\n url === \"about:blank\" ? createEmptyWebBrowserWorkspaceDom(url) : null;\n const tab = {\n id,\n title: request.title?.trim() || inferBrowserWorkspaceTitle(url),\n url,\n partition: request.partition?.trim() || DEFAULT_WEB_PARTITION,\n kind,\n visible,\n createdAt: now,\n updatedAt: now,\n lastFocusedAt: visible ? now : null,\n dom,\n history: [url],\n historyIndex: 0,\n loadedUrl: url === \"about:blank\" ? url : null,\n };\n if (dom) {\n installBrowserWorkspaceWebRuntime(tab, dom);\n }\n getBrowserWorkspaceRuntimeState(\"web\", tab.id);\n clearWebBrowserWorkspaceTabElementRefs(tab.id);\n if (tab.visible) {\n webWorkspaceState.tabs = webWorkspaceState.tabs.map((entry) => ({\n ...entry,\n visible: false,\n }));\n }\n webWorkspaceState.tabs = [...webWorkspaceState.tabs, tab];\n return cloneWebBrowserWorkspaceTabState(tab);\n });\n }\n\n const payload = await requestBrowserWorkspace<{ tab: BrowserWorkspaceTab }>(\n \"/tabs\",\n {\n method: \"POST\",\n body: JSON.stringify(request),\n },\n env,\n );\n return payload.tab;\n}\n\nexport async function navigateBrowserWorkspaceTab(\n request: NavigateBrowserWorkspaceTabRequest,\n env: NodeJS.ProcessEnv = process.env,\n): Promise<BrowserWorkspaceTab> {\n const nextUrl = assertBrowserWorkspaceUrl(request.url);\n\n if (!isBrowserWorkspaceBridgeConfigured(env)) {\n return withWebStateLock(() => {\n const index = getWebBrowserWorkspaceTabIndex(request.id);\n if (index < 0) {\n throw createBrowserWorkspaceNotFoundError(request.id);\n }\n\n const existing = webWorkspaceState.tabs[index];\n const updatedAt = getBrowserWorkspaceTimestamp();\n const state = getBrowserWorkspaceRuntimeState(\"web\", existing.id);\n clearWebBrowserWorkspaceTabElementRefs(existing.id);\n pushWebBrowserWorkspaceHistory(existing, nextUrl);\n const nextDom =\n nextUrl === \"about:blank\"\n ? createEmptyWebBrowserWorkspaceDom(nextUrl)\n : null;\n const nextTab = {\n ...existing,\n title: inferBrowserWorkspaceTitle(nextUrl),\n url: nextUrl,\n updatedAt,\n dom: nextDom,\n loadedUrl: nextUrl === \"about:blank\" ? nextUrl : null,\n };\n if (nextDom) {\n installBrowserWorkspaceWebRuntime(nextTab, nextDom);\n }\n resetBrowserWorkspaceRuntimeNavigationState(state);\n webWorkspaceState.tabs[index] = nextTab;\n return cloneWebBrowserWorkspaceTabState(nextTab);\n });\n }\n\n const navigateBody: { url: string; partition?: string } = { url: nextUrl };\n if (request.partition !== undefined) {\n navigateBody.partition = request.partition;\n }\n\n const payload = await requestBrowserWorkspace<{ tab: BrowserWorkspaceTab }>(\n `/tabs/${encodeURIComponent(request.id)}/navigate`,\n {\n method: \"POST\",\n body: JSON.stringify(navigateBody),\n },\n env,\n );\n return payload.tab;\n}\n\nexport async function showBrowserWorkspaceTab(\n id: string,\n env: NodeJS.ProcessEnv = process.env,\n): Promise<BrowserWorkspaceTab> {\n if (!isBrowserWorkspaceBridgeConfigured(env)) {\n return withWebStateLock(() => {\n getWebBrowserWorkspaceTabState(id);\n const lastFocusedAt = getBrowserWorkspaceTimestamp();\n webWorkspaceState.tabs = webWorkspaceState.tabs.map((tab) => ({\n ...tab,\n visible: tab.id === id,\n lastFocusedAt: tab.id === id ? lastFocusedAt : tab.lastFocusedAt,\n updatedAt: tab.id === id ? lastFocusedAt : tab.updatedAt,\n }));\n return cloneWebBrowserWorkspaceTabState(\n getWebBrowserWorkspaceTabState(id),\n );\n });\n }\n\n const payload = await requestBrowserWorkspace<{ tab: BrowserWorkspaceTab }>(\n `/tabs/${encodeURIComponent(id)}/show`,\n { method: \"POST\" },\n env,\n );\n return payload.tab;\n}\n\nexport async function hideBrowserWorkspaceTab(\n id: string,\n env: NodeJS.ProcessEnv = process.env,\n): Promise<BrowserWorkspaceTab> {\n if (!isBrowserWorkspaceBridgeConfigured(env)) {\n return withWebStateLock(() => {\n const index = getWebBrowserWorkspaceTabIndex(id);\n if (index < 0) {\n throw createBrowserWorkspaceNotFoundError(id);\n }\n\n const updatedAt = getBrowserWorkspaceTimestamp();\n const nextTab = {\n ...webWorkspaceState.tabs[index],\n visible: false,\n updatedAt,\n };\n webWorkspaceState.tabs[index] = nextTab;\n return cloneWebBrowserWorkspaceTabState(nextTab);\n });\n }\n\n const payload = await requestBrowserWorkspace<{ tab: BrowserWorkspaceTab }>(\n `/tabs/${encodeURIComponent(id)}/hide`,\n { method: \"POST\" },\n env,\n );\n return payload.tab;\n}\n\nexport async function closeBrowserWorkspaceTab(\n id: string,\n env: NodeJS.ProcessEnv = process.env,\n): Promise<boolean> {\n if (!isBrowserWorkspaceBridgeConfigured(env)) {\n return withWebStateLock(() => {\n const initialLength = webWorkspaceState.tabs.length;\n clearWebBrowserWorkspaceTabElementRefs(id);\n clearBrowserWorkspaceRuntimeState(\"web\", id);\n webWorkspaceState.tabs = webWorkspaceState.tabs.filter(\n (tab) => tab.id !== id,\n );\n return webWorkspaceState.tabs.length !== initialLength;\n });\n }\n\n const payload = await requestBrowserWorkspace<{ closed?: boolean }>(\n `/tabs/${encodeURIComponent(id)}`,\n { method: \"DELETE\" },\n env,\n );\n return payload.closed === true;\n}\n\nexport async function evaluateBrowserWorkspaceTab(\n request: EvaluateBrowserWorkspaceTabRequest,\n env: NodeJS.ProcessEnv = process.env,\n): Promise<unknown> {\n return evaluateBrowserWorkspaceTabDesktop(request, env);\n}\n\nexport async function snapshotBrowserWorkspaceTab(\n id: string,\n env: NodeJS.ProcessEnv = process.env,\n): Promise<{ data: string }> {\n return snapshotBrowserWorkspaceTabDesktop(id, env);\n}\n\n// ────────────────────────────────────────────────────────────────────\n// Main command router\n// ────────────────────────────────────────────────────────────────────\n\nexport async function executeBrowserWorkspaceCommand(\n command: BrowserWorkspaceCommand,\n env: NodeJS.ProcessEnv = process.env,\n): Promise<BrowserWorkspaceCommandResult> {\n command = normalizeBrowserWorkspaceCommand(command);\n switch (command.subaction) {\n case \"batch\": {\n const steps = Array.isArray(command.steps) ? command.steps : [];\n if (steps.length === 0) {\n throw new Error(\n \"Eliza browser workspace batch requires at least one step.\",\n );\n }\n const results: BrowserWorkspaceCommandResult[] = [];\n for (const step of steps) {\n results.push(await executeBrowserWorkspaceCommand(step, env));\n }\n return {\n mode: getBrowserWorkspaceMode(env),\n subaction: command.subaction,\n steps: results,\n value: results.at(-1)?.value,\n };\n }\n case \"list\":\n return {\n mode: getBrowserWorkspaceMode(env),\n subaction: command.subaction,\n tabs: await listBrowserWorkspaceTabs(env),\n };\n case \"open\": {\n const tab = await openBrowserWorkspaceTab(\n {\n partition: resolveBrowserWorkspaceCommandPartition(\n command,\n AGENT_BROWSER_WORKSPACE_PARTITION,\n ),\n show: command.show,\n title: command.title,\n url: command.url,\n },\n env,\n );\n clearBrowserWorkspaceElementRefs(getBrowserWorkspaceMode(env), tab.id);\n return {\n mode: getBrowserWorkspaceMode(env),\n subaction: command.subaction,\n tab,\n };\n }\n case \"navigate\": {\n const id = isBrowserWorkspaceBridgeConfigured(env)\n ? await resolveDesktopBrowserWorkspaceTargetTabId(command, env)\n : findWebBrowserWorkspaceTargetTabId(command);\n clearBrowserWorkspaceElementRefs(getBrowserWorkspaceMode(env), id);\n return {\n mode: getBrowserWorkspaceMode(env),\n subaction: command.subaction,\n tab: await navigateBrowserWorkspaceTab(\n {\n id,\n url: command.url ?? \"\",\n },\n env,\n ),\n };\n }\n case \"show\": {\n const id = isBrowserWorkspaceBridgeConfigured(env)\n ? await resolveDesktopBrowserWorkspaceTargetTabId(command, env)\n : findWebBrowserWorkspaceTargetTabId(command);\n return {\n mode: getBrowserWorkspaceMode(env),\n subaction: command.subaction,\n tab: await showBrowserWorkspaceTab(id, env),\n };\n }\n case \"hide\": {\n const id = isBrowserWorkspaceBridgeConfigured(env)\n ? await resolveDesktopBrowserWorkspaceTargetTabId(command, env)\n : findWebBrowserWorkspaceTargetTabId(command);\n return {\n mode: getBrowserWorkspaceMode(env),\n subaction: command.subaction,\n tab: await hideBrowserWorkspaceTab(id, env),\n };\n }\n case \"close\": {\n const id = isBrowserWorkspaceBridgeConfigured(env)\n ? await resolveDesktopBrowserWorkspaceTargetTabId(command, env)\n : findWebBrowserWorkspaceTargetTabId(command);\n clearBrowserWorkspaceElementRefs(getBrowserWorkspaceMode(env), id);\n clearBrowserWorkspaceRuntimeState(getBrowserWorkspaceMode(env), id);\n return {\n mode: getBrowserWorkspaceMode(env),\n subaction: command.subaction,\n closed: await closeBrowserWorkspaceTab(id, env),\n };\n }\n case \"eval\": {\n if (!isBrowserWorkspaceBridgeConfigured(env)) {\n return (await executeWebBrowserWorkspaceUtilityCommand(\n command,\n )) as BrowserWorkspaceCommandResult;\n }\n const id = await resolveDesktopBrowserWorkspaceTargetTabId(command, env);\n return {\n mode: \"desktop\",\n subaction: command.subaction,\n value: await evaluateBrowserWorkspaceTab(\n {\n id,\n script: command.script ?? \"\",\n },\n env,\n ),\n };\n }\n case \"screenshot\": {\n if (!isBrowserWorkspaceBridgeConfigured(env)) {\n return (await executeWebBrowserWorkspaceUtilityCommand(\n command,\n )) as BrowserWorkspaceCommandResult;\n }\n const id = await resolveDesktopBrowserWorkspaceTargetTabId(command, env);\n return {\n mode: \"desktop\",\n subaction: command.subaction,\n snapshot: await snapshotBrowserWorkspaceTab(id, env),\n };\n }\n case \"clipboard\":\n case \"console\":\n case \"cookies\":\n case \"dialog\":\n case \"drag\":\n case \"errors\":\n case \"frame\":\n case \"highlight\":\n case \"mouse\":\n case \"network\":\n case \"set\":\n case \"storage\":\n case \"upload\": {\n if (!isBrowserWorkspaceBridgeConfigured(env)) {\n return (await executeWebBrowserWorkspaceUtilityCommand(\n command,\n )) as BrowserWorkspaceCommandResult;\n }\n return executeDesktopBrowserWorkspaceUtilityCommand(command, env);\n }\n case \"diff\": {\n if (!isBrowserWorkspaceBridgeConfigured(env)) {\n return (await executeWebBrowserWorkspaceUtilityCommand(\n command,\n )) as BrowserWorkspaceCommandResult;\n }\n const id = await resolveDesktopBrowserWorkspaceTargetTabId(command, env);\n const runtime = getBrowserWorkspaceRuntimeState(\"desktop\", id);\n const snapshot = await getDesktopBrowserWorkspaceSnapshotRecord(\n command,\n env,\n );\n if (command.diffAction === \"screenshot\") {\n const screenshot = await snapshotBrowserWorkspaceTab(id, env);\n const currentData = screenshot.data;\n const baseline = command.baselinePath?.trim()\n ? await fsp.readFile(\n path.resolve(command.baselinePath.trim()),\n \"base64\",\n )\n : runtime.lastScreenshotData;\n runtime.lastScreenshotData = currentData;\n return {\n mode: \"desktop\",\n subaction: command.subaction,\n value: {\n baselineLength: baseline?.length ?? 0,\n changed: baseline !== currentData,\n currentLength: currentData.length,\n },\n };\n }\n if (command.diffAction === \"url\") {\n const leftUrl = command.url?.trim() || snapshot.url;\n const rightUrl = command.secondaryUrl?.trim();\n if (!rightUrl) {\n throw new Error(\n \"Eliza browser workspace diff url requires secondaryUrl.\",\n );\n }\n const left = await browserWorkspacePageFetch(leftUrl);\n const right = await browserWorkspacePageFetch(rightUrl);\n return {\n mode: \"desktop\",\n subaction: command.subaction,\n value: diffBrowserWorkspaceSnapshots(\n createBrowserWorkspaceSnapshotRecord(\n leftUrl,\n left.url || leftUrl,\n await left.text(),\n ),\n createBrowserWorkspaceSnapshotRecord(\n rightUrl,\n right.url || rightUrl,\n await right.text(),\n ),\n ),\n };\n }\n const baseline = command.baselinePath?.trim()\n ? (JSON.parse(\n await fsp.readFile(\n path.resolve(command.baselinePath.trim()),\n \"utf8\",\n ),\n ) as import(\"./browser-workspace-types.js\").BrowserWorkspaceSnapshotRecord)\n : runtime.lastSnapshot;\n const diff = diffBrowserWorkspaceSnapshots(baseline, snapshot);\n runtime.lastSnapshot = snapshot;\n return { mode: \"desktop\", subaction: command.subaction, value: diff };\n }\n case \"trace\":\n case \"profiler\": {\n if (!isBrowserWorkspaceBridgeConfigured(env)) {\n return (await executeWebBrowserWorkspaceUtilityCommand(\n command,\n )) as BrowserWorkspaceCommandResult;\n }\n const id = await resolveDesktopBrowserWorkspaceTargetTabId(command, env);\n const runtime = getBrowserWorkspaceRuntimeState(\"desktop\", id);\n const target =\n command.subaction === \"trace\" ? runtime.trace : runtime.profiler;\n const stop =\n command.subaction === \"trace\"\n ? command.traceAction === \"stop\"\n : command.profilerAction === \"stop\";\n if (stop) {\n target.active = false;\n const payload = { entries: target.entries };\n const filePath = command.filePath?.trim() || command.outputPath?.trim();\n if (filePath) {\n const { writeBrowserWorkspaceFile } = await import(\n \"./browser-workspace-helpers.js\"\n );\n await writeBrowserWorkspaceFile(\n filePath,\n JSON.stringify(payload, null, 2),\n );\n return {\n mode: \"desktop\",\n subaction: command.subaction,\n value: { path: path.resolve(filePath), ...payload },\n };\n }\n return {\n mode: \"desktop\",\n subaction: command.subaction,\n value: payload,\n };\n }\n target.active = true;\n target.entries = [\n {\n command: `${command.subaction}:start`,\n timestamp: getBrowserWorkspaceTimestamp(),\n },\n ];\n return {\n mode: \"desktop\",\n subaction: command.subaction,\n value: { active: true },\n };\n }\n case \"state\": {\n if (!isBrowserWorkspaceBridgeConfigured(env)) {\n return (await executeWebBrowserWorkspaceUtilityCommand(\n command,\n )) as BrowserWorkspaceCommandResult;\n }\n await assertDesktopBrowserWorkspaceCanAccessProfileSecrets(\n command,\n env,\n \"state\",\n );\n if (command.stateAction === \"load\") {\n const filePath = command.filePath?.trim() || command.outputPath?.trim();\n if (!filePath) {\n throw new Error(\n \"Eliza browser workspace state load requires filePath.\",\n );\n }\n const payload = JSON.parse(\n await fsp.readFile(path.resolve(filePath), \"utf8\"),\n ) as Record<string, unknown>;\n await loadDesktopBrowserWorkspaceSessionState(command, payload, env);\n return {\n mode: \"desktop\",\n subaction: command.subaction,\n value: { loaded: true },\n };\n }\n const payload = await getDesktopBrowserWorkspaceSessionState(\n command,\n env,\n );\n const filePath = command.filePath?.trim() || command.outputPath?.trim();\n if (filePath) {\n const { writeBrowserWorkspaceFile } = await import(\n \"./browser-workspace-helpers.js\"\n );\n await writeBrowserWorkspaceFile(\n filePath,\n JSON.stringify(payload, null, 2),\n );\n return {\n mode: \"desktop\",\n subaction: command.subaction,\n value: { path: path.resolve(filePath), ...payload },\n };\n }\n return { mode: \"desktop\", subaction: command.subaction, value: payload };\n }\n case \"pdf\": {\n if (!isBrowserWorkspaceBridgeConfigured(env)) {\n return (await executeWebBrowserWorkspaceUtilityCommand(\n command,\n )) as BrowserWorkspaceCommandResult;\n }\n const filePath = command.filePath?.trim() || command.outputPath?.trim();\n if (!filePath) {\n throw new Error(\"Eliza browser workspace pdf requires filePath.\");\n }\n const snapshot = await getDesktopBrowserWorkspaceSnapshotRecord(\n command,\n env,\n );\n const pdf = createBrowserWorkspacePdfBuffer(\n snapshot.title,\n snapshot.bodyText,\n );\n const { writeBrowserWorkspaceFile } = await import(\n \"./browser-workspace-helpers.js\"\n );\n const resolved = await writeBrowserWorkspaceFile(filePath, pdf);\n return {\n mode: \"desktop\",\n subaction: command.subaction,\n value: { path: resolved, size: pdf.byteLength },\n };\n }\n case \"tab\": {\n const action = command.tabAction ?? \"list\";\n if (action === \"list\") {\n return {\n mode: getBrowserWorkspaceMode(env),\n subaction: command.subaction,\n tabs: await listBrowserWorkspaceTabs(env),\n };\n }\n if (action === \"new\") {\n return {\n mode: getBrowserWorkspaceMode(env),\n subaction: command.subaction,\n tab: await openBrowserWorkspaceTab(\n {\n partition: resolveBrowserWorkspaceCommandPartition(\n command,\n AGENT_BROWSER_WORKSPACE_PARTITION,\n ),\n show: command.show ?? true,\n title: command.title,\n url: command.url,\n width: command.width,\n height: command.height,\n },\n env,\n ),\n };\n }\n if (action === \"switch\") {\n const tabs = await listBrowserWorkspaceTabs(env);\n const target = command.id?.trim()\n ? tabs.find((tab) => tab.id === command.id?.trim())\n : typeof command.index === \"number\"\n ? (tabs[command.index] ?? null)\n : null;\n if (!target) {\n throw new Error(\n \"Eliza browser workspace tab switch requires a valid id or index.\",\n );\n }\n return {\n mode: getBrowserWorkspaceMode(env),\n subaction: command.subaction,\n tab: await showBrowserWorkspaceTab(target.id, env),\n };\n }\n const targetId =\n command.id?.trim() ||\n (await listBrowserWorkspaceTabs(env))[command.index ?? -1]?.id;\n if (!targetId) {\n throw new Error(\n \"Eliza browser workspace tab close requires a valid id or index.\",\n );\n }\n return {\n mode: getBrowserWorkspaceMode(env),\n subaction: command.subaction,\n closed: await closeBrowserWorkspaceTab(targetId, env),\n };\n }\n case \"window\":\n return {\n mode: getBrowserWorkspaceMode(env),\n subaction: command.subaction,\n tab: await openBrowserWorkspaceTab(\n {\n partition: resolveBrowserWorkspaceCommandPartition(\n command,\n AGENT_BROWSER_WORKSPACE_PARTITION,\n ),\n show: true,\n title: command.title,\n url: command.url,\n width: command.width,\n height: command.height,\n },\n env,\n ),\n };\n case \"back\":\n case \"forward\":\n case \"reload\": {\n if (isBrowserWorkspaceBridgeConfigured(env)) {\n const id = await resolveDesktopBrowserWorkspaceTargetTabId(\n command,\n env,\n );\n clearBrowserWorkspaceElementRefs(\"desktop\", id);\n return executeDesktopBrowserWorkspaceDomCommand(command, env);\n }\n\n return withWebStateLock(async () => {\n const id = findWebBrowserWorkspaceTargetTabId(command);\n const tab = getWebBrowserWorkspaceTabState(id);\n\n if (command.subaction === \"reload\") {\n clearWebBrowserWorkspaceTabElementRefs(tab.id);\n tab.dom = null;\n tab.loadedUrl = null;\n await loadWebBrowserWorkspaceTabDocument(tab);\n return {\n mode: \"web\",\n subaction: command.subaction,\n tab: cloneWebBrowserWorkspaceTabState(tab),\n value: { url: tab.url, title: tab.title },\n };\n }\n\n const delta = command.subaction === \"back\" ? -1 : 1;\n const nextIndex = tab.historyIndex + delta;\n if (nextIndex < 0 || nextIndex >= tab.history.length) {\n return {\n mode: \"web\",\n subaction: command.subaction,\n tab: cloneWebBrowserWorkspaceTabState(tab),\n value: { url: tab.url, title: tab.title, changed: false },\n };\n }\n\n tab.historyIndex = nextIndex;\n tab.url = tab.history[nextIndex] ?? tab.url;\n tab.title = inferBrowserWorkspaceTitle(tab.url);\n clearWebBrowserWorkspaceTabElementRefs(tab.id);\n tab.dom = null;\n tab.loadedUrl = null;\n await loadWebBrowserWorkspaceTabDocument(tab);\n return {\n mode: \"web\",\n subaction: command.subaction,\n tab: cloneWebBrowserWorkspaceTabState(tab),\n value: { url: tab.url, title: tab.title, changed: true },\n };\n });\n }\n case \"inspect\":\n case \"snapshot\":\n case \"check\":\n case \"click\":\n case \"dblclick\":\n case \"find\":\n case \"fill\":\n case \"focus\":\n case \"get\":\n case \"hover\":\n case \"keydown\":\n case \"keyup\":\n case \"keyboardinserttext\":\n case \"keyboardtype\":\n case \"press\":\n case \"scroll\":\n case \"scrollinto\":\n case \"select\":\n case \"type\":\n case \"uncheck\":\n case \"wait\":\n case \"realistic-click\":\n case \"realistic-fill\":\n case \"realistic-type\":\n case \"realistic-press\":\n case \"realistic-upload\":\n case \"cursor-move\":\n case \"cursor-hide\":\n if (\n command.subaction === \"wait\" &&\n !command.selector &&\n !command.findBy &&\n !command.text &&\n !command.url &&\n !command.script &&\n typeof command.timeoutMs === \"number\" &&\n Number.isFinite(command.timeoutMs)\n ) {\n const waitedMs = Math.max(0, command.timeoutMs);\n await sleep(waitedMs);\n return {\n mode: getBrowserWorkspaceMode(env),\n subaction: command.subaction,\n value: { waitedMs },\n };\n }\n if (isBrowserWorkspaceBridgeConfigured(env)) {\n return executeDesktopBrowserWorkspaceDomCommand(command, env);\n }\n return executeWebBrowserWorkspaceDomCommand(command);\n default: {\n const exhaustive: never = command.subaction;\n throw new Error(`Unsupported browser workspace subaction: ${exhaustive}`);\n }\n }\n}\n"],"mappings":"AAsBA,SAAS,+CAA+C;AA+DxD,SAAS,4CAA4C;AAGrD,SAIE,uCAGA,oCAGA,2CAGK;","names":[]}
@@ -1,3 +0,0 @@
1
- export * from "./browser-capture.js";
2
- export * from "./browser-workspace.js";
3
- //# sourceMappingURL=index.d.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/workspace/index.ts"],"sourcesContent":["/**\n * Workspace browser command router — public barrel.\n *\n * This is the multi-backend workspace browser surface (formerly\n * `packages/agent/src/services/browser-workspace.ts` and friends). It owns:\n *\n * - `browser-workspace.ts` — public functions and the main command\n * router `executeBrowserWorkspaceCommand`\n * - `browser-workspace-types.ts` — exported types and interfaces\n * - `browser-workspace-state.ts` — global mutable state\n * - `browser-workspace-helpers.ts` — small utilities and command normalization\n * - `browser-workspace-jsdom.ts` — JSDOM loading and runtime install\n * - `browser-workspace-elements.ts` — element finding, selector parsing\n * - `browser-workspace-network.ts` — HAR, network interception\n * - `browser-workspace-forms.ts` — form control interaction\n * - `browser-workspace-snapshots.ts` — document snapshots, diff, PDF\n * - `browser-workspace-desktop.ts` — desktop bridge HTTP client\n * - `browser-workspace-web.ts` — web-mode (JSDOM-backed) command exec\n * - `browser-capture.ts` — frame-capture helpers for streaming\n *\n * Importers should prefer `@elizaos/plugin-browser/workspace` over the\n * specific `browser-workspace*` subpaths.\n */\n\nexport * from \"./browser-capture.js\";\nexport * from \"./browser-workspace.js\";\n"],"mappings":"AAwBA,cAAc;AACd,cAAc;","names":[]}