@amalgm/browser 0.1.2-preview.35541635545 → 0.1.2-preview.37254096068

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (390) hide show
  1. package/PURPOSE.md +119 -97
  2. package/README.md +51 -56
  3. package/SECURITY.md +10 -8
  4. package/dist/bin/amalgm-browser-mcp.js +2 -3
  5. package/dist/bin/amalgm-browser-mcp.js.map +1 -1
  6. package/dist/bin/amalgm-browser-rest.js +8 -18
  7. package/dist/bin/amalgm-browser-rest.js.map +1 -1
  8. package/dist/src/account.d.ts +8 -0
  9. package/dist/src/account.js +42 -0
  10. package/dist/src/account.js.map +1 -0
  11. package/dist/src/action.d.ts +1 -2
  12. package/dist/src/action.js +3 -7
  13. package/dist/src/action.js.map +1 -1
  14. package/dist/src/adapters/cli/actions.d.ts +0 -1
  15. package/dist/src/adapters/cli/actions.js +0 -7
  16. package/dist/src/adapters/cli/actions.js.map +1 -1
  17. package/dist/src/adapters/cli/help.d.ts +1 -1
  18. package/dist/src/adapters/cli/help.js +1 -4
  19. package/dist/src/adapters/cli/help.js.map +1 -1
  20. package/dist/src/adapters/cli/resources.js +0 -22
  21. package/dist/src/adapters/cli/resources.js.map +1 -1
  22. package/dist/src/adapters/cli/run.js +25 -19
  23. package/dist/src/adapters/cli/run.js.map +1 -1
  24. package/dist/src/adapters/execute.js +2 -2
  25. package/dist/src/adapters/execute.js.map +1 -1
  26. package/dist/src/adapters/http/events.d.ts +5 -2
  27. package/dist/src/adapters/http/events.js +18 -2
  28. package/dist/src/adapters/http/events.js.map +1 -1
  29. package/dist/src/adapters/http/internal-routes.js +9 -4
  30. package/dist/src/adapters/http/internal-routes.js.map +1 -1
  31. package/dist/src/adapters/http/navigation-stream.d.ts +4 -0
  32. package/dist/src/adapters/http/navigation-stream.js +17 -0
  33. package/dist/src/adapters/http/navigation-stream.js.map +1 -0
  34. package/dist/src/adapters/http/openapi.js +2 -8
  35. package/dist/src/adapters/http/openapi.js.map +1 -1
  36. package/dist/src/adapters/http/server.js +54 -14
  37. package/dist/src/adapters/http/server.js.map +1 -1
  38. package/dist/src/adapters/http/session-routes.js +0 -1
  39. package/dist/src/adapters/http/session-routes.js.map +1 -1
  40. package/dist/src/adapters/http/stream.d.ts +6 -0
  41. package/dist/src/adapters/http/stream.js +89 -0
  42. package/dist/src/adapters/http/stream.js.map +1 -0
  43. package/dist/src/adapters/mcp/server.js +2 -2
  44. package/dist/src/adapters/mcp/server.js.map +1 -1
  45. package/dist/src/adapters/mcp/tools.js +2 -4
  46. package/dist/src/adapters/mcp/tools.js.map +1 -1
  47. package/dist/src/adapters/mcp/types.d.ts +3 -2
  48. package/dist/src/adapters/toolbox/manifest.js +1 -1
  49. package/dist/src/adapters/toolbox/manifest.js.map +1 -1
  50. package/dist/src/auth/login.d.ts +3 -1
  51. package/dist/src/auth/login.js +48 -33
  52. package/dist/src/auth/login.js.map +1 -1
  53. package/dist/src/auth/service.js +56 -67
  54. package/dist/src/auth/service.js.map +1 -1
  55. package/dist/src/{drivers/cdp → cdp}/capture.d.ts +1 -1
  56. package/dist/src/{drivers/cdp → cdp}/capture.js +1 -1
  57. package/dist/src/cdp/capture.js.map +1 -0
  58. package/dist/src/{drivers/cdp → cdp}/client.d.ts +3 -1
  59. package/dist/src/{drivers/cdp → cdp}/client.js +51 -14
  60. package/dist/src/cdp/client.js.map +1 -0
  61. package/dist/src/cdp/input.js.map +1 -0
  62. package/dist/src/cdp/navigation.d.ts +5 -0
  63. package/dist/src/cdp/navigation.js +47 -0
  64. package/dist/src/cdp/navigation.js.map +1 -0
  65. package/dist/src/{drivers/cdp → cdp}/screencast.js +1 -1
  66. package/dist/src/cdp/screencast.js.map +1 -0
  67. package/dist/src/chrome/cookie-adapter.d.ts +23 -0
  68. package/dist/src/chrome/cookie-adapter.js +74 -0
  69. package/dist/src/chrome/cookie-adapter.js.map +1 -0
  70. package/dist/src/chrome/cookie-changes.d.ts +12 -0
  71. package/dist/src/chrome/cookie-changes.js +100 -0
  72. package/dist/src/chrome/cookie-changes.js.map +1 -0
  73. package/dist/src/chrome/cookie-observer.d.ts +20 -0
  74. package/dist/src/chrome/cookie-observer.js +44 -0
  75. package/dist/src/chrome/cookie-observer.js.map +1 -0
  76. package/dist/src/chrome/executable.d.ts +1 -0
  77. package/dist/src/chrome/executable.js +55 -0
  78. package/dist/src/chrome/executable.js.map +1 -0
  79. package/dist/src/chrome/flags.d.ts +7 -0
  80. package/dist/src/chrome/flags.js +59 -0
  81. package/dist/src/chrome/flags.js.map +1 -0
  82. package/dist/src/chrome/host.d.ts +25 -0
  83. package/dist/src/chrome/host.js +137 -0
  84. package/dist/src/chrome/host.js.map +1 -0
  85. package/dist/src/chrome/launch.d.ts +11 -0
  86. package/dist/src/chrome/launch.js +105 -0
  87. package/dist/src/chrome/launch.js.map +1 -0
  88. package/dist/src/chrome/relay/editing.d.ts +2 -0
  89. package/dist/src/chrome/relay/editing.js +14 -0
  90. package/dist/src/chrome/relay/editing.js.map +1 -0
  91. package/dist/src/chrome/relay/server.d.ts +18 -0
  92. package/dist/src/chrome/relay/server.js +120 -0
  93. package/dist/src/chrome/relay/server.js.map +1 -0
  94. package/dist/src/chrome/relay/targets.d.ts +11 -0
  95. package/dist/src/chrome/relay/targets.js +59 -0
  96. package/dist/src/chrome/relay/targets.js.map +1 -0
  97. package/dist/src/chrome/relay/view.d.ts +34 -0
  98. package/dist/src/chrome/relay/view.js +185 -0
  99. package/dist/src/chrome/relay/view.js.map +1 -0
  100. package/dist/src/cookies/adapter-credential.d.ts +6 -0
  101. package/dist/src/cookies/adapter-credential.js +33 -0
  102. package/dist/src/cookies/adapter-credential.js.map +1 -0
  103. package/dist/src/cookies/coordinator.d.ts +14 -13
  104. package/dist/src/cookies/coordinator.js +157 -75
  105. package/dist/src/cookies/coordinator.js.map +1 -1
  106. package/dist/src/cookies/database.d.ts +29 -0
  107. package/dist/src/cookies/database.js +113 -0
  108. package/dist/src/cookies/database.js.map +1 -0
  109. package/dist/src/cookies/diff.d.ts +6 -0
  110. package/dist/src/cookies/diff.js +19 -0
  111. package/dist/src/cookies/diff.js.map +1 -0
  112. package/dist/src/cookies/http-store.d.ts +7 -0
  113. package/dist/src/cookies/http-store.js +105 -0
  114. package/dist/src/cookies/http-store.js.map +1 -0
  115. package/dist/src/cookies/jar.d.ts +12 -11
  116. package/dist/src/cookies/jar.js +128 -120
  117. package/dist/src/cookies/jar.js.map +1 -1
  118. package/dist/src/cookies/policy.js +10 -4
  119. package/dist/src/cookies/policy.js.map +1 -1
  120. package/dist/src/cookies/secret-file.d.ts +4 -0
  121. package/dist/src/cookies/secret-file.js +47 -9
  122. package/dist/src/cookies/secret-file.js.map +1 -1
  123. package/dist/src/cookies/types.d.ts +34 -2
  124. package/dist/src/cookies.d.ts +2 -0
  125. package/dist/src/cookies.js +2 -0
  126. package/dist/src/cookies.js.map +1 -1
  127. package/dist/src/defaults.d.ts +1 -5
  128. package/dist/src/defaults.js +49 -58
  129. package/dist/src/defaults.js.map +1 -1
  130. package/dist/src/driver/cli-policy.d.ts +1 -0
  131. package/dist/src/driver/cli-policy.js +17 -0
  132. package/dist/src/driver/cli-policy.js.map +1 -0
  133. package/dist/src/{drivers/headless → driver}/command.d.ts +3 -7
  134. package/dist/src/{drivers/headless → driver}/command.js +29 -29
  135. package/dist/src/driver/command.js.map +1 -0
  136. package/dist/src/{drivers/headless → driver}/driver.d.ts +13 -10
  137. package/dist/src/{drivers/headless → driver}/driver.js +67 -82
  138. package/dist/src/driver/driver.js.map +1 -0
  139. package/dist/src/{interaction/delta.d.ts → driver/evidence.d.ts} +3 -2
  140. package/dist/src/{interaction/delta.js → driver/evidence.js} +6 -3
  141. package/dist/src/driver/evidence.js.map +1 -0
  142. package/dist/src/driver/executable.js.map +1 -0
  143. package/dist/src/driver/stream.d.ts +1 -0
  144. package/dist/src/driver/stream.js +22 -0
  145. package/dist/src/driver/stream.js.map +1 -0
  146. package/dist/src/driver/wait.d.ts +6 -0
  147. package/dist/src/driver/wait.js +28 -0
  148. package/dist/src/driver/wait.js.map +1 -0
  149. package/dist/src/electron/adblock/cache.js.map +1 -0
  150. package/dist/src/electron/adblock/cosmetics.js.map +1 -0
  151. package/dist/src/{drivers/electron/native → electron}/adblock/index.d.ts +0 -1
  152. package/dist/src/{drivers/electron/native → electron}/adblock/index.js +0 -1
  153. package/dist/src/{drivers/electron/native → electron}/adblock/index.js.map +1 -1
  154. package/dist/src/electron/adblock/policy.js.map +1 -0
  155. package/dist/src/electron/adblock/preload.js.map +1 -0
  156. package/dist/src/electron/adblock/settings.js.map +1 -0
  157. package/dist/src/{drivers/electron/native → electron}/contracts.d.ts +0 -14
  158. package/dist/src/{drivers/electron/native → electron}/contracts.js +0 -1
  159. package/dist/src/electron/contracts.js.map +1 -0
  160. package/dist/src/{drivers/electron → electron}/cookie-adapter.d.ts +4 -4
  161. package/dist/src/{drivers/electron → electron}/cookie-adapter.js +9 -6
  162. package/dist/src/electron/cookie-adapter.js.map +1 -0
  163. package/dist/src/electron/cookie-sync.d.ts +6 -0
  164. package/dist/src/electron/cookie-sync.js +18 -0
  165. package/dist/src/electron/cookie-sync.js.map +1 -0
  166. package/dist/src/electron/policy.js.map +1 -0
  167. package/dist/src/electron/session.d.ts +2 -0
  168. package/dist/src/electron/session.js +9 -0
  169. package/dist/src/electron/session.js.map +1 -0
  170. package/dist/src/electron/shell/adblock-ipc.js.map +1 -0
  171. package/dist/src/electron/shell/context-menu.js.map +1 -0
  172. package/dist/src/electron/shell/downloads.js.map +1 -0
  173. package/dist/src/electron/shell/helpers.js.map +1 -0
  174. package/dist/src/electron/shell/permissions.js.map +1 -0
  175. package/dist/src/{drivers/electron/native → electron}/shell/sites.d.ts +1 -3
  176. package/dist/src/{drivers/electron/native → electron}/shell/sites.js +2 -34
  177. package/dist/src/electron/shell/sites.js.map +1 -0
  178. package/dist/src/{drivers/electron/native → electron}/shell/types.d.ts +0 -1
  179. package/dist/src/electron/shell/types.js.map +1 -0
  180. package/dist/src/electron/shell.d.ts +13 -0
  181. package/dist/src/electron/shell.js +73 -0
  182. package/dist/src/electron/shell.js.map +1 -0
  183. package/dist/src/electron/surface/commands.js.map +1 -0
  184. package/dist/src/{drivers/electron/native → electron}/surface/create.js +0 -6
  185. package/dist/src/electron/surface/create.js.map +1 -0
  186. package/dist/src/{drivers/electron/native → electron}/surface/events.js +1 -13
  187. package/dist/src/electron/surface/events.js.map +1 -0
  188. package/dist/src/{drivers/electron/native → electron}/surface/presentation.d.ts +2 -9
  189. package/dist/src/electron/surface/presentation.js +29 -0
  190. package/dist/src/electron/surface/presentation.js.map +1 -0
  191. package/dist/src/{drivers/electron/native → electron}/surface/state.d.ts +5 -0
  192. package/dist/src/{drivers/electron/native → electron}/surface/state.js +10 -4
  193. package/dist/src/electron/surface/state.js.map +1 -0
  194. package/dist/src/{drivers/electron/native → electron}/surface/types.d.ts +2 -8
  195. package/dist/src/electron/surface/types.js.map +1 -0
  196. package/dist/src/{drivers/electron/native → electron}/surface-controller.js +9 -12
  197. package/dist/src/electron/surface-controller.js.map +1 -0
  198. package/dist/src/electron-preload.cjs +1 -1
  199. package/dist/src/electron.cjs +587 -820
  200. package/dist/src/electron.d.cts +4 -14
  201. package/dist/src/electron.d.ts +4 -14
  202. package/dist/src/electron.js +4 -14
  203. package/dist/src/electron.js.map +1 -1
  204. package/dist/src/errors.d.ts +1 -1
  205. package/dist/src/errors.js.map +1 -1
  206. package/dist/src/index.d.ts +2 -3
  207. package/dist/src/index.js +0 -2
  208. package/dist/src/index.js.map +1 -1
  209. package/dist/src/migration/legacy-migration.d.ts +0 -1
  210. package/dist/src/migration/legacy-migration.js +3 -9
  211. package/dist/src/migration/legacy-migration.js.map +1 -1
  212. package/dist/src/migration/legacy-rows.d.ts +1 -2
  213. package/dist/src/migration/legacy-rows.js +0 -14
  214. package/dist/src/migration/legacy-rows.js.map +1 -1
  215. package/dist/src/ports.d.ts +12 -15
  216. package/dist/src/ports.js.map +1 -1
  217. package/dist/src/process.d.ts +1 -0
  218. package/dist/src/process.js +11 -0
  219. package/dist/src/process.js.map +1 -1
  220. package/dist/src/product-service.d.ts +4 -6
  221. package/dist/src/product-service.js +21 -15
  222. package/dist/src/product-service.js.map +1 -1
  223. package/dist/src/recording/encoder.js +1 -1
  224. package/dist/src/recording/encoder.js.map +1 -1
  225. package/dist/src/recording/service.d.ts +4 -0
  226. package/dist/src/recording/service.js +72 -62
  227. package/dist/src/recording/service.js.map +1 -1
  228. package/dist/src/recording/source.js +1 -1
  229. package/dist/src/recording/source.js.map +1 -1
  230. package/dist/src/registry.d.ts +4 -0
  231. package/dist/src/registry.js +17 -0
  232. package/dist/src/registry.js.map +1 -1
  233. package/dist/src/service-options.d.ts +5 -7
  234. package/dist/src/service.d.ts +16 -18
  235. package/dist/src/service.js +108 -108
  236. package/dist/src/service.js.map +1 -1
  237. package/dist/src/sessions/operations.d.ts +12 -0
  238. package/dist/src/sessions/operations.js +56 -0
  239. package/dist/src/sessions/operations.js.map +1 -0
  240. package/dist/src/testing.d.ts +8 -4
  241. package/dist/src/testing.js +7 -5
  242. package/dist/src/testing.js.map +1 -1
  243. package/dist/src/types.d.ts +0 -39
  244. package/docs/ACTIONS.md +0 -4
  245. package/docs/ARCHITECTURE.md +51 -55
  246. package/docs/AUTHENTICATION.md +41 -36
  247. package/docs/AXIOMS.md +13 -11
  248. package/docs/CHROME.md +143 -0
  249. package/docs/CLI.md +63 -31
  250. package/docs/COMPATIBILITY.md +14 -23
  251. package/docs/COOKIES.md +95 -52
  252. package/docs/ELECTRON_INTEGRATION.md +84 -77
  253. package/docs/EVENTS.md +5 -9
  254. package/docs/MCP.md +10 -6
  255. package/docs/MIGRATION.md +43 -36
  256. package/docs/OPERATIONS.md +48 -40
  257. package/docs/README.md +5 -5
  258. package/docs/REALTIME_BOUNDARY.md +3 -3
  259. package/docs/RECORDING.md +16 -15
  260. package/docs/REST.md +57 -26
  261. package/docs/SDK.md +65 -55
  262. package/docs/SHELL_INTEGRATION.md +78 -36
  263. package/docs/TESTING.md +58 -42
  264. package/docs/TOOLBOX_INTEGRATION.md +9 -4
  265. package/docs/TROUBLESHOOTING.md +68 -40
  266. package/examples/basic.ts +1 -0
  267. package/package.json +8 -15
  268. package/skills/use-amalgm-browser/SKILL.md +16 -29
  269. package/skills/use-amalgm-browser/references/actions.md +2 -2
  270. package/dist/src/adapters/http/profile-routes.d.ts +0 -2
  271. package/dist/src/adapters/http/profile-routes.js +0 -42
  272. package/dist/src/adapters/http/profile-routes.js.map +0 -1
  273. package/dist/src/auth/transport.d.ts +0 -8
  274. package/dist/src/auth/transport.js +0 -45
  275. package/dist/src/auth/transport.js.map +0 -1
  276. package/dist/src/drivers/cdp/capture.js.map +0 -1
  277. package/dist/src/drivers/cdp/client.js.map +0 -1
  278. package/dist/src/drivers/cdp/input.js.map +0 -1
  279. package/dist/src/drivers/cdp/screencast.js.map +0 -1
  280. package/dist/src/drivers/cdp/target.d.ts +0 -4
  281. package/dist/src/drivers/cdp/target.js +0 -34
  282. package/dist/src/drivers/cdp/target.js.map +0 -1
  283. package/dist/src/drivers/electron/advertisement.d.ts +0 -12
  284. package/dist/src/drivers/electron/advertisement.js +0 -57
  285. package/dist/src/drivers/electron/advertisement.js.map +0 -1
  286. package/dist/src/drivers/electron/contracts.d.ts +0 -45
  287. package/dist/src/drivers/electron/contracts.js +0 -10
  288. package/dist/src/drivers/electron/contracts.js.map +0 -1
  289. package/dist/src/drivers/electron/cookie-adapter.js.map +0 -1
  290. package/dist/src/drivers/electron/driver.d.ts +0 -19
  291. package/dist/src/drivers/electron/driver.js +0 -115
  292. package/dist/src/drivers/electron/driver.js.map +0 -1
  293. package/dist/src/drivers/electron/native/adblock/cache.js.map +0 -1
  294. package/dist/src/drivers/electron/native/adblock/cosmetics.js.map +0 -1
  295. package/dist/src/drivers/electron/native/adblock/policy.js.map +0 -1
  296. package/dist/src/drivers/electron/native/adblock/preload.js.map +0 -1
  297. package/dist/src/drivers/electron/native/adblock/settings.js.map +0 -1
  298. package/dist/src/drivers/electron/native/config.d.ts +0 -4
  299. package/dist/src/drivers/electron/native/config.js +0 -9
  300. package/dist/src/drivers/electron/native/config.js.map +0 -1
  301. package/dist/src/drivers/electron/native/contracts.js.map +0 -1
  302. package/dist/src/drivers/electron/native/policy.js.map +0 -1
  303. package/dist/src/drivers/electron/native/session.d.ts +0 -4
  304. package/dist/src/drivers/electron/native/session.js +0 -11
  305. package/dist/src/drivers/electron/native/session.js.map +0 -1
  306. package/dist/src/drivers/electron/native/shell/adblock-ipc.js.map +0 -1
  307. package/dist/src/drivers/electron/native/shell/context-menu.js.map +0 -1
  308. package/dist/src/drivers/electron/native/shell/downloads.js.map +0 -1
  309. package/dist/src/drivers/electron/native/shell/helpers.js.map +0 -1
  310. package/dist/src/drivers/electron/native/shell/permissions.js.map +0 -1
  311. package/dist/src/drivers/electron/native/shell/sites.js.map +0 -1
  312. package/dist/src/drivers/electron/native/shell/types.js.map +0 -1
  313. package/dist/src/drivers/electron/native/shell.d.ts +0 -14
  314. package/dist/src/drivers/electron/native/shell.js +0 -115
  315. package/dist/src/drivers/electron/native/shell.js.map +0 -1
  316. package/dist/src/drivers/electron/native/surface/commands.js.map +0 -1
  317. package/dist/src/drivers/electron/native/surface/create.js.map +0 -1
  318. package/dist/src/drivers/electron/native/surface/events.js.map +0 -1
  319. package/dist/src/drivers/electron/native/surface/presentation.js +0 -87
  320. package/dist/src/drivers/electron/native/surface/presentation.js.map +0 -1
  321. package/dist/src/drivers/electron/native/surface/state.js.map +0 -1
  322. package/dist/src/drivers/electron/native/surface/types.js.map +0 -1
  323. package/dist/src/drivers/electron/native/surface-controller.js.map +0 -1
  324. package/dist/src/drivers/electron/policy.d.ts +0 -4
  325. package/dist/src/drivers/electron/policy.js +0 -39
  326. package/dist/src/drivers/electron/policy.js.map +0 -1
  327. package/dist/src/drivers/electron/session.d.ts +0 -4
  328. package/dist/src/drivers/electron/session.js +0 -5
  329. package/dist/src/drivers/electron/session.js.map +0 -1
  330. package/dist/src/drivers/headless/command.js.map +0 -1
  331. package/dist/src/drivers/headless/cookie-adapter.d.ts +0 -16
  332. package/dist/src/drivers/headless/cookie-adapter.js +0 -59
  333. package/dist/src/drivers/headless/cookie-adapter.js.map +0 -1
  334. package/dist/src/drivers/headless/driver.js.map +0 -1
  335. package/dist/src/drivers/headless/executable.js.map +0 -1
  336. package/dist/src/drivers/headless/screencast.d.ts +0 -3
  337. package/dist/src/drivers/headless/screencast.js +0 -21
  338. package/dist/src/drivers/headless/screencast.js.map +0 -1
  339. package/dist/src/headless.d.ts +0 -3
  340. package/dist/src/headless.js +0 -4
  341. package/dist/src/headless.js.map +0 -1
  342. package/dist/src/interaction/delta.js.map +0 -1
  343. package/dist/src/interaction/typing.d.ts +0 -39
  344. package/dist/src/interaction/typing.js +0 -189
  345. package/dist/src/interaction/typing.js.map +0 -1
  346. package/dist/src/profiles/directories.d.ts +0 -9
  347. package/dist/src/profiles/directories.js +0 -57
  348. package/dist/src/profiles/directories.js.map +0 -1
  349. package/dist/src/profiles/service.d.ts +0 -30
  350. package/dist/src/profiles/service.js +0 -89
  351. package/dist/src/profiles/service.js.map +0 -1
  352. package/dist/src/runtime-selector.d.ts +0 -12
  353. package/dist/src/runtime-selector.js +0 -72
  354. package/dist/src/runtime-selector.js.map +0 -1
  355. package/docs/HEADLESS_RUNTIME.md +0 -58
  356. package/examples/custom-driver.ts +0 -45
  357. /package/dist/src/{drivers/cdp → cdp}/input.d.ts +0 -0
  358. /package/dist/src/{drivers/cdp → cdp}/input.js +0 -0
  359. /package/dist/src/{drivers/cdp → cdp}/screencast.d.ts +0 -0
  360. /package/dist/src/{drivers/headless → driver}/executable.d.ts +0 -0
  361. /package/dist/src/{drivers/headless → driver}/executable.js +0 -0
  362. /package/dist/src/{drivers/electron/native → electron}/adblock/cache.d.ts +0 -0
  363. /package/dist/src/{drivers/electron/native → electron}/adblock/cache.js +0 -0
  364. /package/dist/src/{drivers/electron/native → electron}/adblock/cosmetics.d.ts +0 -0
  365. /package/dist/src/{drivers/electron/native → electron}/adblock/cosmetics.js +0 -0
  366. /package/dist/src/{drivers/electron/native → electron}/adblock/policy.d.ts +0 -0
  367. /package/dist/src/{drivers/electron/native → electron}/adblock/policy.js +0 -0
  368. /package/dist/src/{drivers/electron/native → electron}/adblock/preload.d.ts +0 -0
  369. /package/dist/src/{drivers/electron/native → electron}/adblock/preload.js +0 -0
  370. /package/dist/src/{drivers/electron/native → electron}/adblock/settings.d.ts +0 -0
  371. /package/dist/src/{drivers/electron/native → electron}/adblock/settings.js +0 -0
  372. /package/dist/src/{drivers/electron/native → electron}/policy.d.ts +0 -0
  373. /package/dist/src/{drivers/electron/native → electron}/policy.js +0 -0
  374. /package/dist/src/{drivers/electron/native → electron}/shell/adblock-ipc.d.ts +0 -0
  375. /package/dist/src/{drivers/electron/native → electron}/shell/adblock-ipc.js +0 -0
  376. /package/dist/src/{drivers/electron/native → electron}/shell/context-menu.d.ts +0 -0
  377. /package/dist/src/{drivers/electron/native → electron}/shell/context-menu.js +0 -0
  378. /package/dist/src/{drivers/electron/native → electron}/shell/downloads.d.ts +0 -0
  379. /package/dist/src/{drivers/electron/native → electron}/shell/downloads.js +0 -0
  380. /package/dist/src/{drivers/electron/native → electron}/shell/helpers.d.ts +0 -0
  381. /package/dist/src/{drivers/electron/native → electron}/shell/helpers.js +0 -0
  382. /package/dist/src/{drivers/electron/native → electron}/shell/permissions.d.ts +0 -0
  383. /package/dist/src/{drivers/electron/native → electron}/shell/permissions.js +0 -0
  384. /package/dist/src/{drivers/electron/native → electron}/shell/types.js +0 -0
  385. /package/dist/src/{drivers/electron/native → electron}/surface/commands.d.ts +0 -0
  386. /package/dist/src/{drivers/electron/native → electron}/surface/commands.js +0 -0
  387. /package/dist/src/{drivers/electron/native → electron}/surface/create.d.ts +0 -0
  388. /package/dist/src/{drivers/electron/native → electron}/surface/events.d.ts +0 -0
  389. /package/dist/src/{drivers/electron/native → electron}/surface/types.js +0 -0
  390. /package/dist/src/{drivers/electron/native → electron}/surface-controller.d.ts +0 -0
