@hotcell/daemon 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (142) hide show
  1. package/dist/agent-check.d.ts +1 -0
  2. package/dist/agent-check.js +105 -0
  3. package/dist/agent-check.js.map +1 -0
  4. package/dist/api/server.d.ts +64 -0
  5. package/dist/api/server.js +1368 -0
  6. package/dist/api/server.js.map +1 -0
  7. package/dist/api/ws.d.ts +14 -0
  8. package/dist/api/ws.js +214 -0
  9. package/dist/api/ws.js.map +1 -0
  10. package/dist/applevz-check.d.ts +1 -0
  11. package/dist/applevz-check.js +280 -0
  12. package/dist/applevz-check.js.map +1 -0
  13. package/dist/backups.d.ts +29 -0
  14. package/dist/backups.js +76 -0
  15. package/dist/backups.js.map +1 -0
  16. package/dist/capacity.d.ts +63 -0
  17. package/dist/capacity.js +95 -0
  18. package/dist/capacity.js.map +1 -0
  19. package/dist/config.d.ts +241 -0
  20. package/dist/config.js +152 -0
  21. package/dist/config.js.map +1 -0
  22. package/dist/cost.d.ts +9 -0
  23. package/dist/cost.js +19 -0
  24. package/dist/cost.js.map +1 -0
  25. package/dist/density-bench.d.ts +1 -0
  26. package/dist/density-bench.js +97 -0
  27. package/dist/density-bench.js.map +1 -0
  28. package/dist/driver/agent-driver.d.ts +67 -0
  29. package/dist/driver/agent-driver.js +197 -0
  30. package/dist/driver/agent-driver.js.map +1 -0
  31. package/dist/driver/agent.d.ts +94 -0
  32. package/dist/driver/agent.js +319 -0
  33. package/dist/driver/agent.js.map +1 -0
  34. package/dist/driver/applevz.d.ts +95 -0
  35. package/dist/driver/applevz.js +527 -0
  36. package/dist/driver/applevz.js.map +1 -0
  37. package/dist/driver/container.d.ts +99 -0
  38. package/dist/driver/container.js +733 -0
  39. package/dist/driver/container.js.map +1 -0
  40. package/dist/driver/fc-api.d.ts +85 -0
  41. package/dist/driver/fc-api.js +173 -0
  42. package/dist/driver/fc-api.js.map +1 -0
  43. package/dist/driver/firecracker.d.ts +126 -0
  44. package/dist/driver/firecracker.js +560 -0
  45. package/dist/driver/firecracker.js.map +1 -0
  46. package/dist/driver/index.d.ts +17 -0
  47. package/dist/driver/index.js +61 -0
  48. package/dist/driver/index.js.map +1 -0
  49. package/dist/driver/router.d.ts +82 -0
  50. package/dist/driver/router.js +159 -0
  51. package/dist/driver/router.js.map +1 -0
  52. package/dist/driver/types.d.ts +234 -0
  53. package/dist/driver/types.js +2 -0
  54. package/dist/driver/types.js.map +1 -0
  55. package/dist/driver/unsupported.d.ts +50 -0
  56. package/dist/driver/unsupported.js +81 -0
  57. package/dist/driver/unsupported.js.map +1 -0
  58. package/dist/driver/vz-image.d.ts +35 -0
  59. package/dist/driver/vz-image.js +75 -0
  60. package/dist/driver/vz-image.js.map +1 -0
  61. package/dist/e2e-harness.d.ts +1 -0
  62. package/dist/e2e-harness.js +99 -0
  63. package/dist/e2e-harness.js.map +1 -0
  64. package/dist/egress-check.d.ts +8 -0
  65. package/dist/egress-check.js +317 -0
  66. package/dist/egress-check.js.map +1 -0
  67. package/dist/fc-check.d.ts +1 -0
  68. package/dist/fc-check.js +113 -0
  69. package/dist/fc-check.js.map +1 -0
  70. package/dist/index.d.ts +2 -0
  71. package/dist/index.js +114 -0
  72. package/dist/index.js.map +1 -0
  73. package/dist/kernels.d.ts +22 -0
  74. package/dist/kernels.js +134 -0
  75. package/dist/kernels.js.map +1 -0
  76. package/dist/lifecycle.d.ts +49 -0
  77. package/dist/lifecycle.js +111 -0
  78. package/dist/lifecycle.js.map +1 -0
  79. package/dist/logger.d.ts +16 -0
  80. package/dist/logger.js +67 -0
  81. package/dist/logger.js.map +1 -0
  82. package/dist/metrics.d.ts +46 -0
  83. package/dist/metrics.js +92 -0
  84. package/dist/metrics.js.map +1 -0
  85. package/dist/net/firewall.d.ts +4 -0
  86. package/dist/net/firewall.js +80 -0
  87. package/dist/net/firewall.js.map +1 -0
  88. package/dist/pricing.d.ts +36 -0
  89. package/dist/pricing.js +81 -0
  90. package/dist/pricing.js.map +1 -0
  91. package/dist/proxy/allowlist-default.d.ts +23 -0
  92. package/dist/proxy/allowlist-default.js +53 -0
  93. package/dist/proxy/allowlist-default.js.map +1 -0
  94. package/dist/proxy/allowlist.d.ts +43 -0
  95. package/dist/proxy/allowlist.js +87 -0
  96. package/dist/proxy/allowlist.js.map +1 -0
  97. package/dist/proxy/egress.d.ts +49 -0
  98. package/dist/proxy/egress.js +599 -0
  99. package/dist/proxy/egress.js.map +1 -0
  100. package/dist/proxy/ratelimit.d.ts +49 -0
  101. package/dist/proxy/ratelimit.js +74 -0
  102. package/dist/proxy/ratelimit.js.map +1 -0
  103. package/dist/proxy/server.d.ts +26 -0
  104. package/dist/proxy/server.js +202 -0
  105. package/dist/proxy/server.js.map +1 -0
  106. package/dist/router-check.d.ts +1 -0
  107. package/dist/router-check.js +97 -0
  108. package/dist/router-check.js.map +1 -0
  109. package/dist/smoke-fc.d.ts +1 -0
  110. package/dist/smoke-fc.js +183 -0
  111. package/dist/smoke-fc.js.map +1 -0
  112. package/dist/smoke-microvm.d.ts +1 -0
  113. package/dist/smoke-microvm.js +187 -0
  114. package/dist/smoke-microvm.js.map +1 -0
  115. package/dist/smoke-remote.d.ts +20 -0
  116. package/dist/smoke-remote.js +155 -0
  117. package/dist/smoke-remote.js.map +1 -0
  118. package/dist/smoke-vz.d.ts +1 -0
  119. package/dist/smoke-vz.js +161 -0
  120. package/dist/smoke-vz.js.map +1 -0
  121. package/dist/smoke.d.ts +7 -0
  122. package/dist/smoke.js +962 -0
  123. package/dist/smoke.js.map +1 -0
  124. package/dist/store.d.ts +124 -0
  125. package/dist/store.js +578 -0
  126. package/dist/store.js.map +1 -0
  127. package/dist/tracing.d.ts +45 -0
  128. package/dist/tracing.js +144 -0
  129. package/dist/tracing.js.map +1 -0
  130. package/dist/types.d.ts +274 -0
  131. package/dist/types.js +3 -0
  132. package/dist/types.js.map +1 -0
  133. package/dist/util.d.ts +27 -0
  134. package/dist/util.js +63 -0
  135. package/dist/util.js.map +1 -0
  136. package/dist/warmpool-check.d.ts +1 -0
  137. package/dist/warmpool-check.js +83 -0
  138. package/dist/warmpool-check.js.map +1 -0
  139. package/dist/web/dashboard.d.ts +1 -0
  140. package/dist/web/dashboard.js +456 -0
  141. package/dist/web/dashboard.js.map +1 -0
  142. package/package.json +53 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/driver/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAGrD,yDAAyD;AACzD,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,WAAW,EAAE,aAAa,EAAE,SAAS,CAAU,CAAC;AAE7E;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,MAAc;IACzC,OAAO,iBAAiB,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAClD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAY,EAAE,MAAc;IAC5D,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,WAAW;YACd,OAAO,IAAI,eAAe,CAAC,SAAS,EAAE;gBACpC,OAAO,EAAE,MAAM,CAAC,aAAa;gBAC7B,OAAO,EAAE,MAAM,CAAC,aAAa;gBAC7B,MAAM,EAAE,MAAM,CAAC,YAAY;gBAC3B,GAAG,EAAE,MAAM,CAAC,iBAAiB;aAC9B,CAAC,CAAC;QACL,KAAK,aAAa;YAChB,OAAO,IAAI,iBAAiB,CAAC;gBAC3B,KAAK,EAAE,MAAM,CAAC,KAAK;gBACnB,MAAM,EAAE,MAAM,CAAC,QAAQ;gBACvB,MAAM,EAAE,MAAM,CAAC,QAAQ;gBACvB,QAAQ,EAAE,MAAM,CAAC,UAAU;gBAC3B,MAAM,EAAE,MAAM,CAAC,QAAQ;gBACvB,aAAa,EAAE,MAAM,CAAC,eAAe;gBACrC,QAAQ,EAAE,MAAM,CAAC,UAAU;gBAC3B,+DAA+D;gBAC/D,SAAS,EAAE,MAAM,CAAC,YAAY;gBAC9B,uDAAuD;gBACvD,UAAU,EAAE,MAAM,CAAC,UAAU;gBAC7B,UAAU,EAAE,MAAM,CAAC,IAAI;aACxB,CAAC,CAAC;QACL,KAAK,SAAS;YACZ,OAAO,IAAI,aAAa,CAAC;gBACvB,UAAU,EAAE,MAAM,CAAC,YAAY;gBAC/B,MAAM,EAAE,MAAM,CAAC,QAAQ;gBACvB,MAAM,EAAE,MAAM,CAAC,QAAQ;gBACvB,QAAQ,EAAE,MAAM,CAAC,UAAU;gBAC3B,MAAM,EAAE,MAAM,CAAC,QAAQ;gBACvB,aAAa,EAAE,MAAM,CAAC,eAAe;gBACrC,QAAQ,EAAE,MAAM,CAAC,UAAU;gBAC3B,uDAAuD;gBACvD,UAAU,EAAE,MAAM,CAAC,UAAU;gBAC7B,UAAU,EAAE,MAAM,CAAC,IAAI;aACxB,CAAC,CAAC;QACL;YACE,MAAM,IAAI,KAAK,CAAC,mBAAmB,IAAI,gBAAgB,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACxF,CAAC;AACH,CAAC"}
