@amalgm/browser 0.1.2-preview.35541635545 → 0.1.2-preview.37254096068
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/PURPOSE.md +119 -97
- package/README.md +51 -56
- package/SECURITY.md +10 -8
- package/dist/bin/amalgm-browser-mcp.js +2 -3
- package/dist/bin/amalgm-browser-mcp.js.map +1 -1
- package/dist/bin/amalgm-browser-rest.js +8 -18
- package/dist/bin/amalgm-browser-rest.js.map +1 -1
- package/dist/src/account.d.ts +8 -0
- package/dist/src/account.js +42 -0
- package/dist/src/account.js.map +1 -0
- package/dist/src/action.d.ts +1 -2
- package/dist/src/action.js +3 -7
- package/dist/src/action.js.map +1 -1
- package/dist/src/adapters/cli/actions.d.ts +0 -1
- package/dist/src/adapters/cli/actions.js +0 -7
- package/dist/src/adapters/cli/actions.js.map +1 -1
- package/dist/src/adapters/cli/help.d.ts +1 -1
- package/dist/src/adapters/cli/help.js +1 -4
- package/dist/src/adapters/cli/help.js.map +1 -1
- package/dist/src/adapters/cli/resources.js +0 -22
- package/dist/src/adapters/cli/resources.js.map +1 -1
- package/dist/src/adapters/cli/run.js +25 -19
- package/dist/src/adapters/cli/run.js.map +1 -1
- package/dist/src/adapters/execute.js +2 -2
- package/dist/src/adapters/execute.js.map +1 -1
- package/dist/src/adapters/http/events.d.ts +5 -2
- package/dist/src/adapters/http/events.js +18 -2
- package/dist/src/adapters/http/events.js.map +1 -1
- package/dist/src/adapters/http/internal-routes.js +9 -4
- package/dist/src/adapters/http/internal-routes.js.map +1 -1
- package/dist/src/adapters/http/navigation-stream.d.ts +4 -0
- package/dist/src/adapters/http/navigation-stream.js +17 -0
- package/dist/src/adapters/http/navigation-stream.js.map +1 -0
- package/dist/src/adapters/http/openapi.js +2 -8
- package/dist/src/adapters/http/openapi.js.map +1 -1
- package/dist/src/adapters/http/server.js +54 -14
- package/dist/src/adapters/http/server.js.map +1 -1
- package/dist/src/adapters/http/session-routes.js +0 -1
- package/dist/src/adapters/http/session-routes.js.map +1 -1
- package/dist/src/adapters/http/stream.d.ts +6 -0
- package/dist/src/adapters/http/stream.js +89 -0
- package/dist/src/adapters/http/stream.js.map +1 -0
- package/dist/src/adapters/mcp/server.js +2 -2
- package/dist/src/adapters/mcp/server.js.map +1 -1
- package/dist/src/adapters/mcp/tools.js +2 -4
- package/dist/src/adapters/mcp/tools.js.map +1 -1
- package/dist/src/adapters/mcp/types.d.ts +3 -2
- package/dist/src/adapters/toolbox/manifest.js +1 -1
- package/dist/src/adapters/toolbox/manifest.js.map +1 -1
- package/dist/src/auth/login.d.ts +3 -1
- package/dist/src/auth/login.js +48 -33
- package/dist/src/auth/login.js.map +1 -1
- package/dist/src/auth/service.js +56 -67
- package/dist/src/auth/service.js.map +1 -1
- package/dist/src/{drivers/cdp → cdp}/capture.d.ts +1 -1
- package/dist/src/{drivers/cdp → cdp}/capture.js +1 -1
- package/dist/src/cdp/capture.js.map +1 -0
- package/dist/src/{drivers/cdp → cdp}/client.d.ts +3 -1
- package/dist/src/{drivers/cdp → cdp}/client.js +51 -14
- package/dist/src/cdp/client.js.map +1 -0
- package/dist/src/cdp/input.js.map +1 -0
- package/dist/src/cdp/navigation.d.ts +5 -0
- package/dist/src/cdp/navigation.js +47 -0
- package/dist/src/cdp/navigation.js.map +1 -0
- package/dist/src/{drivers/cdp → cdp}/screencast.js +1 -1
- package/dist/src/cdp/screencast.js.map +1 -0
- package/dist/src/chrome/cookie-adapter.d.ts +23 -0
- package/dist/src/chrome/cookie-adapter.js +74 -0
- package/dist/src/chrome/cookie-adapter.js.map +1 -0
- package/dist/src/chrome/cookie-changes.d.ts +12 -0
- package/dist/src/chrome/cookie-changes.js +100 -0
- package/dist/src/chrome/cookie-changes.js.map +1 -0
- package/dist/src/chrome/cookie-observer.d.ts +20 -0
- package/dist/src/chrome/cookie-observer.js +44 -0
- package/dist/src/chrome/cookie-observer.js.map +1 -0
- package/dist/src/chrome/executable.d.ts +1 -0
- package/dist/src/chrome/executable.js +55 -0
- package/dist/src/chrome/executable.js.map +1 -0
- package/dist/src/chrome/flags.d.ts +7 -0
- package/dist/src/chrome/flags.js +59 -0
- package/dist/src/chrome/flags.js.map +1 -0
- package/dist/src/chrome/host.d.ts +25 -0
- package/dist/src/chrome/host.js +137 -0
- package/dist/src/chrome/host.js.map +1 -0
- package/dist/src/chrome/launch.d.ts +11 -0
- package/dist/src/chrome/launch.js +105 -0
- package/dist/src/chrome/launch.js.map +1 -0
- package/dist/src/chrome/relay/editing.d.ts +2 -0
- package/dist/src/chrome/relay/editing.js +14 -0
- package/dist/src/chrome/relay/editing.js.map +1 -0
- package/dist/src/chrome/relay/server.d.ts +18 -0
- package/dist/src/chrome/relay/server.js +120 -0
- package/dist/src/chrome/relay/server.js.map +1 -0
- package/dist/src/chrome/relay/targets.d.ts +11 -0
- package/dist/src/chrome/relay/targets.js +59 -0
- package/dist/src/chrome/relay/targets.js.map +1 -0
- package/dist/src/chrome/relay/view.d.ts +34 -0
- package/dist/src/chrome/relay/view.js +185 -0
- package/dist/src/chrome/relay/view.js.map +1 -0
- package/dist/src/cookies/adapter-credential.d.ts +6 -0
- package/dist/src/cookies/adapter-credential.js +33 -0
- package/dist/src/cookies/adapter-credential.js.map +1 -0
- package/dist/src/cookies/coordinator.d.ts +14 -13
- package/dist/src/cookies/coordinator.js +157 -75
- package/dist/src/cookies/coordinator.js.map +1 -1
- package/dist/src/cookies/database.d.ts +29 -0
- package/dist/src/cookies/database.js +113 -0
- package/dist/src/cookies/database.js.map +1 -0
- package/dist/src/cookies/diff.d.ts +6 -0
- package/dist/src/cookies/diff.js +19 -0
- package/dist/src/cookies/diff.js.map +1 -0
- package/dist/src/cookies/http-store.d.ts +7 -0
- package/dist/src/cookies/http-store.js +105 -0
- package/dist/src/cookies/http-store.js.map +1 -0
- package/dist/src/cookies/jar.d.ts +12 -11
- package/dist/src/cookies/jar.js +128 -120
- package/dist/src/cookies/jar.js.map +1 -1
- package/dist/src/cookies/policy.js +10 -4
- package/dist/src/cookies/policy.js.map +1 -1
- package/dist/src/cookies/secret-file.d.ts +4 -0
- package/dist/src/cookies/secret-file.js +47 -9
- package/dist/src/cookies/secret-file.js.map +1 -1
- package/dist/src/cookies/types.d.ts +34 -2
- package/dist/src/cookies.d.ts +2 -0
- package/dist/src/cookies.js +2 -0
- package/dist/src/cookies.js.map +1 -1
- package/dist/src/defaults.d.ts +1 -5
- package/dist/src/defaults.js +49 -58
- package/dist/src/defaults.js.map +1 -1
- package/dist/src/driver/cli-policy.d.ts +1 -0
- package/dist/src/driver/cli-policy.js +17 -0
- package/dist/src/driver/cli-policy.js.map +1 -0
- package/dist/src/{drivers/headless → driver}/command.d.ts +3 -7
- package/dist/src/{drivers/headless → driver}/command.js +29 -29
- package/dist/src/driver/command.js.map +1 -0
- package/dist/src/{drivers/headless → driver}/driver.d.ts +13 -10
- package/dist/src/{drivers/headless → driver}/driver.js +67 -82
- package/dist/src/driver/driver.js.map +1 -0
- package/dist/src/{interaction/delta.d.ts → driver/evidence.d.ts} +3 -2
- package/dist/src/{interaction/delta.js → driver/evidence.js} +6 -3
- package/dist/src/driver/evidence.js.map +1 -0
- package/dist/src/driver/executable.js.map +1 -0
- package/dist/src/driver/stream.d.ts +1 -0
- package/dist/src/driver/stream.js +22 -0
- package/dist/src/driver/stream.js.map +1 -0
- package/dist/src/driver/wait.d.ts +6 -0
- package/dist/src/driver/wait.js +28 -0
- package/dist/src/driver/wait.js.map +1 -0
- package/dist/src/electron/adblock/cache.js.map +1 -0
- package/dist/src/electron/adblock/cosmetics.js.map +1 -0
- package/dist/src/{drivers/electron/native → electron}/adblock/index.d.ts +0 -1
- package/dist/src/{drivers/electron/native → electron}/adblock/index.js +0 -1
- package/dist/src/{drivers/electron/native → electron}/adblock/index.js.map +1 -1
- package/dist/src/electron/adblock/policy.js.map +1 -0
- package/dist/src/electron/adblock/preload.js.map +1 -0
- package/dist/src/electron/adblock/settings.js.map +1 -0
- package/dist/src/{drivers/electron/native → electron}/contracts.d.ts +0 -14
- package/dist/src/{drivers/electron/native → electron}/contracts.js +0 -1
- package/dist/src/electron/contracts.js.map +1 -0
- package/dist/src/{drivers/electron → electron}/cookie-adapter.d.ts +4 -4
- package/dist/src/{drivers/electron → electron}/cookie-adapter.js +9 -6
- package/dist/src/electron/cookie-adapter.js.map +1 -0
- package/dist/src/electron/cookie-sync.d.ts +6 -0
- package/dist/src/electron/cookie-sync.js +18 -0
- package/dist/src/electron/cookie-sync.js.map +1 -0
- package/dist/src/electron/policy.js.map +1 -0
- package/dist/src/electron/session.d.ts +2 -0
- package/dist/src/electron/session.js +9 -0
- package/dist/src/electron/session.js.map +1 -0
- package/dist/src/electron/shell/adblock-ipc.js.map +1 -0
- package/dist/src/electron/shell/context-menu.js.map +1 -0
- package/dist/src/electron/shell/downloads.js.map +1 -0
- package/dist/src/electron/shell/helpers.js.map +1 -0
- package/dist/src/electron/shell/permissions.js.map +1 -0
- package/dist/src/{drivers/electron/native → electron}/shell/sites.d.ts +1 -3
- package/dist/src/{drivers/electron/native → electron}/shell/sites.js +2 -34
- package/dist/src/electron/shell/sites.js.map +1 -0
- package/dist/src/{drivers/electron/native → electron}/shell/types.d.ts +0 -1
- package/dist/src/electron/shell/types.js.map +1 -0
- package/dist/src/electron/shell.d.ts +13 -0
- package/dist/src/electron/shell.js +73 -0
- package/dist/src/electron/shell.js.map +1 -0
- package/dist/src/electron/surface/commands.js.map +1 -0
- package/dist/src/{drivers/electron/native → electron}/surface/create.js +0 -6
- package/dist/src/electron/surface/create.js.map +1 -0
- package/dist/src/{drivers/electron/native → electron}/surface/events.js +1 -13
- package/dist/src/electron/surface/events.js.map +1 -0
- package/dist/src/{drivers/electron/native → electron}/surface/presentation.d.ts +2 -9
- package/dist/src/electron/surface/presentation.js +29 -0
- package/dist/src/electron/surface/presentation.js.map +1 -0
- package/dist/src/{drivers/electron/native → electron}/surface/state.d.ts +5 -0
- package/dist/src/{drivers/electron/native → electron}/surface/state.js +10 -4
- package/dist/src/electron/surface/state.js.map +1 -0
- package/dist/src/{drivers/electron/native → electron}/surface/types.d.ts +2 -8
- package/dist/src/electron/surface/types.js.map +1 -0
- package/dist/src/{drivers/electron/native → electron}/surface-controller.js +9 -12
- package/dist/src/electron/surface-controller.js.map +1 -0
- package/dist/src/electron-preload.cjs +1 -1
- package/dist/src/electron.cjs +587 -820
- package/dist/src/electron.d.cts +4 -14
- package/dist/src/electron.d.ts +4 -14
- package/dist/src/electron.js +4 -14
- package/dist/src/electron.js.map +1 -1
- package/dist/src/errors.d.ts +1 -1
- package/dist/src/errors.js.map +1 -1
- package/dist/src/index.d.ts +2 -3
- package/dist/src/index.js +0 -2
- package/dist/src/index.js.map +1 -1
- package/dist/src/migration/legacy-migration.d.ts +0 -1
- package/dist/src/migration/legacy-migration.js +3 -9
- package/dist/src/migration/legacy-migration.js.map +1 -1
- package/dist/src/migration/legacy-rows.d.ts +1 -2
- package/dist/src/migration/legacy-rows.js +0 -14
- package/dist/src/migration/legacy-rows.js.map +1 -1
- package/dist/src/ports.d.ts +12 -15
- package/dist/src/ports.js.map +1 -1
- package/dist/src/process.d.ts +1 -0
- package/dist/src/process.js +11 -0
- package/dist/src/process.js.map +1 -1
- package/dist/src/product-service.d.ts +4 -6
- package/dist/src/product-service.js +21 -15
- package/dist/src/product-service.js.map +1 -1
- package/dist/src/recording/encoder.js +1 -1
- package/dist/src/recording/encoder.js.map +1 -1
- package/dist/src/recording/service.d.ts +4 -0
- package/dist/src/recording/service.js +72 -62
- package/dist/src/recording/service.js.map +1 -1
- package/dist/src/recording/source.js +1 -1
- package/dist/src/recording/source.js.map +1 -1
- package/dist/src/registry.d.ts +4 -0
- package/dist/src/registry.js +17 -0
- package/dist/src/registry.js.map +1 -1
- package/dist/src/service-options.d.ts +5 -7
- package/dist/src/service.d.ts +16 -18
- package/dist/src/service.js +108 -108
- package/dist/src/service.js.map +1 -1
- package/dist/src/sessions/operations.d.ts +12 -0
- package/dist/src/sessions/operations.js +56 -0
- package/dist/src/sessions/operations.js.map +1 -0
- package/dist/src/testing.d.ts +8 -4
- package/dist/src/testing.js +7 -5
- package/dist/src/testing.js.map +1 -1
- package/dist/src/types.d.ts +0 -39
- package/docs/ACTIONS.md +0 -4
- package/docs/ARCHITECTURE.md +51 -55
- package/docs/AUTHENTICATION.md +41 -36
- package/docs/AXIOMS.md +13 -11
- package/docs/CHROME.md +143 -0
- package/docs/CLI.md +63 -31
- package/docs/COMPATIBILITY.md +14 -23
- package/docs/COOKIES.md +95 -52
- package/docs/ELECTRON_INTEGRATION.md +84 -77
- package/docs/EVENTS.md +5 -9
- package/docs/MCP.md +10 -6
- package/docs/MIGRATION.md +43 -36
- package/docs/OPERATIONS.md +48 -40
- package/docs/README.md +5 -5
- package/docs/REALTIME_BOUNDARY.md +3 -3
- package/docs/RECORDING.md +16 -15
- package/docs/REST.md +57 -26
- package/docs/SDK.md +65 -55
- package/docs/SHELL_INTEGRATION.md +78 -36
- package/docs/TESTING.md +58 -42
- package/docs/TOOLBOX_INTEGRATION.md +9 -4
- package/docs/TROUBLESHOOTING.md +68 -40
- package/examples/basic.ts +1 -0
- package/package.json +8 -15
- package/skills/use-amalgm-browser/SKILL.md +16 -29
- package/skills/use-amalgm-browser/references/actions.md +2 -2
- package/dist/src/adapters/http/profile-routes.d.ts +0 -2
- package/dist/src/adapters/http/profile-routes.js +0 -42
- package/dist/src/adapters/http/profile-routes.js.map +0 -1
- package/dist/src/auth/transport.d.ts +0 -8
- package/dist/src/auth/transport.js +0 -45
- package/dist/src/auth/transport.js.map +0 -1
- package/dist/src/drivers/cdp/capture.js.map +0 -1
- package/dist/src/drivers/cdp/client.js.map +0 -1
- package/dist/src/drivers/cdp/input.js.map +0 -1
- package/dist/src/drivers/cdp/screencast.js.map +0 -1
- package/dist/src/drivers/cdp/target.d.ts +0 -4
- package/dist/src/drivers/cdp/target.js +0 -34
- package/dist/src/drivers/cdp/target.js.map +0 -1
- package/dist/src/drivers/electron/advertisement.d.ts +0 -12
- package/dist/src/drivers/electron/advertisement.js +0 -57
- package/dist/src/drivers/electron/advertisement.js.map +0 -1
- package/dist/src/drivers/electron/contracts.d.ts +0 -45
- package/dist/src/drivers/electron/contracts.js +0 -10
- package/dist/src/drivers/electron/contracts.js.map +0 -1
- package/dist/src/drivers/electron/cookie-adapter.js.map +0 -1
- package/dist/src/drivers/electron/driver.d.ts +0 -19
- package/dist/src/drivers/electron/driver.js +0 -115
- package/dist/src/drivers/electron/driver.js.map +0 -1
- package/dist/src/drivers/electron/native/adblock/cache.js.map +0 -1
- package/dist/src/drivers/electron/native/adblock/cosmetics.js.map +0 -1
- package/dist/src/drivers/electron/native/adblock/policy.js.map +0 -1
- package/dist/src/drivers/electron/native/adblock/preload.js.map +0 -1
- package/dist/src/drivers/electron/native/adblock/settings.js.map +0 -1
- package/dist/src/drivers/electron/native/config.d.ts +0 -4
- package/dist/src/drivers/electron/native/config.js +0 -9
- package/dist/src/drivers/electron/native/config.js.map +0 -1
- package/dist/src/drivers/electron/native/contracts.js.map +0 -1
- package/dist/src/drivers/electron/native/policy.js.map +0 -1
- package/dist/src/drivers/electron/native/session.d.ts +0 -4
- package/dist/src/drivers/electron/native/session.js +0 -11
- package/dist/src/drivers/electron/native/session.js.map +0 -1
- package/dist/src/drivers/electron/native/shell/adblock-ipc.js.map +0 -1
- package/dist/src/drivers/electron/native/shell/context-menu.js.map +0 -1
- package/dist/src/drivers/electron/native/shell/downloads.js.map +0 -1
- package/dist/src/drivers/electron/native/shell/helpers.js.map +0 -1
- package/dist/src/drivers/electron/native/shell/permissions.js.map +0 -1
- package/dist/src/drivers/electron/native/shell/sites.js.map +0 -1
- package/dist/src/drivers/electron/native/shell/types.js.map +0 -1
- package/dist/src/drivers/electron/native/shell.d.ts +0 -14
- package/dist/src/drivers/electron/native/shell.js +0 -115
- package/dist/src/drivers/electron/native/shell.js.map +0 -1
- package/dist/src/drivers/electron/native/surface/commands.js.map +0 -1
- package/dist/src/drivers/electron/native/surface/create.js.map +0 -1
- package/dist/src/drivers/electron/native/surface/events.js.map +0 -1
- package/dist/src/drivers/electron/native/surface/presentation.js +0 -87
- package/dist/src/drivers/electron/native/surface/presentation.js.map +0 -1
- package/dist/src/drivers/electron/native/surface/state.js.map +0 -1
- package/dist/src/drivers/electron/native/surface/types.js.map +0 -1
- package/dist/src/drivers/electron/native/surface-controller.js.map +0 -1
- package/dist/src/drivers/electron/policy.d.ts +0 -4
- package/dist/src/drivers/electron/policy.js +0 -39
- package/dist/src/drivers/electron/policy.js.map +0 -1
- package/dist/src/drivers/electron/session.d.ts +0 -4
- package/dist/src/drivers/electron/session.js +0 -5
- package/dist/src/drivers/electron/session.js.map +0 -1
- package/dist/src/drivers/headless/command.js.map +0 -1
- package/dist/src/drivers/headless/cookie-adapter.d.ts +0 -16
- package/dist/src/drivers/headless/cookie-adapter.js +0 -59
- package/dist/src/drivers/headless/cookie-adapter.js.map +0 -1
- package/dist/src/drivers/headless/driver.js.map +0 -1
- package/dist/src/drivers/headless/executable.js.map +0 -1
- package/dist/src/drivers/headless/screencast.d.ts +0 -3
- package/dist/src/drivers/headless/screencast.js +0 -21
- package/dist/src/drivers/headless/screencast.js.map +0 -1
- package/dist/src/headless.d.ts +0 -3
- package/dist/src/headless.js +0 -4
- package/dist/src/headless.js.map +0 -1
- package/dist/src/interaction/delta.js.map +0 -1
- package/dist/src/interaction/typing.d.ts +0 -39
- package/dist/src/interaction/typing.js +0 -189
- package/dist/src/interaction/typing.js.map +0 -1
- package/dist/src/profiles/directories.d.ts +0 -9
- package/dist/src/profiles/directories.js +0 -57
- package/dist/src/profiles/directories.js.map +0 -1
- package/dist/src/profiles/service.d.ts +0 -30
- package/dist/src/profiles/service.js +0 -89
- package/dist/src/profiles/service.js.map +0 -1
- package/dist/src/runtime-selector.d.ts +0 -12
- package/dist/src/runtime-selector.js +0 -72
- package/dist/src/runtime-selector.js.map +0 -1
- package/docs/HEADLESS_RUNTIME.md +0 -58
- package/examples/custom-driver.ts +0 -45
- /package/dist/src/{drivers/cdp → cdp}/input.d.ts +0 -0
- /package/dist/src/{drivers/cdp → cdp}/input.js +0 -0
- /package/dist/src/{drivers/cdp → cdp}/screencast.d.ts +0 -0
- /package/dist/src/{drivers/headless → driver}/executable.d.ts +0 -0
- /package/dist/src/{drivers/headless → driver}/executable.js +0 -0
- /package/dist/src/{drivers/electron/native → electron}/adblock/cache.d.ts +0 -0
- /package/dist/src/{drivers/electron/native → electron}/adblock/cache.js +0 -0
- /package/dist/src/{drivers/electron/native → electron}/adblock/cosmetics.d.ts +0 -0
- /package/dist/src/{drivers/electron/native → electron}/adblock/cosmetics.js +0 -0
- /package/dist/src/{drivers/electron/native → electron}/adblock/policy.d.ts +0 -0
- /package/dist/src/{drivers/electron/native → electron}/adblock/policy.js +0 -0
- /package/dist/src/{drivers/electron/native → electron}/adblock/preload.d.ts +0 -0
- /package/dist/src/{drivers/electron/native → electron}/adblock/preload.js +0 -0
- /package/dist/src/{drivers/electron/native → electron}/adblock/settings.d.ts +0 -0
- /package/dist/src/{drivers/electron/native → electron}/adblock/settings.js +0 -0
- /package/dist/src/{drivers/electron/native → electron}/policy.d.ts +0 -0
- /package/dist/src/{drivers/electron/native → electron}/policy.js +0 -0
- /package/dist/src/{drivers/electron/native → electron}/shell/adblock-ipc.d.ts +0 -0
- /package/dist/src/{drivers/electron/native → electron}/shell/adblock-ipc.js +0 -0
- /package/dist/src/{drivers/electron/native → electron}/shell/context-menu.d.ts +0 -0
- /package/dist/src/{drivers/electron/native → electron}/shell/context-menu.js +0 -0
- /package/dist/src/{drivers/electron/native → electron}/shell/downloads.d.ts +0 -0
- /package/dist/src/{drivers/electron/native → electron}/shell/downloads.js +0 -0
- /package/dist/src/{drivers/electron/native → electron}/shell/helpers.d.ts +0 -0
- /package/dist/src/{drivers/electron/native → electron}/shell/helpers.js +0 -0
- /package/dist/src/{drivers/electron/native → electron}/shell/permissions.d.ts +0 -0
- /package/dist/src/{drivers/electron/native → electron}/shell/permissions.js +0 -0
- /package/dist/src/{drivers/electron/native → electron}/shell/types.js +0 -0
- /package/dist/src/{drivers/electron/native → electron}/surface/commands.d.ts +0 -0
- /package/dist/src/{drivers/electron/native → electron}/surface/commands.js +0 -0
- /package/dist/src/{drivers/electron/native → electron}/surface/create.d.ts +0 -0
- /package/dist/src/{drivers/electron/native → electron}/surface/events.d.ts +0 -0
- /package/dist/src/{drivers/electron/native → electron}/surface/types.js +0 -0
- /package/dist/src/{drivers/electron/native → electron}/surface-controller.d.ts +0 -0
package/docs/TESTING.md
CHANGED
|
@@ -1,62 +1,78 @@
|
|
|
1
1
|
# Testing
|
|
2
2
|
|
|
3
3
|
Tests are organized by invariant rather than implementation file. The default
|
|
4
|
-
suite is deterministic and uses injected drivers
|
|
5
|
-
real
|
|
4
|
+
suite is deterministic and uses injected drivers and stores; the real suite
|
|
5
|
+
drives real Chrome.
|
|
6
6
|
|
|
7
7
|
```sh
|
|
8
8
|
npm run check # tree hygiene and strict TypeScript
|
|
9
9
|
npm test # unit and transport contracts
|
|
10
10
|
npx --no-install agent-browser install # provision Chrome for Testing
|
|
11
|
-
npm run test:real # real
|
|
12
|
-
npm run test:electron # real Electron; macOS
|
|
11
|
+
npm run test:real # real Chrome and agent-browser
|
|
13
12
|
npm run verify # check, build, test, package/install
|
|
14
13
|
```
|
|
15
14
|
|
|
16
15
|
## Contract coverage
|
|
17
16
|
|
|
18
|
-
-
|
|
19
|
-
|
|
20
|
-
-
|
|
21
|
-
-
|
|
22
|
-
-
|
|
23
|
-
|
|
24
|
-
-
|
|
25
|
-
|
|
26
|
-
-
|
|
27
|
-
-
|
|
28
|
-
|
|
29
|
-
-
|
|
30
|
-
|
|
31
|
-
-
|
|
32
|
-
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
17
|
+
- one browsing identity: every session browses as the account, and a root
|
|
18
|
+
cannot be reassigned to another account
|
|
19
|
+
- restart reopen, cross-process leases, one action per session, cancellation
|
|
20
|
+
- a session's own live view, and closing the runtime releases Chrome
|
|
21
|
+
- all 22 actions reachable through SDK, CLI, MCP, REST, and Toolbox, from one
|
|
22
|
+
action manifest; an MCP call without a session uses its chat's session
|
|
23
|
+
- two-way cookie sync: sign-ins and sign-outs reach the account, failed
|
|
24
|
+
applies retry without echo, partitioned cookies, protected hosts
|
|
25
|
+
- record-level merges, tombstones, corrupt-jar health, wrong-key redaction
|
|
26
|
+
- auth filtering, login token TTL and hashing, deprecated-input compatibility,
|
|
27
|
+
serialized live login transitions
|
|
28
|
+
- recording frame pacing, backpressure, ffmpeg checks, viability deadline,
|
|
29
|
+
cancellation, and dead-owner recovery
|
|
30
|
+
- SQLite cross-process writes and the encrypted legacy import
|
|
31
|
+
- REST auth, loopback binding, SSE, redaction, and MCP cancellation
|
|
32
|
+
- argv process safety, bounded output and termination, asar resolution
|
|
33
|
+
- Electron URL, popup, permission, download, and ad-block policy, and the
|
|
34
|
+
Electron cookie adapter against an injected store
|
|
35
|
+
|
|
36
|
+
## Real browser
|
|
37
|
+
|
|
38
|
+
`npm run test:real` sets `AMALGM_BROWSER_REAL=1` and drives real Chrome
|
|
39
|
+
through the MCP adapter against a public site. It checks that:
|
|
40
|
+
|
|
41
|
+
- two chats browse side by side in one Chrome as one signed-in account;
|
|
42
|
+
- a viewer watches and drives one chat's live view, only with the runtime
|
|
43
|
+
token;
|
|
44
|
+
- the account stays signed in across restarts and follows sign-outs;
|
|
45
|
+
- a chat keeps browsing, still signed in, after Chrome is killed;
|
|
46
|
+
- loopback cookies never enter the account;
|
|
47
|
+
- a competing owner cannot replace or stop the live Chrome;
|
|
48
|
+
- captures and input follow the selected tab even with repeated URLs;
|
|
49
|
+
- session and service shutdown drain work, HTTP requests, SSE and viewers;
|
|
50
|
+
- raw CDP and advanced CLI calls cannot escape their session;
|
|
51
|
+
- repeated login activation preserves the page, terminal states remain final,
|
|
52
|
+
and recorded imagery can be decoded.
|
|
53
|
+
|
|
54
|
+
CI provisions Chrome for Testing through the locked `agent-browser`
|
|
55
|
+
dependency before this suite. Mocks cannot validate these paths.
|
|
56
|
+
|
|
57
|
+
UI's `test:browser` source examination additionally drives its canonical web
|
|
58
|
+
and Electron browser surfaces through the actual UI routes and Shell gateway.
|
|
59
|
+
It covers human input, companion ownership, login handoff, native cookie
|
|
60
|
+
sharing and deletion, account switching, sign-out, and fractional native bounds.
|
|
45
61
|
|
|
46
62
|
## Package verification
|
|
47
63
|
|
|
48
|
-
`verify:pack` runs `npm pack`,
|
|
49
|
-
checks the compiled
|
|
50
|
-
Electron,
|
|
51
|
-
|
|
64
|
+
`verify:pack` runs `npm pack`, checks the tarball for required files and for
|
|
65
|
+
runtime data or secrets, checks the compiled CLIs, installs the tarball into a
|
|
66
|
+
temporary consumer without Electron, imports the core entry points, and
|
|
67
|
+
confirms the Electron entry resolves to its CommonJS build.
|
|
52
68
|
|
|
53
|
-
|
|
54
|
-
The tree check fails on
|
|
55
|
-
artifacts.
|
|
69
|
+
TypeScript in `src/`, `bin/`, and `test/` is limited to 220 lines per file.
|
|
70
|
+
The tree check also fails on empty or untracked source files, JavaScript
|
|
71
|
+
source in `src/` or `bin/`, and tracked build or runtime artifacts.
|
|
56
72
|
|
|
57
73
|
## Adding behavior
|
|
58
74
|
|
|
59
|
-
Update purpose
|
|
60
|
-
descriptor, every transport projection, documentation, and
|
|
61
|
-
A new action that is not reachable through all five public
|
|
62
|
-
the parity suite.
|
|
75
|
+
Update the purpose and axioms if the model changes, then the typed SDK, the
|
|
76
|
+
shared action descriptor, every transport projection, the documentation, and
|
|
77
|
+
an invariant test. A new action that is not reachable through all five public
|
|
78
|
+
surfaces fails the parity suite.
|
|
@@ -18,12 +18,17 @@ import {
|
|
|
18
18
|
} from '@amalgm/browser/toolbox';
|
|
19
19
|
|
|
20
20
|
tools.register(browserToolboxManifest);
|
|
21
|
-
const execute = createBrowserToolboxExecutor(browser,
|
|
21
|
+
const execute = createBrowserToolboxExecutor(browser, {
|
|
22
|
+
canExecute: (actionId, context) => enabledActionIds.includes(actionId),
|
|
23
|
+
});
|
|
24
|
+
await execute('browser.open', { url: 'https://example.com' }, context);
|
|
22
25
|
```
|
|
23
26
|
|
|
24
|
-
The executor normalizes compatibility aliases once,
|
|
25
|
-
granted, and dispatches the canonical action through the
|
|
26
|
-
fail before session creation
|
|
27
|
+
The executor normalizes compatibility aliases once, asks the optional policy
|
|
28
|
+
whether the action is granted, and dispatches the canonical action through the
|
|
29
|
+
SDK. Disabled actions fail with `AUTHORIZATION_DENIED` before session creation
|
|
30
|
+
or browser execution. Session choice is the same as MCP: an explicit
|
|
31
|
+
`session`, else `context.callerId`, else `default`.
|
|
27
32
|
|
|
28
33
|
Legacy individual `cua_*` actions, old prefixed IDs, and historical aggregate
|
|
29
34
|
grants are adapter aliases. They do not create new SDK action identities. In
|
package/docs/TROUBLESHOOTING.md
CHANGED
|
@@ -1,67 +1,95 @@
|
|
|
1
1
|
# Troubleshooting
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## Chrome was not found
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
Install Google Chrome, run `npx agent-browser install` to download Chrome for
|
|
6
|
+
Testing, or set `AMALGM_BROWSER_EXECUTABLE_PATH`. A configured path that does
|
|
7
|
+
not exist fails with `PROCESS_FAILED` and is not replaced by a search. See
|
|
8
|
+
[Chrome runtime](./CHROME.md) for the search order.
|
|
9
9
|
|
|
10
|
-
##
|
|
10
|
+
## Chrome did not start
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
closed.
|
|
12
|
+
Browser waits 20 seconds for Chrome's DevTools port and reports the end of
|
|
13
|
+
Chrome's stderr. On Linux as root, Browser already adds `--no-sandbox` and
|
|
14
|
+
`--disable-dev-shm-usage`; check the executable runs by hand.
|
|
16
15
|
|
|
17
|
-
##
|
|
16
|
+
## "This browser profile already has a live owner."
|
|
17
|
+
|
|
18
|
+
Another live process holds this root's Chrome lease (`chrome.lease.sqlite`). This happens
|
|
19
|
+
when a one-shot CLI command runs beside `mcp`, `serve`, or an embedding host on
|
|
20
|
+
the same root. Send the work to that process, stop it, or use another root.
|
|
21
|
+
Never delete the lease file or Chrome's lock files. An owner that has died
|
|
22
|
+
releases its lease automatically; the next start retires its orphaned Chrome
|
|
23
|
+
through the exact endpoint published by that profile.
|
|
24
|
+
|
|
25
|
+
## Chrome crashed
|
|
26
|
+
|
|
27
|
+
The runtime logs "Chrome exited; it restarts on next use." An action caught by
|
|
28
|
+
the crash can fail; retry it. A later action starts a new Chrome filled with
|
|
29
|
+
the account's cookies from the jar, and the session keeps browsing. Open pages
|
|
30
|
+
are not restored.
|
|
31
|
+
|
|
32
|
+
## SURFACE_IDENTITY_FAILED
|
|
33
|
+
|
|
34
|
+
Screenshots, CUA double-clicks, and recording need one page for the session.
|
|
35
|
+
Browser records the selected page's target identity through the session relay.
|
|
36
|
+
Repeated URLs are safe. If the target has disappeared or selection cannot be
|
|
37
|
+
proven, switch to the intended tab or open a page, then retry.
|
|
38
|
+
|
|
39
|
+
## An element reference fails
|
|
40
|
+
|
|
41
|
+
Refs such as `@e3` belong to the latest snapshot. After the page changes, an
|
|
42
|
+
old ref fails with `PROCESS_FAILED`. Take a new snapshot.
|
|
43
|
+
|
|
44
|
+
## agent-browser is missing
|
|
18
45
|
|
|
19
46
|
Run `amalgm-browser doctor`, reinstall production dependencies, or set
|
|
20
|
-
`AMALGM_AGENT_BROWSER_BIN`. In packaged Electron builds,
|
|
21
|
-
are unpacked from `app.asar`.
|
|
47
|
+
`AMALGM_AGENT_BROWSER_BIN`. In packaged Electron builds, make sure native
|
|
48
|
+
assets are unpacked from `app.asar`.
|
|
22
49
|
|
|
23
|
-
##
|
|
50
|
+
## "Browser IPC requires a private, user-owned temporary directory"
|
|
24
51
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
52
|
+
agent-browser's sockets live in `/tmp/amalgm-browser-<uid>`. It must be a
|
|
53
|
+
directory owned by the current user with no group or other permissions. Fix or
|
|
54
|
+
remove it.
|
|
28
55
|
|
|
29
|
-
##
|
|
56
|
+
## Recording cannot start
|
|
30
57
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
profile.
|
|
58
|
+
Set `AMALGM_FFMPEG` to a working binary and run `<binary> -version`. Browser
|
|
59
|
+
checks ffmpeg first, then needs a page frame within five seconds, so open a
|
|
60
|
+
page before recording.
|
|
35
61
|
|
|
36
62
|
## Cookie jar reports unhealthy
|
|
37
63
|
|
|
38
|
-
|
|
39
|
-
or hand-edit encrypted
|
|
40
|
-
|
|
41
|
-
|
|
64
|
+
Browsing continues with the cookies Chrome already has, but sign-ins no longer
|
|
65
|
+
sync with other browser stores. Do not print or hand-edit encrypted files. Restore a
|
|
66
|
+
matching `cookie-jar.sqlite` and `browser.key` backup while the runtime is stopped,
|
|
67
|
+
using the SQLite-safe backup procedure in [Operations](./OPERATIONS.md).
|
|
68
|
+
Named auth bundles are separate.
|
|
42
69
|
|
|
43
|
-
## REST returns 401
|
|
70
|
+
## REST returns 401 or 403
|
|
44
71
|
|
|
45
|
-
Health is the only unauthenticated route.
|
|
46
|
-
cookie routes
|
|
47
|
-
|
|
72
|
+
Health is the only unauthenticated route. Send the exact runtime token.
|
|
73
|
+
Internal cookie routes also need `X-Browser-Adapter-Token`. A live-view
|
|
74
|
+
WebSocket closing with `4401` is the same token failure. Non-loopback binding
|
|
75
|
+
requires explicit remote opt-in.
|
|
48
76
|
|
|
49
77
|
## Login handoff fails
|
|
50
78
|
|
|
51
79
|
Tokens are one-time credentials returned only at creation, TTL is at most one
|
|
52
|
-
hour, and completed
|
|
53
|
-
|
|
80
|
+
hour, and completed, cancelled, and expired logins reject reuse. The login page
|
|
81
|
+
uses the login session’s normal runtime stream; check that the selected runtime
|
|
82
|
+
is available.
|
|
54
83
|
|
|
55
84
|
## SQLite is busy or a session conflicts
|
|
56
85
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
SQLite locking.
|
|
86
|
+
Each session allows one action at a time, and another process may hold the
|
|
87
|
+
session's lease. Let the operation finish or cancel it through the owning
|
|
88
|
+
process; stale leases expire. Avoid filesystems with broken SQLite locking.
|
|
61
89
|
|
|
62
90
|
## Migration fails
|
|
63
91
|
|
|
64
|
-
Keep old writers stopped.
|
|
65
|
-
hashes match, and the legacy 32-byte key is available. The importer
|
|
66
|
-
transactional and does not mark completion on failure; fix the
|
|
67
|
-
|
|
92
|
+
Keep old writers stopped. Check that the legacy database exists, the source
|
|
93
|
+
auth blob hashes match, and the legacy 32-byte key is available. The importer
|
|
94
|
+
is transactional and does not mark completion on failure; fix the problem and
|
|
95
|
+
rerun rather than editing the migration marker.
|
package/examples/basic.ts
CHANGED
|
@@ -5,3 +5,4 @@ const session = await browser.createSession({ id: 'example' });
|
|
|
5
5
|
await browser.execute(session.id, { type: 'open', url: 'https://example.com' });
|
|
6
6
|
console.log(await browser.execute(session.id, { type: 'snapshot' }));
|
|
7
7
|
await browser.closeSession(session.id);
|
|
8
|
+
await browser.close();
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@amalgm/browser",
|
|
3
|
-
"version": "0.1.2-preview.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.1.2-preview.37254096068",
|
|
4
|
+
"description": "The amalgm runtime's browser: one Chrome, a session per chat, and the account's cookies in every view.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "git+https://github.com/amalgm-inc/amalgm-browser.git"
|
|
@@ -23,10 +23,6 @@
|
|
|
23
23
|
"types": "./dist/src/index.d.ts",
|
|
24
24
|
"import": "./dist/src/index.js"
|
|
25
25
|
},
|
|
26
|
-
"./headless": {
|
|
27
|
-
"types": "./dist/src/headless.d.ts",
|
|
28
|
-
"import": "./dist/src/headless.js"
|
|
29
|
-
},
|
|
30
26
|
"./electron": {
|
|
31
27
|
"import": {
|
|
32
28
|
"types": "./dist/src/electron.d.ts",
|
|
@@ -80,12 +76,10 @@
|
|
|
80
76
|
],
|
|
81
77
|
"scripts": {
|
|
82
78
|
"build": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\" && tsc -p tsconfig.build.json && npm run build:electron-cjs && tsx scripts/finalize-build.ts",
|
|
83
|
-
"build:electron-cjs": "esbuild src/electron.ts --bundle --platform=node --format=cjs --target=node20 --define:import.meta.dirname=__dirname --define:__AMALGM_BROWSER_ADBLOCK_PRELOAD__=\\\"electron-preload.cjs\\\" --outfile=dist/src/electron.cjs --external:electron && esbuild src/
|
|
79
|
+
"build:electron-cjs": "esbuild src/electron.ts --bundle --platform=node --format=cjs --target=node20 --define:import.meta.dirname=__dirname --define:__AMALGM_BROWSER_ADBLOCK_PRELOAD__=\\\"electron-preload.cjs\\\" --outfile=dist/src/electron.cjs --external:electron && esbuild src/electron/adblock/preload.ts --bundle --platform=node --format=cjs --target=node20 --outfile=dist/src/electron-preload.cjs --external:electron",
|
|
84
80
|
"check": "tsx scripts/check-tree.ts && tsc -p tsconfig.json && tsc -p tsconfig.test.json",
|
|
85
81
|
"test": "tsx --test --test-concurrency=1 --test-timeout=30000 test/*.test.ts",
|
|
86
|
-
"test:real": "cross-env AMALGM_BROWSER_REAL=1 tsx --test --test-timeout=
|
|
87
|
-
"pretest:electron": "npm run build",
|
|
88
|
-
"test:electron": "tsx scripts/run-electron-test.ts",
|
|
82
|
+
"test:real": "cross-env AMALGM_BROWSER_REAL=1 tsx --test --test-concurrency=1 --test-timeout=120000 test/real-*.test.ts",
|
|
89
83
|
"verify": "npm run check && npm run build && npm test && npm run verify:pack",
|
|
90
84
|
"verify:pack": "tsx scripts/verify-package.ts",
|
|
91
85
|
"prepack": "npm run build",
|
|
@@ -132,8 +126,7 @@
|
|
|
132
126
|
"workflow": "verify.yml",
|
|
133
127
|
"jobs": [
|
|
134
128
|
"verify",
|
|
135
|
-
"real-
|
|
136
|
-
"real-electron"
|
|
129
|
+
"real-browser"
|
|
137
130
|
],
|
|
138
131
|
"verify": "verify",
|
|
139
132
|
"cli": [
|
|
@@ -157,11 +150,11 @@
|
|
|
157
150
|
"@amalgm/core"
|
|
158
151
|
]
|
|
159
152
|
},
|
|
160
|
-
"gitHead": "
|
|
153
|
+
"gitHead": "9a5d40729134e87c55fdbb7a52ad42711eef7163",
|
|
161
154
|
"amalgmSource": {
|
|
162
155
|
"repository": "amalgm-inc/amalgm-browser",
|
|
163
156
|
"branch": "preview",
|
|
164
|
-
"commit": "
|
|
165
|
-
"occurrence": "
|
|
157
|
+
"commit": "9a5d40729134e87c55fdbb7a52ad42711eef7163",
|
|
158
|
+
"occurrence": "37254096068"
|
|
166
159
|
}
|
|
167
160
|
}
|
|
@@ -22,7 +22,7 @@ The package installs three executables alongside the SDK:
|
|
|
22
22
|
- `amalgm-browser-mcp` — the MCP server (also reachable as `amalgm-browser mcp`).
|
|
23
23
|
- `amalgm-browser-rest` — the authenticated loopback REST API (also `amalgm-browser serve --token <token>`).
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
Browser runs one headless Chrome per runtime and drives it through the bundled `agent-browser`. It uses an installed Chrome, Chromium, or Brave, or the Chrome for Testing that `agent-browser install` downloads; `AMALGM_BROWSER_EXECUTABLE_PATH` picks a specific executable.
|
|
26
26
|
|
|
27
27
|
### MCP setup
|
|
28
28
|
|
|
@@ -59,26 +59,18 @@ const snapshot = await browser.execute(session.id, { type: 'snapshot' });
|
|
|
59
59
|
await browser.execute(session.id, { type: 'click', target: '@e3' });
|
|
60
60
|
|
|
61
61
|
await browser.closeSession(session.id);
|
|
62
|
+
await browser.close(); // stops Chrome
|
|
62
63
|
```
|
|
63
64
|
|
|
64
|
-
|
|
65
|
+
Through MCP the identical sequence is `browser_open`, `browser_snapshot`, `browser_click`, `browser_close`, each taking an optional `session` field. Without it, a call uses the calling chat's session when the host names the chat, and `default` otherwise.
|
|
65
66
|
|
|
66
|
-
|
|
67
|
-
amalgm-browser open https://example.com --session research
|
|
68
|
-
amalgm-browser snapshot --session research
|
|
69
|
-
amalgm-browser click @e3 --session research
|
|
70
|
-
amalgm-browser close --session research
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
Through MCP the identical sequence is `browser_open`, `browser_snapshot`, `browser_click`, `browser_close`, each taking an optional `session` field (defaulting to `default`).
|
|
67
|
+
Each CLI command is its own process: it starts Chrome, runs one step, and stops Chrome, so the next command starts on a new blank tab. Use the CLI for single steps such as `amalgm-browser open https://example.com`, and MCP, REST (`amalgm-browser serve`), or the SDK for multi-step flows.
|
|
74
68
|
|
|
75
69
|
## Core concepts
|
|
76
70
|
|
|
77
71
|
### Sessions
|
|
78
72
|
|
|
79
|
-
A session is a persistent page context: one
|
|
80
|
-
|
|
81
|
-
Backend selection (headless Chromium, an operator-supplied CDP endpoint, or a visible desktop surface when Browser is embedded in a host app) happens once, before session creation, and never changes during a session's lifetime. You do not choose a backend per command and should not ask users to.
|
|
73
|
+
A session is a persistent page context: its own tabs in the runtime's one Chrome. Every session browses as the same signed-in account and shares its cookies, so a sign-in in one session is visible in all of them. Create or name a session once at the start of a task, pass the same session id to every subsequent action, and close it when the task ends. Sessions are cheap to keep open and expensive to churn — reopening a page resets navigation state and every element reference you have collected.
|
|
82
74
|
|
|
83
75
|
### Tabs
|
|
84
76
|
|
|
@@ -100,8 +92,8 @@ Browser actions are individual commands over one shared session, and the orderin
|
|
|
100
92
|
1. Call `open` once per page, not once per command. The session holds the page.
|
|
101
93
|
2. Call `snapshot` to get refs, then act with those refs. Do not re-issue `tab` or `open` before each action — that resets the page context and every `@ref` you hold goes stale.
|
|
102
94
|
3. Re-snapshot only when the page has actually changed: after navigation, after a tab switch, after a click that triggered new content.
|
|
103
|
-
4. When a multi-step sequence fails, classify the failure by the specific command that failed, not by the sequence as a whole. Every action returns a typed error with a stable code (see [Error handling](#error-handling)); a
|
|
104
|
-
5. Keep one owner per session.
|
|
95
|
+
4. When a multi-step sequence fails, classify the failure by the specific command that failed, not by the sequence as a whole. Every action returns a typed error with a stable code (see [Error handling](#error-handling)); a stale ref at step four fails step four with `PROCESS_FAILED`, not the session. Usually the fix is a fresh `snapshot` and a retry of that one step.
|
|
96
|
+
5. Keep one owner per session. A session runs one action at a time, and two processes driving the same session id get `CONFLICT` rather than silently interleaving. Only one process can run a state root's Chrome; another process on the same root gets `CONFLICT` ("This browser profile already has a live owner.").
|
|
105
97
|
|
|
106
98
|
## Reading pages: snapshots vs screenshots
|
|
107
99
|
|
|
@@ -117,12 +109,10 @@ Screenshot and computer-use coordinates are CSS pixels with a 1:1 mapping betwee
|
|
|
117
109
|
|
|
118
110
|
## Forms and input
|
|
119
111
|
|
|
120
|
-
The core input actions cover ordinary DOM forms:
|
|
112
|
+
The core input actions cover ordinary DOM forms. A `fill` input:
|
|
121
113
|
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
amalgm-browser select @e9 "US" --session research
|
|
125
|
-
amalgm-browser press Enter --session research
|
|
114
|
+
```json
|
|
115
|
+
{ "target": "@e7", "text": "jane@example.com", "submit": true }
|
|
126
116
|
```
|
|
127
117
|
|
|
128
118
|
- `fill` sets a target's text; pass `submit: true` to submit the surrounding form in the same action.
|
|
@@ -151,7 +141,7 @@ When a task needs a human to log in, let the host provide the login interface. `
|
|
|
151
141
|
|
|
152
142
|
## MCP tools
|
|
153
143
|
|
|
154
|
-
The MCP server exposes twenty-two tools — the canonical action names prefixed with `browser_`. Session actions accept an optional `session` string
|
|
144
|
+
The MCP server exposes twenty-two tools — the canonical action names prefixed with `browser_`. Session actions accept an optional `session` string; without it they use the calling chat's session when the host names the chat, and `default` otherwise. `browser_record_list` and `browser_auth_list` list service-wide metadata, while `browser_auth_link_create` creates a separate login session; these three tools do not accept `session`.
|
|
155
145
|
|
|
156
146
|
| Group | Tools |
|
|
157
147
|
| --- | --- |
|
|
@@ -164,7 +154,7 @@ The MCP server exposes twenty-two tools — the canonical action names prefixed
|
|
|
164
154
|
|
|
165
155
|
`browser_cli` is the escape hatch: it runs an advanced `agent-browser` argv action for operations outside the canonical set. Prefer the named tools whenever one exists.
|
|
166
156
|
|
|
167
|
-
The CLI provides direct commands for the fifteen core browsing and computer-use actions, such as `amalgm-browser open` and `amalgm-browser snapshot`. Use `amalgm-browser action <name> --input <json>` for any of the twenty-two product actions, including authentication and recording, or use the resource commands (`sessions`, `
|
|
157
|
+
The CLI provides direct commands for the fifteen core browsing and computer-use actions, such as `amalgm-browser open` and `amalgm-browser snapshot`. Use `amalgm-browser action <name> --input <json>` for any of the twenty-two product actions, including authentication and recording, or use the resource commands (`sessions`, `auth`, `recordings`, `doctor`).
|
|
168
158
|
|
|
169
159
|
## Error handling
|
|
170
160
|
|
|
@@ -173,15 +163,12 @@ Failures are typed `BrowserError` values with stable codes:
|
|
|
173
163
|
| Code | Meaning |
|
|
174
164
|
| --- | --- |
|
|
175
165
|
| `INVALID_INPUT` | Malformed action input; fix the call, do not retry as-is. |
|
|
176
|
-
| `NOT_FOUND` |
|
|
177
|
-
| `CONFLICT` |
|
|
178
|
-
| `CAPABILITY_UNSUPPORTED` | The active backend does not implement this action group; nothing is silently approximated. |
|
|
166
|
+
| `NOT_FOUND` | The session, bundle, recording, or login does not exist. |
|
|
167
|
+
| `CONFLICT` | The session is busy or owned by another process, or another process runs this root's Chrome. |
|
|
179
168
|
| `AUTHORIZATION_DENIED` | The caller is not permitted to perform the action. |
|
|
180
169
|
| `TIMEOUT` / `ABORTED` | The operation ran out of time or was cancelled. |
|
|
181
|
-
| `PROCESS_FAILED` |
|
|
182
|
-
| `SURFACE_IDENTITY_FAILED` | A
|
|
183
|
-
|
|
184
|
-
Check `session.capabilities` before relying on optional groups (computer use, recording, auth, full-page capture) — a backend that lacks a capability refuses it explicitly rather than faking it.
|
|
170
|
+
| `PROCESS_FAILED` | agent-browser, Chrome, or ffmpeg failed — including a stale `@ref` or missing target; re-snapshot and retry that step. |
|
|
171
|
+
| `SURFACE_IDENTITY_FAILED` | A screenshot, computer-use double-click, or recording could not tell which of the session's tabs is its page; this fails closed. Switch to or close tabs, then retry. |
|
|
185
172
|
|
|
186
173
|
CLI exit codes map the same taxonomy: `0` success, `2` invalid input, `3` authorization denied, `4` not found, `5` timeout or cancellation, `1` any other typed failure. Pass `--timeout <ms>` to bound any blocking CLI operation.
|
|
187
174
|
|
|
@@ -31,7 +31,7 @@ Use computer use for canvas, WebGL, image-only, or custom controls without DOM s
|
|
|
31
31
|
|
|
32
32
|
## Tabs and dialogs
|
|
33
33
|
|
|
34
|
-
`tab` takes `action: "list" | "new" | "switch" | "close"`, with `id` identifying the tab for `switch` and `close`. Switching tabs invalidates snapshot refs; re-snapshot after switching.
|
|
34
|
+
`tab` takes `action: "list" | "new" | "switch" | "close"`, with `id` identifying the tab for `switch` and `close`. Switching tabs invalidates snapshot refs; re-snapshot after switching.
|
|
35
35
|
|
|
36
36
|
`dialog` takes `action: "accept" | "dismiss"`, with optional `text` supplied only for prompt dialogs.
|
|
37
37
|
|
|
@@ -46,7 +46,7 @@ Use computer use for canvas, WebGL, image-only, or custom controls without DOM s
|
|
|
46
46
|
- `auth_load` — load a bundle into the session by `bundleId`.
|
|
47
47
|
- `auth_list` — list sanitized profiles, bundles, and login sessions. Never returns raw cookie or token values.
|
|
48
48
|
|
|
49
|
-
|
|
49
|
+
Every session browses as the signed-in amalgm account, so it already carries that account's cookies. An auth bundle is an explicitly saved, named credential snapshot; loading one adds its state to the session.
|
|
50
50
|
|
|
51
51
|
## Recording
|
|
52
52
|
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
export async function routeProfiles(context) {
|
|
2
|
-
const [resource, id] = context.path;
|
|
3
|
-
if (resource !== 'profiles')
|
|
4
|
-
return false;
|
|
5
|
-
if (!id && context.method === 'GET') {
|
|
6
|
-
context.json(200, { profiles: context.browser.listProfiles() });
|
|
7
|
-
return true;
|
|
8
|
-
}
|
|
9
|
-
if (!id && context.method === 'POST') {
|
|
10
|
-
const body = await context.body();
|
|
11
|
-
context.json(201, { profile: context.browser.createProfile({
|
|
12
|
-
...(typeof body.id === 'string' ? { id: body.id } : {}),
|
|
13
|
-
name: typeof body.name === 'string' ? body.name : String(body.id || 'profile'),
|
|
14
|
-
kind: 'durable',
|
|
15
|
-
}) });
|
|
16
|
-
return true;
|
|
17
|
-
}
|
|
18
|
-
if (id === 'prune' && context.method === 'POST') {
|
|
19
|
-
const body = await context.body();
|
|
20
|
-
context.json(200, { removed: context.browser.pruneProfiles(Number(body.maxAgeMs) || undefined) });
|
|
21
|
-
return true;
|
|
22
|
-
}
|
|
23
|
-
if (id && context.method === 'GET') {
|
|
24
|
-
context.json(200, { status: context.browser.inspectProfile(id) });
|
|
25
|
-
return true;
|
|
26
|
-
}
|
|
27
|
-
if (id && context.method === 'PATCH') {
|
|
28
|
-
const body = await context.body();
|
|
29
|
-
context.json(200, { profile: context.browser.updateProfile(id, {
|
|
30
|
-
...(typeof body.name === 'string' ? { name: body.name } : {}),
|
|
31
|
-
...(body.kind === 'durable' || body.kind === 'ephemeral' ? { kind: body.kind } : {}),
|
|
32
|
-
}) });
|
|
33
|
-
return true;
|
|
34
|
-
}
|
|
35
|
-
if (id && context.method === 'DELETE') {
|
|
36
|
-
context.browser.deleteProfile(id);
|
|
37
|
-
context.json(200, { deleted: id });
|
|
38
|
-
return true;
|
|
39
|
-
}
|
|
40
|
-
return false;
|
|
41
|
-
}
|
|
42
|
-
//# sourceMappingURL=profile-routes.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"profile-routes.js","sourceRoot":"","sources":["../../../../src/adapters/http/profile-routes.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import type { BrowserLoginSession, BrowserRuntimeContext } from '../types.js';
|
|
2
|
-
export interface LoginTransportInput {
|
|
3
|
-
transport?: string;
|
|
4
|
-
liveUrl?: string;
|
|
5
|
-
context?: BrowserRuntimeContext;
|
|
6
|
-
}
|
|
7
|
-
export declare function resolveLoginTransport(input: LoginTransportInput, env?: NodeJS.ProcessEnv): Pick<BrowserLoginSession, 'transport' | 'liveUrl' | 'setupStatus'>;
|
|
8
|
-
export declare function noVncUrl(value: string | undefined): string | undefined;
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
export function resolveLoginTransport(input, env = process.env) {
|
|
2
|
-
const requested = normalizeTransport(input.transport || env.AMALGM_BROWSER_LOGIN_TRANSPORT);
|
|
3
|
-
const liveUrl = noVncUrl(input.liveUrl || env.AMALGM_BROWSER_NOVNC_PUBLIC_URL || env.AMALGM_BROWSER_NOVNC_URL);
|
|
4
|
-
if (requested === 'electron-surface' || (!requested && input.context?.clientKind === 'desktop')) {
|
|
5
|
-
return { transport: 'electron-surface', setupStatus: 'ready' };
|
|
6
|
-
}
|
|
7
|
-
if (requested === 'novnc' || liveUrl) {
|
|
8
|
-
return {
|
|
9
|
-
transport: 'novnc',
|
|
10
|
-
...(liveUrl ? { liveUrl } : {}),
|
|
11
|
-
setupStatus: liveUrl ? 'ready' : 'missing_novnc_url',
|
|
12
|
-
};
|
|
13
|
-
}
|
|
14
|
-
return { transport: 'external', setupStatus: requested === 'manual' ? 'manual' : 'ready' };
|
|
15
|
-
}
|
|
16
|
-
export function noVncUrl(value) {
|
|
17
|
-
if (!value)
|
|
18
|
-
return undefined;
|
|
19
|
-
try {
|
|
20
|
-
const url = new URL(value);
|
|
21
|
-
if (!['http:', 'https:'].includes(url.protocol))
|
|
22
|
-
return undefined;
|
|
23
|
-
if (!url.searchParams.has('autoconnect'))
|
|
24
|
-
url.searchParams.set('autoconnect', '1');
|
|
25
|
-
if (!url.searchParams.has('resize'))
|
|
26
|
-
url.searchParams.set('resize', 'scale');
|
|
27
|
-
return url.toString();
|
|
28
|
-
}
|
|
29
|
-
catch {
|
|
30
|
-
return undefined;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
function normalizeTransport(value) {
|
|
34
|
-
const clean = String(value || '').trim().toLowerCase();
|
|
35
|
-
if (['electron', 'electron-splitview', 'desktop', 'electron-surface'].includes(clean))
|
|
36
|
-
return 'electron-surface';
|
|
37
|
-
if (['novnc', 'vnc', 'remote', 'remote-live-view'].includes(clean))
|
|
38
|
-
return 'novnc';
|
|
39
|
-
if (['none', 'manual'].includes(clean))
|
|
40
|
-
return 'manual';
|
|
41
|
-
if (['external', 'amalgm-live', 'live', 'browser-auth-live', 'cdp-live'].includes(clean))
|
|
42
|
-
return 'external';
|
|
43
|
-
return undefined;
|
|
44
|
-
}
|
|
45
|
-
//# sourceMappingURL=transport.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"transport.js","sourceRoot":"","sources":["../../../src/auth/transport.ts"],"names":[],"mappings":"AAQA,MAAM,UAAU,qBAAqB,CACnC,KAA0B,EAC1B,MAAyB,OAAO,CAAC,GAAG;IAEpC,MAAM,SAAS,GAAG,kBAAkB,CAAC,KAAK,CAAC,SAAS,IAAI,GAAG,CAAC,8BAA8B,CAAC,CAAC;IAC5F,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,CAAC,OAAO,IAAI,GAAG,CAAC,+BAA+B,IAAI,GAAG,CAAC,wBAAwB,CAAC,CAAC;IAC/G,IAAI,SAAS,KAAK,kBAAkB,IAAI,CAAC,CAAC,SAAS,IAAI,KAAK,CAAC,OAAO,EAAE,UAAU,KAAK,SAAS,CAAC,EAAE,CAAC;QAChG,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC;IACjE,CAAC;IACD,IAAI,SAAS,KAAK,OAAO,IAAI,OAAO,EAAE,CAAC;QACrC,OAAO;YACL,SAAS,EAAE,OAAO;YAClB,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC/B,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,mBAAmB;SACrD,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,WAAW,EAAE,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;AAC7F,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,KAAyB;IAChD,IAAI,CAAC,KAAK;QAAE,OAAO,SAAS,CAAC;IAC7B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC;QAC3B,IAAI,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC;YAAE,OAAO,SAAS,CAAC;QAClE,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,aAAa,CAAC;YAAE,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC;QACnF,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC;YAAE,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAC7E,OAAO,GAAG,CAAC,QAAQ,EAAE,CAAC;IACxB,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,SAAS,CAAC;IAAC,CAAC;AAC/B,CAAC;AAED,SAAS,kBAAkB,CAAC,KAAyB;IACnD,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACvD,IAAI,CAAC,UAAU,EAAE,oBAAoB,EAAE,SAAS,EAAE,kBAAkB,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,kBAAkB,CAAC;IACjH,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,kBAAkB,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,OAAO,CAAC;IACnF,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,QAAQ,CAAC;IACxD,IAAI,CAAC,UAAU,EAAE,aAAa,EAAE,MAAM,EAAE,mBAAmB,EAAE,UAAU,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,UAAU,CAAC;IAC5G,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"capture.js","sourceRoot":"","sources":["../../../../src/drivers/cdp/capture.ts"],"names":[],"mappings":"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"}
|