@@ -2,68 +2,76 @@
2
2
 
3
3
  ## State layout
4
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.
5
+ The root is chosen by the `@amalgm/core` product state-dir law:
6
+ `AMALGM_BROWSER_DIR` (or `AMALGM_BROWSER_ROOT`), then `$AMALGM_DIR/browser`,
7
+ then `~/.amalgm/users/<scope>/browser`. It contains:
11
8
 
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.
9
+ | Path | Contents |
10
+ | --- | --- |
11
+ | `chrome/` | Chrome's user data directory |
12
+ | `chrome.lease.sqlite` | OS-held exclusive lease for the process running Chrome |
13
+ | `cookie-adapter.json` | private native-adapter capability published by the host |
14
+ | `browser.db` (+ WAL files) | sessions, auth-bundle metadata, login sessions |
15
+ | `cookie-jar.sqlite` (+ WAL files) | the account's encrypted cookie records and tombstones |
16
+ | `cookie-observer/` | SDK-generated private Chrome cookie extension |
17
+ | `browser.key` | the local encryption key |
18
+ | `auth-bundles/` | encrypted auth-bundle payloads |
19
+ | `login-secrets.enc` | hashed login tokens |
20
+ | `screenshots/`, `temporary/` | agent-browser output and short-lived state files |
21
+ | `.amalgm/recordings/` | recordings when no artifact destination is given |
22
+
23
+ Directories are private and secret files are mode `0600` where the platform
24
+ supports POSIX permissions. Do not put the root inside a source repository.
25
+ Do not copy a live SQLite database without its committed WAL state; stop the
26
+ runtime or use a SQLite-safe snapshot for both `browser.db` and `cookie-jar.sqlite`.
14
27
 