@@ -0,0 +1,82 @@
1
+ import type { Config } from "../config.js";
2
+ import type { SandboxStore } from "../store.js";
3
+ import type { ExecEvent, ExecOptions, FileChangeEvent, FileInfo, ListFilesOptions, MkdirOptions, ReadFileOptions, StartProcessOptions, WaitForPortOptions, WatchOptions, WriteFileOptions } from "../types.js";
4
+ import type { CreateOptions, Driver, HostInfo, ProcessLiveness, SandboxStats, StartProcessResult, TcpBridge, TerminalOptions, TerminalSession } from "./types.js";
5
+ /**
6
+ * Per-sandbox driver router. Implements the `Driver` surface but, instead of
7
+ * doing the work itself, dispatches each call to the runtime driver that backs
8
+ * the addressed sandbox — so a single daemon can run container sandboxes and
9
+ * Apple VZ microVM sandboxes side by side ("swap the isolation tier per sandbox,
10
+ * change nothing else"). Every existing `driver.<op>(id, …)` call site keeps
11
+ * working unchanged; the routing happens here.
12
+ *
13
+ * The sandbox→driver mapping is the record's `driver` field (set at create from
14
+ * the request, persisted in the store). `create`/`start` carry the choice on
15
+ * their `CreateOptions`; id-addressed ops read it back from the store. An unset
16
+ * or unknown value falls back to the daemon default driver. Driver instances are
17
+ * built lazily by name and cached, so an unused driver is never constructed.
18
+ */
19
+ export declare class DriverRouter implements Driver {
20
+ private readonly config;
21
+ private readonly store;
22
+ private readonly defaultName;
23
+ readonly name: string;
24
+ private instances;
25
+ constructor(config: Config, store: SandboxStore, defaultName: string);
26
+ /** Get (constructing + caching on first use) the driver instance for a name. */
27
+ private instance;
28
+ /** The driver backing an existing sandbox (from its record), or the default. */
29
+ private forId;
30
+ /** The driver chosen for a create/start (opts wins, then the record, then default). */
31
+ private forOpts;
32
+ create(opts: CreateOptions): Promise<void>;
33
+ start(opts: CreateOptions): Promise<void>;
34
+ stop(id: string): Promise<void>;
35
+ /** Fast-pause via the backing driver, or `stop` when it doesn't support
36
+ * snapshots — so callers can always call `snapshot` through the router and
37
+ * get the strongest pause the sandbox's isolation tier offers. */
38
+ snapshot(id: string): Promise<void>;
39
+ /** Whether the backing driver can memory-snapshot this sandbox right now. */
40
+ canSnapshot(id: string): boolean;
41
+ destroy(id: string): Promise<void>;
42
+ exec(id: string, command: string, opts: ExecOptions, onEvent: (e: ExecEvent) => void): Promise<number>;
43
+ writeFile(id: string, opts: WriteFileOptions): Promise<void>;
44
+ readFile(id: string, opts: ReadFileOptions): Promise<string>;
45
+ mkdir(id: string, opts: MkdirOptions): Promise<void>;
46
+ listFiles(id: string, opts: ListFilesOptions): Promise<FileInfo[]>;
47
+ watchFiles(id: string, path: string, opts: WatchOptions & {
48
+ signal: AbortSignal;
49
+ }, onEvent: (e: FileChangeEvent) => void): Promise<void>;
50
+ startProcess(id: string, procId: string, command: string, opts: StartProcessOptions): Promise<StartProcessResult>;
51
+ listProcesses(id: string, procs: Array<{
52
+ procId: string;
53
+ pid: number;
54
+ }>): Promise<ProcessLiveness[]>;
55
+ killProcess(id: string, pid: number, signal?: string): Promise<void>;
56
+ streamProcessLogs(id: string, logPath: string, opts: {
57
+ follow: boolean;
58
+ signal: AbortSignal;
59
+ }, onData: (chunk: string) => void): Promise<void>;
60
+ waitForPort(id: string, port: number, opts: WaitForPortOptions): Promise<boolean>;
61
+ openTcpBridge(id: string, port: number, host: string): Promise<TcpBridge>;
62
+ openTerminal(id: string, opts: TerminalOptions): Promise<TerminalSession>;
63
+ createBackup(id: string, tarPath: string): Promise<{
64
+ bytes: number;
65
+ }>;
66
+ restoreBackup(id: string, tarPath: string): Promise<void>;
67
+ stats(id: string): Promise<SandboxStats>;
68
+ /** Ping the default driver — the daemon's fail-fast startup check. Other
69
+ * drivers are validated lazily when a sandbox first selects them. */
70
+ ping(): Promise<void>;
71
+ /**
72
+ * Host capacity for admission control. All drivers describe the same physical
73
+ * host, but each sees it differently — Docker Desktop on macOS reports its own
74
+ * VM's memory, not the Mac's — so ask every instantiated driver and take the
75
+ * most complete view (max). Committed-memory accounting is already
76
+ * driver-agnostic (it sums per-sandbox caps from the store).
77
+ */
78
+ hostInfo(): Promise<HostInfo>;
79
+ /** Best-effort teardown of any driver-held background resources (e.g. the VZ
80
+ * warm pool's pre-booted spare VMs) on daemon shutdown. */
81
+ shutdown(): Promise<void>;
82
+ }
@@ -0,0 +1,159 @@
1
+ import { createNamedDriver } from "./index.js";
2
+ /**
3
+ * Per-sandbox driver router. Implements the `Driver` surface but, instead of
4
+ * doing the work itself, dispatches each call to the runtime driver that backs
5
+ * the addressed sandbox — so a single daemon can run container sandboxes and
6
+ * Apple VZ microVM sandboxes side by side ("swap the isolation tier per sandbox,
7
+ * change nothing else"). Every existing `driver.<op>(id, …)` call site keeps
8
+ * working unchanged; the routing happens here.
9
+ *
10
+ * The sandbox→driver mapping is the record's `driver` field (set at create from
11
+ * the request, persisted in the store). `create`/`start` carry the choice on
12
+ * their `CreateOptions`; id-addressed ops read it back from the store. An unset
13
+ * or unknown value falls back to the daemon default driver. Driver instances are
14
+ * built lazily by name and cached, so an unused driver is never constructed.
15
+ */
16
+ export class DriverRouter {
17
+ config;
18
+ store;
19
+ defaultName;
20
+ name;
21
+ instances = new Map();
22
+ constructor(config, store, defaultName) {
23
+ this.config = config;
24
+ this.store = store;
25
+ this.defaultName = defaultName;
26
+ this.name = defaultName;
27
+ }
28
+ /** Get (constructing + caching on first use) the driver instance for a name. */
29
+ instance(name) {
30
+ const key = name || this.defaultName;
31
+ let d = this.instances.get(key);
32
+ if (!d) {
33
+ d = createNamedDriver(key, this.config);
34
+ this.instances.set(key, d);
35
+ }
36
+ return d;
37
+ }
38
+ /** The driver backing an existing sandbox (from its record), or the default. */
39
+ forId(id) {
40
+ return this.instance(this.store.get(id)?.driver);
41
+ }
42
+ /** The driver chosen for a create/start (opts wins, then the record, then default). */
43
+ forOpts(opts) {
44
+ return this.instance(opts.driver ?? this.store.get(opts.id)?.driver);
45
+ }
46
+ // --- lifecycle (choice carried on opts) -----------------------------------
47
+ create(opts) {
48
+ return this.forOpts(opts).create(opts);
49
+ }
50
+ start(opts) {
51
+ return this.forOpts(opts).start(opts);
52
+ }
53
+ stop(id) {
54
+ return this.forId(id).stop(id);
55
+ }
56
+ /** Fast-pause via the backing driver, or `stop` when it doesn't support
57
+ * snapshots — so callers can always call `snapshot` through the router and
58
+ * get the strongest pause the sandbox's isolation tier offers. */
59
+ snapshot(id) {
60
+ const d = this.forId(id);
61
+ return typeof d.snapshot === "function" ? d.snapshot(id) : d.stop(id);
62
+ }
63
+ /** Whether the backing driver can memory-snapshot this sandbox right now. */
64
+ canSnapshot(id) {
65
+ const d = this.forId(id);
66
+ return typeof d.snapshot === "function" && (d.canSnapshot ? d.canSnapshot(id) : true);
67
+ }
68
+ destroy(id) {
69
+ return this.forId(id).destroy(id);
70
+ }
71
+ // --- id-addressed ops (driver resolved from the record) -------------------
72
+ exec(id, command, opts, onEvent) {
73
+ return this.forId(id).exec(id, command, opts, onEvent);
74
+ }
75
+ writeFile(id, opts) {
76
+ return this.forId(id).writeFile(id, opts);
77
+ }
78
+ readFile(id, opts) {
79
+ return this.forId(id).readFile(id, opts);
80
+ }
81
+ mkdir(id, opts) {
82
+ return this.forId(id).mkdir(id, opts);
83
+ }
84
+ listFiles(id, opts) {
85
+ return this.forId(id).listFiles(id, opts);
86
+ }
87
+ watchFiles(id, path, opts, onEvent) {
88
+ return this.forId(id).watchFiles(id, path, opts, onEvent);
89
+ }
90
+ startProcess(id, procId, command, opts) {
91
+ return this.forId(id).startProcess(id, procId, command, opts);
92
+ }
93
+ listProcesses(id, procs) {
94
+ return this.forId(id).listProcesses(id, procs);
95
+ }
96
+ killProcess(id, pid, signal) {
97
+ return this.forId(id).killProcess(id, pid, signal);
98
+ }
99
+ streamProcessLogs(id, logPath, opts, onData) {
100
+ return this.forId(id).streamProcessLogs(id, logPath, opts, onData);
101
+ }
102
+ waitForPort(id, port, opts) {
103
+ return this.forId(id).waitForPort(id, port, opts);
104
+ }
105
+ openTcpBridge(id, port, host) {
106
+ return this.forId(id).openTcpBridge(id, port, host);
107
+ }
108
+ openTerminal(id, opts) {
109
+ return this.forId(id).openTerminal(id, opts);
110
+ }
111
+ createBackup(id, tarPath) {
112
+ return this.forId(id).createBackup(id, tarPath);
113
+ }
114
+ restoreBackup(id, tarPath) {
115
+ return this.forId(id).restoreBackup(id, tarPath);
116
+ }
117
+ stats(id) {
118
+ return this.forId(id).stats(id);
119
+ }
120
+ // --- host-level (default driver) ------------------------------------------
121
+ /** Ping the default driver — the daemon's fail-fast startup check. Other
122
+ * drivers are validated lazily when a sandbox first selects them. */
123
+ ping() {
124
+ return this.instance(this.defaultName).ping();
125
+ }
126
+ /**
127
+ * Host capacity for admission control. All drivers describe the same physical
128
+ * host, but each sees it differently — Docker Desktop on macOS reports its own
129
+ * VM's memory, not the Mac's — so ask every instantiated driver and take the
130
+ * most complete view (max). Committed-memory accounting is already
131
+ * driver-agnostic (it sums per-sandbox caps from the store).
132
+ */
133
+ async hostInfo() {
134
+ const drivers = new Set([this.instance(this.defaultName), ...this.instances.values()]);
135
+ let best = { memoryMb: 0, cpus: 0 };
136
+ for (const d of drivers) {
137
+ try {
138
+ const h = await d.hostInfo();
139
+ best = { memoryMb: Math.max(best.memoryMb, h.memoryMb), cpus: Math.max(best.cpus, h.cpus) };
140
+ }
141
+ catch {
142
+ /* an unavailable driver (e.g. Docker down) shouldn't break capacity */
143
+ }
144
+ }
145
+ if (best.memoryMb === 0)
146
+ return this.instance(this.defaultName).hostInfo();
147
+ return best;
148
+ }
149
+ /** Best-effort teardown of any driver-held background resources (e.g. the VZ
150
+ * warm pool's pre-booted spare VMs) on daemon shutdown. */
151
+ async shutdown() {
152
+ for (const d of this.instances.values()) {
153
+ const drain = d.drainPool;
154
+ if (typeof drain === "function")
155
+ await drain.call(d).catch(() => { });
156
+ }
157
+ }
158
+ }
159
+ //# sourceMappingURL=router.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router.js","sourceRoot":"","sources":["../../src/driver/router.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,234 @@
1
+ import type { ExecEvent, ExecOptions, FileChangeEvent, FileInfo, ListFilesOptions, MkdirOptions, ReadFileOptions, ResourceLimits, StartProcessOptions, WaitForPortOptions, WatchOptions, WriteFileOptions } from "../types.js";
2
+ export type { ResourceLimits } from "../types.js";
3
+ /** A live bidirectional byte stream bridged to a port inside a sandbox. */
4
+ export interface TcpBridge {
5
+ /** Raw duplex carrying bytes to/from the in-container TCP relay. */
6
+ stream: NodeJS.ReadWriteStream;
7
+ /** Tear down the bridge and the in-container relay process. */
8
+ close(): void;
9
+ }
10
+ /** Options for opening an interactive terminal (PTY) inside a sandbox. */
11
+ export interface TerminalOptions {
12
+ /** Initial terminal width in columns. */
13
+ cols?: number;
14
+ /** Initial terminal height in rows. */
15
+ rows?: number;
16
+ cwd?: string;
17
+ env?: Record<string, string>;
18
+ }
19
+ /**
20
+ * A live interactive shell (PTY) inside a sandbox. `stream` is a raw duplex:
21
+ * write bytes to send keystrokes to the shell's stdin, read bytes to receive its
22
+ * terminal output (already TTY-cooked, no Docker stream framing). This is the
23
+ * interactive-exec primitive the in-sandbox agent (Phase 3) and the dashboard
24
+ * terminal both build on.
25
+ */
26
+ export interface TerminalSession {
27
+ stream: NodeJS.ReadWriteStream;
28
+ /** Inform the PTY of a new client window size. */
29
+ resize(cols: number, rows: number): void;
30
+ /** Tear down the shell and its exec. */
31
+ close(): void;
32
+ }
33
+ /** Result of launching a background process. */
34
+ export interface StartProcessResult {
35
+ procId: string;
36
+ pid: number;
37
+ logPath: string;
38
+ }
39
+ /** Liveness view of a tracked background process. */
40
+ export interface ProcessLiveness {
41
+ procId: string;
42
+ pid: number;
43
+ running: boolean;
44
+ }
45
+ /** A point-in-time resource snapshot for a running sandbox. */
46
+ export interface SandboxStats {
47
+ /** Instantaneous CPU usage as a percent of one core (can exceed 100). */
48
+ cpuPercent: number;
49
+ /** Cumulative CPU time the container has consumed, in nanoseconds (resets on
50
+ * container recreation). The cost meter integrates the delta of this. */
51
+ cpuTotalUsageNs: number;
52
+ /** Number of CPUs visible to the container (CPU% is over all of them). */
53
+ onlineCpus: number;
54
+ /** Resident memory in bytes (page cache excluded where the runtime reports it). */
55
+ memBytes: number;
56
+ /** Memory limit in bytes (0 if unlimited/unknown). */
57
+ memLimitBytes: number;
58
+ /** Cumulative network bytes received across all interfaces. */
59
+ netRxBytes: number;
60
+ /** Cumulative network bytes transmitted across all interfaces. */
61
+ netTxBytes: number;
62
+ /** Number of processes/threads in the container. */
63
+ pids: number;
64
+ /** ISO timestamp the snapshot was taken. */
65
+ sampledAt: string;
66
+ }
67
+ export interface CreateOptions {
68
+ id: string;
69
+ image: string;
70
+ /**
71
+ * Runtime driver to back this sandbox (per-sandbox isolation selection). The
72
+ * `DriverRouter` reads it to dispatch `create`/`start`; later id-addressed ops
73
+ * resolve the driver from the sandbox record. Empty → the daemon default.
74
+ */
75
+ driver?: string;
76
+ env?: Record<string, string>;
77
+ labels?: Record<string, string>;
78
+ /**
79
+ * Back `/workspace` with a named volume so files outlive the container. With
80
+ * persistence the container is cattle: `stop` removes it, `start` recreates it,
81
+ * and the workspace survives. Defaults to true.
82
+ */
83
+ persist?: boolean;
84
+ /**
85
+ * Ordered shell commands run once, after the container starts at create time
86
+ * (e.g. `npm i kimiflare`). Best-effort: a non-zero exit is logged, not fatal.
87
+ * Not re-run on resume — with persistence the workspace already has the result.
88
+ */
89
+ setup?: string[];
90
+ /**
91
+ * Git repository URL cloned into `/workspace` at create time (before `setup`),
92
+ * so an agent comes up with the code in place. Private repos: embed a token in
93
+ * the URL (`https://<token>@github.com/owner/repo.git`). A clone failure fails
94
+ * create (unlike best-effort `setup`).
95
+ */
96
+ repo?: string;
97
+ /** Branch/tag to check out when cloning `repo` (default: the repo's default branch). */
98
+ repoRef?: string;
99
+ /** Hard CPU/memory/PID caps for the sandbox (resolved effective values). */
100
+ limits?: ResourceLimits;
101
+ }
102
+ /**
103
+ * Runtime-driver interface — the core abstraction of sbx.
104
+ *
105
+ * Phase 0 ships the `container` driver (Docker Engine API). Future drivers
106
+ * (`firecracker` on Linux, `applevz` on macOS) implement this same surface so
107
+ * the daemon, SDK, and CLI are unchanged when you swap isolation tiers.
108
+ *
109
+ * Drivers are addressed by the public sandbox `id`; they derive their own
110
+ * backing-resource name from it and stay otherwise stateless.
111
+ */
112
+ export interface Driver {
113
+ readonly name: string;
114
+ /** Provision and start a sandbox (creating its persistent volume if needed). */
115
+ create(opts: CreateOptions): Promise<void>;
116
+ /**
117
+ * Stop a sandbox, freeing its compute. With persistence the container is
118
+ * removed but its workspace volume is kept, so `start` can recreate it with
119
+ * the data intact. In-container processes do not survive a stop.
120
+ */
121
+ stop(id: string): Promise<void>;
122
+ /**
123
+ * (Re)create and start a sandbox's container, reattaching its persistent
124
+ * volume. Used to resume a stopped sandbox; the workspace is preserved.
125
+ */
126
+ start(opts: CreateOptions): Promise<void>;
127
+ /**
128
+ * Optional fast-pause: save the sandbox's full live state (guest RAM + device
129
+ * state) to disk and free its compute, such that the next `start` resumes
130
+ * **without a kernel boot** — background processes/servers come back live.
131
+ * Only microVM drivers can implement this; callers must feature-detect
132
+ * (`typeof driver.snapshot === "function"`) and fall back to `stop`, whose
133
+ * contract (workspace survives, processes don't) is the lowest common
134
+ * denominator. Implementations must sync the guest fs first so a restore
135
+ * failure can safely degrade to a cold boot with the workspace intact.
136
+ */
137
+ snapshot?(id: string): Promise<void>;
138
+ /**
139
+ * Whether `snapshot` can fast-pause this sandbox *right now* (VM live, host
140
+ * OS supports save/restore). Callers use this to pick pause semantics up
141
+ * front — e.g. the idle reaper only pauses a sandbox with running background
142
+ * processes when they'll survive the resume.
143
+ */
144
+ canSnapshot?(id: string): boolean;
145
+ /**
146
+ * Run a command inside the sandbox, streaming output via `onEvent`.
147
+ * Resolves with the process exit code.
148
+ */
149
+ exec(id: string, command: string, opts: ExecOptions, onEvent: (e: ExecEvent) => void): Promise<number>;
150
+ /** Write a file inside the sandbox. */
151
+ writeFile(id: string, opts: WriteFileOptions): Promise<void>;
152
+ /** Read a file from the sandbox, returning its UTF-8 contents. */
153
+ readFile(id: string, opts: ReadFileOptions): Promise<string>;
154
+ /** Create a directory inside the sandbox. */
155
+ mkdir(id: string, opts: MkdirOptions): Promise<void>;
156
+ /** List files and directories at the given path. */
157
+ listFiles(id: string, opts: ListFilesOptions): Promise<FileInfo[]>;
158
+ /**
159
+ * Watch a path (recursively) for file changes, invoking `onEvent` per change
160
+ * until `opts.signal` aborts. Resolves when watching stops.
161
+ */
162
+ watchFiles(id: string, path: string, opts: WatchOptions & {
163
+ signal: AbortSignal;
164
+ }, onEvent: (e: FileChangeEvent) => void): Promise<void>;
165
+ /**
166
+ * Launch a detached background process. `procId` is daemon-supplied so the
167
+ * in-container logfile is deterministic. Resolves once the process is spawned.
168
+ */
169
+ startProcess(id: string, procId: string, command: string, opts: StartProcessOptions): Promise<StartProcessResult>;
170
+ /** Report liveness for the given in-container PIDs. */
171
+ listProcesses(id: string, procs: Array<{
172
+ procId: string;
173
+ pid: number;
174
+ }>): Promise<ProcessLiveness[]>;
175
+ /** Send a signal to a process group (default TERM). */
176
+ killProcess(id: string, pid: number, signal?: string): Promise<void>;
177
+ /** Stream a process logfile to `onData`; `follow` tails it until aborted. */
178
+ streamProcessLogs(id: string, logPath: string, opts: {
179
+ follow: boolean;
180
+ signal: AbortSignal;
181
+ }, onData: (chunk: string) => void): Promise<void>;
182
+ /** Block until a TCP port is listening inside the sandbox, or timeout. */
183
+ waitForPort(id: string, port: number, opts: WaitForPortOptions): Promise<boolean>;
184
+ /**
185
+ * Open a raw bidirectional byte bridge to `host:port` inside the sandbox.
186
+ * Used by the preview-URL proxy; goes through the Docker socket so it works
187
+ * even where container IPs are unreachable from the host (macOS Docker Desktop).
188
+ */
189
+ openTcpBridge(id: string, port: number, host: string): Promise<TcpBridge>;
190
+ /**
191
+ * Open an interactive shell (PTY) inside the sandbox. Returns a duplex byte
192
+ * stream (write = stdin, read = terminal output) plus resize/close controls.
193
+ * Backs the dashboard's live terminal over WebSocket. The sandbox must be live.
194
+ */
195
+ openTerminal(id: string, opts: TerminalOptions): Promise<TerminalSession>;
196
+ /**
197
+ * Archive the sandbox's `/workspace` to a tar file at `tarPath` on the daemon
198
+ * host. Returns the number of bytes written. The sandbox must be running.
199
+ */
200
+ createBackup(id: string, tarPath: string): Promise<{
201
+ bytes: number;
202
+ }>;
203
+ /**
204
+ * Replace the sandbox's `/workspace` with the contents of the tar at
205
+ * `tarPath`. Existing workspace contents are cleared first. The sandbox must
206
+ * be running; the backup may originate from a different sandbox.
207
+ */
208
+ restoreBackup(id: string, tarPath: string): Promise<void>;
209
+ /**
210
+ * Permanently destroy the sandbox and free its resources, including its
211
+ * persistent workspace volume. This is irreversible — use `stop` to pause.
212
+ */
213
+ destroy(id: string): Promise<void>;
214
+ /**
215
+ * Snapshot the sandbox's live resource usage (CPU, memory, network, pids).
216
+ * The sandbox must be running.
217
+ */
218
+ stats(id: string): Promise<SandboxStats>;
219
+ /** Liveness check for the underlying runtime (e.g. Docker daemon reachable). */
220
+ ping(): Promise<void>;
221
+ /**
222
+ * Total host capacity available to the runtime — total memory (MiB) and CPU
223
+ * count. Backs the capacity meter + admission control. For the container
224
+ * driver this is the Docker host/VM's `MemTotal` / `NCPU`.
225
+ */
226
+ hostInfo(): Promise<HostInfo>;
227
+ }
228
+ /** Total host capacity as seen by the runtime. */
229
+ export interface HostInfo {
230
+ /** Total memory available to the runtime, in MiB. */
231
+ memoryMb: number;
232
+ /** Number of CPUs available to the runtime. */
233
+ cpus: number;
234
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/driver/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,50 @@
1
+ import type { CreateOptions, Driver, HostInfo, ProcessLiveness, SandboxStats, StartProcessResult, TcpBridge, TerminalOptions, TerminalSession } from "./types.js";
2
+ import type { ExecEvent, ExecOptions, FileChangeEvent, FileInfo, ListFilesOptions, MkdirOptions, ReadFileOptions, StartProcessOptions, WaitForPortOptions, WatchOptions, WriteFileOptions } from "../types.js";
3
+ /**
4
+ * Base class for runtime drivers that are part of the architecture but not yet
5
+ * built (the Phase 3 microVM drivers). It implements the whole `Driver` surface
6
+ * so the seam — driver selection, the daemon/SDK/CLI layering — is real and
7
+ * compiles today; every operation throws a clear "not implemented" error, and
8
+ * each concrete subclass overrides `ping()` to explain what host support it needs.
9
+ *
10
+ * When a microVM driver is actually implemented (on a KVM Linux box / a Mac with
11
+ * Virtualization.framework) it stops extending this and implements the methods
12
+ * for real — nothing else in the codebase changes.
13
+ */
14
+ export declare abstract class UnsupportedDriver implements Driver {
15
+ abstract readonly name: string;
16
+ /** Subclasses throw a host-specific "this driver needs X" error here. */
17
+ abstract ping(): Promise<void>;
18
+ protected fail(op: string): never;
19
+ create(_opts: CreateOptions): Promise<void>;
20
+ stop(_id: string): Promise<void>;
21
+ start(_opts: CreateOptions): Promise<void>;
22
+ exec(_id: string, _command: string, _opts: ExecOptions, _onEvent: (e: ExecEvent) => void): Promise<number>;
23
+ writeFile(_id: string, _opts: WriteFileOptions): Promise<void>;
24
+ readFile(_id: string, _opts: ReadFileOptions): Promise<string>;
25
+ mkdir(_id: string, _opts: MkdirOptions): Promise<void>;
26
+ listFiles(_id: string, _opts: ListFilesOptions): Promise<FileInfo[]>;
27
+ watchFiles(_id: string, _path: string, _opts: WatchOptions & {
28
+ signal: AbortSignal;
29
+ }, _onEvent: (e: FileChangeEvent) => void): Promise<void>;
30
+ startProcess(_id: string, _procId: string, _command: string, _opts: StartProcessOptions): Promise<StartProcessResult>;
31
+ listProcesses(_id: string, _procs: Array<{
32
+ procId: string;
33
+ pid: number;
34
+ }>): Promise<ProcessLiveness[]>;
35
+ killProcess(_id: string, _pid: number, _signal?: string): Promise<void>;
36
+ streamProcessLogs(_id: string, _logPath: string, _opts: {
37
+ follow: boolean;
38
+ signal: AbortSignal;
39
+ }, _onData: (chunk: string) => void): Promise<void>;
40
+ waitForPort(_id: string, _port: number, _opts: WaitForPortOptions): Promise<boolean>;
41
+ openTcpBridge(_id: string, _port: number, _host: string): Promise<TcpBridge>;
42
+ openTerminal(_id: string, _opts: TerminalOptions): Promise<TerminalSession>;
43
+ createBackup(_id: string, _tarPath: string): Promise<{
44
+ bytes: number;
45
+ }>;
46
+ restoreBackup(_id: string, _tarPath: string): Promise<void>;
47
+ destroy(_id: string): Promise<void>;
48
+ stats(_id: string): Promise<SandboxStats>;
49
+ hostInfo(): Promise<HostInfo>;
50
+ }
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Base class for runtime drivers that are part of the architecture but not yet
3
+ * built (the Phase 3 microVM drivers). It implements the whole `Driver` surface
4
+ * so the seam — driver selection, the daemon/SDK/CLI layering — is real and
5
+ * compiles today; every operation throws a clear "not implemented" error, and
6
+ * each concrete subclass overrides `ping()` to explain what host support it needs.
7
+ *
8
+ * When a microVM driver is actually implemented (on a KVM Linux box / a Mac with
9
+ * Virtualization.framework) it stops extending this and implements the methods
10
+ * for real — nothing else in the codebase changes.
11
+ */
12
+ export class UnsupportedDriver {
13
+ fail(op) {
14
+ throw new Error(`driver "${this.name}" does not implement ${op} yet — it is a planned ` +
15
+ `Phase 3 microVM driver (see docs/plan.md). Use SBX_DRIVER=container.`);
16
+ }
17
+ async create(_opts) {
18
+ this.fail("create");
19
+ }
20
+ async stop(_id) {
21
+ this.fail("stop");
22
+ }
23
+ async start(_opts) {
24
+ this.fail("start");
25
+ }
26
+ async exec(_id, _command, _opts, _onEvent) {
27
+ this.fail("exec");
28
+ }
29
+ async writeFile(_id, _opts) {
30
+ this.fail("writeFile");
31
+ }
32
+ async readFile(_id, _opts) {
33
+ this.fail("readFile");
34
+ }
35
+ async mkdir(_id, _opts) {
36
+ this.fail("mkdir");
37
+ }
38
+ async listFiles(_id, _opts) {
39
+ this.fail("listFiles");
40
+ }
41
+ async watchFiles(_id, _path, _opts, _onEvent) {
42
+ this.fail("watchFiles");
43
+ }
44
+ async startProcess(_id, _procId, _command, _opts) {
45
+ this.fail("startProcess");
46
+ }
47
+ async listProcesses(_id, _procs) {
48
+ this.fail("listProcesses");
49
+ }
50
+ async killProcess(_id, _pid, _signal) {
51
+ this.fail("killProcess");
52
+ }
53
+ async streamProcessLogs(_id, _logPath, _opts, _onData) {
54
+ this.fail("streamProcessLogs");
55
+ }
56
+ async waitForPort(_id, _port, _opts) {
57
+ this.fail("waitForPort");
58
+ }
59
+ async openTcpBridge(_id, _port, _host) {
60
+ this.fail("openTcpBridge");
61
+ }
62
+ async openTerminal(_id, _opts) {
63
+ this.fail("openTerminal");
64
+ }
65
+ async createBackup(_id, _tarPath) {
66
+ this.fail("createBackup");
67
+ }
68
+ async restoreBackup(_id, _tarPath) {
69
+ this.fail("restoreBackup");
70
+ }
71
+ async destroy(_id) {
72
+ this.fail("destroy");
73
+ }
74
+ async stats(_id) {
75
+ this.fail("stats");
76
+ }
77
+ async hostInfo() {
78
+ this.fail("hostInfo");
79
+ }
80
+ }
81
+ //# sourceMappingURL=unsupported.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unsupported.js","sourceRoot":"","sources":["../../src/driver/unsupported.ts"],"names":[],"mappings":"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"}