@amalgm/browser 0.1.0
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/CHANGELOG.md +16 -0
- package/LICENSE +5 -0
- package/PURPOSE.md +117 -0
- package/README.md +120 -0
- package/SECURITY.md +49 -0
- package/dist/bin/amalgm-browser-mcp.d.ts +2 -0
- package/dist/bin/amalgm-browser-mcp.js +5 -0
- package/dist/bin/amalgm-browser-mcp.js.map +1 -0
- package/dist/bin/amalgm-browser-rest.d.ts +2 -0
- package/dist/bin/amalgm-browser-rest.js +20 -0
- package/dist/bin/amalgm-browser-rest.js.map +1 -0
- package/dist/bin/amalgm-browser.d.ts +2 -0
- package/dist/bin/amalgm-browser.js +4 -0
- package/dist/bin/amalgm-browser.js.map +1 -0
- package/dist/src/action.d.ts +5 -0
- package/dist/src/action.js +42 -0
- package/dist/src/action.js.map +1 -0
- package/dist/src/adapters/actions.d.ts +10 -0
- package/dist/src/adapters/actions.js +41 -0
- package/dist/src/adapters/actions.js.map +1 -0
- package/dist/src/adapters/cli/actions.d.ts +7 -0
- package/dist/src/adapters/cli/actions.js +63 -0
- package/dist/src/adapters/cli/actions.js.map +1 -0
- package/dist/src/adapters/cli/args.d.ts +8 -0
- package/dist/src/adapters/cli/args.js +41 -0
- package/dist/src/adapters/cli/args.js.map +1 -0
- package/dist/src/adapters/cli/help.d.ts +1 -0
- package/dist/src/adapters/cli/help.js +29 -0
- package/dist/src/adapters/cli/help.js.map +1 -0
- package/dist/src/adapters/cli/resources.d.ts +4 -0
- package/dist/src/adapters/cli/resources.js +116 -0
- package/dist/src/adapters/cli/resources.js.map +1 -0
- package/dist/src/adapters/cli/run.d.ts +7 -0
- package/dist/src/adapters/cli/run.js +108 -0
- package/dist/src/adapters/cli/run.js.map +1 -0
- package/dist/src/adapters/execute.d.ts +4 -0
- package/dist/src/adapters/execute.js +91 -0
- package/dist/src/adapters/execute.js.map +1 -0
- package/dist/src/adapters/http/auth-routes.d.ts +2 -0
- package/dist/src/adapters/http/auth-routes.js +93 -0
- package/dist/src/adapters/http/auth-routes.js.map +1 -0
- package/dist/src/adapters/http/events.d.ts +3 -0
- package/dist/src/adapters/http/events.js +20 -0
- package/dist/src/adapters/http/events.js.map +1 -0
- package/dist/src/adapters/http/internal-routes.d.ts +2 -0
- package/dist/src/adapters/http/internal-routes.js +35 -0
- package/dist/src/adapters/http/internal-routes.js.map +1 -0
- package/dist/src/adapters/http/openapi.d.ts +1 -0
- package/dist/src/adapters/http/openapi.js +78 -0
- package/dist/src/adapters/http/openapi.js.map +1 -0
- package/dist/src/adapters/http/profile-routes.d.ts +2 -0
- package/dist/src/adapters/http/profile-routes.js +42 -0
- package/dist/src/adapters/http/profile-routes.js.map +1 -0
- package/dist/src/adapters/http/recording-routes.d.ts +2 -0
- package/dist/src/adapters/http/recording-routes.js +41 -0
- package/dist/src/adapters/http/recording-routes.js.map +1 -0
- package/dist/src/adapters/http/request.d.ts +4 -0
- package/dist/src/adapters/http/request.js +44 -0
- package/dist/src/adapters/http/request.js.map +1 -0
- package/dist/src/adapters/http/server.d.ts +2 -0
- package/dist/src/adapters/http/server.js +114 -0
- package/dist/src/adapters/http/server.js.map +1 -0
- package/dist/src/adapters/http/session-routes.d.ts +2 -0
- package/dist/src/adapters/http/session-routes.js +54 -0
- package/dist/src/adapters/http/session-routes.js.map +1 -0
- package/dist/src/adapters/http/types.d.ts +29 -0
- package/dist/src/adapters/http/types.js +2 -0
- package/dist/src/adapters/http/types.js.map +1 -0
- package/dist/src/adapters/mcp/server.d.ts +3 -0
- package/dist/src/adapters/mcp/server.js +74 -0
- package/dist/src/adapters/mcp/server.js.map +1 -0
- package/dist/src/adapters/mcp/tools.d.ts +3 -0
- package/dist/src/adapters/mcp/tools.js +45 -0
- package/dist/src/adapters/mcp/tools.js.map +1 -0
- package/dist/src/adapters/mcp/types.d.ts +17 -0
- package/dist/src/adapters/mcp/types.js +2 -0
- package/dist/src/adapters/mcp/types.js.map +1 -0
- package/dist/src/adapters/toolbox/aliases.d.ts +5 -0
- package/dist/src/adapters/toolbox/aliases.js +14 -0
- package/dist/src/adapters/toolbox/aliases.js.map +1 -0
- package/dist/src/adapters/toolbox/executor.d.ts +6 -0
- package/dist/src/adapters/toolbox/executor.js +13 -0
- package/dist/src/adapters/toolbox/executor.js.map +1 -0
- package/dist/src/adapters/toolbox/manifest.d.ts +15 -0
- package/dist/src/adapters/toolbox/manifest.js +24 -0
- package/dist/src/adapters/toolbox/manifest.js.map +1 -0
- package/dist/src/artifacts.d.ts +14 -0
- package/dist/src/artifacts.js +28 -0
- package/dist/src/artifacts.js.map +1 -0
- package/dist/src/auth/filter.d.ts +3 -0
- package/dist/src/auth/filter.js +60 -0
- package/dist/src/auth/filter.js.map +1 -0
- package/dist/src/auth/login.d.ts +41 -0
- package/dist/src/auth/login.js +145 -0
- package/dist/src/auth/login.js.map +1 -0
- package/dist/src/auth/portable.d.ts +18 -0
- package/dist/src/auth/portable.js +48 -0
- package/dist/src/auth/portable.js.map +1 -0
- package/dist/src/auth/service.d.ts +29 -0
- package/dist/src/auth/service.js +104 -0
- package/dist/src/auth/service.js.map +1 -0
- package/dist/src/auth/transport.d.ts +8 -0
- package/dist/src/auth/transport.js +45 -0
- package/dist/src/auth/transport.js.map +1 -0
- package/dist/src/auth/vault.d.ts +10 -0
- package/dist/src/auth/vault.js +27 -0
- package/dist/src/auth/vault.js.map +1 -0
- package/dist/src/cli.d.ts +2 -0
- package/dist/src/cli.js +3 -0
- package/dist/src/cli.js.map +1 -0
- package/dist/src/cookies/coordinator.d.ts +17 -0
- package/dist/src/cookies/coordinator.js +93 -0
- package/dist/src/cookies/coordinator.js.map +1 -0
- package/dist/src/cookies/jar.d.ts +21 -0
- package/dist/src/cookies/jar.js +146 -0
- package/dist/src/cookies/jar.js.map +1 -0
- package/dist/src/cookies/policy.d.ts +6 -0
- package/dist/src/cookies/policy.js +58 -0
- package/dist/src/cookies/policy.js.map +1 -0
- package/dist/src/cookies/secret-file.d.ts +10 -0
- package/dist/src/cookies/secret-file.js +80 -0
- package/dist/src/cookies/secret-file.js.map +1 -0
- package/dist/src/cookies/types.d.ts +64 -0
- package/dist/src/cookies/types.js +2 -0
- package/dist/src/cookies/types.js.map +1 -0
- package/dist/src/cookies.d.ts +5 -0
- package/dist/src/cookies.js +5 -0
- package/dist/src/cookies.js.map +1 -0
- package/dist/src/defaults.d.ts +24 -0
- package/dist/src/defaults.js +107 -0
- package/dist/src/defaults.js.map +1 -0
- package/dist/src/drivers/cdp/capture.d.ts +5 -0
- package/dist/src/drivers/cdp/capture.js +39 -0
- package/dist/src/drivers/cdp/capture.js.map +1 -0
- package/dist/src/drivers/cdp/client.d.ts +8 -0
- package/dist/src/drivers/cdp/client.js +88 -0
- package/dist/src/drivers/cdp/client.js.map +1 -0
- package/dist/src/drivers/cdp/input.d.ts +2 -0
- package/dist/src/drivers/cdp/input.js +15 -0
- package/dist/src/drivers/cdp/input.js.map +1 -0
- package/dist/src/drivers/cdp/screencast.d.ts +2 -0
- package/dist/src/drivers/cdp/screencast.js +39 -0
- package/dist/src/drivers/cdp/screencast.js.map +1 -0
- package/dist/src/drivers/cdp/target.d.ts +4 -0
- package/dist/src/drivers/cdp/target.js +34 -0
- package/dist/src/drivers/cdp/target.js.map +1 -0
- package/dist/src/drivers/electron/advertisement.d.ts +12 -0
- package/dist/src/drivers/electron/advertisement.js +57 -0
- package/dist/src/drivers/electron/advertisement.js.map +1 -0
- package/dist/src/drivers/electron/contracts.d.ts +45 -0
- package/dist/src/drivers/electron/contracts.js +10 -0
- package/dist/src/drivers/electron/contracts.js.map +1 -0
- package/dist/src/drivers/electron/cookie-adapter.d.ts +17 -0
- package/dist/src/drivers/electron/cookie-adapter.js +69 -0
- package/dist/src/drivers/electron/cookie-adapter.js.map +1 -0
- package/dist/src/drivers/electron/driver.d.ts +19 -0
- package/dist/src/drivers/electron/driver.js +115 -0
- package/dist/src/drivers/electron/driver.js.map +1 -0
- package/dist/src/drivers/electron/native/adblock/cache.d.ts +4 -0
- package/dist/src/drivers/electron/native/adblock/cache.js +54 -0
- package/dist/src/drivers/electron/native/adblock/cache.js.map +1 -0
- package/dist/src/drivers/electron/native/adblock/cosmetics.d.ts +11 -0
- package/dist/src/drivers/electron/native/adblock/cosmetics.js +45 -0
- package/dist/src/drivers/electron/native/adblock/cosmetics.js.map +1 -0
- package/dist/src/drivers/electron/native/adblock/index.d.ts +44 -0
- package/dist/src/drivers/electron/native/adblock/index.js +153 -0
- package/dist/src/drivers/electron/native/adblock/index.js.map +1 -0
- package/dist/src/drivers/electron/native/adblock/policy.d.ts +2 -0
- package/dist/src/drivers/electron/native/adblock/policy.js +12 -0
- package/dist/src/drivers/electron/native/adblock/policy.js.map +1 -0
- package/dist/src/drivers/electron/native/adblock/preload.d.ts +1 -0
- package/dist/src/drivers/electron/native/adblock/preload.js +131 -0
- package/dist/src/drivers/electron/native/adblock/preload.js.map +1 -0
- package/dist/src/drivers/electron/native/adblock/settings.d.ts +9 -0
- package/dist/src/drivers/electron/native/adblock/settings.js +37 -0
- package/dist/src/drivers/electron/native/adblock/settings.js.map +1 -0
- package/dist/src/drivers/electron/native/config.d.ts +4 -0
- package/dist/src/drivers/electron/native/config.js +9 -0
- package/dist/src/drivers/electron/native/config.js.map +1 -0
- package/dist/src/drivers/electron/native/contracts.d.ts +174 -0
- package/dist/src/drivers/electron/native/contracts.js +20 -0
- package/dist/src/drivers/electron/native/contracts.js.map +1 -0
- package/dist/src/drivers/electron/native/policy.d.ts +7 -0
- package/dist/src/drivers/electron/native/policy.js +43 -0
- package/dist/src/drivers/electron/native/policy.js.map +1 -0
- package/dist/src/drivers/electron/native/session.d.ts +4 -0
- package/dist/src/drivers/electron/native/session.js +11 -0
- package/dist/src/drivers/electron/native/session.js.map +1 -0
- package/dist/src/drivers/electron/native/shell/adblock-ipc.d.ts +10 -0
- package/dist/src/drivers/electron/native/shell/adblock-ipc.js +44 -0
- package/dist/src/drivers/electron/native/shell/adblock-ipc.js.map +1 -0
- package/dist/src/drivers/electron/native/shell/context-menu.d.ts +11 -0
- package/dist/src/drivers/electron/native/shell/context-menu.js +129 -0
- package/dist/src/drivers/electron/native/shell/context-menu.js.map +1 -0
- package/dist/src/drivers/electron/native/shell/downloads.d.ts +11 -0
- package/dist/src/drivers/electron/native/shell/downloads.js +90 -0
- package/dist/src/drivers/electron/native/shell/downloads.js.map +1 -0
- package/dist/src/drivers/electron/native/shell/helpers.d.ts +5 -0
- package/dist/src/drivers/electron/native/shell/helpers.js +53 -0
- package/dist/src/drivers/electron/native/shell/helpers.js.map +1 -0
- package/dist/src/drivers/electron/native/shell/permissions.d.ts +16 -0
- package/dist/src/drivers/electron/native/shell/permissions.js +107 -0
- package/dist/src/drivers/electron/native/shell/permissions.js.map +1 -0
- package/dist/src/drivers/electron/native/shell/sites.d.ts +24 -0
- package/dist/src/drivers/electron/native/shell/sites.js +119 -0
- package/dist/src/drivers/electron/native/shell/sites.js.map +1 -0
- package/dist/src/drivers/electron/native/shell/types.d.ts +13 -0
- package/dist/src/drivers/electron/native/shell/types.js +2 -0
- package/dist/src/drivers/electron/native/shell/types.js.map +1 -0
- package/dist/src/drivers/electron/native/shell.d.ts +14 -0
- package/dist/src/drivers/electron/native/shell.js +115 -0
- package/dist/src/drivers/electron/native/shell.js.map +1 -0
- package/dist/src/drivers/electron/native/surface/commands.d.ts +4 -0
- package/dist/src/drivers/electron/native/surface/commands.js +49 -0
- package/dist/src/drivers/electron/native/surface/commands.js.map +1 -0
- package/dist/src/drivers/electron/native/surface/create.d.ts +4 -0
- package/dist/src/drivers/electron/native/surface/create.js +46 -0
- package/dist/src/drivers/electron/native/surface/create.js.map +1 -0
- package/dist/src/drivers/electron/native/surface/events.d.ts +3 -0
- package/dist/src/drivers/electron/native/surface/events.js +55 -0
- package/dist/src/drivers/electron/native/surface/events.js.map +1 -0
- package/dist/src/drivers/electron/native/surface/presentation.d.ts +15 -0
- package/dist/src/drivers/electron/native/surface/presentation.js +87 -0
- package/dist/src/drivers/electron/native/surface/presentation.js.map +1 -0
- package/dist/src/drivers/electron/native/surface/state.d.ts +7 -0
- package/dist/src/drivers/electron/native/surface/state.js +45 -0
- package/dist/src/drivers/electron/native/surface/state.js.map +1 -0
- package/dist/src/drivers/electron/native/surface/types.d.ts +39 -0
- package/dist/src/drivers/electron/native/surface/types.js +2 -0
- package/dist/src/drivers/electron/native/surface/types.js.map +1 -0
- package/dist/src/drivers/electron/native/surface-controller.d.ts +6 -0
- package/dist/src/drivers/electron/native/surface-controller.js +138 -0
- package/dist/src/drivers/electron/native/surface-controller.js.map +1 -0
- package/dist/src/drivers/electron/policy.d.ts +4 -0
- package/dist/src/drivers/electron/policy.js +39 -0
- package/dist/src/drivers/electron/policy.js.map +1 -0
- package/dist/src/drivers/electron/session.d.ts +4 -0
- package/dist/src/drivers/electron/session.js +5 -0
- package/dist/src/drivers/electron/session.js.map +1 -0
- package/dist/src/drivers/headless/command.d.ts +25 -0
- package/dist/src/drivers/headless/command.js +114 -0
- package/dist/src/drivers/headless/command.js.map +1 -0
- package/dist/src/drivers/headless/cookie-adapter.d.ts +16 -0
- package/dist/src/drivers/headless/cookie-adapter.js +59 -0
- package/dist/src/drivers/headless/cookie-adapter.js.map +1 -0
- package/dist/src/drivers/headless/driver.d.ts +31 -0
- package/dist/src/drivers/headless/driver.js +238 -0
- package/dist/src/drivers/headless/driver.js.map +1 -0
- package/dist/src/drivers/headless/executable.d.ts +8 -0
- package/dist/src/drivers/headless/executable.js +56 -0
- package/dist/src/drivers/headless/executable.js.map +1 -0
- package/dist/src/drivers/headless/screencast.d.ts +3 -0
- package/dist/src/drivers/headless/screencast.js +21 -0
- package/dist/src/drivers/headless/screencast.js.map +1 -0
- package/dist/src/electron.d.ts +14 -0
- package/dist/src/electron.js +15 -0
- package/dist/src/electron.js.map +1 -0
- package/dist/src/errors.d.ts +9 -0
- package/dist/src/errors.js +25 -0
- package/dist/src/errors.js.map +1 -0
- package/dist/src/events.d.ts +13 -0
- package/dist/src/events.js +32 -0
- package/dist/src/events.js.map +1 -0
- package/dist/src/headless.d.ts +3 -0
- package/dist/src/headless.js +4 -0
- package/dist/src/headless.js.map +1 -0
- package/dist/src/http.d.ts +3 -0
- package/dist/src/http.js +3 -0
- package/dist/src/http.js.map +1 -0
- package/dist/src/ids.d.ts +2 -0
- package/dist/src/ids.js +9 -0
- package/dist/src/ids.js.map +1 -0
- package/dist/src/index.d.ts +14 -0
- package/dist/src/index.js +11 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/interaction/delta.d.ts +25 -0
- package/dist/src/interaction/delta.js +102 -0
- package/dist/src/interaction/delta.js.map +1 -0
- package/dist/src/interaction/typing.d.ts +39 -0
- package/dist/src/interaction/typing.js +189 -0
- package/dist/src/interaction/typing.js.map +1 -0
- package/dist/src/mcp.d.ts +3 -0
- package/dist/src/mcp.js +3 -0
- package/dist/src/mcp.js.map +1 -0
- package/dist/src/migration/legacy-cookies.d.ts +2 -0
- package/dist/src/migration/legacy-cookies.js +60 -0
- package/dist/src/migration/legacy-cookies.js.map +1 -0
- package/dist/src/migration/legacy-crypto.d.ts +1 -0
- package/dist/src/migration/legacy-crypto.js +35 -0
- package/dist/src/migration/legacy-crypto.js.map +1 -0
- package/dist/src/migration/legacy-migration.d.ts +20 -0
- package/dist/src/migration/legacy-migration.js +81 -0
- package/dist/src/migration/legacy-migration.js.map +1 -0
- package/dist/src/migration/legacy-rows.d.ts +5 -0
- package/dist/src/migration/legacy-rows.js +72 -0
- package/dist/src/migration/legacy-rows.js.map +1 -0
- package/dist/src/persistence/sqlite-registry.d.ts +32 -0
- package/dist/src/persistence/sqlite-registry.js +136 -0
- package/dist/src/persistence/sqlite-registry.js.map +1 -0
- package/dist/src/ports.d.ts +93 -0
- package/dist/src/ports.js +4 -0
- package/dist/src/ports.js.map +1 -0
- package/dist/src/process.d.ts +4 -0
- package/dist/src/process.js +63 -0
- package/dist/src/process.js.map +1 -0
- package/dist/src/product-service.d.ts +30 -0
- package/dist/src/product-service.js +38 -0
- package/dist/src/product-service.js.map +1 -0
- package/dist/src/profiles/directories.d.ts +9 -0
- package/dist/src/profiles/directories.js +57 -0
- package/dist/src/profiles/directories.js.map +1 -0
- package/dist/src/profiles/service.d.ts +30 -0
- package/dist/src/profiles/service.js +89 -0
- package/dist/src/profiles/service.js.map +1 -0
- package/dist/src/recording/encoder.d.ts +22 -0
- package/dist/src/recording/encoder.js +89 -0
- package/dist/src/recording/encoder.js.map +1 -0
- package/dist/src/recording/sampler.d.ts +18 -0
- package/dist/src/recording/sampler.js +33 -0
- package/dist/src/recording/sampler.js.map +1 -0
- package/dist/src/recording/service.d.ts +27 -0
- package/dist/src/recording/service.js +180 -0
- package/dist/src/recording/service.js.map +1 -0
- package/dist/src/recording/source.d.ts +1 -0
- package/dist/src/recording/source.js +21 -0
- package/dist/src/recording/source.js.map +1 -0
- package/dist/src/recording.d.ts +3 -0
- package/dist/src/recording.js +4 -0
- package/dist/src/recording.js.map +1 -0
- package/dist/src/registry.d.ts +15 -0
- package/dist/src/registry.js +46 -0
- package/dist/src/registry.js.map +1 -0
- package/dist/src/runtime-selector.d.ts +12 -0
- package/dist/src/runtime-selector.js +78 -0
- package/dist/src/runtime-selector.js.map +1 -0
- package/dist/src/service-options.d.ts +19 -0
- package/dist/src/service-options.js +2 -0
- package/dist/src/service-options.js.map +1 -0
- package/dist/src/service.d.ts +39 -0
- package/dist/src/service.js +204 -0
- package/dist/src/service.js.map +1 -0
- package/dist/src/sessions/leases.d.ts +10 -0
- package/dist/src/sessions/leases.js +41 -0
- package/dist/src/sessions/leases.js.map +1 -0
- package/dist/src/sessions/prune.d.ts +2 -0
- package/dist/src/sessions/prune.js +8 -0
- package/dist/src/sessions/prune.js.map +1 -0
- package/dist/src/testing.d.ts +18 -0
- package/dist/src/testing.js +21 -0
- package/dist/src/testing.js.map +1 -0
- package/dist/src/toolbox.d.ts +3 -0
- package/dist/src/toolbox.js +4 -0
- package/dist/src/toolbox.js.map +1 -0
- package/dist/src/types.d.ts +273 -0
- package/dist/src/types.js +2 -0
- package/dist/src/types.js.map +1 -0
- package/docs/ACTIONS.md +27 -0
- package/docs/ARCHITECTURE.md +71 -0
- package/docs/AUTHENTICATION.md +56 -0
- package/docs/AXIOMS.md +20 -0
- package/docs/CLI.md +61 -0
- package/docs/COMPATIBILITY.md +45 -0
- package/docs/COOKIES.md +61 -0
- package/docs/ELECTRON_INTEGRATION.md +87 -0
- package/docs/ENGINE_INTEGRATION.md +73 -0
- package/docs/EVENTS.md +30 -0
- package/docs/HEADLESS_RUNTIME.md +58 -0
- package/docs/MCP.md +36 -0
- package/docs/MIGRATION.md +64 -0
- package/docs/OPERATIONS.md +69 -0
- package/docs/README.md +21 -0
- package/docs/REALTIME_BOUNDARY.md +33 -0
- package/docs/RECORDING.md +55 -0
- package/docs/REST.md +69 -0
- package/docs/SDK.md +101 -0
- package/docs/TESTING.md +57 -0
- package/docs/TOOLBOX_INTEGRATION.md +34 -0
- package/docs/TROUBLESHOOTING.md +67 -0
- package/examples/basic.ts +7 -0
- package/examples/custom-driver.ts +45 -0
- package/package.json +78 -0
- package/skills/use-amalgm-browser/SKILL.md +42 -0
- package/skills/use-amalgm-browser/agents/openai.yaml +4 -0
- package/skills/use-amalgm-browser/references/actions.md +40 -0
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# Electron integration
|
|
2
|
+
|
|
3
|
+
Electron is an optional peer dependency and appears only behind
|
|
4
|
+
`@amalgm/browser/electron`. Headless consumers do not load it.
|
|
5
|
+
|
|
6
|
+
## Composition
|
|
7
|
+
|
|
8
|
+
The package contains both sides of the visible boundary:
|
|
9
|
+
|
|
10
|
+
- `createBrowserShell` owns native page sites, policy, downloads, permissions,
|
|
11
|
+
context menus, popup conversion, ad blocking, and safe teardown.
|
|
12
|
+
- `createBrowserSurfaceController` owns automation surfaces, bounds,
|
|
13
|
+
presentation, capture, focus, find, zoom, and surface state.
|
|
14
|
+
- `ElectronBrowserDriver` presents those verified surfaces to the Browser SDK.
|
|
15
|
+
- host advertisement helpers publish a private, atomic loopback CDP bridge.
|
|
16
|
+
|
|
17
|
+
The application renderer supplies presentation and IPC wiring; it is not a
|
|
18
|
+
browser-state authority.
|
|
19
|
+
|
|
20
|
+
## Partition isolation
|
|
21
|
+
|
|
22
|
+
Always obtain the physical Browser session with `getBrowserSession` or
|
|
23
|
+
`isolatedBrowserSession`. Both require the exact partition:
|
|
24
|
+
|
|
25
|
+
```text
|
|
26
|
+
persist:amalgm-browser
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Do not pass Electron `defaultSession` to the shell or cookie adapter. The
|
|
30
|
+
Browser partition owns its cookies, cache, storage, service workers,
|
|
31
|
+
permissions, zoom, and request policy without touching application auth.
|
|
32
|
+
|
|
33
|
+
## Surface identity
|
|
34
|
+
|
|
35
|
+
Protocol 6 uses native page targets; protocol 5 remains a rolling-compatibility
|
|
36
|
+
reader for the prior webview bridge. A requested automation surface receives a
|
|
37
|
+
neutral marker URL, surface ID, and session stamp. The driver binds this
|
|
38
|
+
identity and verifies it before every action.
|
|
39
|
+
|
|
40
|
+
It never selects a target by order, target count, active tab, or URL. Identical
|
|
41
|
+
URLs in two sessions remain distinct. A destroyed target may be reattached
|
|
42
|
+
once only to the same verified identity. Mismatch or ambiguity fails before
|
|
43
|
+
input, capture, or recording.
|
|
44
|
+
|
|
45
|
+
## Native shell policy
|
|
46
|
+
|
|
47
|
+
The shell provides:
|
|
48
|
+
|
|
49
|
+
- safe `http`, `https`, and controlled external-protocol navigation
|
|
50
|
+
- popup-to-tab and child-window disposition
|
|
51
|
+
- page state, favicon, navigation, and load-failure events
|
|
52
|
+
- back, forward, reload, focus, location, find, and zoom commands
|
|
53
|
+
- spellcheck-aware context menus
|
|
54
|
+
- unique basename-only download destinations and lifecycle actions
|
|
55
|
+
- requesting-frame permission origins with fail-closed defaults
|
|
56
|
+
- browser-only shortcuts and renderer ownership checks
|
|
57
|
+
- off-screen parking and fixed automation viewport behavior
|
|
58
|
+
|
|
59
|
+
The host maps these typed contracts to its visible chrome; the renderer should
|
|
60
|
+
not reproduce their policy.
|
|
61
|
+
|
|
62
|
+
## Cookies and ad blocking
|
|
63
|
+
|
|
64
|
+
Construct `ElectronCookieAdapter` with the isolated partition's `Cookies`
|
|
65
|
+
object. Its stable adapter ID is `electron:default-session` for historical jar
|
|
66
|
+
compatibility; the object itself is never Electron `defaultSession`.
|
|
67
|
+
|
|
68
|
+
`NativeAdBlocker` uses Ghostery-compatible filtering, a compiled cache,
|
|
69
|
+
seven-day refresh, a last-good-cache fallback, cosmetic rules, scriptlets,
|
|
70
|
+
mutation observation, and per-site settings. `AMALGM_BROWSER_ADBLOCK=0`
|
|
71
|
+
disables it explicitly. Filtering is attached only to Browser contents, not the
|
|
72
|
+
application renderer, API, or auth traffic.
|
|
73
|
+
|
|
74
|
+
## Host advertisement
|
|
75
|
+
|
|
76
|
+
`writeHostAdvertisement` validates a loopback CDP URL, writes atomically with
|
|
77
|
+
private permissions, and records PID/protocol/target types. The selector
|
|
78
|
+
rejects stale, dead, remote, or incompatible advertisements. Call
|
|
79
|
+
`removeHostAdvertisement` during owner teardown; it only removes an
|
|
80
|
+
advertisement owned by the expected PID.
|
|
81
|
+
|
|
82
|
+
## Verification
|
|
83
|
+
|
|
84
|
+
`npm run test:electron` runs a real macOS Electron harness. It checks the exact
|
|
85
|
+
partition, two simultaneous same-URL surfaces, action isolation, failure before
|
|
86
|
+
identity mismatch, one remount, CSS-pixel capture, fixed off-screen viewport,
|
|
87
|
+
and page-only WebM recording.
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# Engine integration
|
|
2
|
+
|
|
3
|
+
Engine consumes `@amalgm/browser`; Browser never imports Engine. The extraction
|
|
4
|
+
repository is complete independently, but the Engine switchover is deliberately
|
|
5
|
+
a later change.
|
|
6
|
+
|
|
7
|
+
## Composition boundary
|
|
8
|
+
|
|
9
|
+
At startup Engine constructs one Browser product and injects:
|
|
10
|
+
|
|
11
|
+
- `ElectronBrowserDriver` and the native Electron host on desktop;
|
|
12
|
+
- caller/owner/client/project context and authorization;
|
|
13
|
+
- Realtime-backed cwd and artifact resolution;
|
|
14
|
+
- an event sink into the existing relay;
|
|
15
|
+
- the existing Browser storage root and optional legacy database path.
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
import { createBrowser } from '@amalgm/browser';
|
|
19
|
+
import { ElectronBrowserDriver } from '@amalgm/browser/electron';
|
|
20
|
+
|
|
21
|
+
const browser = createBrowser({
|
|
22
|
+
root: engineBrowserRoot,
|
|
23
|
+
legacyDatabaseFile: engineDatabaseFile,
|
|
24
|
+
electronDriver: new ElectronBrowserDriver(visibleHost),
|
|
25
|
+
eventSink: browserEventRelay,
|
|
26
|
+
authorization: engineBrowserAuthorization,
|
|
27
|
+
});
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Engine registers `browserToolboxManifest`, delegates old REST/IPC handlers to
|
|
31
|
+
the SDK, and starts standalone MCP or REST adapters where needed. It must not
|
|
32
|
+
translate Browser behavior or keep another implementation.
|
|
33
|
+
|
|
34
|
+
## Cutover order
|
|
35
|
+
|
|
36
|
+
1. Add the package and compose it behind existing Engine Browser entry points.
|
|
37
|
+
2. Run old compatibility tests and the package contracts without dual writes.
|
|
38
|
+
3. Stop old Browser writers and back up the Engine DB and Browser directory.
|
|
39
|
+
4. Start the package once with `legacyDatabaseFile`; verify the migration
|
|
40
|
+
result, entity counts, cookie tombstones, encrypted bundles, and modes.
|
|
41
|
+
5. Point Toolbox, MCP, REST, Electron IPC, and event relay at the one package
|
|
42
|
+
instance.
|
|
43
|
+
6. Verify visible and headless sessions plus rollback readiness.
|
|
44
|
+
7. Remove Engine's Browser action code, registry policy, cookie authority,
|
|
45
|
+
auth vault, recorder, process wrapper, copied tests, and stale docs in one
|
|
46
|
+
cleanup change.
|
|
47
|
+
|
|
48
|
+
Never run old and new writers against the same Browser state. A compatibility
|
|
49
|
+
route may delegate to the new service, but it must not mirror writes.
|
|
50
|
+
|
|
51
|
+
## Existing data
|
|
52
|
+
|
|
53
|
+
The package reuses `$AMALGM_DIR/browser`, the exact Electron partition
|
|
54
|
+
`persist:amalgm-browser`, profile directories, recording locations, and native
|
|
55
|
+
ad-block directory. Its built-in read-only legacy import handles Engine
|
|
56
|
+
profiles, encrypted auth/cookie-source rows, cookie revisions and tombstones,
|
|
57
|
+
login rows, and token hashes. See [MIGRATION.md](./MIGRATION.md).
|
|
58
|
+
|
|
59
|
+
## Rollback
|
|
60
|
+
|
|
61
|
+
The importer never mutates the legacy Engine database or deletes legacy blob
|
|
62
|
+
files. If verification fails before cutover, stop the package, restore the
|
|
63
|
+
Browser-directory backup if it was shared, and resume the old writer. After
|
|
64
|
+
new traffic begins, rollback requires a deliberate maintenance window and
|
|
65
|
+
restoring the pre-cutover backup; do not let the old implementation consume
|
|
66
|
+
new-format writes opportunistically.
|
|
67
|
+
|
|
68
|
+
## Post-cutover boundary
|
|
69
|
+
|
|
70
|
+
Engine may retain only composition, authorization, Realtime/artifact context,
|
|
71
|
+
event relay, UI presentation, and renderer wiring. Native Browser shell policy
|
|
72
|
+
and visible-surface behavior live in the package's Electron export, even though
|
|
73
|
+
Engine owns the Electron application lifecycle.
|
package/docs/EVENTS.md
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Events
|
|
2
|
+
|
|
3
|
+
Browser emits version-1 state transitions through an injected
|
|
4
|
+
`BrowserEventSink`. `BrowserEventBus` provides a bounded standalone history and
|
|
5
|
+
subscription implementation; REST exposes it as SSE.
|
|
6
|
+
|
|
7
|
+
Event families are:
|
|
8
|
+
|
|
9
|
+
- `session.created`, `session.ready`, `session.closed`, `session.failed`
|
|
10
|
+
- `surface.requested`, `surface.bound`, `surface.updated`, `surface.lost`
|
|
11
|
+
- `page.navigated`, `page.failed`
|
|
12
|
+
- `profile.updated`
|
|
13
|
+
- `recording.started`, `recording.stopped`
|
|
14
|
+
- `login.updated`
|
|
15
|
+
- `cookie-jar.changed`
|
|
16
|
+
- `download.updated`
|
|
17
|
+
- `permission.requested`
|
|
18
|
+
|
|
19
|
+
Every event has a stable random ID, ISO timestamp, version, and only the
|
|
20
|
+
resource identifiers/metadata required by that transition. Navigation uses a
|
|
21
|
+
sanitized origin rather than a sensitive full URL. Error text is redacted and
|
|
22
|
+
bounded. Cookie values, auth payloads, login tokens, storage contents, keys,
|
|
23
|
+
authorization headers, and captured pixels are forbidden.
|
|
24
|
+
|
|
25
|
+
`GET /v1/events` sends retained events after `Last-Event-ID`, then live events
|
|
26
|
+
and heartbeat comments. A disconnect removes the listener. A missing history
|
|
27
|
+
cursor safely returns retained history rather than inventing ordering.
|
|
28
|
+
|
|
29
|
+
Engine or Realtime may relay these events verbatim. That relay does not become
|
|
30
|
+
the Browser authority and must not enrich an event with Browser secrets.
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Headless runtime
|
|
2
|
+
|
|
3
|
+
Headless is the default for standalone SDK/CLI use, servers, automations,
|
|
4
|
+
agents, and background jobs. It uses `agent-browser` behind `BrowserDriver`;
|
|
5
|
+
the core service does not know its command-line arguments.
|
|
6
|
+
|
|
7
|
+
## Process and executable selection
|
|
8
|
+
|
|
9
|
+
Resolution prefers:
|
|
10
|
+
|
|
11
|
+
1. `AMALGM_AGENT_BROWSER_BIN`
|
|
12
|
+
2. the platform-native binary shipped by `agent-browser`
|
|
13
|
+
3. the package's JavaScript wrapper
|
|
14
|
+
4. an `agent-browser` executable on PATH
|
|
15
|
+
|
|
16
|
+
When packaged in Electron, native binaries and ffmpeg are resolved from
|
|
17
|
+
`app.asar.unpacked`. Every process uses an argv array with `shell: false`, a
|
|
18
|
+
safe explicit cwd, bounded stdout/stderr, an operation timeout, cancellation,
|
|
19
|
+
SIGTERM, and bounded SIGKILL escalation.
|
|
20
|
+
|
|
21
|
+
## Configuration
|
|
22
|
+
|
|
23
|
+
- `AMALGM_BROWSER_EXECUTABLE_PATH` — explicit Chromium executable
|
|
24
|
+
- `AMALGM_BROWSER_PROVIDER` — external provider understood by agent-browser
|
|
25
|
+
- `AMALGM_BROWSER_CDP_URL` — attach to an operator-owned CDP endpoint
|
|
26
|
+
- `AMALGM_AGENT_BROWSER_BIN` — explicit agent-browser executable
|
|
27
|
+
- `AMALGM_BROWSER_HEADED=1` — explicit standalone headed debug mode
|
|
28
|
+
- `AMALGM_FFMPEG` — encoder override
|
|
29
|
+
|
|
30
|
+
An explicit CDP endpoint remains a headless-driver session in the domain model;
|
|
31
|
+
it does not opt into Electron surfaces. Ordinary background work never opens a
|
|
32
|
+
headed window or steals focus.
|
|
33
|
+
|
|
34
|
+
## Profiles and state
|
|
35
|
+
|
|
36
|
+
Each session uses its assigned Browser profile directory. Durable profiles
|
|
37
|
+
survive explicit reuse; ephemeral profiles are pruned only when not live,
|
|
38
|
+
referenced, or physically Chromium-locked. Backend-local cookies remain in
|
|
39
|
+
that profile. The trusted headless cookie adapter reconciles individual records
|
|
40
|
+
through the encrypted logical jar without inspecting Electron.
|
|
41
|
+
|
|
42
|
+
## Capture and input
|
|
43
|
+
|
|
44
|
+
Accessibility snapshots create stable `@eN` references for ordinary DOM
|
|
45
|
+
actions. Direct CDP resolves the session's actual target for screenshot,
|
|
46
|
+
computer use, and recording—never the first or only page. Viewport screenshots
|
|
47
|
+
are normalized to CSS pixels even when device pixel ratio exceeds one;
|
|
48
|
+
full-page capture is height-bounded.
|
|
49
|
+
|
|
50
|
+
Computer use supports screenshot, click, double click, move, scroll, type,
|
|
51
|
+
keypress, and drag. Native CDP input is page-scoped. Use it for canvas, WebGL,
|
|
52
|
+
image-only, or hostile custom controls; prefer snapshot references elsewhere.
|
|
53
|
+
|
|
54
|
+
## Real verification
|
|
55
|
+
|
|
56
|
+
`npm run test:real` launches the bundled Chromium runtime and verifies
|
|
57
|
+
navigation, snapshot, exact-target CDP capture, DPR normalization, page-scoped
|
|
58
|
+
typing, and real page-only recording.
|
package/docs/MCP.md
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# MCP server
|
|
2
|
+
|
|
3
|
+
Run `amalgm-browser-mcp` or `amalgm-browser mcp`. The server speaks
|
|
4
|
+
newline-delimited JSON-RPC over stdio and implements MCP tool listing and tool
|
|
5
|
+
calls without Engine.
|
|
6
|
+
|
|
7
|
+
The 22 tools are the canonical action names prefixed with `browser_`:
|
|
8
|
+
|
|
9
|
+
```text
|
|
10
|
+
browser_open browser_snapshot browser_screenshot
|
|
11
|
+
browser_click browser_fill browser_press
|
|
12
|
+
browser_select browser_eval browser_wait
|
|
13
|
+
browser_cli browser_dialog browser_tab
|
|
14
|
+
browser_console browser_close browser_cua
|
|
15
|
+
browser_record_start browser_record_stop browser_record_list
|
|
16
|
+
browser_auth_list browser_auth_link_create
|
|
17
|
+
browser_auth_save browser_auth_load
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Schemas derive from the same action descriptor array used by CLI, REST, and
|
|
21
|
+
Toolbox. The optional `session` field selects the persistent session; otherwise
|
|
22
|
+
the adapter uses `default`.
|
|
23
|
+
|
|
24
|
+
`notifications/cancelled` aborts the active SDK operation identified by the
|
|
25
|
+
JSON-RPC request ID. Text results are bounded. Captures are emitted as MCP image
|
|
26
|
+
content when the result is an image. Recording and resource results contain
|
|
27
|
+
sanitized metadata.
|
|
28
|
+
|
|
29
|
+
Raw cookie values, auth payloads, encryption keys, bearer headers, and stored
|
|
30
|
+
login token hashes are not MCP tools or resource output. Login-link creation is
|
|
31
|
+
the deliberate one-time credential-delivery operation; callers must treat its
|
|
32
|
+
returned token-bearing URL as a secret.
|
|
33
|
+
|
|
34
|
+
Toolbox uses a different compatibility namespace,
|
|
35
|
+
`toolbox__browser_<action>`, documented in
|
|
36
|
+
[TOOLBOX_INTEGRATION.md](./TOOLBOX_INTEGRATION.md).
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# Migration
|
|
2
|
+
|
|
3
|
+
Browser preserves existing user state through path reuse plus a versioned
|
|
4
|
+
legacy import. Migration is read-only with respect to the legacy Engine DB and
|
|
5
|
+
is recorded as `engine-browser-v1` metadata in the new registry.
|
|
6
|
+
|
|
7
|
+
## Automatic path
|
|
8
|
+
|
|
9
|
+
When `createBrowser()` uses its normal `$AMALGM_DIR/browser` root, it checks
|
|
10
|
+
for `$AMALGM_DIR/amalgm.db`. An explicit root does not guess a database;
|
|
11
|
+
provide `legacyDatabaseFile` to opt in, or `false` to disable import.
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
const browser = createBrowser({
|
|
15
|
+
root: '/state/browser',
|
|
16
|
+
legacyDatabaseFile: '/state/amalgm.db',
|
|
17
|
+
});
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
The importer opens the old DB read-only and imports inside one new-registry
|
|
21
|
+
transaction:
|
|
22
|
+
|
|
23
|
+
- `browser_profiles` into durable/ephemeral profile metadata;
|
|
24
|
+
- ordinary `browser_auth_bundles` after hash and AES-GCM verification;
|
|
25
|
+
- the `browser-cookie-source` bundle into record-level cookies and tombstones;
|
|
26
|
+
- `browser_login_sessions` plus stored token hashes.
|
|
27
|
+
|
|
28
|
+
The source database path is recorded only after successful completion. A
|
|
29
|
+
second start reports `already-migrated` and makes no changes. A failure rolls
|
|
30
|
+
back SQLite metadata and leaves the source untouched.
|
|
31
|
+
|
|
32
|
+
## State reused in place
|
|
33
|
+
|
|
34
|
+
- Electron partition `persist:amalgm-browser`
|
|
35
|
+
- `$AMALGM_DIR/browser` root and headless profile directories
|
|
36
|
+
- existing project `.amalgm/recordings`
|
|
37
|
+
- native Electron `userData/browser/adblock` cache and settings
|
|
38
|
+
- bridge protocol 5 advertisement readers during rolling upgrade
|
|
39
|
+
- legacy key from `AMALGM_BROWSER_AUTH_KEY` or
|
|
40
|
+
`auth-bundles/keys/local-device.key`
|
|
41
|
+
|
|
42
|
+
The new registry also imports `registry-v1.json` transactionally once when
|
|
43
|
+
present. It never deletes that source file automatically.
|
|
44
|
+
|
|
45
|
+
## Verification checklist
|
|
46
|
+
|
|
47
|
+
1. Stop all legacy Browser writers.
|
|
48
|
+
2. Back up the Engine DB and Browser directory.
|
|
49
|
+
3. Run import against a copy first.
|
|
50
|
+
4. Compare profile, bundle, login, cookie-record, and tombstone counts.
|
|
51
|
+
5. Open a durable headless profile and the isolated Electron partition.
|
|
52
|
+
6. Load a named auth bundle and verify only its declared domains.
|
|
53
|
+
7. Confirm DB/key/encrypted files are private and the source is unchanged.
|
|
54
|
+
8. Re-run and confirm an idempotent no-op.
|
|
55
|
+
|
|
56
|
+
Representative encrypted legacy fixtures exercise this sequence in the test
|
|
57
|
+
suite.
|
|
58
|
+
|
|
59
|
+
## Non-destructive rollback
|
|
60
|
+
|
|
61
|
+
Before cutover, discard the new Browser root and continue from the untouched
|
|
62
|
+
legacy source. After cutover writes occur, restore the complete pre-cutover
|
|
63
|
+
backup rather than mixing formats or replaying selected files. Never copy
|
|
64
|
+
cookies into a different Electron partition merely to normalize names.
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# Operations
|
|
2
|
+
|
|
3
|
+
## State layout
|
|
4
|
+
|
|
5
|
+
Root selection follows the `@amalgm/core` product state-dir law:
|
|
6
|
+
`AMALGM_BROWSER_DIR` (or its legacy spelling `AMALGM_BROWSER_ROOT`), then
|
|
7
|
+
`$AMALGM_DIR/browser`, then `~/.amalgm/users/<scope>/browser`. The root contains `browser.db`, WAL files, encrypted
|
|
8
|
+
cookie/login state, `browser.key`, auth bundles, profiles, and fallback
|
|
9
|
+
artifacts. Directories are private and secret/DB files are mode `0600` where
|
|
10
|
+
the platform supports POSIX permissions.
|
|
11
|
+
|
|
12
|
+
Do not put the root inside a source repository. Do not back up a live SQLite
|
|
13
|
+
DB by copying only `browser.db`; stop writers or use a SQLite-safe snapshot.
|
|
14
|
+
|
|
15
|
+
## Environment
|
|
16
|
+
|
|
17
|
+
| Variable | Purpose |
|
|
18
|
+
| --- | --- |
|
|
19
|
+
| `AMALGM_BROWSER_DIR` | standalone state root (`AMALGM_BROWSER_ROOT` legacy alias) |
|
|
20
|
+
| `AMALGM_DIR` | Amalgm state root |
|
|
21
|
+
| `AMALGM_BROWSER_BACKEND` | explicit debug force: headless/electron |
|
|
22
|
+
| `AMALGM_BROWSER_CDP_URL` | operator-owned CDP endpoint |
|
|
23
|
+
| `AMALGM_BROWSER_HEADED` | explicit headed standalone Chromium |
|
|
24
|
+
| `AMALGM_BROWSER_EXECUTABLE_PATH` | Chromium executable |
|
|
25
|
+
| `AMALGM_AGENT_BROWSER_BIN` | agent-browser executable |
|
|
26
|
+
| `AMALGM_BROWSER_PROVIDER` | external agent-browser provider |
|
|
27
|
+
| `AMALGM_FFMPEG` | ffmpeg executable |
|
|
28
|
+
| `AMALGM_BROWSER_TOKEN` | REST bearer token |
|
|
29
|
+
| `AMALGM_BROWSER_ADAPTER_TOKEN` | restricted cookie-adapter token |
|
|
30
|
+
| `AMALGM_BROWSER_HOST`, `AMALGM_BROWSER_PORT` | REST listen address |
|
|
31
|
+
| `AMALGM_BROWSER_ALLOW_REMOTE=1` | remote bind opt-in |
|
|
32
|
+
| `AMALGM_BROWSER_NOVNC_PUBLIC_URL` | public login handoff URL |
|
|
33
|
+
| `AMALGM_BROWSER_NOVNC_URL` | internal noVNC fallback URL |
|
|
34
|
+
| `AMALGM_BROWSER_LOGIN_TRANSPORT` | default human-login transport |
|
|
35
|
+
| `AMALGM_BROWSER_ADBLOCK=0` | native ad-block kill switch |
|
|
36
|
+
| `AMALGM_BROWSER_WCV=0` | temporary protocol-5 surface compatibility |
|
|
37
|
+
| `AMALGM_RUNTIME_STATE_DIR` | Electron bridge advertisement directory |
|
|
38
|
+
| `AMALGM_RUNTIME_LABEL`, `AMALGM_BRANCH` | labeled bridge discovery |
|
|
39
|
+
| `AMALGM_BROWSER_AUTH_KEY` | legacy-import key override only |
|
|
40
|
+
| `AMALGM_BROWSER_DEBUG=1` | sanitized debug logging |
|
|
41
|
+
|
|
42
|
+
## Process model
|
|
43
|
+
|
|
44
|
+
Multiple processes may share SQLite metadata: entity writes do not replace a
|
|
45
|
+
whole registry and cross-process leases prevent concurrent action/close races
|
|
46
|
+
on one session. A live browser process and encoder still have one owner. Run
|
|
47
|
+
one long-lived service for sustained MCP/REST work; use explicit session IDs
|
|
48
|
+
for CLI reuse.
|
|
49
|
+
|
|
50
|
+
## Health and observability
|
|
51
|
+
|
|
52
|
+
Use `/v1/health` for process health, `/v1/capabilities` for installed drivers,
|
|
53
|
+
`doctor` for basic CLI diagnostics, resource listing for durable state, and SSE
|
|
54
|
+
for sanitized transitions. Never log request bodies for auth or internal
|
|
55
|
+
cookie routes.
|
|
56
|
+
|
|
57
|
+
## Retention
|
|
58
|
+
|
|
59
|
+
Prune abandoned sessions and stale ephemeral profiles on an operator-defined
|
|
60
|
+
schedule. Durable, referenced, live, or Chromium-locked profiles are retained.
|
|
61
|
+
Artifacts are sensitive; the injected store or host owns retention and access
|
|
62
|
+
control. Browser does not delete successful recordings automatically.
|
|
63
|
+
|
|
64
|
+
## Remote REST
|
|
65
|
+
|
|
66
|
+
Loopback is the safe default. Remote binding requires explicit opt-in and a
|
|
67
|
+
strong bearer token; use TLS and network access control in front of the local
|
|
68
|
+
server. Keep the adapter-token endpoints private even when ordinary REST is
|
|
69
|
+
remote.
|
package/docs/README.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Documentation
|
|
2
|
+
|
|
3
|
+
Start with [the product purpose](../PURPOSE.md), then use the guide matching
|
|
4
|
+
your integration:
|
|
5
|
+
|
|
6
|
+
- [Architecture](./ARCHITECTURE.md) and [axiom map](./AXIOMS.md)
|
|
7
|
+
- [SDK](./SDK.md), [actions](./ACTIONS.md), [CLI](./CLI.md),
|
|
8
|
+
[MCP](./MCP.md), and [REST](./REST.md)
|
|
9
|
+
- [Headless runtime](./HEADLESS_RUNTIME.md) and
|
|
10
|
+
[Electron integration](./ELECTRON_INTEGRATION.md)
|
|
11
|
+
- [Cookies](./COOKIES.md), [authentication](./AUTHENTICATION.md), and
|
|
12
|
+
[recording](./RECORDING.md)
|
|
13
|
+
- [Events](./EVENTS.md) and the [Realtime boundary](./REALTIME_BOUNDARY.md)
|
|
14
|
+
- [Toolbox](./TOOLBOX_INTEGRATION.md) and
|
|
15
|
+
[Engine](./ENGINE_INTEGRATION.md) composition
|
|
16
|
+
- [Migration](./MIGRATION.md) and [compatibility](./COMPATIBILITY.md)
|
|
17
|
+
- [Operations](./OPERATIONS.md), [testing](./TESTING.md), and
|
|
18
|
+
[troubleshooting](./TROUBLESHOOTING.md)
|
|
19
|
+
|
|
20
|
+
The package is ESM-only, requires Node.js 20+, and exposes deliberate entry
|
|
21
|
+
points rather than internal implementation modules.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Realtime boundary
|
|
2
|
+
|
|
3
|
+
Realtime owns files, workspace identity, project context, current working
|
|
4
|
+
directory, and general application-state synchronization. Browser owns browser
|
|
5
|
+
sessions, profiles, drivers, cookies, auth resources, recordings, and Browser
|
|
6
|
+
events.
|
|
7
|
+
|
|
8
|
+
Browser receives opaque project/cwd/artifact values through
|
|
9
|
+
`BrowserRuntimeContext` or an injected `BrowserArtifactStore`. It never imports
|
|
10
|
+
Realtime or infers a project from Chat records.
|
|
11
|
+
|
|
12
|
+
An invisible host-provided cwd flow looks like:
|
|
13
|
+
|
|
14
|
+
```ts
|
|
15
|
+
await browser.execute(sessionId, action, {
|
|
16
|
+
projectRef: realtimeProject.id,
|
|
17
|
+
cwdRef: realtimeProject.cwdRef,
|
|
18
|
+
artifactDestination: await realtime.resolveArtifactDirectory(realtimeProject),
|
|
19
|
+
signal,
|
|
20
|
+
});
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
This is equivalent to a host resolving `amalgm cwd <project>` before the call;
|
|
24
|
+
Browser consumes the result but does not create another project registry.
|
|
25
|
+
|
|
26
|
+
Browser may persist its own operational metadata and encrypted secrets.
|
|
27
|
+
Realtime may store or transport an encrypted Browser resource only as an
|
|
28
|
+
opaque, authorized blob. Browser remains responsible for its schema,
|
|
29
|
+
encryption, exclusions, merge rules, and decryption.
|
|
30
|
+
|
|
31
|
+
Realtime may relay sanitized Browser events and place Browser artifacts. It
|
|
32
|
+
does not become the session, cookie, or auth authority. Standalone Browser must
|
|
33
|
+
continue to work without Realtime through explicit local adapters.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Recording
|
|
2
|
+
|
|
3
|
+
Recording is a Browser lifecycle, not a screenshot loop in an adapter.
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
const started = await browser.recordings.start({
|
|
7
|
+
sessionId: session.id,
|
|
8
|
+
fps: 15,
|
|
9
|
+
name: 'checkout',
|
|
10
|
+
context: { artifactDestination: projectRoot, signal },
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
const stopped = await browser.recordings.stop(session.id);
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Invariants
|
|
17
|
+
|
|
18
|
+
- one active recording per session
|
|
19
|
+
- FPS clamped to 1–30
|
|
20
|
+
- ffmpeg verified before browser capture starts
|
|
21
|
+
- exact verified page target, never application chrome or a first target
|
|
22
|
+
- first capturable frame required before the encoder starts
|
|
23
|
+
- one latest-frame slot separates paint frequency from encoding cadence
|
|
24
|
+
- static pages receive honest wall-clock duration
|
|
25
|
+
- animation floods do not create an unbounded queue
|
|
26
|
+
- source stop, encoder flush, and forced termination are bounded
|
|
27
|
+
- zero-frame or failed artifacts are removed
|
|
28
|
+
|
|
29
|
+
The result reports `wallSeconds`, `videoSeconds`, encoded `frames`, received
|
|
30
|
+
frames, skipped ticks, and sanitized artifact metadata. These fields are
|
|
31
|
+
deliberately distinct; there is no ambiguous generic duration.
|
|
32
|
+
|
|
33
|
+
## Artifacts
|
|
34
|
+
|
|
35
|
+
The local artifact adapter resolves in this order:
|
|
36
|
+
|
|
37
|
+
1. `context.artifactDestination`
|
|
38
|
+
2. the embedding host's injected artifact store/context
|
|
39
|
+
3. the standalone Browser root
|
|
40
|
+
|
|
41
|
+
Project destinations use `<project>/.amalgm/recordings/<name>-<id>.webm`.
|
|
42
|
+
Browser does not maintain a current-project registry. Artifacts are sensitive
|
|
43
|
+
user data and the embedding store owns access control and retention.
|
|
44
|
+
|
|
45
|
+
## Failure and restart visibility
|
|
46
|
+
|
|
47
|
+
Missing ffmpeg or spawn failure returns a typed process error without crashing
|
|
48
|
+
MCP or REST. Active rows record their owner PID. Startup marks a dead owner's
|
|
49
|
+
row failed, while a live foreign owner remains visible and returns a conflict
|
|
50
|
+
to stop/force-stop. `forceStop(sessionId)` aborts a locally owned encoder and
|
|
51
|
+
marks it failed; a service never claims it controlled another process.
|
|
52
|
+
|
|
53
|
+
Both real headless and real Electron suites encode a page-only WebM. Unit
|
|
54
|
+
contracts cover static pages, frame floods, backpressure, capture viability,
|
|
55
|
+
missing ffmpeg, cancellation, and bounded stop.
|
package/docs/REST.md
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# REST API
|
|
2
|
+
|
|
3
|
+
Run either:
|
|
4
|
+
|
|
5
|
+
```sh
|
|
6
|
+
amalgm-browser serve --token replace-me
|
|
7
|
+
AMALGM_BROWSER_TOKEN=replace-me amalgm-browser-rest
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
The server binds loopback by default. Remote binding requires explicit
|
|
11
|
+
`allowRemote` in the SDK, `--allow-remote` in the CLI, or
|
|
12
|
+
`AMALGM_BROWSER_ALLOW_REMOTE=1` for the standalone binary. All routes except
|
|
13
|
+
`GET /v1/health` require `Authorization: Bearer <token>`.
|
|
14
|
+
|
|
15
|
+
## Discovery and streaming
|
|
16
|
+
|
|
17
|
+
- `GET /v1/health`
|
|
18
|
+
- `GET /v1/openapi.json`
|
|
19
|
+
- `GET /v1/capabilities`
|
|
20
|
+
- `GET /v1/events` (SSE; supports `Last-Event-ID`)
|
|
21
|
+
|
|
22
|
+
## Sessions and actions
|
|
23
|
+
|
|
24
|
+
- `GET|POST /v1/sessions`
|
|
25
|
+
- `POST /v1/sessions/prune`
|
|
26
|
+
- `GET|DELETE /v1/sessions/:sessionId`
|
|
27
|
+
- `POST /v1/sessions/:sessionId/cancel`
|
|
28
|
+
- `POST /v1/sessions/:sessionId/actions/:action`
|
|
29
|
+
|
|
30
|
+
Every one of the 22 canonical actions has an action route generated from the
|
|
31
|
+
shared descriptor. Resource-specific routes below expose richer lifecycle
|
|
32
|
+
operations.
|
|
33
|
+
|
|
34
|
+
## Profiles, auth, and recording
|
|
35
|
+
|
|
36
|
+
- `GET|POST /v1/profiles`; `POST /v1/profiles/prune`
|
|
37
|
+
- `GET|PATCH|DELETE /v1/profiles/:profileId`
|
|
38
|
+
- `GET|POST /v1/auth/bundles`
|
|
39
|
+
- `POST /v1/auth/bundles/import`
|
|
40
|
+
- `GET|DELETE /v1/auth/bundles/:bundleId`
|
|
41
|
+
- `POST /v1/auth/bundles/:bundleId/load|export`
|
|
42
|
+
- `GET|POST /v1/auth/login-sessions`
|
|
43
|
+
- `GET /v1/auth/login-sessions/:loginId`
|
|
44
|
+
- `POST /v1/auth/login-sessions/:loginId/activate|input|complete|cancel`
|
|
45
|
+
- `GET|POST /v1/recordings`
|
|
46
|
+
- `GET /v1/recordings/:recordingId`
|
|
47
|
+
- `POST /v1/recordings/:recordingId/stop|cancel`
|
|
48
|
+
|
|
49
|
+
The generated OpenAPI document is the route inventory and excludes internal
|
|
50
|
+
raw-cookie schemas.
|
|
51
|
+
|
|
52
|
+
## Internal cookie transport
|
|
53
|
+
|
|
54
|
+
`/internal/v1/*` is reserved for trusted physical cookie adapters. It requires
|
|
55
|
+
both the bearer token and `X-Browser-Adapter-Token`, is handled only after
|
|
56
|
+
authorization, sends `Cache-Control: no-store`, and is omitted from public
|
|
57
|
+
OpenAPI. Never expose this transport through an untrusted reverse proxy.
|
|
58
|
+
|
|
59
|
+
## Limits and errors
|
|
60
|
+
|
|
61
|
+
Defaults are a 512 KB request body, 2 MB JSON output, and 120-second request
|
|
62
|
+
deadline. Client disconnect aborts unfinished work. Errors use:
|
|
63
|
+
|
|
64
|
+
```json
|
|
65
|
+
{"error":{"code":"INVALID_INPUT","message":"sanitized explanation"}}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
SSE emits only versioned sanitized Browser events, sends heartbeats, resumes
|
|
69
|
+
from retained history, and removes listeners on disconnect.
|