15
28
  ## Environment
16
29
 
17
30
  | Variable | Purpose |
18
31
  | --- | --- |
19
- | `AMALGM_BROWSER_DIR` | standalone state root (`AMALGM_BROWSER_ROOT` legacy alias) |
32
+ | `AMALGM_BROWSER_DIR` | state root (`AMALGM_BROWSER_ROOT` also accepted) |
20
33
  | `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 |
34
+ | `AMALGM_BROWSER_EXECUTABLE_PATH` | Chrome executable (`AGENT_BROWSER_EXECUTABLE_PATH` also accepted) |
25
35
  | `AMALGM_AGENT_BROWSER_BIN` | agent-browser executable |
26
- | `AMALGM_BROWSER_PROVIDER` | external agent-browser provider |
27
36
  | `AMALGM_FFMPEG` | ffmpeg executable |
28
37
  | `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 |
38
+ | `AMALGM_BROWSER_ADAPTER_TOKEN` | internal cookie-route token |
39
+ | `AMALGM_BROWSER_HOST`, `AMALGM_BROWSER_PORT` | `amalgm-browser-rest` listen address |
40
+ | `AMALGM_BROWSER_ALLOW_REMOTE=1` | `amalgm-browser-rest` remote bind opt-in |
41
+ | `AMALGM_BROWSER_ADBLOCK=0` | Electron ad-block kill switch |
39
42
  | `AMALGM_BROWSER_AUTH_KEY` | legacy-import key override only |
