@amalgm/browser 0.1.2-preview.34176754339 → 0.1.2-preview.34320564379
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 +29 -15
- package/README.md +13 -6
- package/docs/AXIOMS.md +3 -2
- package/docs/COMPATIBILITY.md +7 -6
- package/docs/ELECTRON_INTEGRATION.md +6 -0
- package/docs/EVENTS.md +1 -1
- package/docs/HEADLESS_RUNTIME.md +1 -1
- package/docs/MCP.md +1 -1
- package/docs/README.md +5 -3
- package/docs/SDK.md +1 -1
- package/docs/SHELL_INTEGRATION.md +54 -0
- package/docs/TESTING.md +7 -2
- package/package.json +5 -5
- package/skills/use-amalgm-browser/SKILL.md +176 -30
- package/skills/use-amalgm-browser/references/actions.md +33 -16
- package/docs/ENGINE_INTEGRATION.md +0 -73
package/PURPOSE.md
CHANGED
|
@@ -9,15 +9,17 @@ and REST API while selecting the correct underlying browser implementation
|
|
|
9
9
|
from host context. In the macOS desktop app, browser work can occur in a
|
|
10
10
|
visible Electron surface that the user can watch and control. Everywhere else,
|
|
11
11
|
the same work runs in an isolated headless Chromium session. Browser state
|
|
12
|
-
belongs to Browser, never to Chat, Agents, Engine, or the application
|
|
12
|
+
belongs to Browser, never to Chat, Agents, Shell, Engine, or the application
|
|
13
|
+
renderer.
|
|
13
14
|
|
|
14
15
|
Browser serves users browsing visibly in Amalgm, agents using Browser through
|
|
15
16
|
a Toolbox, background automations and sub-agents, standalone SDK and CLI
|
|
16
17
|
consumers, MCP and REST clients, and future browser-driver implementations.
|
|
17
18
|
|
|
18
|
-
Amalgm
|
|
19
|
-
execution context, artifact storage, event relay, and UI
|
|
19
|
+
Amalgm Shell is the active composition root. It may provide host capabilities,
|
|
20
|
+
execution context, artifact storage, event relay, and UI coordination through
|
|
20
21
|
public Browser ports. It does not own a second browser implementation.
|
|
22
|
+
Amalgm Engine is historical reference evidence only.
|
|
21
23
|
|
|
22
24
|
## Primitives
|
|
23
25
|
|
|
@@ -73,7 +75,7 @@ including the exact two-parent merge commit that becomes managed source.
|
|
|
73
75
|
Managed releases bind to one exact published Core version and build from the
|
|
74
76
|
locked dependency graph on the supported Node toolchain.
|
|
75
77
|
|
|
76
|
-
1. Browser owns browser state and never depends on Chat, Agents, Engine,
|
|
78
|
+
1. Browser owns browser state and never depends on Chat, Agents, Shell, Engine,
|
|
77
79
|
Realtime, or an application renderer to define it.
|
|
78
80
|
2. Every state change passes through `BrowserService`; drivers execute actions
|
|
79
81
|
and adapters expose the service without reimplementing its rules.
|
|
@@ -82,9 +84,11 @@ locked dependency graph on the supported Node toolchain.
|
|
|
82
84
|
4. Every page and visible surface belongs to exactly one session. Visible
|
|
83
85
|
identity is stamped and verified; ambiguity or mismatch fails closed before
|
|
84
86
|
an action, and reconnection may only recover the same verified surface.
|
|
85
|
-
5.
|
|
86
|
-
|
|
87
|
-
|
|
87
|
+
5. Requested capability and fresh host evidence select a backend before session
|
|
88
|
+
creation. Work requiring a visible surface selects a compatible Electron
|
|
89
|
+
host or fails clearly; background work selects headless; work that merely
|
|
90
|
+
prefers visibility may fall back to headless. An explicit operator CDP
|
|
91
|
+
endpoint and a standalone headed window are always deliberate overrides.
|
|
88
92
|
6. One action has one meaning across drivers. Backend differences are explicit
|
|
89
93
|
capabilities or typed unsupported-operation errors.
|
|
90
94
|
7. Cancellation and deadlines reach the underlying CDP call, encoder, fetch,
|
|
@@ -120,16 +124,20 @@ locked dependency graph on the supported Node toolchain.
|
|
|
120
124
|
17. TypeScript under `src/` and `bin/` is the sole implementation source. The
|
|
121
125
|
SDK owns behavior; CLI, MCP, REST, Toolbox, and Electron IPC remain thin
|
|
122
126
|
adapters with parity tests.
|
|
123
|
-
18. Browser installs and operates without Engine or Electron. Behavior
|
|
124
|
-
unseen session follows from these axioms without another special case.
|
|
127
|
+
18. Browser installs and operates without Shell, Engine, or Electron. Behavior
|
|
128
|
+
on an unseen session follows from these axioms without another special case.
|
|
129
|
+
19. Shell composes exactly one Browser service. Electron supplies a hardened
|
|
130
|
+
visible host and isolated cookie adapter to that service; it never creates a
|
|
131
|
+
second Browser registry, session authority, or action implementation.
|
|
125
132
|
|
|
126
133
|
## Predictable behavior
|
|
127
134
|
|
|
128
|
-
Before session creation, the host context
|
|
129
|
-
session keeps that backend until close; a lost visible page
|
|
130
|
-
reattaches to its original stamped surface or fails before
|
|
131
|
-
surfaces dispatch the same typed action through
|
|
132
|
-
stays headless unless
|
|
135
|
+
Before session creation, the requested capability and host context select one
|
|
136
|
+
capable backend. The session keeps that backend until close; a lost visible page
|
|
137
|
+
either verifies and reattaches to its original stamped surface or fails before
|
|
138
|
+
acting. All public surfaces dispatch the same typed action through
|
|
139
|
+
`BrowserService`. Background work stays headless unless visibility is requested
|
|
140
|
+
or an operator explicitly asks for a headed debug window.
|
|
133
141
|
|
|
134
142
|
The visible Electron partition and every headless profile keep physically
|
|
135
143
|
separate Chromium stores. Their adapters may reconcile individual cookie
|
|
@@ -137,9 +145,15 @@ records through Browser's encrypted jar, including tombstoned deletions, but
|
|
|
137
145
|
they cannot inspect one another. Named auth bundles are separate, explicit
|
|
138
146
|
snapshots. Captures, input coordinates, and recordings all address the same
|
|
139
147
|
verified page, while large artifacts leave the API through the injected store.
|
|
140
|
-
|
|
148
|
+
Shell and Realtime can compose and relay Browser without becoming Browser.
|
|
141
149
|
|
|
142
150
|
The Browser build supplies its Electron CommonJS adapter and companion preload as
|
|
143
151
|
SDK-owned artifacts; a UI copies those bytes without rebuilding Browser behavior.
|
|
144
152
|
Desktop bridge discovery uses one host-selected machine namespace and a validated
|
|
145
153
|
Core binding; neither a shared user root nor an unknown lane selects another host.
|
|
154
|
+
|
|
155
|
+
Headless source examinations provision Chrome through the locked agent-browser
|
|
156
|
+
launcher and record the actual browser identity and failing operation. Installing
|
|
157
|
+
the npm dependency supplies the launcher, not Chrome; ambient browser discovery
|
|
158
|
+
is not proof that the declared browser prerequisite was provisioned. Process
|
|
159
|
+
and test deadlines retain the same bounds during diagnosis.
|
package/README.md
CHANGED
|
@@ -5,17 +5,24 @@ isolated headless automation. Its TypeScript SDK owns behavior; the CLI, MCP
|
|
|
5
5
|
server, REST API, Toolbox manifest, Electron host integration, and packaged
|
|
6
6
|
skill are projections of the same actions.
|
|
7
7
|
|
|
8
|
-
Browser is independent of Amalgm Engine, Chat, Agents, Tools, and
|
|
8
|
+
Browser is independent of Amalgm Shell, Engine, Chat, Agents, Tools, and
|
|
9
|
+
Realtime. Shell composes Browser through its public ports; it does not define
|
|
10
|
+
Browser behavior.
|
|
9
11
|
Read the [purpose and axioms](./PURPOSE.md) for the product contract.
|
|
10
12
|
|
|
11
13
|
## Install
|
|
12
14
|
|
|
13
|
-
Node.js
|
|
15
|
+
Node.js 24 or newer is required.
|
|
14
16
|
|
|
15
17
|
```sh
|
|
16
18
|
npm install @amalgm/browser
|
|
19
|
+
npx --no-install agent-browser install
|
|
17
20
|
```
|
|
18
21
|
|
|
22
|
+
The `agent-browser` dependency supplies the launcher. Its `install` command
|
|
23
|
+
downloads Chrome for Testing; an existing Chrome or an explicit CDP endpoint
|
|
24
|
+
can also supply the browser.
|
|
25
|
+
|
|
19
26
|
Electron is an optional peer dependency. Server consumers can install and
|
|
20
27
|
import the core or headless exports without loading Electron.
|
|
21
28
|
|
|
@@ -36,7 +43,7 @@ const snapshot = await browser.execute(session.id, { type: 'snapshot' });
|
|
|
36
43
|
await browser.closeSession(session.id);
|
|
37
44
|
```
|
|
38
45
|
|
|
39
|
-
Standalone use selects the
|
|
46
|
+
Standalone use selects the headless runtime. A desktop composition can
|
|
40
47
|
inject `ElectronBrowserDriver`; an explicit `AMALGM_BROWSER_CDP_URL` attaches
|
|
41
48
|
the headless driver to an operator-owned Chromium endpoint. Backend selection
|
|
42
49
|
happens before session creation and never changes during the session.
|
|
@@ -102,8 +109,8 @@ uses its local fallback. See [recording](./docs/RECORDING.md).
|
|
|
102
109
|
`WebContentsView` surfaces, identity, shell policy, cookies, and ad blocking.
|
|
103
110
|
- [Toolbox integration](./docs/TOOLBOX_INTEGRATION.md) covers the single
|
|
104
111
|
`browser` tool, capability grants, and legacy aliases.
|
|
105
|
-
- [
|
|
106
|
-
|
|
112
|
+
- [Shell integration](./docs/SHELL_INTEGRATION.md) covers the one-service
|
|
113
|
+
composition boundary and the historical Engine cutover rule.
|
|
107
114
|
|
|
108
115
|
## Verify
|
|
109
116
|
|
|
@@ -115,7 +122,7 @@ npm run test:electron # macOS real-Electron harness
|
|
|
115
122
|
|
|
116
123
|
Verification covers strict TypeScript, the 220-line source limit, runtime and
|
|
117
124
|
adapter contracts, migration fixtures, package installation, and tarball
|
|
118
|
-
hygiene. The opt-in suites use real
|
|
125
|
+
hygiene. The opt-in suites use real Chromium and real Electron.
|
|
119
126
|
|
|
120
127
|
The complete documentation index is [docs/README.md](./docs/README.md).
|
|
121
128
|
|
package/docs/AXIOMS.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Axiom map
|
|
2
2
|
|
|
3
|
-
[PURPOSE.md](../PURPOSE.md) is the authoritative list of primitives and
|
|
3
|
+
[PURPOSE.md](../PURPOSE.md) is the authoritative list of primitives and 19
|
|
4
4
|
product axioms. This document maps them to observable boundaries.
|
|
5
5
|
|
|
6
6
|
| Axioms | Consequence | Evidence |
|
|
@@ -12,7 +12,8 @@ product axioms. This document maps them to observable boundaries.
|
|
|
12
12
|
| 14 | Capture and recording address the actual page | DPR, target, sampler, and real-runtime tests |
|
|
13
13
|
| 15 | Context enters through ports; events are sanitized | artifact and SSE contracts |
|
|
14
14
|
| 16 | Existing state is imported safely | transactional legacy fixture test |
|
|
15
|
-
| 17–18 | One TypeScript implementation works without Engine
|
|
15
|
+
| 17–18 | One TypeScript implementation works without Shell, Engine, or Electron | package install and adapter parity tests |
|
|
16
|
+
| 19 | Shell composes one Browser service; Electron is a host adapter | Shell composition and Electron harness tests |
|
|
16
17
|
|
|
17
18
|
When behavior fails, classify it against this map. If code drifted, restore the
|
|
18
19
|
axiom everywhere it applies. If the axiom is incomplete, update
|
package/docs/COMPATIBILITY.md
CHANGED
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
## Runtime and package
|
|
4
4
|
|
|
5
|
-
- Node.js:
|
|
6
|
-
- modules: ESM
|
|
5
|
+
- Node.js: 24 or newer
|
|
6
|
+
- modules: ESM core imports; ESM and generated CommonJS for
|
|
7
|
+
`@amalgm/browser/electron`
|
|
7
8
|
- Electron: optional peer, version 33 or newer
|
|
8
9
|
- Electron surface protocols: writes protocol 6; reads protocols 5 and 6
|
|
9
10
|
- Browser partition: exactly `persist:amalgm-browser`
|
|
@@ -21,11 +22,11 @@ Historical aggregate Browser grants, older prefixed IDs, and individual
|
|
|
21
22
|
`cua_*` names are normalized in the Toolbox compatibility adapter. They are
|
|
22
23
|
not core action aliases and never create doubled Browser prefixes.
|
|
23
24
|
|
|
24
|
-
## Engine routes and data
|
|
25
|
+
## Historical Engine routes and data
|
|
25
26
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
restricted adapter transport, not public OpenAPI.
|
|
27
|
+
During a bounded historical cutover, Engine routes may delegate into this SDK.
|
|
28
|
+
They must not remain as a parallel production implementation. Raw cookie
|
|
29
|
+
bootstrap and merge use the restricted adapter transport, not public OpenAPI.
|
|
29
30
|
|
|
30
31
|
Legacy Engine profiles, encrypted auth/cookie-source bundles, cookie
|
|
31
32
|
tombstones, and login sessions are supported by the versioned importer. Paths
|
|
@@ -3,6 +3,12 @@
|
|
|
3
3
|
Electron is an optional peer dependency and appears only behind
|
|
4
4
|
`@amalgm/browser/electron`. Headless consumers do not load it.
|
|
5
5
|
|
|
6
|
+
The published Electron entry has both ESM and generated CommonJS conditions.
|
|
7
|
+
Desktop builds may copy `electron.cjs` and `electron-preload.cjs` into their
|
|
8
|
+
own generated output so Electron ships the native adapter without the full
|
|
9
|
+
headless dependency graph. Both files are build products of Browser's
|
|
10
|
+
TypeScript source and must never be edited or reimplemented by a host app.
|
|
11
|
+
|
|
6
12
|
## Composition
|
|
7
13
|
|
|
8
14
|
The package contains both sides of the visible boundary:
|
package/docs/EVENTS.md
CHANGED
|
@@ -26,5 +26,5 @@ authorization headers, and captured pixels are forbidden.
|
|
|
26
26
|
and heartbeat comments. A disconnect removes the listener. A missing history
|
|
27
27
|
cursor safely returns retained history rather than inventing ordering.
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
Shell or Realtime may relay these events verbatim. That relay does not become
|
|
30
30
|
the Browser authority and must not enrich an event with Browser secrets.
|
package/docs/HEADLESS_RUNTIME.md
CHANGED
|
@@ -53,6 +53,6 @@ image-only, or hostile custom controls; prefer snapshot references elsewhere.
|
|
|
53
53
|
|
|
54
54
|
## Real verification
|
|
55
55
|
|
|
56
|
-
`npm run test:real` launches the
|
|
56
|
+
`npm run test:real` launches the installed Chromium runtime and verifies
|
|
57
57
|
navigation, snapshot, exact-target CDP capture, DPR normalization, page-scoped
|
|
58
58
|
typing, and real page-only recording.
|
package/docs/MCP.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Run `amalgm-browser-mcp` or `amalgm-browser mcp`. The server speaks
|
|
4
4
|
newline-delimited JSON-RPC over stdio and implements MCP tool listing and tool
|
|
5
|
-
calls without Engine.
|
|
5
|
+
calls without Shell or Engine.
|
|
6
6
|
|
|
7
7
|
The 22 tools are the canonical action names prefixed with `browser_`:
|
|
8
8
|
|
package/docs/README.md
CHANGED
|
@@ -12,10 +12,12 @@ your integration:
|
|
|
12
12
|
[recording](./RECORDING.md)
|
|
13
13
|
- [Events](./EVENTS.md) and the [Realtime boundary](./REALTIME_BOUNDARY.md)
|
|
14
14
|
- [Toolbox](./TOOLBOX_INTEGRATION.md) and
|
|
15
|
-
[
|
|
15
|
+
[Shell](./SHELL_INTEGRATION.md) composition
|
|
16
16
|
- [Migration](./MIGRATION.md) and [compatibility](./COMPATIBILITY.md)
|
|
17
17
|
- [Operations](./OPERATIONS.md), [testing](./TESTING.md), and
|
|
18
18
|
[troubleshooting](./TROUBLESHOOTING.md)
|
|
19
19
|
|
|
20
|
-
The package is ESM-only
|
|
21
|
-
|
|
20
|
+
The core package is ESM-only and requires Node.js 24+. The deliberate
|
|
21
|
+
`@amalgm/browser/electron` entry point additionally provides a generated
|
|
22
|
+
CommonJS condition for Electron main processes; no internal implementation
|
|
23
|
+
module is public.
|
package/docs/SDK.md
CHANGED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Shell integration
|
|
2
|
+
|
|
3
|
+
Amalgm Shell consumes `@amalgm/browser`; Browser never imports Shell. Shell is
|
|
4
|
+
the active composition root, while the old Engine implementation is historical
|
|
5
|
+
migration evidence only.
|
|
6
|
+
|
|
7
|
+
## Composition boundary
|
|
8
|
+
|
|
9
|
+
One Shell runtime constructs exactly one `BrowserProductService` and exposes
|
|
10
|
+
its MCP and HTTP adapters. It may inject caller context, authorization,
|
|
11
|
+
artifacts, events, and an optional visible-host driver. It does not translate
|
|
12
|
+
actions or create another registry, cookie jar, profile store, or session
|
|
13
|
+
authority.
|
|
14
|
+
|
|
15
|
+
This composition becomes active only in a signed machine service plan that
|
|
16
|
+
declares Browser. Merely installing the SDK must not create Browser databases
|
|
17
|
+
or portable state in a Core-and-Files-only release.
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
import { createBrowser } from '@amalgm/browser';
|
|
21
|
+
import { ElectronBrowserDriver } from '@amalgm/browser/electron';
|
|
22
|
+
|
|
23
|
+
const browser = createBrowser({
|
|
24
|
+
root: shellBrowserRoot,
|
|
25
|
+
electronDriver: visibleHost
|
|
26
|
+
? new ElectronBrowserDriver(visibleHost)
|
|
27
|
+
: undefined,
|
|
28
|
+
eventSink: browserEventRelay,
|
|
29
|
+
authorization: shellBrowserAuthorization,
|
|
30
|
+
});
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Background work selects the headless driver. Work requiring a visible surface
|
|
34
|
+
selects the compatible Electron host before the session is created and fails
|
|
35
|
+
clearly when that capability is absent. The backend is immutable for the
|
|
36
|
+
session lifetime.
|
|
37
|
+
|
|
38
|
+
## Electron boundary
|
|
39
|
+
|
|
40
|
+
Electron owns application lifecycle and supplies Browser's hardened native
|
|
41
|
+
surface host plus the isolated Browser cookie adapter. React supplies visual
|
|
42
|
+
chrome and bounds. Neither is a second Browser service. Application auth stays
|
|
43
|
+
in Electron's `defaultSession`; websites stay in `persist:amalgm-browser`.
|
|
44
|
+
|
|
45
|
+
The UI and Shell must bind to the same exact published Browser release. A
|
|
46
|
+
desktop build copies Browser's generated native adapter, while Shell installs
|
|
47
|
+
the complete SDK for headless and service execution.
|
|
48
|
+
|
|
49
|
+
## Historical cutover rule
|
|
50
|
+
|
|
51
|
+
Legacy Engine data may be imported once through `legacyDatabaseFile`. The
|
|
52
|
+
importer is read-only with respect to the legacy database. Old and new writers
|
|
53
|
+
must never run against the same Browser state; after cutover, Engine Browser
|
|
54
|
+
code is deleted rather than retained as a fallback.
|
package/docs/TESTING.md
CHANGED
|
@@ -7,7 +7,8 @@ real browser processes.
|
|
|
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 headless Chromium
|
|
11
12
|
npm run test:electron # real Electron; macOS
|
|
12
13
|
npm run verify # check, build, test, package/install
|
|
13
14
|
```
|
|
@@ -32,7 +33,11 @@ npm run verify # check, build, test, package/install
|
|
|
32
33
|
|
|
33
34
|
## Real boundaries
|
|
34
35
|
|
|
35
|
-
|
|
36
|
+
Source CI provisions Chrome for Testing through the locked `agent-browser`
|
|
37
|
+
dependency before the headless suite, which launches that real browser and ffmpeg.
|
|
38
|
+
The suite records command phases and the live CDP browser identity; it never logs
|
|
39
|
+
page data, process output, or command arguments. Provisioning and browser action
|
|
40
|
+
deadlines are separate, and the action deadlines remain unchanged. The Electron harness
|
|
36
41
|
launches the actual Electron binary with two `WebContentsView` surfaces and
|
|
37
42
|
checks partition identity, isolation, capture, remount, and WebM recording.
|
|
38
43
|
These tests exist because mocks cannot validate CDP target identity or physical
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@amalgm/browser",
|
|
3
|
-
"version": "0.1.2-preview.
|
|
3
|
+
"version": "0.1.2-preview.34320564379",
|
|
4
4
|
"description": "Safe persistent browser automation across headless Chromium and visible Electron surfaces.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -100,7 +100,7 @@
|
|
|
100
100
|
"node": ">=24"
|
|
101
101
|
},
|
|
102
102
|
"dependencies": {
|
|
103
|
-
"@amalgm/core": "0.
|
|
103
|
+
"@amalgm/core": "0.5.1-preview.34318364556",
|
|
104
104
|
"@ghostery/adblocker": "^2.18.1",
|
|
105
105
|
"agent-browser": "0.26.0",
|
|
106
106
|
"better-sqlite3": "^12.10.1",
|
|
@@ -157,11 +157,11 @@
|
|
|
157
157
|
"package.json"
|
|
158
158
|
]
|
|
159
159
|
},
|
|
160
|
-
"gitHead": "
|
|
160
|
+
"gitHead": "26f755c33736141e211756f1e5f84f18afcea651",
|
|
161
161
|
"amalgmSource": {
|
|
162
162
|
"repository": "amalgm-inc/amalgm-browser",
|
|
163
163
|
"branch": "preview",
|
|
164
|
-
"commit": "
|
|
165
|
-
"occurrence": "
|
|
164
|
+
"commit": "26f755c33736141e211756f1e5f84f18afcea651",
|
|
165
|
+
"occurrence": "34320564379"
|
|
166
166
|
}
|
|
167
167
|
}
|
|
@@ -1,42 +1,188 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: use-amalgm-browser
|
|
3
|
-
description:
|
|
3
|
+
description: Drive real web pages with Browser (@amalgm/browser) through its MCP server, CLI, or TypeScript SDK — persistent sessions, accessibility snapshots with stable @refs, screenshots, form filling, browser-scoped computer use, WebM recordings, and human login handoff. Use it whenever an agent needs to navigate a site, read or verify page content, fill and submit forms, operate canvas or image-only UIs, browse while authenticated, or record what happened on a page.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
#
|
|
6
|
+
# Browser
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
or headless Chromium; do not ask users to choose a backend during normal work.
|
|
8
|
+
Browser is one safe, persistent, observable way for agents to operate the web. You open a page once into a named session, read it as a structured accessibility snapshot, act on elements through stable references, and only fall back to pixels when pixels are the interface. MCP and the generic CLI action command expose twenty-two product actions. The SDK exposes core browsing through `browser.execute()` and authentication, login handoff, and recording through `browser.auth`, `browser.login`, and `browser.recordings`; REST exposes the same service through action and resource routes.
|
|
10
9
|
|
|
11
|
-
##
|
|
10
|
+
## Installation
|
|
12
11
|
|
|
13
|
-
|
|
14
|
-
2. Call `browser_snapshot` to read the page and obtain stable `@eN` references.
|
|
15
|
-
3. Prefer `browser_click`, `browser_fill`, `browser_select`, and `browser_press`
|
|
16
|
-
with snapshot references.
|
|
17
|
-
4. Re-run `browser_snapshot` after navigation or material page changes.
|
|
18
|
-
5. Use `browser_screenshot` only when pixels matter.
|
|
19
|
-
6. Use `browser_cua` for canvas, WebGL, image-only, or hostile custom controls.
|
|
20
|
-
7. Keep the same `session` value throughout one task. Close it when finished.
|
|
12
|
+
Browser requires Node.js 24 or newer.
|
|
21
13
|
|
|
22
|
-
|
|
23
|
-
|
|
14
|
+
```bash
|
|
15
|
+
npm install @amalgm/browser
|
|
16
|
+
npx --no-install agent-browser install
|
|
17
|
+
```
|
|
24
18
|
|
|
25
|
-
|
|
19
|
+
The package installs three executables alongside the SDK:
|
|
26
20
|
|
|
27
|
-
-
|
|
28
|
-
-
|
|
29
|
-
-
|
|
30
|
-
genuine surface reconnection.
|
|
31
|
-
- Never request or print raw cookies, tokens, auth payloads, or storage values.
|
|
32
|
-
- Use `browser_auth_link_create` when a human must complete authentication.
|
|
33
|
-
- Use named auth bundles explicitly; do not treat a profile as an auth bundle.
|
|
21
|
+
- `amalgm-browser` — the CLI; prints stable JSON to stdout.
|
|
22
|
+
- `amalgm-browser-mcp` — the MCP server (also reachable as `amalgm-browser mcp`).
|
|
23
|
+
- `amalgm-browser-rest` — the authenticated loopback REST API (also `amalgm-browser serve --token <token>`).
|
|
34
24
|
|
|
35
|
-
|
|
25
|
+
The `agent-browser` dependency supplies the launcher; its `install` command downloads Chrome for Testing. An existing Chrome installation can also supply the standalone headless browser. Setting `AMALGM_BROWSER_CDP_URL` attaches to a Chromium endpoint you already run instead.
|
|
36
26
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
27
|
+
### MCP setup
|
|
28
|
+
|
|
29
|
+
To register the MCP server with an MCP-capable client (Claude Code, Cursor, or any client that speaks MCP over stdio), point it at the `amalgm-browser-mcp` binary:
|
|
30
|
+
|
|
31
|
+
```json
|
|
32
|
+
{
|
|
33
|
+
"mcpServers": {
|
|
34
|
+
"browser": {
|
|
35
|
+
"command": "npx",
|
|
36
|
+
"args": ["-y", "-p", "@amalgm/browser", "amalgm-browser-mcp"]
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
The server speaks newline-delimited JSON-RPC over stdio and exposes the tools listed in [MCP tools](#mcp-tools). Screenshots come back as MCP image content; everything else is bounded, sanitized JSON.
|
|
43
|
+
|
|
44
|
+
## Quickstart
|
|
45
|
+
|
|
46
|
+
Open a page, read it, and click something. With the SDK:
|
|
47
|
+
|
|
48
|
+
```ts
|
|
49
|
+
import { createBrowser } from '@amalgm/browser';
|
|
50
|
+
|
|
51
|
+
const browser = createBrowser();
|
|
52
|
+
const session = await browser.createSession({ id: 'research' });
|
|
53
|
+
|
|
54
|
+
await browser.execute(session.id, { type: 'open', url: 'https://example.com' });
|
|
55
|
+
|
|
56
|
+
// Returns the accessibility tree with stable @refs like @e3.
|
|
57
|
+
const snapshot = await browser.execute(session.id, { type: 'snapshot' });
|
|
58
|
+
|
|
59
|
+
await browser.execute(session.id, { type: 'click', target: '@e3' });
|
|
60
|
+
|
|
61
|
+
await browser.closeSession(session.id);
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
The same flow on the CLI — note that every invocation reuses one `--session` value:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
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`).
|
|
74
|
+
|
|
75
|
+
## Core concepts
|
|
76
|
+
|
|
77
|
+
### Sessions
|
|
78
|
+
|
|
79
|
+
A session is a persistent page context: one live browser state that survives across commands. Create it 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, cookies-in-flight, and every element reference you have collected.
|
|
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.
|
|
82
|
+
|
|
83
|
+
### Tabs
|
|
84
|
+
|
|
85
|
+
A session can hold multiple tabs. `tab` with `action: "list" | "new" | "switch" | "close"` (plus an `id` for switch/close) manages them. Switching tabs changes which page your snapshot refs describe — treat a tab switch like a navigation and take a fresh snapshot afterward.
|
|
86
|
+
|
|
87
|
+
### Snapshot references (@refs)
|
|
88
|
+
|
|
89
|
+
`snapshot` returns the page's accessibility tree, with every interactive element tagged with a stable reference such as `@e12`. These refs are the preferred target grammar for `click`, `fill`, and `select`. Two fallbacks exist when a ref is unavailable:
|
|
90
|
+
|
|
91
|
+
- `text=Sign in` — match by visible label.
|
|
92
|
+
- `#submit` or any CSS selector — structural match.
|
|
93
|
+
|
|
94
|
+
Refs belong to the latest snapshot of the current tab. Navigation, tab switches, and material page changes invalidate them; re-run `snapshot` after any of these and use the fresh refs.
|
|
95
|
+
|
|
96
|
+
## Command sequencing
|
|
97
|
+
|
|
98
|
+
Browser actions are individual commands over one shared session, and the ordering rules matter more than any single call:
|
|
99
|
+
|
|
100
|
+
1. Call `open` once per page, not once per command. The session holds the page.
|
|
101
|
+
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
|
+
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 `NOT_FOUND` on step four means a stale ref or changed page at step four, not a broken session. Usually the fix is a fresh `snapshot` and a retry of that one step.
|
|
104
|
+
5. Keep one owner per session. Two processes driving the same session id conflict; the second gets a lease conflict rather than silently interleaving.
|
|
105
|
+
|
|
106
|
+
## Reading pages: snapshots vs screenshots
|
|
107
|
+
|
|
108
|
+
`snapshot` and `screenshot` answer different questions.
|
|
109
|
+
|
|
110
|
+
Use `snapshot` to know what is on the page and what you can do to it: it returns text, structure, roles, and actionable refs, and it is what you should reason over for navigation, form state, and content extraction. Use `screenshot` only when pixels are the question — verifying layout, reading a canvas, checking that an image rendered. `screenshot` accepts `fullPage: true` for beyond-the-viewport capture.
|
|
111
|
+
|
|
112
|
+
When you need visual verification, look at the returned screenshot image itself. Do not infer visual appearance from the accessibility snapshot — the snapshot deliberately abstracts away pixels.
|
|
113
|
+
|
|
114
|
+
Screenshot and computer-use coordinates are CSS pixels with a 1:1 mapping between the image and the viewport, so a coordinate you read off a screenshot is the coordinate you pass to `cua`.
|
|
115
|
+
|
|
116
|
+
`console` reads console output and page errors from the session (`clear: true` empties the buffer), and `eval` runs a JavaScript expression in the page when you need a computed answer the snapshot does not surface.
|
|
117
|
+
|
|
118
|
+
## Forms and input
|
|
119
|
+
|
|
120
|
+
The core input actions cover ordinary DOM forms:
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
amalgm-browser fill @e7 "jane@example.com" --session research
|
|
124
|
+
amalgm-browser select @e9 "US" --session research
|
|
125
|
+
amalgm-browser press Enter --session research
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
- `fill` sets a target's text; pass `submit: true` to submit the surrounding form in the same action.
|
|
129
|
+
- `select` picks a native `<option>` by value.
|
|
130
|
+
- `press` sends a key or key combination to the page.
|
|
131
|
+
- `dialog` accepts or dismisses a native page dialog (`action: "accept" | "dismiss"`, with optional `text` for prompts).
|
|
132
|
+
- `wait` blocks on a selector appearing, a URL match, or a duration (`selector`, `url`, `ms`, `timeoutMs`) — use it between an action and the snapshot that reads its result.
|
|
133
|
+
|
|
134
|
+
For interfaces without usable DOM semantics — canvas editors, WebGL, image-only controls, hostile custom widgets — use `cua`, browser-scoped computer use. It takes one `operation` per call:
|
|
135
|
+
|
|
136
|
+
```json
|
|
137
|
+
{ "kind": "click", "x": 320, "y": 240, "button": "left" }
|
|
138
|
+
{ "kind": "type", "text": "hello" }
|
|
139
|
+
{ "kind": "drag", "path": [{ "x": 10, "y": 10 }, { "x": 80, "y": 90 }] }
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
The full operation set is `screenshot`, `click`, `double_click`, `move`, `scroll`, `type`, `keypress`, and `drag`; see [references/actions.md](references/actions.md) for every shape. Reach for `cua` as the fallback, not the default — snapshot refs are more reliable wherever the DOM is honest.
|
|
143
|
+
|
|
144
|
+
## Authentication and recording
|
|
145
|
+
|
|
146
|
+
When a task needs a human to log in, let the host provide the login interface. `browser.login.create()` and the authenticated REST login creation route return a TTL-bound login token and a relative `/browser-auth/...` URL; the host must serve that interface and transport. Treat the creation result as a secret. The token authorizes activation and completion until the login is completed, cancelled, or expires. MCP sanitizes the token and URL, so its `browser_auth_link_create` result cannot supply a usable login credential.
|
|
147
|
+
|
|
148
|
+
`auth_save` stores a session's authenticated state as a named encrypted bundle, and `auth_load` restores a bundle by `bundleId`. Completing a login handoff saves its bundle automatically. `auth_list` shows sanitized bundle and login metadata; ordinary action results do not return raw cookie or storage values.
|
|
149
|
+
|
|
150
|
+
`record_start` / `record_stop` / `record_list` manage page-only WebM recordings of a session. Start recording only after the page is open, and stop before closing the session. Results report `wallSeconds` (elapsed clock time) and `videoSeconds` (encoded footage) separately.
|
|
151
|
+
|
|
152
|
+
## MCP tools
|
|
153
|
+
|
|
154
|
+
The MCP server exposes twenty-two tools — the canonical action names prefixed with `browser_`. Session actions accept an optional `session` string and default to `default`. `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
|
+
|
|
156
|
+
| Group | Tools |
|
|
157
|
+
| --- | --- |
|
|
158
|
+
| Navigate & read | `browser_open`, `browser_snapshot`, `browser_screenshot`, `browser_console`, `browser_wait` |
|
|
159
|
+
| Act on elements | `browser_click`, `browser_fill`, `browser_press`, `browser_select`, `browser_eval` |
|
|
160
|
+
| Session & page | `browser_tab`, `browser_dialog`, `browser_close`, `browser_cli` |
|
|
161
|
+
| Computer use | `browser_cua` |
|
|
162
|
+
| Recording | `browser_record_start`, `browser_record_stop`, `browser_record_list` |
|
|
163
|
+
| Authentication | `browser_auth_list`, `browser_auth_link_create`, `browser_auth_save`, `browser_auth_load` |
|
|
164
|
+
|
|
165
|
+
`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
|
+
|
|
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`, `profiles`, `auth`, `recordings`, `capabilities`, `doctor`).
|
|
168
|
+
|
|
169
|
+
## Error handling
|
|
170
|
+
|
|
171
|
+
Failures are typed `BrowserError` values with stable codes:
|
|
172
|
+
|
|
173
|
+
| Code | Meaning |
|
|
174
|
+
| --- | --- |
|
|
175
|
+
| `INVALID_INPUT` | Malformed action input; fix the call, do not retry as-is. |
|
|
176
|
+
| `NOT_FOUND` | Target, session, or resource does not exist — often a stale `@ref`; re-snapshot. |
|
|
177
|
+
| `CONFLICT` | Another owner holds the session or resource. |
|
|
178
|
+
| `CAPABILITY_UNSUPPORTED` | The active backend does not implement this action group; nothing is silently approximated. |
|
|
179
|
+
| `AUTHORIZATION_DENIED` | The caller is not permitted to perform the action. |
|
|
180
|
+
| `TIMEOUT` / `ABORTED` | The operation ran out of time or was cancelled. |
|
|
181
|
+
| `PROCESS_FAILED` | The underlying browser process failed. |
|
|
182
|
+
| `SURFACE_IDENTITY_FAILED` | A visible desktop surface no longer matches the session; this fails closed. Retry once only after a genuine reconnection, never against a different surface. |
|
|
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.
|
|
185
|
+
|
|
186
|
+
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
|
+
|
|
188
|
+
For the complete target grammar, computer-use operation shapes, and tab, dialog, auth, and recording inputs, see [references/actions.md](references/actions.md).
|
|
@@ -1,14 +1,20 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Action reference
|
|
2
|
+
|
|
3
|
+
MCP (`browser_<action>`) and the generic CLI command (`amalgm-browser action <name> --input <json>`) expose the product action catalog. The CLI also has direct commands for core browsing and computer use. SDK core actions use `browser.execute(sessionId, action)`; authentication, login, and recording use `browser.auth`, `browser.login`, and `browser.recordings`. REST provides action and resource routes over those services. This reference covers the input shapes that need more detail than the main page gives.
|
|
2
4
|
|
|
3
5
|
## Targets
|
|
4
6
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
-
|
|
7
|
+
`click`, `fill`, and `select` take a `target` string in one grammar:
|
|
8
|
+
|
|
9
|
+
- `@e12` — a stable reference from the latest accessibility snapshot. Preferred.
|
|
10
|
+
- `text=Sign in` — visible-text fallback when no ref is available.
|
|
11
|
+
- `#submit` (or any CSS selector) — structural fallback.
|
|
12
|
+
|
|
13
|
+
Refs are valid only for the latest snapshot of the current tab. After navigation, a tab switch, or a material page change, run `snapshot` again and use the new refs.
|
|
8
14
|
|
|
9
15
|
## Computer use
|
|
10
16
|
|
|
11
|
-
|
|
17
|
+
`cua` performs one browser-scoped operation per call. Coordinates are CSS pixels and map 1:1 to viewport screenshots returned by `screenshot`.
|
|
12
18
|
|
|
13
19
|
```json
|
|
14
20
|
{ "kind": "screenshot" }
|
|
@@ -21,20 +27,31 @@ Call `browser_cua` with one `operation`:
|
|
|
21
27
|
{ "kind": "drag", "path": [{ "x": 10, "y": 10 }, { "x": 80, "y": 90 }] }
|
|
22
28
|
```
|
|
23
29
|
|
|
24
|
-
|
|
25
|
-
interfaces without usable DOM semantics.
|
|
30
|
+
Use computer use for canvas, WebGL, image-only, or custom controls without DOM semantics. Ordinary DOM work should use snapshot refs — they survive layout shifts that break coordinates.
|
|
26
31
|
|
|
27
32
|
## Tabs and dialogs
|
|
28
33
|
|
|
29
|
-
|
|
30
|
-
|
|
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. Sessions bound to a visible desktop surface may reject switching to a surface they do not own.
|
|
35
|
+
|
|
36
|
+
`dialog` takes `action: "accept" | "dismiss"`, with optional `text` supplied only for prompt dialogs.
|
|
37
|
+
|
|
38
|
+
## Waiting
|
|
39
|
+
|
|
40
|
+
`wait` blocks on whichever condition you supply: `selector` (element appears), `url` (location matches), or `ms` (fixed delay), bounded by `timeoutMs`. Prefer `selector` or `url` over fixed delays.
|
|
41
|
+
|
|
42
|
+
## Authentication
|
|
43
|
+
|
|
44
|
+
- `auth_link_create` — create a TTL-bound human login handoff. Input: `targetUrl` (required), optional `domains`, `ttlMs` (clamped to one minute–one hour), `transport`, `liveUrl`. SDK `browser.login.create()` and authenticated REST creation return a token and relative URL once; the host must serve the login interface. The token remains valid until completion, cancellation, or expiry. MCP redacts it and cannot return a usable credential.
|
|
45
|
+
- `auth_save` — save the session's authenticated state as a named encrypted bundle. Input: `name` (required), optional `domains`.
|
|
46
|
+
- `auth_load` — load a bundle into the session by `bundleId`.
|
|
47
|
+
- `auth_list` — list sanitized profiles, bundles, and login sessions. Never returns raw cookie or token values.
|
|
48
|
+
|
|
49
|
+
A profile is a browser state directory; an auth bundle is an explicitly saved, named credential snapshot. They are separate — loading a profile does not load a bundle.
|
|
31
50
|
|
|
32
|
-
|
|
51
|
+
## Recording
|
|
33
52
|
|
|
34
|
-
|
|
53
|
+
- `record_start` — begin a page-only WebM recording. Optional `fps` (clamped 1–30) and `name`. The page must be open first.
|
|
54
|
+
- `record_stop` — stop the session's recording; call before `close`.
|
|
55
|
+
- `record_list` — list recordings and active status.
|
|
35
56
|
|
|
36
|
-
|
|
37
|
-
- `browser_auth_save`: explicitly save named encrypted browser state.
|
|
38
|
-
- `browser_auth_load`: explicitly load a named bundle into a session.
|
|
39
|
-
- `browser_record_start`, `browser_record_stop`, `browser_record_list`: manage
|
|
40
|
-
page-only WebM recordings.
|
|
57
|
+
Results report `wallSeconds` (elapsed clock time) and `videoSeconds` (encoded footage) under those exact names.
|
|
@@ -1,73 +0,0 @@
|
|
|
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.
|