@ulpi/browse 2.3.3 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (279) hide show
  1. package/README.md +8 -2
  2. package/dist/browse.cjs +3445 -1636
  3. package/dist/lib.mjs +29504 -0
  4. package/dist/types/a11y.d.ts +32 -0
  5. package/dist/types/a11y.d.ts.map +1 -0
  6. package/dist/types/app/android/bridge.d.ts +41 -0
  7. package/dist/types/app/android/bridge.d.ts.map +1 -0
  8. package/dist/types/app/android/emulator.d.ts +32 -0
  9. package/dist/types/app/android/emulator.d.ts.map +1 -0
  10. package/dist/types/app/android/manager.d.ts +62 -0
  11. package/dist/types/app/android/manager.d.ts.map +1 -0
  12. package/dist/types/app/android/protocol.d.ts +162 -0
  13. package/dist/types/app/android/protocol.d.ts.map +1 -0
  14. package/dist/types/app/android/sim-service.d.ts +33 -0
  15. package/dist/types/app/android/sim-service.d.ts.map +1 -0
  16. package/dist/types/app/index.d.ts +15 -0
  17. package/dist/types/app/index.d.ts.map +1 -0
  18. package/dist/types/app/ios/bridge.d.ts +53 -0
  19. package/dist/types/app/ios/bridge.d.ts.map +1 -0
  20. package/dist/types/app/ios/controller.d.ts +131 -0
  21. package/dist/types/app/ios/controller.d.ts.map +1 -0
  22. package/dist/types/app/ios/manager.d.ts +96 -0
  23. package/dist/types/app/ios/manager.d.ts.map +1 -0
  24. package/dist/types/app/ios/protocol.d.ts +122 -0
  25. package/dist/types/app/ios/protocol.d.ts.map +1 -0
  26. package/dist/types/app/ios/sim-service.d.ts +37 -0
  27. package/dist/types/app/ios/sim-service.d.ts.map +1 -0
  28. package/dist/types/app/macos/bridge.d.ts +22 -0
  29. package/dist/types/app/macos/bridge.d.ts.map +1 -0
  30. package/dist/types/app/manager.d.ts +50 -0
  31. package/dist/types/app/manager.d.ts.map +1 -0
  32. package/dist/types/app/normalize.d.ts +27 -0
  33. package/dist/types/app/normalize.d.ts.map +1 -0
  34. package/dist/types/app/resolve-app.d.ts +31 -0
  35. package/dist/types/app/resolve-app.d.ts.map +1 -0
  36. package/dist/types/app/types.d.ts +77 -0
  37. package/dist/types/app/types.d.ts.map +1 -0
  38. package/dist/types/automation/action-context.d.ts +110 -0
  39. package/dist/types/automation/action-context.d.ts.map +1 -0
  40. package/dist/types/automation/command.d.ts +138 -0
  41. package/dist/types/automation/command.d.ts.map +1 -0
  42. package/dist/types/automation/events.d.ts +72 -0
  43. package/dist/types/automation/events.d.ts.map +1 -0
  44. package/dist/types/automation/executor.d.ts +39 -0
  45. package/dist/types/automation/executor.d.ts.map +1 -0
  46. package/dist/types/automation/index.d.ts +11 -0
  47. package/dist/types/automation/index.d.ts.map +1 -0
  48. package/dist/types/automation/registry.d.ts +38 -0
  49. package/dist/types/automation/registry.d.ts.map +1 -0
  50. package/dist/types/automation/rules.d.ts +52 -0
  51. package/dist/types/automation/rules.d.ts.map +1 -0
  52. package/dist/types/automation/target.d.ts +76 -0
  53. package/dist/types/automation/target.d.ts.map +1 -0
  54. package/dist/types/browser/consent.d.ts +13 -0
  55. package/dist/types/browser/consent.d.ts.map +1 -0
  56. package/dist/types/browser/cookie-import.d.ts +94 -0
  57. package/dist/types/browser/cookie-import.d.ts.map +1 -0
  58. package/dist/types/browser/detection.d.ts +22 -0
  59. package/dist/types/browser/detection.d.ts.map +1 -0
  60. package/dist/types/browser/emulation.d.ts +30 -0
  61. package/dist/types/browser/emulation.d.ts.map +1 -0
  62. package/dist/types/browser/events.d.ts +19 -0
  63. package/dist/types/browser/events.d.ts.map +1 -0
  64. package/dist/types/browser/index.d.ts +17 -0
  65. package/dist/types/browser/index.d.ts.map +1 -0
  66. package/dist/types/browser/macros.d.ts +9 -0
  67. package/dist/types/browser/macros.d.ts.map +1 -0
  68. package/dist/types/browser/manager.d.ts +272 -0
  69. package/dist/types/browser/manager.d.ts.map +1 -0
  70. package/dist/types/browser/png-compare.d.ts +36 -0
  71. package/dist/types/browser/png-compare.d.ts.map +1 -0
  72. package/dist/types/browser/profiles.d.ts +29 -0
  73. package/dist/types/browser/profiles.d.ts.map +1 -0
  74. package/dist/types/browser/react-devtools.d.ts +75 -0
  75. package/dist/types/browser/react-devtools.d.ts.map +1 -0
  76. package/dist/types/browser/readiness.d.ts +19 -0
  77. package/dist/types/browser/readiness.d.ts.map +1 -0
  78. package/dist/types/browser/refs.d.ts +70 -0
  79. package/dist/types/browser/refs.d.ts.map +1 -0
  80. package/dist/types/browser/serp.d.ts +16 -0
  81. package/dist/types/browser/serp.d.ts.map +1 -0
  82. package/dist/types/browser/snapshot-window.d.ts +31 -0
  83. package/dist/types/browser/snapshot-window.d.ts.map +1 -0
  84. package/dist/types/browser/snapshot.d.ts +41 -0
  85. package/dist/types/browser/snapshot.d.ts.map +1 -0
  86. package/dist/types/browser/tabs.d.ts +67 -0
  87. package/dist/types/browser/tabs.d.ts.map +1 -0
  88. package/dist/types/browser/target.d.ts +106 -0
  89. package/dist/types/browser/target.d.ts.map +1 -0
  90. package/dist/types/browser/youtube.d.ts +26 -0
  91. package/dist/types/browser/youtube.d.ts.map +1 -0
  92. package/dist/types/cli.d.ts +14 -0
  93. package/dist/types/cli.d.ts.map +1 -0
  94. package/dist/types/cloud/auth.d.ts +80 -0
  95. package/dist/types/cloud/auth.d.ts.map +1 -0
  96. package/dist/types/cloud/docker.d.ts +76 -0
  97. package/dist/types/cloud/docker.d.ts.map +1 -0
  98. package/dist/types/cloud/firecracker.d.ts +142 -0
  99. package/dist/types/cloud/firecracker.d.ts.map +1 -0
  100. package/dist/types/cloud/golden-snapshot.d.ts +122 -0
  101. package/dist/types/cloud/golden-snapshot.d.ts.map +1 -0
  102. package/dist/types/cloud/index.d.ts +26 -0
  103. package/dist/types/cloud/index.d.ts.map +1 -0
  104. package/dist/types/cloud/orchestrator-interface.d.ts +63 -0
  105. package/dist/types/cloud/orchestrator-interface.d.ts.map +1 -0
  106. package/dist/types/cloud/orchestrator.d.ts +58 -0
  107. package/dist/types/cloud/orchestrator.d.ts.map +1 -0
  108. package/dist/types/cloud/proxy.d.ts +34 -0
  109. package/dist/types/cloud/proxy.d.ts.map +1 -0
  110. package/dist/types/cloud/reaper.d.ts +49 -0
  111. package/dist/types/cloud/reaper.d.ts.map +1 -0
  112. package/dist/types/cloud/server.d.ts +19 -0
  113. package/dist/types/cloud/server.d.ts.map +1 -0
  114. package/dist/types/cloud/sessions.d.ts +85 -0
  115. package/dist/types/cloud/sessions.d.ts.map +1 -0
  116. package/dist/types/cloud/vm-orchestrator.d.ts +133 -0
  117. package/dist/types/cloud/vm-orchestrator.d.ts.map +1 -0
  118. package/dist/types/cloud/vm-warm-pool.d.ts +104 -0
  119. package/dist/types/cloud/vm-warm-pool.d.ts.map +1 -0
  120. package/dist/types/cloud/warm-pool.d.ts +85 -0
  121. package/dist/types/cloud/warm-pool.d.ts.map +1 -0
  122. package/dist/types/cloud/ws.d.ts +61 -0
  123. package/dist/types/cloud/ws.d.ts.map +1 -0
  124. package/dist/types/commands/meta/auth.d.ts +6 -0
  125. package/dist/types/commands/meta/auth.d.ts.map +1 -0
  126. package/dist/types/commands/meta/flows.d.ts +15 -0
  127. package/dist/types/commands/meta/flows.d.ts.map +1 -0
  128. package/dist/types/commands/meta/index.d.ts +14 -0
  129. package/dist/types/commands/meta/index.d.ts.map +1 -0
  130. package/dist/types/commands/meta/inspection.d.ts +7 -0
  131. package/dist/types/commands/meta/inspection.d.ts.map +1 -0
  132. package/dist/types/commands/meta/profile.d.ts +11 -0
  133. package/dist/types/commands/meta/profile.d.ts.map +1 -0
  134. package/dist/types/commands/meta/recording.d.ts +7 -0
  135. package/dist/types/commands/meta/recording.d.ts.map +1 -0
  136. package/dist/types/commands/meta/screenshots.d.ts +7 -0
  137. package/dist/types/commands/meta/screenshots.d.ts.map +1 -0
  138. package/dist/types/commands/meta/sessions.d.ts +7 -0
  139. package/dist/types/commands/meta/sessions.d.ts.map +1 -0
  140. package/dist/types/commands/meta/sim.d.ts +10 -0
  141. package/dist/types/commands/meta/sim.d.ts.map +1 -0
  142. package/dist/types/commands/meta/system.d.ts +8 -0
  143. package/dist/types/commands/meta/system.d.ts.map +1 -0
  144. package/dist/types/commands/meta/tabs.d.ts +6 -0
  145. package/dist/types/commands/meta/tabs.d.ts.map +1 -0
  146. package/dist/types/commands/meta/youtube.d.ts +7 -0
  147. package/dist/types/commands/meta/youtube.d.ts.map +1 -0
  148. package/dist/types/commands/read.d.ts +16 -0
  149. package/dist/types/commands/read.d.ts.map +1 -0
  150. package/dist/types/commands/write.d.ts +17 -0
  151. package/dist/types/commands/write.d.ts.map +1 -0
  152. package/dist/types/config.d.ts +101 -0
  153. package/dist/types/config.d.ts.map +1 -0
  154. package/dist/types/constants.d.ts +36 -0
  155. package/dist/types/constants.d.ts.map +1 -0
  156. package/dist/types/detection/frameworks.d.ts +27 -0
  157. package/dist/types/detection/frameworks.d.ts.map +1 -0
  158. package/dist/types/detection/index.d.ts +64 -0
  159. package/dist/types/detection/index.d.ts.map +1 -0
  160. package/dist/types/detection/infrastructure.d.ts +82 -0
  161. package/dist/types/detection/infrastructure.d.ts.map +1 -0
  162. package/dist/types/detection/saas.d.ts +39 -0
  163. package/dist/types/detection/saas.d.ts.map +1 -0
  164. package/dist/types/enable.d.ts +10 -0
  165. package/dist/types/enable.d.ts.map +1 -0
  166. package/dist/types/engine/chrome.d.ts +45 -0
  167. package/dist/types/engine/chrome.d.ts.map +1 -0
  168. package/dist/types/engine/index.d.ts +9 -0
  169. package/dist/types/engine/index.d.ts.map +1 -0
  170. package/dist/types/engine/providers.d.ts +36 -0
  171. package/dist/types/engine/providers.d.ts.map +1 -0
  172. package/dist/types/engine/resolver.d.ts +36 -0
  173. package/dist/types/engine/resolver.d.ts.map +1 -0
  174. package/dist/types/expect.d.ts +68 -0
  175. package/dist/types/expect.d.ts.map +1 -0
  176. package/dist/types/export/index.d.ts +8 -0
  177. package/dist/types/export/index.d.ts.map +1 -0
  178. package/dist/types/export/record.d.ts +28 -0
  179. package/dist/types/export/record.d.ts.map +1 -0
  180. package/dist/types/export/replay.d.ts +9 -0
  181. package/dist/types/export/replay.d.ts.map +1 -0
  182. package/dist/types/flow-parser.d.ts +32 -0
  183. package/dist/types/flow-parser.d.ts.map +1 -0
  184. package/dist/types/install-skill.d.ts +8 -0
  185. package/dist/types/install-skill.d.ts.map +1 -0
  186. package/dist/types/lib.d.ts +27 -0
  187. package/dist/types/lib.d.ts.map +1 -0
  188. package/dist/types/mcp/index.d.ts +10 -0
  189. package/dist/types/mcp/index.d.ts.map +1 -0
  190. package/dist/types/mcp/server.d.ts +9 -0
  191. package/dist/types/mcp/server.d.ts.map +1 -0
  192. package/dist/types/mcp/tools/index.d.ts +36 -0
  193. package/dist/types/mcp/tools/index.d.ts.map +1 -0
  194. package/dist/types/network/buffers.d.ts +53 -0
  195. package/dist/types/network/buffers.d.ts.map +1 -0
  196. package/dist/types/network/har.d.ts +10 -0
  197. package/dist/types/network/har.d.ts.map +1 -0
  198. package/dist/types/network/index.d.ts +6 -0
  199. package/dist/types/network/index.d.ts.map +1 -0
  200. package/dist/types/perf-audit/diff.d.ts +43 -0
  201. package/dist/types/perf-audit/diff.d.ts.map +1 -0
  202. package/dist/types/perf-audit/dom-analysis.d.ts +74 -0
  203. package/dist/types/perf-audit/dom-analysis.d.ts.map +1 -0
  204. package/dist/types/perf-audit/formatter.d.ts +34 -0
  205. package/dist/types/perf-audit/formatter.d.ts.map +1 -0
  206. package/dist/types/perf-audit/index.d.ts +128 -0
  207. package/dist/types/perf-audit/index.d.ts.map +1 -0
  208. package/dist/types/perf-audit/persist.d.ts +40 -0
  209. package/dist/types/perf-audit/persist.d.ts.map +1 -0
  210. package/dist/types/perf-audit/recommendations.d.ts +18 -0
  211. package/dist/types/perf-audit/recommendations.d.ts.map +1 -0
  212. package/dist/types/perf-audit/resource-analyzer.d.ts +46 -0
  213. package/dist/types/perf-audit/resource-analyzer.d.ts.map +1 -0
  214. package/dist/types/perf-audit/web-vitals.d.ts +73 -0
  215. package/dist/types/perf-audit/web-vitals.d.ts.map +1 -0
  216. package/dist/types/proxy/index.d.ts +6 -0
  217. package/dist/types/proxy/index.d.ts.map +1 -0
  218. package/dist/types/proxy/pool.d.ts +44 -0
  219. package/dist/types/proxy/pool.d.ts.map +1 -0
  220. package/dist/types/proxy/providers.d.ts +32 -0
  221. package/dist/types/proxy/providers.d.ts.map +1 -0
  222. package/dist/types/sdk/client.d.ts +37 -0
  223. package/dist/types/sdk/client.d.ts.map +1 -0
  224. package/dist/types/sdk/index.d.ts +17 -0
  225. package/dist/types/sdk/index.d.ts.map +1 -0
  226. package/dist/types/sdk/session.d.ts +95 -0
  227. package/dist/types/sdk/session.d.ts.map +1 -0
  228. package/dist/types/sdk/transports/cloud.d.ts +89 -0
  229. package/dist/types/sdk/transports/cloud.d.ts.map +1 -0
  230. package/dist/types/sdk/transports/index.d.ts +3 -0
  231. package/dist/types/sdk/transports/index.d.ts.map +1 -0
  232. package/dist/types/sdk/transports/local.d.ts +56 -0
  233. package/dist/types/sdk/transports/local.d.ts.map +1 -0
  234. package/dist/types/sdk.d.ts +35 -0
  235. package/dist/types/sdk.d.ts.map +1 -0
  236. package/dist/types/security/auth-vault.d.ts +32 -0
  237. package/dist/types/security/auth-vault.d.ts.map +1 -0
  238. package/dist/types/security/domain-filter.d.ts +31 -0
  239. package/dist/types/security/domain-filter.d.ts.map +1 -0
  240. package/dist/types/security/index.d.ts +10 -0
  241. package/dist/types/security/index.d.ts.map +1 -0
  242. package/dist/types/security/policy.d.ts +20 -0
  243. package/dist/types/security/policy.d.ts.map +1 -0
  244. package/dist/types/security/sanitize.d.ts +6 -0
  245. package/dist/types/security/sanitize.d.ts.map +1 -0
  246. package/dist/types/server.d.ts +13 -0
  247. package/dist/types/server.d.ts.map +1 -0
  248. package/dist/types/session/concurrency.d.ts +28 -0
  249. package/dist/types/session/concurrency.d.ts.map +1 -0
  250. package/dist/types/session/encryption.d.ts +8 -0
  251. package/dist/types/session/encryption.d.ts.map +1 -0
  252. package/dist/types/session/index.d.ts +7 -0
  253. package/dist/types/session/index.d.ts.map +1 -0
  254. package/dist/types/session/manager.d.ts +110 -0
  255. package/dist/types/session/manager.d.ts.map +1 -0
  256. package/dist/types/session/persist.d.ts +87 -0
  257. package/dist/types/session/persist.d.ts.map +1 -0
  258. package/dist/types/session/tab-lock.d.ts +26 -0
  259. package/dist/types/session/tab-lock.d.ts.map +1 -0
  260. package/dist/types/session/target-factory.d.ts +88 -0
  261. package/dist/types/session/target-factory.d.ts.map +1 -0
  262. package/dist/types/sim-cli.d.ts +8 -0
  263. package/dist/types/sim-cli.d.ts.map +1 -0
  264. package/dist/types/types.d.ts +45 -0
  265. package/dist/types/types.d.ts.map +1 -0
  266. package/dist/types/visual.d.ts +79 -0
  267. package/dist/types/visual.d.ts.map +1 -0
  268. package/package.json +22 -3
  269. package/skill/browse/SKILL.md +286 -0
  270. package/skill/{references → browse/references}/commands.md +203 -18
  271. package/skill/browse-aeo/SKILL.md +148 -0
  272. package/skill/browse-config/SKILL.md +200 -0
  273. package/skill/browse-geo/SKILL.md +225 -0
  274. package/skill/browse-qa/SKILL.md +143 -0
  275. package/skill/browse-seo/SKILL.md +188 -0
  276. package/skill/browse-stealth/SKILL.md +246 -0
  277. package/skill/SKILL.md +0 -496
  278. /package/skill/{references → browse/references}/guides.md +0 -0
  279. /package/skill/{references → browse/references}/permissions.md +0 -0