40
- | `AMALGM_BROWSER_DEBUG=1` | sanitized debug logging |
43
+ | `AMALGM_BROWSER_DEBUG` | sanitized debug logging |
41
44
 
42
45
  ## Process model
43
46
 
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.
47
+ One process runs a root's Chrome. It holds an exclusive SQLite lease, and
48
+ another process gets `CONFLICT` when it needs Chrome on the same root.
49
+ The OS releases the lease on process death; never remove its file. Recovery
50
+ retires an orphan only through the exact endpoint in `chrome/DevToolsActivePort`.
51
+ Run one long-lived runtime (`mcp`, `serve`, or an embedding host) for
52
+ sustained work. If Chrome dies, the next action starts a new one.
53
+
54
+ Processes may still share the SQLite metadata: entity writes never replace the
55
+ whole registry, and cross-process leases stop two processes from acting on,
56
+ closing, or creating the same session at once.
49
57
 
50
58
  ## Health and observability
51
59
 
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.
60
+ Use `GET /v1/health` for process health, `doctor` for basic CLI diagnostics,
61
+ resource listings for durable state, and SSE for sanitized transitions. Set
62
+ `AMALGM_BROWSER_DEBUG` for sanitized debug logs. Never log request bodies for
63
+ auth or internal cookie routes.
56
64
 
57
65
  ## Retention
58
66
 
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.
67
+ `sessions prune` (default 24 hours) deletes closed and failed sessions that
68
+ have not changed within the age limit. Artifacts are sensitive; the injected
69
+ artifact store or host owns their retention and access control. Browser does
70
+ not delete finished recordings.
63
71
 
64
72
  ## Remote REST
65
73
 
66
74
  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
75
+ strong bearer token; put TLS and network access control in front of the
76
+ server. Keep the internal cookie routes private even when ordinary REST is
69
77
  remote.
package/docs/README.md CHANGED
@@ -6,7 +6,7 @@ your integration:
6
6
  - [Architecture](./ARCHITECTURE.md) and [axiom map](./AXIOMS.md)
7
7
  - [SDK](./SDK.md), [actions](./ACTIONS.md), [CLI](./CLI.md),
8
8
  [MCP](./MCP.md), and [REST](./REST.md)
9
- - [Headless runtime](./HEADLESS_RUNTIME.md) and
9
+ - [Chrome runtime](./CHROME.md) and
10
10
  [Electron integration](./ELECTRON_INTEGRATION.md)
11
11
  - [Cookies](./COOKIES.md), [authentication](./AUTHENTICATION.md), and
12
12
  [recording](./RECORDING.md)
@@ -17,7 +17,7 @@ your integration:
17
17
  - [Operations](./OPERATIONS.md), [testing](./TESTING.md), and
18
18
  [troubleshooting](./TROUBLESHOOTING.md)
19
19
 
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.
20
+ The core package is ESM-only and requires Node.js 24+. The
21
+ `@amalgm/browser/electron` entry point also provides a generated CommonJS
22
+ condition for Electron main processes; no internal implementation module is
23
+ public.
@@ -1,9 +1,9 @@
1
1
  # Realtime boundary
2
2
 
3
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.
4
+ directory, and general application-state synchronization. Browser owns the
5
+ runtime's Chrome, browser sessions, the account's cookie jar, auth resources,
6
+ recordings, and Browser events.
7
7
 
8
8
  Browser receives opaque project/cwd/artifact values through
9
9
  `BrowserRuntimeContext` or an injected `BrowserArtifactStore`. It never imports
package/docs/RECORDING.md CHANGED
@@ -18,27 +18,27 @@ const stopped = await browser.recordings.stop(session.id);
18
18
  - one active recording per session
19
19
  - FPS clamped to 1–30
20
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
21
+ - the session's own page, found as for screenshots; an ambiguous page fails
22
+ with `SURFACE_IDENTITY_FAILED`
23
+ - a first page frame required within five seconds, before the encoder starts
23
24
  - one latest-frame slot separates paint frequency from encoding cadence
24
25
  - static pages receive honest wall-clock duration
25
26
  - animation floods do not create an unbounded queue
26
27
  - source stop, encoder flush, and forced termination are bounded
27
28
  - zero-frame or failed artifacts are removed
28
29
 
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.
30
+ A stopped recording reports `wallSeconds`, `videoSeconds`, `frames`
31
+ (encoded), `framesReceived`, `skippedTicks`, an optional `warning`, and the
32
+ artifact's metadata (`id`, `kind`, `path`, `mimeType`, `bytes`, `createdAt`).
33
+ These fields are deliberately distinct; there is no ambiguous generic
34
+ duration. The video is VP9 WebM.
32
35
 
33
36
  ## Artifacts