@@ -0,0 +1,122 @@
1
+ /**
2
+ * Golden snapshot manager — builds and manages a pre-warmed VM snapshot
3
+ * for near-instant (<200ms) VM provisioning via Firecracker restore.
4
+ *
5
+ * Golden snapshot flow:
6
+ * 1. build() — boot a fresh VM, launch Chromium, wait for health,
7
+ * pause, snapshot memory + state to disk
8
+ * 2. clone(id) — restore a new VM from the golden snapshot
9
+ * 3. rebuild() — delete old snapshot and rebuild from scratch
10
+ *
11
+ * The golden snapshot captures a fully-booted VM with Chromium running
12
+ * and the browse server healthy. Cloning from this snapshot skips the
13
+ * entire boot + browser launch sequence (~5-10s → <200ms).
14
+ *
15
+ * Host setup requirements (for health-check mode):
16
+ * - Tap device `tap-golden` with host IP 172.16.0.1/24
17
+ * - iptables/nftables rules for NAT if the VM needs internet
18
+ * - VmConfig.network must be set with tapDevice: 'tap-golden'
19
+ *
20
+ * Without network, the manager waits a fixed boot time (5s) instead.
21
+ *
22
+ * Snapshot files are stored at 0o600 for security:
23
+ * {snapshotDir}/snapshot — VM state (CPU, devices)
24
+ * {snapshotDir}/memory — Full memory image (~memSizeMb)
25
+ * {snapshotDir}/golden-metadata.json — Build metadata for validation
26
+ */
27
+ import { FirecrackerClient, type VmConfig } from './firecracker';
28
+ export interface GoldenSnapshotOptions {
29
+ /** Firecracker client */
30
+ firecracker: FirecrackerClient;
31
+ /** Path to vmlinux kernel */
32
+ kernelPath: string;
33
+ /** Path to rootfs ext4 image */
34
+ rootfsPath: string;
35
+ /** Directory to store golden snapshot files (default /var/lib/browse-cloud/golden) */
36
+ snapshotDir?: string;
37
+ /** Memory per VM in MB (default 512) */
38
+ memSizeMb?: number;
39
+ /** vCPUs per VM (default 1) */
40
+ vcpuCount?: number;
41
+ /** Browse server port inside VM (default 9400) */
42
+ browsePort?: number;
43
+ /** Health check timeout for the golden VM in ms (default 30000) */
44
+ healthTimeout?: number;
45
+ /** Network config for the golden build VM (optional — skips health check if absent) */
46
+ network?: VmConfig['network'];
47
+ }
48
+ export declare class GoldenSnapshotManager {
49
+ private firecracker;
50
+ private kernelPath;
51
+ private rootfsPath;
52
+ private snapshotDir;
53
+ private memSizeMb;
54
+ private vcpuCount;
55
+ private browsePort;
56
+ private healthTimeout;
57
+ private network;
58
+ private ready;
59
+ /** The auth token baked into the golden snapshot. All clones share it. */
60
+ private _authToken;
61
+ private snapshotPath;
62
+ private memPath;
63
+ private metadataPath;
64
+ constructor(opts: GoldenSnapshotOptions);
65
+ /** The auth token baked into the golden snapshot. All clones inherit it. */
66
+ get authToken(): string;
67
+ /**
68
+ * Build the golden snapshot from scratch.
69
+ *
70
+ * Boots a fresh VM, waits for the browse server to become healthy
71
+ * (or waits a fixed time if no network is configured), pauses the VM,
72
+ * and snapshots its memory + state to disk.
73
+ *
74
+ * This is a heavy operation (~10-30s) and should only be done once
75
+ * or when kernel/rootfs changes require a rebuild.
76
+ */
77
+ build(): Promise<void>;
78
+ /**
79
+ * Create a new VM from the golden snapshot.
80
+ *
81
+ * Calls `firecracker.restoreVm()` which spawns a new Firecracker process,
82
+ * loads the snapshot, and resumes the VM. The restored VM is fully running
83
+ * with the browse server ready after this call.
84
+ *
85
+ * @param vmId - Unique identifier for the cloned VM
86
+ */
87
+ clone(vmId: string): Promise<void>;
88
+ /**
89
+ * Rebuild the golden snapshot from scratch.
90
+ *
91
+ * Deletes existing snapshot files and builds a new one.
92
+ * Use this when kernel or rootfs has been updated.
93
+ */
94
+ rebuild(): Promise<void>;
95
+ /**
96
+ * Check if the golden snapshot is ready for cloning.
97
+ *
98
+ * Returns true if the snapshot has been built or loaded from disk,
99
+ * AND the snapshot files still exist on disk.
100
+ */
101
+ isReady(): boolean;
102
+ /**
103
+ * Attempt to load an existing golden snapshot from disk.
104
+ *
105
+ * If snapshot files and metadata exist from a previous build,
106
+ * loads them without rebuilding. This allows recovery after
107
+ * a gateway restart without the cost of a full rebuild.
108
+ *
109
+ * @returns true if a valid snapshot was found and loaded
110
+ */
111
+ loadFromDisk(): boolean;
112
+ /**
113
+ * Poll the browse server health endpoint until it responds 200
114
+ * or the timeout is exceeded.
115
+ */
116
+ private waitForHealth;
117
+ /** Check if all three snapshot files exist on disk. */
118
+ private snapshotFilesExist;
119
+ /** Delete snapshot files (best-effort). */
120
+ private deleteSnapshotFiles;
121
+ }
122
+ //# sourceMappingURL=golden-snapshot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"golden-snapshot.d.ts","sourceRoot":"","sources":["../../../src/cloud/golden-snapshot.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAMH,OAAO,EAAE,iBAAiB,EAAE,KAAK,QAAQ,EAAE,MAAM,eAAe,CAAC;AAgBjE,MAAM,WAAW,qBAAqB;IACpC,yBAAyB;IACzB,WAAW,EAAE,iBAAiB,CAAC;IAC/B,6BAA6B;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,gCAAgC;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,sFAAsF;IACtF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wCAAwC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,+BAA+B;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kDAAkD;IAClD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mEAAmE;IACnE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,uFAAuF;IACvF,OAAO,CAAC,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC;CAC/B;AAkBD,qBAAa,qBAAqB;IAChC,OAAO,CAAC,WAAW,CAAoB;IACvC,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,OAAO,CAAkC;IAEjD,OAAO,CAAC,KAAK,CAAS;IACtB,0EAA0E;IAC1E,OAAO,CAAC,UAAU,CAAM;IACxB,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,YAAY,CAAS;gBAEjB,IAAI,EAAE,qBAAqB;IAgBvC,4EAA4E;IAC5E,IAAI,SAAS,IAAI,MAAM,CAEtB;IAID;;;;;;;;;OASG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAwG5B;;;;;;;;OAQG;IACG,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBxC;;;;;OAKG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAU9B;;;;;OAKG;IACH,OAAO,IAAI,OAAO;IAQlB;;;;;;;;OAQG;IACH,YAAY,IAAI,OAAO;IAyDvB;;;OAGG;IACH,OAAO,CAAC,aAAa;IAiDrB,uDAAuD;IACvD,OAAO,CAAC,kBAAkB;IAW1B,2CAA2C;IAC3C,OAAO,CAAC,mBAAmB;CAS5B"}
@@ -0,0 +1,26 @@
1
+ export { ApiKeyVault, createJwt, validateJwt, resolveJwtSecret, hashApiKey } from './auth';
2
+ export type { ApiKeyRecord, ApiKeyListEntry, CreateKeyResult } from './auth';
3
+ export { CloudSessionManager, TenantAccessError } from './sessions';
4
+ export type { CloudConfig } from './server';
5
+ export { handleUpgrade, closeAllConnections, broadcastSessionEvent } from './ws';
6
+ export type { WsConnection, HandleUpgradeOpts } from './ws';
7
+ export { DockerClient, DockerApiError } from './docker';
8
+ export type { ContainerCreateOptions, ContainerInfo, DockerClientOptions } from './docker';
9
+ export type { Orchestrator, SessionHandle, FrozenSession } from './orchestrator-interface';
10
+ export { ContainerOrchestrator } from './orchestrator';
11
+ export type { ContainerOrchestratorOptions } from './orchestrator';
12
+ export { proxyCommand, ProxyError } from './proxy';
13
+ export type { ProxyOptions } from './proxy';
14
+ export { ContainerReaper } from './reaper';
15
+ export type { ReaperOptions } from './reaper';
16
+ export { WarmPool } from './warm-pool';
17
+ export type { WarmPoolOptions, PoolEntry } from './warm-pool';
18
+ export { FirecrackerClient, FirecrackerApiError } from './firecracker';
19
+ export type { VmConfig, FirecrackerClientOptions } from './firecracker';
20
+ export { GoldenSnapshotManager } from './golden-snapshot';
21
+ export type { GoldenSnapshotOptions } from './golden-snapshot';
22
+ export { VmOrchestrator } from './vm-orchestrator';
23
+ export type { VmOrchestratorOptions } from './vm-orchestrator';
24
+ export { VmWarmPool } from './vm-warm-pool';
25
+ export type { VmWarmPoolOptions, VmPoolEntry } from './vm-warm-pool';
26
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cloud/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,WAAW,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAC3F,YAAY,EAAE,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAC;AAC7E,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACpE,YAAY,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,MAAM,CAAC;AACjF,YAAY,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AACxD,YAAY,EAAE,sBAAsB,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAC3F,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAC3F,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AACvD,YAAY,EAAE,4BAA4B,EAAE,MAAM,gBAAgB,CAAC;AACnE,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACnD,YAAY,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAC3C,YAAY,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,YAAY,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACvE,YAAY,EAAE,QAAQ,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AACxE,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,YAAY,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,YAAY,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5C,YAAY,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Shared orchestrator interface for session isolation backends.
3
+ *
4
+ * Both ContainerOrchestrator (Docker) and VmOrchestrator (microVM)
5
+ * implement this contract. The cloud gateway selects a backend at
6
+ * startup via BROWSE_CLOUD_ISOLATION env var.
7
+ *
8
+ * Design invariants:
9
+ * - One orchestrator instance per gateway process
10
+ * - Session IDs are tenant-scoped: `tenant:<tenantId>:session:<id>`
11
+ * - Each session maps 1:1 to an isolated backend (container or VM)
12
+ * - Freeze/resume allows session persistence across compute recycling
13
+ */
14
+ /** Handle to a provisioned session (container or VM). */
15
+ export interface SessionHandle {
16
+ /** Unique session ID (tenant-scoped) */
17
+ sessionId: string;
18
+ /** Tenant that owns this session */
19
+ tenantId: string;
20
+ /** Internal address for command proxying (e.g. '172.17.0.2:9400') */
21
+ internalAddress: string;
22
+ /** Auth token for the internal browse server */
23
+ internalToken: string;
24
+ /** Backend-specific ID (container ID, VM ID) */
25
+ backendId: string;
26
+ /** When the session was provisioned (ISO 8601) */
27
+ createdAt: string;
28
+ }
29
+ /** Frozen session metadata — persisted after compute is released. */
30
+ export interface FrozenSession {
31
+ sessionId: string;
32
+ tenantId: string;
33
+ /** Backend-specific snapshot reference (image ID, snapshot path) */
34
+ snapshotRef: string;
35
+ /** When the session was frozen (ISO 8601) */
36
+ frozenAt: string;
37
+ /** Auth token from the original session — must be reused on resume
38
+ * because VM snapshots restore with the same in-process token. */
39
+ internalToken?: string;
40
+ /** Allowed domains from the original session — must be reapplied on resume. */
41
+ allowedDomains?: string;
42
+ }
43
+ /** Common orchestrator interface — container and VM backends implement this. */
44
+ export interface Orchestrator {
45
+ /** Provision a new isolated session. */
46
+ provision(tenantId: string, opts?: {
47
+ sessionId?: string;
48
+ allowedDomains?: string;
49
+ }): Promise<SessionHandle>;
50
+ /** Execute a browse command on a provisioned session. */
51
+ executeCommand(handle: SessionHandle, command: string, args: string[]): Promise<string>;
52
+ /** Terminate a session and clean up its resources. */
53
+ terminate(handle: SessionHandle): Promise<void>;
54
+ /** Freeze a session (save state, release compute). */
55
+ freeze(handle: SessionHandle): Promise<FrozenSession>;
56
+ /** Resume a frozen session. */
57
+ resume(tenantId: string, frozen: FrozenSession): Promise<SessionHandle>;
58
+ /** List active sessions for a tenant. */
59
+ list(tenantId: string): SessionHandle[];
60
+ /** Shut down the orchestrator and clean up all resources. */
61
+ shutdown(): Promise<void>;
62
+ }
63
+ //# sourceMappingURL=orchestrator-interface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orchestrator-interface.d.ts","sourceRoot":"","sources":["../../../src/cloud/orchestrator-interface.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH,yDAAyD;AACzD,MAAM,WAAW,aAAa;IAC5B,wCAAwC;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,oCAAoC;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,qEAAqE;IACrE,eAAe,EAAE,MAAM,CAAC;IACxB,gDAAgD;IAChD,aAAa,EAAE,MAAM,CAAC;IACtB,gDAAgD;IAChD,SAAS,EAAE,MAAM,CAAC;IAClB,kDAAkD;IAClD,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,qEAAqE;AACrE,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,oEAAoE;IACpE,WAAW,EAAE,MAAM,CAAC;IACpB,6CAA6C;IAC7C,QAAQ,EAAE,MAAM,CAAC;IACjB;uEACmE;IACnE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,+EAA+E;IAC/E,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAID,gFAAgF;AAChF,MAAM,WAAW,YAAY;IAC3B,wCAAwC;IACxC,SAAS,CACP,QAAQ,EAAE,MAAM,EAChB,IAAI,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,cAAc,CAAC,EAAE,MAAM,CAAA;KAAE,GACrD,OAAO,CAAC,aAAa,CAAC,CAAC;IAE1B,yDAAyD;IACzD,cAAc,CACZ,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,GACb,OAAO,CAAC,MAAM,CAAC,CAAC;IAEnB,sDAAsD;IACtD,SAAS,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEhD,sDAAsD;IACtD,MAAM,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IAEtD,+BAA+B;IAC/B,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IAExE,yCAAyC;IACzC,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa,EAAE,CAAC;IAExC,6DAA6D;IAC7D,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Container orchestrator — Docker-based session isolation.
3
+ *
4
+ * Implements the Orchestrator interface using DockerClient.
5
+ * Each session runs in its own Docker container with:
6
+ * - Memory and CPU limits
7
+ * - Its own browse server on port 9400
8
+ * - A known auth token (set via BROWSE_AUTH_TOKEN env var)
9
+ * - Labels for tenant tracking and orphan detection
10
+ *
11
+ * The gateway proxies commands to each container's internal
12
+ * browse server via the proxyCommand() HTTP function.
13
+ */
14
+ import { DockerClient } from './docker';
15
+ import type { Orchestrator, SessionHandle, FrozenSession } from './orchestrator-interface';
16
+ import type { WarmPool } from './warm-pool';
17
+ export interface ContainerOrchestratorOptions {
18
+ /** Docker client instance */
19
+ docker: DockerClient;
20
+ /** Docker image name for session containers */
21
+ imageName: string;
22
+ /** Memory limit per container in bytes (default 512 MB) */
23
+ memoryLimit?: number;
24
+ /** CPU limit in nanoCPUs (default 0.5 CPU = 500_000_000) */
25
+ cpuLimit?: number;
26
+ /** Container health check timeout in ms (default 30000) */
27
+ healthTimeout?: number;
28
+ /** Optional warm container pool for fast provisioning */
29
+ pool?: WarmPool;
30
+ }
31
+ export declare class ContainerOrchestrator implements Orchestrator {
32
+ private docker;
33
+ private imageName;
34
+ private memoryLimit;
35
+ private cpuLimit;
36
+ private healthTimeout;
37
+ private pool;
38
+ /** Active session handles keyed by sessionId */
39
+ private handles;
40
+ /** Session ID sets keyed by tenantId */
41
+ private tenantHandles;
42
+ constructor(opts: ContainerOrchestratorOptions);
43
+ provision(tenantId: string, opts?: {
44
+ sessionId?: string;
45
+ allowedDomains?: string;
46
+ }): Promise<SessionHandle>;
47
+ executeCommand(handle: SessionHandle, command: string, args: string[]): Promise<string>;
48
+ terminate(handle: SessionHandle): Promise<void>;
49
+ freeze(handle: SessionHandle): Promise<FrozenSession>;
50
+ resume(tenantId: string, frozen: FrozenSession): Promise<SessionHandle>;
51
+ /** Return all active container IDs tracked by this orchestrator. */
52
+ getActiveBackendIds(): Set<string>;
53
+ list(tenantId: string): SessionHandle[];
54
+ shutdown(): Promise<void>;
55
+ private trackHandle;
56
+ private untrackHandle;
57
+ }
58
+ //# sourceMappingURL=orchestrator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orchestrator.d.ts","sourceRoot":"","sources":["../../../src/cloud/orchestrator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,EAAE,YAAY,EAAsB,MAAM,UAAU,CAAC;AAC5D,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAE3F,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAc5C,MAAM,WAAW,4BAA4B;IAC3C,6BAA6B;IAC7B,MAAM,EAAE,YAAY,CAAC;IACrB,+CAA+C;IAC/C,SAAS,EAAE,MAAM,CAAC;IAClB,2DAA2D;IAC3D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,2DAA2D;IAC3D,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,yDAAyD;IACzD,IAAI,CAAC,EAAE,QAAQ,CAAC;CACjB;AAID,qBAAa,qBAAsB,YAAW,YAAY;IACxD,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,IAAI,CAAkB;IAE9B,gDAAgD;IAChD,OAAO,CAAC,OAAO,CAAoC;IACnD,wCAAwC;IACxC,OAAO,CAAC,aAAa,CAAkC;gBAE3C,IAAI,EAAE,4BAA4B;IAWxC,SAAS,CACb,QAAQ,EAAE,MAAM,EAChB,IAAI,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,cAAc,CAAC,EAAE,MAAM,CAAA;KAAE,GACrD,OAAO,CAAC,aAAa,CAAC;IAuEnB,cAAc,CAClB,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,GACb,OAAO,CAAC,MAAM,CAAC;IAOZ,SAAS,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAgB/C,MAAM,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC;IA+DrD,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC;IA2C7E,oEAAoE;IACpE,mBAAmB,IAAI,GAAG,CAAC,MAAM,CAAC;IAQlC,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa,EAAE;IAYjC,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAe/B,OAAO,CAAC,WAAW;IAWnB,OAAO,CAAC,aAAa;CAWtB"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * HTTP command proxy — forwards browse commands to container-internal servers.
3
+ *
4
+ * The cloud gateway uses this to proxy tenant requests into isolated
5
+ * containers (or VMs), each running their own browse server on port 9400.
6
+ *
7
+ * Protocol:
8
+ * POST http://{host}:{port}/command
9
+ * Body: { command, args }
10
+ * Headers: Authorization: Bearer {token}, Content-Type: application/json
11
+ * Response: text/plain (success) or JSON { error } (failure)
12
+ */
13
+ export interface ProxyOptions {
14
+ /** Target address (host:port) */
15
+ address: string;
16
+ /** Auth token for the target server */
17
+ token: string;
18
+ /** Request timeout in ms (default 30000) */
19
+ timeout?: number;
20
+ }
21
+ export declare class ProxyError extends Error {
22
+ statusCode: number;
23
+ targetAddress: string;
24
+ constructor(statusCode: number, message: string, targetAddress: string);
25
+ }
26
+ /**
27
+ * Proxy a browse command to a container-internal server.
28
+ *
29
+ * Sends POST /command with the container's auth token.
30
+ * Returns the response body as a string on success.
31
+ * Throws ProxyError on HTTP errors or transport failures.
32
+ */
33
+ export declare function proxyCommand(command: string, args: string[], opts: ProxyOptions): Promise<string>;
34
+ //# sourceMappingURL=proxy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../../../src/cloud/proxy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAMH,MAAM,WAAW,YAAY;IAC3B,iCAAiC;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,uCAAuC;IACvC,KAAK,EAAE,MAAM,CAAC;IACd,4CAA4C;IAC5C,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAID,qBAAa,UAAW,SAAQ,KAAK;IAE1B,UAAU,EAAE,MAAM;IAElB,aAAa,EAAE,MAAM;gBAFrB,UAAU,EAAE,MAAM,EACzB,OAAO,EAAE,MAAM,EACR,aAAa,EAAE,MAAM;CAK/B;AAID;;;;;;GAMG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,EACd,IAAI,EAAE,YAAY,GACjB,OAAO,CAAC,MAAM,CAAC,CAkFjB"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Orphan container reaper — detects and removes containers with no
3
+ * matching session in the gateway.
4
+ *
5
+ * Safety net for crash recovery: if the gateway process dies, its
6
+ * containers survive. On the next gateway startup the reaper finds
7
+ * orphaned containers (those not tracked by the orchestrator) and
8
+ * removes them after a configurable grace period.
9
+ *
10
+ * All operations are best-effort — the reaper never throws from reap().
11
+ */
12
+ import { DockerClient } from './docker';
13
+ export interface ReaperOptions {
14
+ /** Docker client */
15
+ docker: DockerClient;
16
+ /** Function that returns active session backend IDs */
17
+ getActiveIds: () => Set<string>;
18
+ /** Minimum age before reaping (ms, default 300000 = 5 min) */
19
+ minAgeMs?: number;
20
+ /** Reap interval (ms, default 60000 = 60s) */
21
+ intervalMs?: number;
22
+ /** Also reap committed snapshot images older than TTL (ms, default 3600000 = 1 hour) */
23
+ snapshotTtlMs?: number;
24
+ }
25
+ export declare class ContainerReaper {
26
+ private docker;
27
+ private getActiveIds;
28
+ private minAgeMs;
29
+ private intervalMs;
30
+ private timer;
31
+ constructor(opts: ReaperOptions);
32
+ /** Start the periodic reap interval. */
33
+ start(): void;
34
+ /** Stop the periodic reap interval. */
35
+ stop(): void;
36
+ /** Run one reap cycle. Returns counts of reaped resources. */
37
+ reap(): Promise<{
38
+ containers: number;
39
+ images: number;
40
+ }>;
41
+ /** Alias for reap() — convenient for one-shot manual invocation. */
42
+ reapOnce(): Promise<{
43
+ containers: number;
44
+ }>;
45
+ private reapContainers;
46
+ /** Calculate container age in ms from the browse-cloud.created label. */
47
+ private containerAge;
48
+ }
49
+ //# sourceMappingURL=reaper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reaper.d.ts","sourceRoot":"","sources":["../../../src/cloud/reaper.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,YAAY,EAAsB,MAAM,UAAU,CAAC;AAU5D,MAAM,WAAW,aAAa;IAC5B,oBAAoB;IACpB,MAAM,EAAE,YAAY,CAAC;IACrB,uDAAuD;IACvD,YAAY,EAAE,MAAM,GAAG,CAAC,MAAM,CAAC,CAAC;IAChC,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,8CAA8C;IAC9C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,wFAAwF;IACxF,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAID,qBAAa,eAAe;IAC1B,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,YAAY,CAAoB;IACxC,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,KAAK,CAA+B;gBAEhC,IAAI,EAAE,aAAa;IAQ/B,wCAAwC;IACxC,KAAK,IAAI,IAAI;IAUb,uCAAuC;IACvC,IAAI,IAAI,IAAI;IAQZ,8DAA8D;IACxD,IAAI,IAAI,OAAO,CAAC;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAoB7D,oEAAoE;IAC9D,QAAQ,IAAI,OAAO,CAAC;QAAE,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;YAOnC,cAAc;IAiC5B,yEAAyE;IACzE,OAAO,CAAC,YAAY;CAarB"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Cloud server — multi-tenant HTTP API for remote browser automation.
3
+ *
4
+ * Separate entry point from the local server (src/server.ts).
5
+ * Wraps the same SessionManager + executeCommand infrastructure
6
+ * behind JWT-authenticated, tenant-scoped routes.
7
+ *
8
+ * Auth flow: API key -> JWT exchange -> Bearer token on all /v1/ routes.
9
+ * Sessions are prefixed `tenant:<tenantId>:session:<id>` for isolation.
10
+ */
11
+ export interface CloudConfig {
12
+ port: number;
13
+ host: string;
14
+ dbPath: string;
15
+ jwtSecret: Buffer;
16
+ adminKey: string | undefined;
17
+ localDir: string;
18
+ }
19
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/cloud/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAsBH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,QAAQ,EAAE,MAAM,CAAC;CAClB"}
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Cloud session manager — tenant-scoped session lifecycle on top of SessionManager.
3
+ *
4
+ * Wraps the generic SessionManager with tenant isolation:
5
+ * - Session IDs are prefixed `tenant:<tenantId>:session:<id>`
6
+ * - Each tenant has a configurable session limit
7
+ * - All accessors validate tenant ownership before touching a session
8
+ *
9
+ * Throws TenantAccessError (maps to HTTP 403) when a tenant tries to
10
+ * reach a session it does not own.
11
+ */
12
+ import type { SessionManager, Session } from '../session/manager';
13
+ export declare class TenantAccessError extends Error {
14
+ constructor(tenantId: string, sessionId: string);
15
+ }
16
+ export declare class CloudSessionManager {
17
+ private sessionManager;
18
+ private maxSessionsPerTenant;
19
+ /** Tracks which session IDs belong to each tenant */
20
+ private tenantSessions;
21
+ constructor(sessionManager: SessionManager, maxSessionsPerTenant?: number);
22
+ /**
23
+ * Provision a new session for a tenant.
24
+ *
25
+ * Generates a scoped ID `tenant:<tenantId>:session:<id>`, creates the
26
+ * underlying session via SessionManager, and tracks it in tenantSessions.
27
+ *
28
+ * Throws if the tenant has reached its session limit (429-friendly message).
29
+ */
30
+ provision(tenantId: string, opts?: {
31
+ allowedDomains?: string;
32
+ sessionId?: string;
33
+ }): Promise<{
34
+ sessionId: string;
35
+ createdAt: string;
36
+ }>;
37
+ /**
38
+ * List sessions belonging to a tenant.
39
+ *
40
+ * Filters the global session list by the tenant prefix.
41
+ */
42
+ list(tenantId: string): Array<{
43
+ id: string;
44
+ tabs: number;
45
+ url: string;
46
+ idleSeconds: number;
47
+ }>;
48
+ /**
49
+ * Get an existing session, verifying tenant ownership.
50
+ *
51
+ * Throws TenantAccessError if the session does not belong to the tenant.
52
+ * Throws a generic Error if the session does not exist.
53
+ */
54
+ get(tenantId: string, sessionId: string): Session;
55
+ /**
56
+ * Get an existing session or create it, verifying tenant ownership.
57
+ *
58
+ * Throws TenantAccessError if the session ID does not match the tenant prefix.
59
+ */
60
+ getOrCreate(tenantId: string, sessionId: string, allowedDomains?: string): Promise<Session>;
61
+ /**
62
+ * Terminate a session, verifying tenant ownership.
63
+ *
64
+ * Throws TenantAccessError if the session does not belong to the tenant.
65
+ */
66
+ terminate(tenantId: string, sessionId: string): Promise<void>;
67
+ /**
68
+ * Return the number of sessions currently tracked for a tenant.
69
+ */
70
+ getSessionCount(tenantId: string): number;
71
+ /**
72
+ * Check whether a tenant has reached its session limit.
73
+ */
74
+ isAtLimit(tenantId: string): boolean;
75
+ /**
76
+ * Validate that a session ID has the correct tenant prefix.
77
+ * Throws TenantAccessError if the prefix does not match.
78
+ */
79
+ private validateTenantOwnership;
80
+ /** Add a session ID to the tenant tracking set. */
81
+ private trackSession;
82
+ /** Remove a session ID from the tenant tracking set. */
83
+ private untrackSession;
84
+ }
85
+ //# sourceMappingURL=sessions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sessions.d.ts","sourceRoot":"","sources":["../../../src/cloud/sessions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAIlE,qBAAa,iBAAkB,SAAQ,KAAK;gBAC9B,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;CAIhD;AAID,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,oBAAoB,CAAS;IACrC,qDAAqD;IACrD,OAAO,CAAC,cAAc,CAAkC;gBAE5C,cAAc,EAAE,cAAc,EAAE,oBAAoB,SAAK;IAKrE;;;;;;;OAOG;IACG,SAAS,CACb,QAAQ,EAAE,MAAM,EAChB,IAAI,CAAC,EAAE;QAAE,cAAc,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GACrD,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IAgBpD;;;;OAIG;IACH,IAAI,CACF,QAAQ,EAAE,MAAM,GACf,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC;IAaxE;;;;;OAKG;IACH,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO;IAUjD;;;;OAIG;IACG,WAAW,CACf,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,cAAc,CAAC,EAAE,MAAM,GACtB,OAAO,CAAC,OAAO,CAAC;IAQnB;;;;OAIG;IACG,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOnE;;OAEG;IACH,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;IAIzC;;OAEG;IACH,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAMpC;;;OAGG;IACH,OAAO,CAAC,uBAAuB;IAM/B,mDAAmD;IACnD,OAAO,CAAC,YAAY;IASpB,wDAAwD;IACxD,OAAO,CAAC,cAAc;CAQvB"}
@@ -0,0 +1,133 @@
1
+ /**
2
+ * VM orchestrator — Firecracker microVM-based session isolation.
3
+ *
4
+ * Implements the Orchestrator interface using FirecrackerClient.
5
+ * Each session runs in its own microVM with:
6
+ * - Dedicated kernel + rootfs image
7
+ * - Its own browse server on port 9400
8
+ * - A known auth token (passed via kernel boot args or init script)
9
+ * - Network isolation via tap devices
10
+ *
11
+ * The gateway proxies commands to each VM's internal browse server
12
+ * via the proxyCommand() HTTP function.
13
+ *
14
+ * Auth token injection: the token is passed via kernel boot args as
15
+ * BROWSE_AUTH_TOKEN=<uuid>. The rootfs init script parses /proc/cmdline
16
+ * and exports matching BROWSE_* vars before launching the browse server.
17
+ *
18
+ * Networking: Firecracker VMs require host-side tap device setup (ip tuntap,
19
+ * ip addr, iptables NAT) which must be done BEFORE createVm(). This
20
+ * orchestrator generates tap device names and guest IPs but does NOT create
21
+ * the tap devices — the host environment must pre-provision them or a setup
22
+ * script must run before the orchestrator. Without real tap devices,
23
+ * provision() will fail at the health check step.
24
+ *
25
+ * IP assignment: simplified counter-based scheme using 172.16.0.0/24.
26
+ * Host-side tap devices all share 172.16.0.1; each guest gets
27
+ * 172.16.0.{N} where N increments per VM. Production deployments
28
+ * should use proper network namespaces with per-VM subnets.
29
+ */
30
+ import { FirecrackerClient } from './firecracker';
31
+ import type { Orchestrator, SessionHandle, FrozenSession } from './orchestrator-interface';
32
+ import type { VmWarmPool } from './vm-warm-pool';
33
+ /**
34
+ * Callback that provisions host-side networking for a VM.
35
+ * Must create the tap device, assign IPs, and configure NAT/routing.
36
+ * Returns the guest IP that the VM will be reachable at.
37
+ *
38
+ * If not provided, the orchestrator uses a fabricated IP scheme that
39
+ * will NOT work without external network setup.
40
+ */
41
+ export type NetworkProvider = (vmId: string, tapDevice: string) => Promise<{
42
+ guestIp: string;
43
+ }>;
44
+ export interface VmOrchestratorOptions {
45
+ /** Firecracker client */
46
+ firecracker: FirecrackerClient;
47
+ /** Path to vmlinux kernel */
48
+ kernelPath: string;
49
+ /** Path to rootfs ext4 image */
50
+ rootfsPath: string;
51
+ /** Memory per VM in MB (default 512) */
52
+ memSizeMb?: number;
53
+ /** vCPUs per VM (default 1) */
54
+ vcpuCount?: number;
55
+ /** Browse server port inside VM (default 9400) */
56
+ browsePort?: number;
57
+ /** Health check timeout in ms (default 30000) */
58
+ healthTimeout?: number;
59
+ /** Directory for snapshot files (default /var/lib/browse-cloud/snapshots) */
60
+ snapshotDir?: string;
61
+ /** Optional VM warm pool for pre-cloned paused VMs */
62
+ pool?: VmWarmPool | null;
63
+ /**
64
+ * Host-side network provisioning callback. Creates tap device, assigns IPs,
65
+ * configures NAT. Returns the guest IP. Required for production use.
66
+ * When omitted, falls back to fabricated 172.16.0.x IPs (development only).
67
+ */
68
+ networkProvider?: NetworkProvider;
69
+ }
70
+ export declare class VmOrchestrator implements Orchestrator {
71
+ private firecracker;
72
+ private kernelPath;
73
+ private rootfsPath;
74
+ private memSizeMb;
75
+ private vcpuCount;
76
+ private browsePort;
77
+ private healthTimeout;
78
+ private snapshotDir;
79
+ private pool;
80
+ private networkProvider;
81
+ /** Active session handles keyed by sessionId */
82
+ private handles;
83
+ /** Session ID sets keyed by tenantId */
84
+ private tenantHandles;
85
+ /**
86
+ * Counter-based IP suffix for guest IPs.
87
+ * Starts at 2 (172.16.0.2) and increments per VM.
88
+ * Wraps at 254 to stay within a /24 subnet.
89
+ *
90
+ * NOTE: This simplified scheme assumes no more than ~252 concurrent VMs.
91
+ * Production deployments should use per-VM network namespaces with
92
+ * dedicated subnets (e.g., 172.16.{X}.2 per VM).
93
+ */
94
+ private nextIpSuffix;
95
+ constructor(opts: VmOrchestratorOptions);
96
+ provision(tenantId: string, opts?: {
97
+ sessionId?: string;
98
+ allowedDomains?: string;
99
+ }): Promise<SessionHandle>;
100
+ executeCommand(handle: SessionHandle, command: string, args: string[]): Promise<string>;
101
+ terminate(handle: SessionHandle): Promise<void>;
102
+ freeze(handle: SessionHandle): Promise<FrozenSession>;
103
+ resume(tenantId: string, frozen: FrozenSession): Promise<SessionHandle>;
104
+ list(tenantId: string): SessionHandle[];
105
+ shutdown(): Promise<void>;
106
+ /** Return all active VM IDs tracked by this orchestrator. */
107
+ getActiveVmIds(): Set<string>;
108
+ private trackHandle;
109
+ private untrackHandle;
110
+ /**
111
+ * Allocate a guest IP address using counter-based scheme.
112
+ *
113
+ * Returns IPs in the 172.16.0.0/24 range starting from 172.16.0.2.
114
+ * Wraps at 254 to avoid broadcast address.
115
+ *
116
+ * NOTE: Production should use per-VM network namespaces with
117
+ * dedicated subnets for proper isolation.
118
+ */
119
+ private allocateGuestIp;
120
+ /**
121
+ * Poll the browse server's /health endpoint until it responds.
122
+ *
123
+ * Uses native http.get with a short timeout per attempt.
124
+ * Throws if the server doesn't become healthy within the deadline.
125
+ */
126
+ private waitForHealth;
127
+ /**
128
+ * Single health check attempt — returns true if the browse server
129
+ * responds with HTTP 200, false otherwise.
130
+ */
131
+ private checkHealth;
132
+ }
133
+ //# sourceMappingURL=vm-orchestrator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vm-orchestrator.d.ts","sourceRoot":"","sources":["../../../src/cloud/vm-orchestrator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAMH,OAAO,EAAE,iBAAiB,EAAiB,MAAM,eAAe,CAAC;AACjE,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAE3F,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAajD;;;;;;;GAOG;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAEhG,MAAM,WAAW,qBAAqB;IACpC,yBAAyB;IACzB,WAAW,EAAE,iBAAiB,CAAC;IAC/B,6BAA6B;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,gCAAgC;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,wCAAwC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,+BAA+B;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kDAAkD;IAClD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iDAAiD;IACjD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,6EAA6E;IAC7E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,sDAAsD;IACtD,IAAI,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC;IACzB;;;;OAIG;IACH,eAAe,CAAC,EAAE,eAAe,CAAC;CACnC;AAUD,qBAAa,cAAe,YAAW,YAAY;IACjD,OAAO,CAAC,WAAW,CAAoB;IACvC,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,IAAI,CAAgC;IAC5C,OAAO,CAAC,eAAe,CAAyB;IAEhD,gDAAgD;IAChD,OAAO,CAAC,OAAO,CAAsC;IACrD,wCAAwC;IACxC,OAAO,CAAC,aAAa,CAAkC;IAEvD;;;;;;;;OAQG;IACH,OAAO,CAAC,YAAY,CAAK;gBAEb,IAAI,EAAE,qBAAqB;IAejC,SAAS,CACb,QAAQ,EAAE,MAAM,EAChB,IAAI,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,cAAc,CAAC,EAAE,MAAM,CAAA;KAAE,GACrD,OAAO,CAAC,aAAa,CAAC;IAiInB,cAAc,CAClB,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,GACb,OAAO,CAAC,MAAM,CAAC;IAOZ,SAAS,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAc/C,MAAM,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC;IAoDrD,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC;IA0D7E,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa,EAAE;IAYjC,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAsB/B,6DAA6D;IAC7D,cAAc,IAAI,GAAG,CAAC,MAAM,CAAC;IAU7B,OAAO,CAAC,WAAW;IAWnB,OAAO,CAAC,aAAa;IAcrB;;;;;;;;OAQG;IACH,OAAO,CAAC,eAAe;IAQvB;;;;;OAKG;YACW,aAAa;IAc3B;;;OAGG;IACH,OAAO,CAAC,WAAW;CAkBpB"}