34
37
 
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`.
38
+ An embedding host may inject its own `artifactStore`. The default local store
39
+ writes to `context.artifactDestination` when given, otherwise to the Browser
40
+ root, at `<destination>/.amalgm/recordings/<name>-<timestamp>.webm`. The name
41
+ defaults to the session ID.
42
42
  Browser does not maintain a current-project registry. Artifacts are sensitive
43
43
  user data and the embedding store owns access control and retention.
44
44
 
@@ -50,6 +50,7 @@ row failed, while a live foreign owner remains visible and returns a conflict
50
50
  to stop/force-stop. `forceStop(sessionId)` aborts a locally owned encoder and
51
51
  marks it failed; a service never claims it controlled another process.
52
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.
53
+ `browser.close()` stops this process's recordings and keeps what was captured.
54
+
55
+ Unit contracts cover static pages, frame floods, backpressure, capture
56
+ viability, missing ffmpeg, cancellation, and dead-owner recovery.
package/docs/REST.md CHANGED
@@ -7,34 +7,52 @@ amalgm-browser serve --token replace-me
7
7
  AMALGM_BROWSER_TOKEN=replace-me amalgm-browser-rest
8
8
  ```
9
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>`.
10
+ The server binds loopback by default. Remote binding requires `allowRemote`
11
+ in the SDK, `--allow-remote` in the CLI, or `AMALGM_BROWSER_ALLOW_REMOTE=1`
12
+ for `amalgm-browser-rest`, which also reads `AMALGM_BROWSER_HOST` and
13
+ `AMALGM_BROWSER_PORT`. Every route except `GET /v1/health` requires the
14
+ token, sent as `Authorization: Bearer <token>`, as `X-Amalgm-Runtime-Token`,
15
+ or, for WebSocket clients that cannot set headers, as the subprotocol
16
+ `amalgm-runtime-token.<token>`. A missing or wrong token gets `401`.
14
17
 
15
- ## Discovery and streaming
18
+ ## Discovery and events
16
19
 
17
20
  - `GET /v1/health`
18
21
  - `GET /v1/openapi.json`
19
- - `GET /v1/capabilities`
20
22
  - `GET /v1/events` (SSE; supports `Last-Event-ID`)
21
23
 
22
24
  ## Sessions and actions
23
25
 
24
- - `GET|POST /v1/sessions`
25
- - `POST /v1/sessions/prune`
26
+ - `GET|POST /v1/sessions` (`POST` takes an optional `id`)
27
+ - `POST /v1/sessions/prune` (optional `maxAgeMs`)
26
28
  - `GET|DELETE /v1/sessions/:sessionId`
27
29
  - `POST /v1/sessions/:sessionId/cancel`
28
30
  - `POST /v1/sessions/:sessionId/actions/:action`
31
+ - `GET /v1/sessions/:sessionId/stream` (WebSocket)
29
32
 
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
+ Each of the 22 actions has an action route generated from the shared
34
+ descriptor; the path's session ID is the action's session.
33
35
 
34
- ## Profiles, auth, and recording
36
+ The stream route upgrades to a WebSocket that relays the session's live view,
37
+ in agent-browser's stream format:
38
+
39
+ - out: `status`, `tabs` (only this session's tabs), and `frame` (a base64
40
+ JPEG plus metadata);
41
+ - in: `input_mouse`, `input_keyboard`, and `input_touch`.
42
+
43
+ Messages pass through unchanged. Send keyboard input as a full key event, not
44
+ just `key` and `code`:
45
+
46
+ ```json
47
+ {"type":"input_keyboard","eventType":"keyDown","key":"Enter","code":"Enter","text":"\r","windowsVirtualKeyCode":13,"modifiers":0}
48
+ ```
49
+
50
+ A browser cannot read a refused handshake, so a missing or wrong token
51
+ completes the handshake and then closes with code `4401`. A missing session or
52
+ a failed upstream closes with `1011` and the reason `<CODE>: <message>`.
53
+
54
+ ## Auth and recording
35
55
 
36
- - `GET|POST /v1/profiles`; `POST /v1/profiles/prune`
37
- - `GET|PATCH|DELETE /v1/profiles/:profileId`
38
56
  - `GET|POST /v1/auth/bundles`
39
57
  - `POST /v1/auth/bundles/import`
40
58
  - `GET|DELETE /v1/auth/bundles/:bundleId`
@@ -46,24 +64,37 @@ operations.
46
64
  - `GET /v1/recordings/:recordingId`
47
65
  - `POST /v1/recordings/:recordingId/stop|cancel`
48
66
 
49
- The generated OpenAPI document is the route inventory and excludes internal
50
- raw-cookie schemas.
51
-
52
- ## Internal cookie transport
67
+ ## Internal cookie routes
53
68
 
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.
69
+ `/internal/v1/cookies/metadata|bootstrap` (`GET`),
70
+ `/internal/v1/cookies/delta?after=<version>` (`GET`),
71
+ `/internal/v1/cookies/changes` (value-free SSE), and
72
+ `/internal/v1/cookies/install|merge` (`POST`) serve trusted cookie adapters
73
+ in other processes. They require the runtime token and a matching
74
+ `X-Browser-Adapter-Token`, and answer `401` unless the server was given an
75
+ adapter token (`AMALGM_BROWSER_ADAPTER_TOKEN` for the CLI). They are not in
76
+ the OpenAPI document. Never expose them through an untrusted reverse proxy.
58
77
 
59
78
  ## Limits and errors
60
79
 
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:
80
+ Defaults are a 512 KB request body (larger bodies are `INVALID_INPUT`), 2 MB
81
+ JSON output, and a 120-second request deadline. Client disconnect aborts
82
+ unfinished work. Every JSON response sends `Cache-Control: no-store`. Typed
83
+ errors use:
63
84
 
64
85
  ```json
65
86
  {"error":{"code":"INVALID_INPUT","message":"sanitized explanation"}}
66
87
  ```
67
88
 
68
- SSE emits only versioned sanitized Browser events, sends heartbeats, resumes
69
- from retained history, and removes listeners on disconnect.
89
+ Status codes: `400` invalid input, `403` authorization denied, `404` not
90
+ found, `409` conflict, `413` output too large (`OUTPUT_TOO_LARGE`), `504`
91
+ timeout, `500` anything else. The token check's `401` has its own body:
92
+ `{"error":"Missing or invalid Amalgm runtime token"}`.
93
+
94
+ Closing the HTTP adapter cancels and drains its admitted requests and closes
95
+ its SSE and live-view connections. The embedding host separately owns closing
96
+ the Browser service.
97
+
98
+ SSE sends only versioned sanitized events, replays retained history after
99
+ `Last-Event-ID`, sends a heartbeat every 15 seconds, and removes its listener
100
+ on disconnect.
package/docs/SDK.md CHANGED
@@ -4,63 +4,75 @@ The package is ESM-only and supports Node.js 24 or newer.
4
4
 
5
5
  ```ts
6
6
  import { createBrowser, BrowserError } from '@amalgm/browser';
7
+
8
+ const browser = createBrowser({ root, account: { id: user.id, name: user.name } });
7
9
  ```
8
10
 
9
- `createBrowser(options)` returns `BrowserProductService`. Defaults include a
10
- SQLite registry, local artifact store, encrypted cookie/auth files, headless
11
- driver, event bus, system clock, safe logger, and runtime selector. Injected
12
- ports can replace registry, drivers, selector, event sink, clock, ID generator,
13
- logger, authorization, profile directories, artifact store, process launcher,
14
- cookie jar/coordinator, auth vault, login secret store, and ffmpeg. Native
15
- ad-block construction separately accepts an injected fetch implementation.
11
+ `createBrowser(options)` returns the browser service (`BrowserService`). Every
12
+ option is optional:
13
+
14
+ - `root`: state root (see [operations](./OPERATIONS.md))
15
+ - `account`: who every session browses as; default `{ id: 'local', name: 'Local' }`
16
+ - `legacyDatabaseFile`: legacy import source, or `false` (see
17
+ [migration](./MIGRATION.md))
18
+ - injected ports: `registry`, `driver`, `eventSink`, `clock`, `logger`,
19
+ `authorization`, `id`, `artifactStore`, `processLauncher`, `cookieJar`,
20
+ `authVault`, `loginSecrets`, and `ffmpegBinary`
21
+
22
+ By default Browser uses a SQLite registry, the runtime's Chrome driver, an
23
+ event bus, a local artifact store, encrypted cookie rows and auth files under
24
+ the root. Chrome starts on the first action. [`examples/basic.ts`](../examples/basic.ts)
25
+ opens a page, snapshots it, and closes.
26
+
27
+ ## Account
28
+
29
+ `browser.account` is the account record. There is one browsing identity per
30
+ root: sessions, auth bundles, and logins all belong to it, and a different
31
+ `account` on an existing root takes them over.
16
32
 
17
33
  ## Sessions and actions
18
34
 
19
- - `createSession({ id?, profileId?, profileKind?, context? })`
35
+ - `createSession({ id?, context? })`: creates the session, or reopens an
36
+ existing ready one; after a restart, call it before `execute` (the adapters
37
+ do this on every call). `context.ownerId` is stored as the session's owner.
20
38
  - `getSession(id)` / `listSessions()`
21
- - `execute(sessionId, BrowserAction, context?)`
39
+ - `execute(sessionId, BrowserAction, context?)`: one action at a time per
40
+ session
41
+ - `streamUrl(sessionId, context?)`: loopback WebSocket URL for the session's
42
+ live view
22
43
  - `cancel(sessionId)`
23
- - `closeSession(sessionId, context?)`
24
- - `pruneSessions(maxAgeMs?)`
44
+ - `closeSession(sessionId, context?)`: closes the session's tabs
45
+ - `pruneSessions(maxAgeMs?)`: deletes old closed and failed sessions
46
+ - `close()`: stops recordings, detaches every session, syncs cookies, stops
47
+ Chrome, and closes the registry
25
48
 
26
49
  `BrowserAction` is a discriminated union for `open`, `snapshot`, `screenshot`,
27
50
  `click`, `fill`, `press`, `select`, `eval`, `wait`, `cli`, `dialog`, `tab`,
28
51
  `console`, `cua`, and `close`. See [ACTIONS.md](./ACTIONS.md). Blocking calls
29
- take `context.signal`; cancellation propagates to the driver, CDP, encoder, or
30
- child process.
31
-
32
- ## Profiles
33
-
34
- - `createProfile({ id?, name, kind? })`
35
- - `listProfiles()` / `getProfile(id)` / `inspectProfile(id)`
36
- - `updateProfile(id, { name?, kind? })`
37
- - `deleteProfile(id)` / `pruneProfiles(maxAgeMs?)`
38
-
39
- Inspection returns `live`, `referenced`, and physical `locked` status. Delete
40
- and prune refuse live, referenced, or Chromium-locked profiles.
52
+ take `context.signal`; cancellation reaches the driver, CDP, encoder, or child
53
+ process.
41
54
 
42
55
  ## Authentication and login
43
56
 
44
57
  - `browser.auth.list()` / `get(id)` / `delete(id)`
45
- - `browser.auth.save({ sessionId, name, domains?, context? })`
58
+ - `browser.auth.save({ sessionId, name, id?, domains?, context? })`
46
59
  - `browser.auth.load({ sessionId, bundleId, context? })`
47
60
  - `browser.auth.exportEncrypted(id, portableKey, context?)`
48
61
  - `browser.auth.importEncrypted(resource, portableKey, context?)`
49
- - `browser.login.create(...)` / `list()` / `get(id)`
62
+ - `browser.login.create({ targetUrl, domains?, ttlMs?, transport?, liveUrl?, context? })`
63
+ - `browser.login.list()` / `get(id)`
50
64
  - `browser.login.activate(id, token, context?)`
51
65
  - `browser.login.input(id, token, cuaOperation, context?)`
52
- - `browser.login.complete(...)` / `cancel(id, token)`
66
+ - `browser.login.complete({ id, token, bundleName?, context? })` /
67
+ `cancel(id, token)`
53
68
 
54
- The token and token-bearing URL exist only in the one-time login creation
55
- result. Stored login resources contain a hash and ordinary list/get projections
56
- never return the credential.
69
+ The token and handoff URL appear only in the login creation result. See
70
+ [authentication](./AUTHENTICATION.md).
57
71
 
58
72
  ## Cookies
59
73
 
60
- `browser.cookies` is the encrypted jar. `browser.cookieAdapters` registers and
61
- reconciles trusted physical-store adapters. This is an embedding API, not an
62
- ordinary automation API; raw cookie values must not be projected to users.
63
- See [COOKIES.md](./COOKIES.md).
74
+ `browser.cookies` is the account's encrypted cookie jar. It is an embedding
75
+ API; never show raw cookie values to users. See [COOKIES.md](./COOKIES.md).
64
76
 
65
77
  ## Recordings
66
78
 
@@ -68,34 +80,32 @@ See [COOKIES.md](./COOKIES.md).
68
80
  - `stop(sessionId)` / `forceStop(sessionId)`
69
81
  - `list()` / `get(recordingId)` / `activeRecordings()`
70
82
 
71
- FPS is clamped to 1–30. Artifact placement uses `context.artifactDestination`
72
- before the standalone fallback.
83
+ See [RECORDING.md](./RECORDING.md).
73
84
 
74
85
  ## Runtime context
75
86
 
76
87
  `BrowserRuntimeContext` accepts opaque `ownerId`, `callerId`, `clientKind`,
77
- `projectRef`, `cwdRef`, `artifactDestination`, authorization context, and
78
- `AbortSignal`. Browser does not discover these from Chat or a workspace
79
- registry.
88
+ `projectRef`, `cwdRef`, `artifactDestination`, `authorization`, and `signal`.
89
+ Browser does not discover these from Chat or a workspace registry. An
90
+ injected `authorization` port is asked before `sessions.create`,
91
+ `sessions.close`, `sessions.stream`, `actions.<type>`, `auth.export`, and
92
+ `auth.import`.
80
93
 
81
- ## Errors and capabilities
94
+ ## Errors
82
95
 
83
- Failures are `BrowserError` values with stable codes such as `INVALID_INPUT`,
84
- `NOT_FOUND`, `CONFLICT`, `CAPABILITY_UNSUPPORTED`, `AUTHORIZATION_DENIED`,
85
- `TIMEOUT`, `ABORTED`, `PROCESS_FAILED`, and `SURFACE_IDENTITY_MISMATCH`.
86
- Inspect `session.capabilities` before optional behavior. Unsupported behavior
87
- fails explicitly; it is not silently approximated.
96
+ Failures are `BrowserError` values with one of these codes: `ABORTED`,
97
+ `AUTHORIZATION_DENIED`, `CONFLICT`, `INVALID_INPUT`, `NOT_FOUND`,
98
+ `PROCESS_FAILED`, `SURFACE_IDENTITY_FAILED`, `TIMEOUT`.
88
99
 
89
100
  ## Entry points
90
101
 
91
- - `@amalgm/browser` — service, ports, types, persistence, migration
92
- - `@amalgm/browser/headless` — headless driver and executable resolution
93
- - `@amalgm/browser/electron` — Electron-only host and native shell
94
- - `@amalgm/browser/cookies` — trusted cookie integration
95
- - `@amalgm/browser/recording` — recording components
96
- - `@amalgm/browser/toolbox`, `/mcp`, `/http` — adapters
97
- - `@amalgm/browser/testing` — deterministic test driver
98
-
99
- The [custom driver example](../examples/custom-driver.ts) implements the small
100
- `BrowserDriver` contract for a remote provider. A provider must advertise only
101
- capabilities it implements and must honor the runtime cancellation signal.
102
+ - `@amalgm/browser`: service, ports, types, persistence, migration
103
+ - `@amalgm/browser/electron`: the desktop app's in-app browser
104
+ - `@amalgm/browser/cookies`: cookie jar, coordinator, and policy
105
+ - `@amalgm/browser/recording`: recording components
106
+ - `@amalgm/browser/toolbox`, `/mcp`, `/http`: adapters
107
+ - `@amalgm/browser/testing`: `TestBrowserDriver` and `MemoryBrowserRegistry`
108
+
109
+ A custom `driver` implements the `BrowserDriver` port (`open`, `execute`,
110
+ `close`, `saveState`, `loadState`, `startScreencast`, `streamUrl`, `dispose`)
111
+ and must honor the runtime cancellation signal.
@@ -1,54 +1,96 @@
1
1
  # Shell integration
2
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.
3
+ Amalgm Shell consumes `@amalgm/browser`; Browser never imports Shell. One Shell
4
+ runtime creates exactly one Browser service, mounts its adapters, and closes
5
+ it on shutdown. It never creates another registry, cookie jar, or session
6
+ authority.
6
7
 
7
- ## Composition boundary
8
+ This composition is active only in a signed machine service plan that
9
+ declares Browser. Installing the SDK alone must not create Browser databases
10
+ or state.
8
11
 
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.
12
+ ## Create the service
14
13
 
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.
14
+ Shell creates the service lazily, as the signed-in Amalgm account:
18
15
 
19
16
  ```ts
20
17
  import { createBrowser } from '@amalgm/browser';
21
- import { ElectronBrowserDriver } from '@amalgm/browser/electron';
22
18
 
23
19
  const browser = createBrowser({
24
- root: shellBrowserRoot,
25
- electronDriver: visibleHost
26
- ? new ElectronBrowserDriver(visibleHost)
27
- : undefined,
28
- eventSink: browserEventRelay,
29
- authorization: shellBrowserAuthorization,
20
+ root: runtimeBrowserRoot,
21
+ account: { id: userId, name: userEmail },
22
+ eventSink: browserEventRelay, // optional
23
+ authorization: shellBrowserAuthorization, // optional
30
24
  });
31
25
  ```
32
26
 
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.
27
+ `account` is who every session browses as. Without it the runtime browses as
28
+ `{ id: 'local', name: 'Local' }`. On an existing root, a different account
29
+ takes over every session, auth bundle, and login, along with the root's
30
+ cookie jar, so give each account its own root. Chrome is not started until
31
+ the first action.
32
+
33
+ ## Map chats to sessions
34
+
35
+ Mount the MCP adapter at `/mcp/browser` and pass the calling chat, from the
36
+ chat relay's `x-amalgm-session-id` header, as both `callerId` and `ownerId`:
37
+
38
+ ```ts
39
+ import { createBrowserMcpServer } from '@amalgm/browser/mcp';
40
+
41
+ const mcp = createBrowserMcpServer(browser);
42
+
43
+ async function onMcpMessage(message, headers) {
44
+ const chat = headers['x-amalgm-session-id'];
45
+ return mcp.handle(message, typeof chat === 'string' ? { callerId: chat, ownerId: chat } : {});
46
+ }
47
+ ```
48
+
49
+ A tool call without a `session` argument then runs in the session named after
50
+ the chat, and any session the call creates is owned by that chat. Each chat
51
+ gets its own tabs while all chats share the account's sign-ins. `handle`
52
+ returns the JSON-RPC result or throws; Shell writes the JSON-RPC response.
53
+ `notifications/cancelled` aborts the matching call.
54
+
55
+ ## REST and live view
56
+
57
+ Shell serves `/browser/*` HTTP requests and WebSocket upgrades by handing them
58
+ in-process to the REST adapter's `server` (from `createBrowserHttpServer`),
59
+ which never listens on a port. It reroots the path onto `/v1/*`. After Shell's
60
+ gateway admits a request, Shell stamps the REST adapter's own random token as
61
+ the `x-amalgm-runtime-token` header. The internal cookie routes are not exposed
62
+ through Shell.
63
+
64
+ A viewer opens `/browser/sessions/<id>/stream` to watch and drive one
65
+ session's live view (see [REST](./REST.md)). In process,
66
+ `browser.streamUrl(sessionId)` returns the same stream's loopback WebSocket
67
+ URL.
68
+
69
+ ## Shutdown
70
+
71
+ ```ts
72
+ await browser.close();
73
+ ```
37
74
 
38
- ## Electron boundary
75
+ `close` stops active recordings, detaches every session, syncs cookies one
76
+ last time, stops Chrome, and closes the registry; Shell does not close the
77
+ database itself. Sessions stay in the registry and reopen when next used after
78
+ the runtime restarts. While the runtime runs, it owns the root's Chrome; a
79
+ second process on the same root gets `CONFLICT` when it tries to start Chrome.
39
80
 
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`.
81
+ ## Electron
44
82
 
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.
83
+ Electron owns the application lifecycle and hosts the user's in-app browser
84
+ tabs through `@amalgm/browser/electron` (see
85
+ [Electron integration](./ELECTRON_INTEGRATION.md)). Application auth stays in
86
+ Electron's `defaultSession`; websites stay in the account-specific
87
+ `persist:amalgm-browser-<account hash>` partition. Its cookies sync with the
88
+ runtime through Browser's private adapter port. Managed UI and Shell bind to
89
+ the same exact published Browser release.
48
90
 
49
- ## Historical cutover rule
91
+ ## Legacy import
50
92
 
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.
93
+ Legacy Engine data may be imported once through `legacyDatabaseFile` (see
94
+ [migration](./MIGRATION.md)). The importer never writes to the legacy
95
+ database. Legacy and current writers must never run against the same Browser
96
+ state.