humanish 0.98.0 → 0.99.1

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 (36) hide show
  1. package/AGENTS.md +2 -0
  2. package/README.md +3 -2
  3. package/dist/browser-control-client.js +4 -2
  4. package/dist/browser-control-client.js.map +1 -1
  5. package/dist/browser-control-dispatcher.js +1 -1
  6. package/dist/browser-control-dispatcher.js.map +1 -1
  7. package/dist/computer-use.js +21 -8
  8. package/dist/computer-use.js.map +1 -1
  9. package/dist/doctor-lab.js +1 -1
  10. package/dist/doctor-lab.js.map +1 -1
  11. package/dist/local-firecracker-desktop.js +35 -19
  12. package/dist/local-firecracker-desktop.js.map +1 -1
  13. package/dist/local-runtime-host.d.ts +31 -0
  14. package/dist/local-runtime-host.js +128 -0
  15. package/dist/local-runtime-host.js.map +1 -0
  16. package/dist/local-runtime-release.d.ts +2 -0
  17. package/dist/local-runtime-release.js +14 -4
  18. package/dist/local-runtime-release.js.map +1 -1
  19. package/dist/local-runtime-ssh.d.ts +21 -0
  20. package/dist/local-runtime-ssh.js +89 -0
  21. package/dist/local-runtime-ssh.js.map +1 -0
  22. package/dist/local-runtime.d.ts +2 -3
  23. package/dist/local-runtime.js +37 -19
  24. package/dist/local-runtime.js.map +1 -1
  25. package/dist/restricted-codex-session.js +23 -9
  26. package/dist/restricted-codex-session.js.map +1 -1
  27. package/docs/architecture/browser-control.md +6 -0
  28. package/docs/architecture/local-browser-runtime.md +61 -14
  29. package/docs/architecture/restricted-codex-analysis.md +4 -2
  30. package/docs/contracts/schemas.md +1 -1
  31. package/docs/goals/current.md +7 -6
  32. package/docs/ramp/README.md +8 -1
  33. package/docs/release/0.99.0-local-browser-mac.md +34 -0
  34. package/docs/release/0.99.1-action-recovery.md +19 -0
  35. package/docs/release/open-source-readiness.md +10 -0
  36. package/package.json +1 -1
@@ -1,19 +1,15 @@
1
- import { execFile } from "node:child_process";
2
1
  import { randomUUID } from "node:crypto";
3
2
  import { mkdir, mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
4
3
  import { connect, createServer } from "node:net";
5
- import { tmpdir } from "node:os";
6
4
  import path from "node:path";
7
5
  import { setTimeout as delay } from "node:timers/promises";
8
- import { promisify } from "node:util";
9
6
  import { connectGuestBootstrap } from "./guest-bootstrap.js";
10
7
  import { ownDesktopAllocation } from "./desktop-session.js";
11
- const exec = promisify(execFile);
12
- const docker = async (args) => (await exec("docker", args, {
13
- timeout: 60_000, maxBuffer: 1024 * 1024
14
- })).stdout.trim();
8
+ import { runtimeDocker, runtimeExec, usesLima } from "./local-runtime-host.js";
9
+ import { openLimaTunnel } from "./local-runtime-ssh.js";
10
+ const docker = async (args) => (await runtimeDocker(args, {}, 60_000)).stdout.trim();
15
11
  const readLogs = async (id) => {
16
- const result = await exec("docker", ["logs", "--tail", "100", id], { timeout: 10_000, maxBuffer: 1024 * 1024 });
12
+ const result = await runtimeDocker(["logs", "--tail", "100", id], {}, 10_000);
17
13
  return result.stdout + result.stderr;
18
14
  };
19
15
  /** One VM and an opaque TCP forward to the explicitly selected loopback app. */
@@ -26,15 +22,17 @@ export async function createLocalFirecrackerDesktop(options) {
26
22
  options.signal?.throwIfAborted();
27
23
  await mkdir(options.outputRoot, { recursive: true, mode: 0o700 });
28
24
  // Unix socket paths have a small fixed limit; project paths may be much longer.
29
- const work = await mkdtemp(path.join(tmpdir(), "humanish-fc-"));
25
+ const work = await mkdtemp("/tmp/humanish-fc-");
26
+ const lima = usesLima();
30
27
  const sockets = new Set();
31
28
  let container;
32
29
  let client;
33
30
  const stop = new AbortController();
34
31
  const signal = options.signal ? AbortSignal.any([options.signal, stop.signal]) : stop.signal;
35
- const socketRoot = path.join(work, "vm");
36
- const cidfile = path.join(work, "container-id");
37
- await mkdir(socketRoot, { mode: 0o700 });
32
+ let remoteWork;
33
+ let tunnel;
34
+ let socketRoot = path.join(work, "vm"), cidfile = path.join(work, "container-id");
35
+ let controlSocket = path.join(socketRoot, "vsock.sock");
38
36
  const forward = createServer(incoming => {
39
37
  if (signal.aborted) {
40
38
  incoming.destroy();
@@ -62,7 +60,7 @@ export async function createLocalFirecrackerDesktop(options) {
62
60
  options.signal?.removeEventListener("abort", aborted);
63
61
  // Docker can create the container before its command's reply is interrupted.
64
62
  // Only this invocation's private cidfile is cleanup authority.
65
- container ??= await readFile(cidfile, "utf8").then(value => /^[a-f0-9]{64}$/.test(value.trim()) ? value.trim() : undefined, () => undefined);
63
+ container ??= await (lima ? runtimeExec("cat", [cidfile]).then(result => result.stdout) : readFile(cidfile, "utf8")).then(value => /^[a-f0-9]{64}$/.test(value.trim()) ? value.trim() : undefined, () => undefined);
66
64
  if (container) {
67
65
  try {
68
66
  await docker(["rm", "--force", "--volumes", container]);
@@ -73,7 +71,11 @@ export async function createLocalFirecrackerDesktop(options) {
73
71
  return { status: "unconfirmed", reason: "release_failed" };
74
72
  }
75
73
  }
74
+ if (tunnel && !await tunnel.close())
75
+ return { status: "unconfirmed", reason: "release_failed" };
76
76
  try {
77
+ if (remoteWork)
78
+ await runtimeExec("rm", ["-rf", "--", remoteWork]);
77
79
  await rm(work, { recursive: true, force: true });
78
80
  }
79
81
  catch {
@@ -83,10 +85,24 @@ export async function createLocalFirecrackerDesktop(options) {
83
85
  })();
84
86
  const aborted = () => { void close(); };
85
87
  try {
86
- await new Promise((resolve, reject) => {
87
- forward.once("error", reject);
88
- forward.listen(path.join(socketRoot, "vsock.sock_8000"), () => { forward.off("error", reject); resolve(); });
89
- });
88
+ let uid = process.getuid?.() || 1000, gid = process.getgid?.() || 1000;
89
+ if (lima) {
90
+ remoteWork = (await runtimeExec("mktemp", ["-d", "/tmp/humanish-fc-XXXXXX"])).stdout.trim();
91
+ socketRoot = remoteWork;
92
+ cidfile = `${remoteWork}/container-id`;
93
+ controlSocket = path.join(work, "vsock.sock");
94
+ uid = Number((await runtimeExec("id", ["-u"])).stdout.trim());
95
+ gid = Number((await runtimeExec("id", ["-g"])).stdout.trim());
96
+ tunnel = await openLimaTunnel({ work, socketRoot, appUrl: url, signal });
97
+ }
98
+ else {
99
+ await mkdir(socketRoot, { mode: 0o700 });
100
+ }
101
+ if (!lima)
102
+ await new Promise((resolve, reject) => {
103
+ forward.once("error", reject);
104
+ forward.listen(path.join(socketRoot, "vsock.sock_8000"), () => { forward.off("error", reject); resolve(); });
105
+ });
90
106
  const created = await docker(["create", "--rm", "--cidfile", cidfile, "--init", "--user", "0:0", "--read-only", "--cap-drop", "ALL",
91
107
  "--cap-add", "NET_ADMIN", "--cap-add", "SETUID", "--cap-add", "SETGID", "--cap-add", "CHOWN",
92
108
  "--device", "/dev/kvm", "--device", "/dev/net/tun", "--security-opt", "no-new-privileges",
@@ -94,7 +110,7 @@ export async function createLocalFirecrackerDesktop(options) {
94
110
  "--tmpfs", "/tmp:rw,nosuid,nodev,size=16m", "--stop-timeout", "5",
95
111
  "--mount", `type=bind,src=${socketRoot},dst=/run/vm`,
96
112
  "--mount", "type=volume,dst=/run/state,volume-nocopy",
97
- options.assets.image, url.port, String(process.getuid?.() || 1000), String(process.getgid?.() || 1000)]);
113
+ options.assets.image, url.port, String(uid), String(gid)]);
98
114
  if (!/^[a-f0-9]{64}$/.test(created))
99
115
  throw new Error("Docker did not return a container ID.");
100
116
  container = created;
@@ -115,7 +131,7 @@ export async function createLocalFirecrackerDesktop(options) {
115
131
  if (performance.now() >= deadline)
116
132
  throw new Error("Firecracker browser startup timed out.");
117
133
  stream = await new Promise(resolve => {
118
- const socket = connect(path.join(socketRoot, "vsock.sock"));
134
+ const socket = connect(controlSocket);
119
135
  socket.once("connect", () => resolve(socket));
120
136
  socket.once("error", () => { socket.destroy(); resolve(undefined); });
121
137
  });
@@ -1 +1 @@
1
- {"version":3,"file":"local-firecracker-desktop.js","sourceRoot":"","sources":["../src/local-firecracker-desktop.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC3E,OAAO,EAAE,OAAO,EAAE,YAAY,EAAe,MAAM,UAAU,CAAC;AAC9D,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,UAAU,IAAI,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,oBAAoB,EAAuB,MAAM,sBAAsB,CAAC;AAEjF,MAAM,IAAI,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;AACjC,MAAM,MAAM,GAAG,KAAK,EAAE,IAAc,EAAmB,EAAE,CAAC,CAAC,MAAM,IAAI,CAAC,QAAQ,EAAE,IAAI,EAAE;IACpF,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,GAAG,IAAI;CACxC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;AAClB,MAAM,QAAQ,GAAG,KAAK,EAAE,EAAU,EAAmB,EAAE;IACrD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,CAAC,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,GAAG,IAAI,EAAE,CAAC,CAAC;IAChH,OAAO,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;AACvC,CAAC,CAAC;AAQF,gFAAgF;AAChF,MAAM,CAAC,KAAK,UAAU,6BAA6B,CAAC,OAEnD;IACC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACpC,IAAI,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC;WAChG,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,IAAI,EAAE,CAAC;QACxF,MAAM,IAAI,KAAK,CAAC,yEAAyE,CAAC,CAAC;IAC7F,CAAC;IACD,OAAO,CAAC,MAAM,EAAE,cAAc,EAAE,CAAC;IACjC,MAAM,KAAK,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAClE,gFAAgF;IAChF,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,cAAc,CAAC,CAAC,CAAC;IAChE,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAClC,IAAI,SAA6B,CAAC;IAClC,IAAI,MAAqE,CAAC;IAC1E,MAAM,IAAI,GAAG,IAAI,eAAe,EAAE,CAAC;IACnC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC;IAC7F,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACzC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;IAChD,MAAM,KAAK,CAAC,UAAU,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACzC,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,CAAC,EAAE;QACtC,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;YAAC,OAAO;QAAC,CAAC;QACnD,MAAM,MAAM,GAAG,OAAO,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,QAAQ,EAAE,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,gBAAgB,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/F,KAAK,MAAM,MAAM,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,EAAE,CAAC;YACxC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACpB,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;YACnD,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACtE,CAAC;QACD,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC7C,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;QAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;IACjG,CAAC,CAAC,CAAC;IACH,IAAI,OAAwD,CAAC;IAC7D,MAAM,KAAK,GAA4B,GAAG,EAAE,CAAC,OAAO,KAAK,CAAC,KAAK,IAAI,EAAE;QACnE,IAAI,CAAC,KAAK,EAAE,CAAC;QAAC,MAAM,EAAE,KAAK,EAAE,CAAC;QAC9B,KAAK,MAAM,MAAM,IAAI,OAAO;YAAE,MAAM,CAAC,OAAO,EAAE,CAAC;QAC/C,IAAI,OAAO,CAAC,SAAS;YAAE,OAAO,CAAC,KAAK,EAAE,CAAC;QACvC,OAAO,CAAC,MAAM,EAAE,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACtD,6EAA6E;QAC7E,+DAA+D;QAC/D,SAAS,KAAK,MAAM,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QAC7I,IAAI,SAAS,EAAE,CAAC;YACd,IAAI,CAAC;gBACH,MAAM,MAAM,CAAC,CAAC,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC,CAAC;YAC1D,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,MAAM,GAAI,KAA6B,CAAC,MAAM,IAAI,EAAE,CAAC;gBAC3D,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,sBAAsB,SAAS,EAAE,CAAC;oBAAE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,gBAAgB,EAAE,CAAC;YACtH,CAAC;QACH,CAAC;QACD,IAAI,CAAC;YAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAAC,CAAC;QACzD,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,gBAAgB,EAAE,CAAC;QAAC,CAAC;QACrE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC;IACtD,CAAC,CAAC,EAAE,CAAC;IACL,MAAM,OAAO,GAAG,GAAS,EAAE,GAAG,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;IAC9C,IAAI,CAAC;QACH,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC1C,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YAC9B,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,iBAAiB,CAAC,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/G,CAAC,CAAC,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,KAAK;YACjI,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,WAAW,EAAE,OAAO;YAC5F,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,cAAc,EAAE,gBAAgB,EAAE,mBAAmB;YACzF,UAAU,EAAE,uBAAuB,EAAE,UAAU,EAAE,IAAI,EAAE,eAAe,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,cAAc,EAAE,KAAK;YAClH,SAAS,EAAE,+BAA+B,EAAE,gBAAgB,EAAE,GAAG;YACjE,SAAS,EAAE,iBAAiB,UAAU,cAAc;YACpD,SAAS,EAAE,0CAA0C;YACrD,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,IAAI,IAAI,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC;QAC3G,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;QAC9F,SAAS,GAAG,OAAO,CAAC;QACpB,MAAM,CAAC,cAAc,EAAE,CAAC;QACxB,MAAM,MAAM,CAAC,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC;QACnC,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC;QAC5C,OAAO,CAAC,CAAC,MAAM,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,6BAA6B,CAAC,EAAE,CAAC;YAC5E,MAAM,CAAC,cAAc,EAAE,CAAC;YACxB,IAAI,MAAM,MAAM,CAAC,CAAC,SAAS,EAAE,UAAU,EAAE,oBAAoB,EAAE,SAAS,CAAC,CAAC,KAAK,MAAM;gBAAE,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;YAC7I,IAAI,WAAW,CAAC,GAAG,EAAE,IAAI,QAAQ;gBAAE,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;YAC9F,MAAM,KAAK,CAAC,GAAG,EAAE,SAAS,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;QAC1C,CAAC;QACD,IAAI,MAA0B,CAAC;QAC/B,OAAO,CAAC,MAAM,EAAE,CAAC;YACf,MAAM,CAAC,cAAc,EAAE,CAAC;YACxB,IAAI,WAAW,CAAC,GAAG,EAAE,IAAI,QAAQ;gBAAE,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;YAC7F,MAAM,GAAG,MAAM,IAAI,OAAO,CAAqB,OAAO,CAAC,EAAE;gBACvD,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC,CAAC;gBAC5D,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;gBAC9C,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACxE,CAAC,CAAC,CAAC;YACH,IAAI,CAAC,MAAM;gBAAE,MAAM,KAAK,CAAC,GAAG,EAAE,SAAS,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;QACvD,CAAC;QACD,MAAM,QAAQ,GAAG,EAAE,UAAU,EAAE,UAAU,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE,EAAE,eAAe,EAAE,OAAO,CAAC,MAAM,CAAC,eAAe,EAAE,CAAC;QACxH,MAAM,GAAG,MAAM,qBAAqB,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;QAC/D,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;QACrB,KAAK,MAAM,MAAM,IAAI;YACnB,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE;YAC3E,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,GAAG,EAAE;SACxD;YAAE,MAAM,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC,CAAC,EAAE,GAAG,MAAM,EAAE,IAAI,EAAE,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC/H,MAAM,CAAC,cAAc,EAAE,CAAC;QACxB,OAAO,CAAC,MAAM,EAAE,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QACnE,OAAO,oBAAoB,CAAC,EAAE,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,IAAI,EAAE;gBACvE,MAAM,MAAM,GAAG,MAAM,KAAK,EAAE,CAAC;gBAC7B,OAAO,MAAM,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,gBAAgB,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;YACrG,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC7B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,SAAS,EAAE,CAAC;YACd,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;YACvD,8EAA8E;YAC9E,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,WAAW,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QACrI,CAAC;QACD,MAAM,KAAK,EAAE,CAAC;QACd,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"local-firecracker-desktop.js","sourceRoot":"","sources":["../src/local-firecracker-desktop.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ export declare const LIMA_INSTANCE = "humanish-runtime";
2
+ export interface RuntimeHostOptions {
3
+ env?: NodeJS.ProcessEnv;
4
+ signal?: AbortSignal;
5
+ platform?: NodeJS.Platform;
6
+ arch?: string;
7
+ }
8
+ export declare const usesLima: (options?: RuntimeHostOptions) => boolean;
9
+ export declare function runtimeArchitecture(options?: RuntimeHostOptions): "amd64" | "arm64" | undefined;
10
+ export declare function hostExec(file: string, args: string[], options?: RuntimeHostOptions, timeout?: number): Promise<{
11
+ stdout: string;
12
+ stderr: string;
13
+ }>;
14
+ /** Commands inside the Linux host. Lima carries argv; no shell interpolation. */
15
+ export declare function runtimeExec(file: string, args: string[], options?: RuntimeHostOptions, timeout?: number): Promise<{
16
+ stdout: string;
17
+ stderr: string;
18
+ }>;
19
+ export declare function runtimeDocker(args: string[], options?: RuntimeHostOptions, timeout?: number): Promise<{
20
+ stdout: string;
21
+ stderr: string;
22
+ }>;
23
+ export declare const LIMA_TEMPLATE = "minimumLimaVersion: 2.2.0\nvmType: vz\narch: aarch64\nnestedVirtualization: true\ncpus: 6\nmemory: 8GiB\ndisk: 80GiB\nimages:\n - location: https://cloud.debian.org/images/cloud/trixie/20260712-2537/debian-13-genericcloud-arm64-20260712-2537.qcow2\n arch: aarch64\n digest: sha512:8543d795f2fde630eb66c492f245a8c1da19dedc636e0a8e7b3d0f95920e1a05aa911ef2d82d177d41cc53ced5fccbd2a3945d07fa5e15018914c4d864bb07ed\nmounts: []\ncontainerd:\n system: false\n user: false\nssh:\n forwardAgent: false\nportForwards:\n - guestIP: 0.0.0.0\n guestIPMustBeZero: false\n guestPortRange: [1, 65535]\n proto: any\n ignore: true\nprovision:\n - mode: system\n script: |\n #!/bin/sh\n set -eu\n export DEBIAN_FRONTEND=noninteractive\n apt-get update\n apt-get install -y --no-install-recommends docker.io docker-cli ca-certificates\n systemctl enable --now docker\n";
24
+ export declare function limaStatus(options?: RuntimeHostOptions): Promise<{
25
+ ready: boolean;
26
+ exists: boolean;
27
+ message: string;
28
+ }>;
29
+ export declare function prepareLima(options?: RuntimeHostOptions, progress?: (message: string) => void): Promise<void>;
30
+ /** Copy across the OS boundary explicitly; shared folders cannot carry sockets. */
31
+ export declare function loadRuntimeArchive(archive: string, options: RuntimeHostOptions): Promise<void>;
@@ -0,0 +1,128 @@
1
+ import { execFile } from "node:child_process";
2
+ import { mkdtemp, rm, writeFile } from "node:fs/promises";
3
+ import { tmpdir } from "node:os";
4
+ import path from "node:path";
5
+ import { promisify } from "node:util";
6
+ const exec = promisify(execFile);
7
+ export const LIMA_INSTANCE = "humanish-runtime";
8
+ export const usesLima = (options = {}) => (options.platform ?? process.platform) === "darwin";
9
+ export function runtimeArchitecture(options = {}) {
10
+ const platform = options.platform ?? process.platform, arch = options.arch ?? process.arch;
11
+ if (platform === "linux" && arch === "x64")
12
+ return "amd64";
13
+ if ((platform === "linux" || platform === "darwin") && arch === "arm64")
14
+ return "arm64";
15
+ return undefined;
16
+ }
17
+ export async function hostExec(file, args, options = {}, timeout = 15_000) {
18
+ return exec(file, args, { env: options.env ?? process.env, timeout, maxBuffer: 1024 * 1024,
19
+ ...(options.signal ? { signal: options.signal } : {}) });
20
+ }
21
+ /** Commands inside the Linux host. Lima carries argv; no shell interpolation. */
22
+ export async function runtimeExec(file, args, options = {}, timeout = 15_000) {
23
+ return usesLima(options)
24
+ ? hostExec("limactl", ["shell", "--workdir", "/", LIMA_INSTANCE, "--", file, ...args], options, timeout)
25
+ : hostExec(file, args, options, timeout);
26
+ }
27
+ export async function runtimeDocker(args, options = {}, timeout = 15_000) {
28
+ return usesLima(options)
29
+ ? runtimeExec("sudo", ["-n", "docker", "--host", "unix:///var/run/docker.sock", ...args], options, timeout)
30
+ : runtimeExec("docker", args, options, timeout);
31
+ }
32
+ // No host mounts, agent forwarding or automatic app-port discovery. Per-study
33
+ // OpenSSH forwards grant just the selected app and browser-control sockets.
34
+ export const LIMA_TEMPLATE = `minimumLimaVersion: 2.2.0
35
+ vmType: vz
36
+ arch: aarch64
37
+ nestedVirtualization: true
38
+ cpus: 6
39
+ memory: 8GiB
40
+ disk: 80GiB
41
+ images:
42
+ - location: https://cloud.debian.org/images/cloud/trixie/20260712-2537/debian-13-genericcloud-arm64-20260712-2537.qcow2
43
+ arch: aarch64
44
+ digest: sha512:8543d795f2fde630eb66c492f245a8c1da19dedc636e0a8e7b3d0f95920e1a05aa911ef2d82d177d41cc53ced5fccbd2a3945d07fa5e15018914c4d864bb07ed
45
+ mounts: []
46
+ containerd:
47
+ system: false
48
+ user: false
49
+ ssh:
50
+ forwardAgent: false
51
+ portForwards:
52
+ - guestIP: 0.0.0.0
53
+ guestIPMustBeZero: false
54
+ guestPortRange: [1, 65535]
55
+ proto: any
56
+ ignore: true
57
+ provision:
58
+ - mode: system
59
+ script: |
60
+ #!/bin/sh
61
+ set -eu
62
+ export DEBIAN_FRONTEND=noninteractive
63
+ apt-get update
64
+ apt-get install -y --no-install-recommends docker.io docker-cli ca-certificates
65
+ systemctl enable --now docker
66
+ `;
67
+ export async function limaStatus(options = {}) {
68
+ const chip = (await hostExec("sysctl", ["-n", "machdep.cpu.brand_string"], options)).stdout.trim();
69
+ const generation = /^Apple M(\d+)/.exec(chip);
70
+ if (!generation || Number(generation[1]) < 3)
71
+ throw new Error("Local Firecracker on Mac requires an M3 or newer Apple Silicon Mac with nested virtualization.");
72
+ let version;
73
+ try {
74
+ version = (await hostExec("limactl", ["--version"], options)).stdout;
75
+ }
76
+ catch {
77
+ throw new Error("Install Lima 2.2 or newer (brew install lima), then run humanish runtime setup. Docker Desktop is not required.");
78
+ }
79
+ const match = /\b(\d+)\.(\d+)\.\d+/.exec(version);
80
+ if (!match || Number(match[1]) < 2 || (Number(match[1]) === 2 && Number(match[2]) < 2))
81
+ throw new Error("Update Lima to 2.2 or newer (brew upgrade lima), then run humanish runtime setup.");
82
+ const output = (await hostExec("limactl", ["list", "--json"], options)).stdout.trim();
83
+ const instance = output.split("\n").filter(Boolean).map(line => JSON.parse(line))
84
+ .find(value => value.name === LIMA_INSTANCE);
85
+ if (instance && (instance.name !== LIMA_INSTANCE || instance.vmType !== "vz" || instance.arch !== "aarch64"))
86
+ throw new Error(`The existing ${LIMA_INSTANCE} Lima instance is incompatible. Humanish will not replace it.`);
87
+ return { ready: instance?.status === "Running", exists: !!instance,
88
+ message: instance ? "The Humanish Lima host is stopped. Run humanish runtime setup to start it."
89
+ : "Run humanish runtime setup to create the Humanish Lima host and install the browser runtime." };
90
+ }
91
+ export async function prepareLima(options = {}, progress) {
92
+ const status = await limaStatus(options);
93
+ if (status.ready)
94
+ return;
95
+ progress?.(status.exists ? "Starting the Humanish Lima host…" : "Preparing the Humanish Lima host (first setup downloads Linux and Docker)…");
96
+ if (status.exists) {
97
+ await hostExec("limactl", ["start", "--tty=false", LIMA_INSTANCE], options, 15 * 60_000);
98
+ }
99
+ else {
100
+ const work = await mkdtemp(path.join(tmpdir(), "humanish-lima-"));
101
+ try {
102
+ const file = path.join(work, "host.yaml");
103
+ await writeFile(file, LIMA_TEMPLATE, { mode: 0o600 });
104
+ await hostExec("limactl", ["start", "--tty=false", "--name", LIMA_INSTANCE, file], options, 15 * 60_000);
105
+ }
106
+ finally {
107
+ await rm(work, { recursive: true, force: true });
108
+ }
109
+ }
110
+ }
111
+ /** Copy across the OS boundary explicitly; shared folders cannot carry sockets. */
112
+ export async function loadRuntimeArchive(archive, options) {
113
+ if (!usesLima(options)) {
114
+ await runtimeDocker(["load", "--input", archive], options, 10 * 60_000);
115
+ return;
116
+ }
117
+ const work = (await runtimeExec("mktemp", ["-d", "/tmp/humanish-image-XXXXXX"], options)).stdout.trim();
118
+ try {
119
+ await hostExec("limactl", ["copy", archive, `${LIMA_INSTANCE}:${work}/runtime.tar.gz`], options, 10 * 60_000);
120
+ await runtimeDocker(["load", "--input", `${work}/runtime.tar.gz`], options, 10 * 60_000);
121
+ }
122
+ finally {
123
+ // Cancellation must not skip removal of this invocation's copied archive.
124
+ const { signal: _signal, ...cleanup } = options;
125
+ await runtimeExec("rm", ["-rf", "--", work], cleanup);
126
+ }
127
+ }
128
+ //# sourceMappingURL=local-runtime-host.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-runtime-host.js","sourceRoot":"","sources":["../src/local-runtime-host.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,5 @@
1
1
  import type { LocalRuntimeRelease } from "./local-runtime.js";
2
2
  /** Updated with the verified, public runtime artifact before release. */
3
3
  export declare const LOCAL_RUNTIME_RELEASE: LocalRuntimeRelease;
4
+ /** Architecture-specific artifacts; each retains matching sources and notices. */
5
+ export declare const LOCAL_RUNTIME_RELEASES: Partial<Record<"amd64" | "arm64", LocalRuntimeRelease>>;
@@ -1,8 +1,18 @@
1
1
  /** Updated with the verified, public runtime artifact before release. */
2
2
  export const LOCAL_RUNTIME_RELEASE = {
3
- url: "https://github.com/danielgwilson/humanish/releases/download/runtime-2026.09.24.1/runtime-linux-amd64.tar.gz",
4
- sha256: "8df88a82b9615bf35ddcd4a60b1be6f95f178a254d88aab79871aace4a22ac56",
5
- bytes: 596136865,
6
- image: "sha256:9597abdb46255190640443ea485010d2a45f51699e7cb47372d6ee895d280f5c"
3
+ url: "https://github.com/danielgwilson/humanish/releases/download/runtime-2026.09.24.3/runtime-linux-amd64.tar.gz",
4
+ sha256: "936e4bdc5c844347c6d6ae2149f1f96cfcabab0c33c8dd7fb3ae1b74b3b91812",
5
+ bytes: 596154336,
6
+ image: "sha256:062f7e9eb8096f6e48906ec0d277c3a9d086ef4ebd275aa2efc43edcd86e5349"
7
+ };
8
+ /** Architecture-specific artifacts; each retains matching sources and notices. */
9
+ export const LOCAL_RUNTIME_RELEASES = {
10
+ amd64: LOCAL_RUNTIME_RELEASE,
11
+ arm64: {
12
+ url: "https://github.com/danielgwilson/humanish/releases/download/runtime-2026.09.24.4/runtime-linux-arm64.tar.gz",
13
+ sha256: "9b396d1d222917ffbac21ae448340fdcc563a9b2f757682d9806248941125cda",
14
+ bytes: 582659561,
15
+ image: "sha256:ed92f65a1f5b064952ea8b289f6bc1e7b5a9babe15ed1c7efec49e395e86eead"
16
+ }
7
17
  };
8
18
  //# sourceMappingURL=local-runtime-release.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"local-runtime-release.js","sourceRoot":"","sources":["../src/local-runtime-release.ts"],"names":[],"mappings":"AAEA,yEAAyE;AACzE,MAAM,CAAC,MAAM,qBAAqB,GAAwB;IACxD,GAAG,EAAE,6GAA6G;IAClH,MAAM,EAAE,kEAAkE;IAC1E,KAAK,EAAE,SAAS;IAChB,KAAK,EAAE,yEAAyE;CACjF,CAAC"}
1
+ {"version":3,"file":"local-runtime-release.js","sourceRoot":"","sources":["../src/local-runtime-release.ts"],"names":[],"mappings":"AAEA,yEAAyE;AACzE,MAAM,CAAC,MAAM,qBAAqB,GAAwB;IACxD,GAAG,EAAE,6GAA6G;IAClH,MAAM,EAAE,kEAAkE;IAC1E,KAAK,EAAE,SAAS;IAChB,KAAK,EAAE,yEAAyE;CACjF,CAAC;AAEF,kFAAkF;AAClF,MAAM,CAAC,MAAM,sBAAsB,GAA4D;IAC7F,KAAK,EAAE,qBAAqB;IAC5B,KAAK,EAAE;QACL,GAAG,EAAE,6GAA6G;QAClH,MAAM,EAAE,kEAAkE;QAC1E,KAAK,EAAE,SAAS;QAChB,KAAK,EAAE,yEAAyE;KACjF;CACF,CAAC"}
@@ -0,0 +1,21 @@
1
+ /** Standard OpenSSH streamlocal forwarding; no browser-control protocol here. */
2
+ export declare function openRuntimeSshTunnel(options: {
3
+ config: string;
4
+ destination: string;
5
+ localSocket: string;
6
+ remoteSocket: string;
7
+ appSocket: string;
8
+ appHost: string;
9
+ appPort: number;
10
+ signal: AbortSignal;
11
+ }): Promise<{
12
+ close(): Promise<boolean>;
13
+ }>;
14
+ export declare function openLimaTunnel(options: {
15
+ work: string;
16
+ socketRoot: string;
17
+ appUrl: URL;
18
+ signal: AbortSignal;
19
+ }): Promise<{
20
+ close(): Promise<boolean>;
21
+ }>;
@@ -0,0 +1,89 @@
1
+ import { spawn } from "node:child_process";
2
+ import path from "node:path";
3
+ import { setTimeout as delay } from "node:timers/promises";
4
+ import { hostExec, LIMA_INSTANCE } from "./local-runtime-host.js";
5
+ /** Standard OpenSSH streamlocal forwarding; no browser-control protocol here. */
6
+ export async function openRuntimeSshTunnel(options) {
7
+ options.signal.throwIfAborted();
8
+ const child = spawn("ssh", ["-F", options.config, "-T", "-a", "-o", "BatchMode=yes",
9
+ "-o", "ControlMaster=no", "-o", "ControlPath=none", "-o", "ExitOnForwardFailure=yes",
10
+ "-o", "ConnectTimeout=15", "-o", "StreamLocalBindMask=0177",
11
+ "-L", `${options.localSocket}:${options.remoteSocket}`,
12
+ "-R", `${options.appSocket}:${options.appHost}:${options.appPort}`,
13
+ options.destination, "sh -c 'printf \"HUMANISH_SSH_READY\\n\"; exec cat'"], { stdio: ["pipe", "pipe", "pipe"] });
14
+ let exited = false;
15
+ const closed = new Promise(resolve => child.once("close", () => { exited = true; resolve(); }));
16
+ child.stdin.on("error", () => { });
17
+ let closing;
18
+ const close = () => closing ??= (async () => {
19
+ options.signal.removeEventListener("abort", aborted);
20
+ // EOF also closes the remote cat if the parent dies unexpectedly. Do not
21
+ // detach/multiplex this SSH child into Lima's persistent control connection.
22
+ child.stdin.end();
23
+ await Promise.race([closed, delay(1000)]);
24
+ if (!exited)
25
+ child.kill("SIGTERM");
26
+ await Promise.race([closed, delay(1000)]);
27
+ if (!exited)
28
+ child.kill("SIGKILL");
29
+ await Promise.race([closed, delay(1000)]);
30
+ return exited;
31
+ })();
32
+ const aborted = () => { void close(); };
33
+ options.signal.addEventListener("abort", aborted, { once: true });
34
+ try {
35
+ await new Promise((resolve, reject) => {
36
+ const timer = setTimeout(() => finish(new Error("Lima SSH forwarding timed out.")), 20_000);
37
+ let bytes = 0, output = "", ready = false;
38
+ const finish = (error) => {
39
+ if (ready)
40
+ return;
41
+ ready = true;
42
+ clearTimeout(timer);
43
+ if (error)
44
+ reject(error);
45
+ else
46
+ resolve();
47
+ };
48
+ child.once("error", () => finish(new Error("Could not start SSH for the Lima browser.")));
49
+ child.once("close", () => finish(new Error("Lima SSH forwarding closed before it was ready.")));
50
+ child.stderr.on("data", (data) => {
51
+ bytes += data.length;
52
+ if (bytes > 64 * 1024) {
53
+ finish(new Error("Lima SSH forwarding failed."));
54
+ void close();
55
+ }
56
+ });
57
+ child.stdout.on("data", (data) => {
58
+ bytes += data.length;
59
+ if (bytes > 64 * 1024) {
60
+ finish(new Error("Lima SSH forwarding failed."));
61
+ void close();
62
+ return;
63
+ }
64
+ if (!ready) {
65
+ output += data.toString();
66
+ if (output === "HUMANISH_SSH_READY\n")
67
+ finish();
68
+ }
69
+ });
70
+ });
71
+ options.signal.throwIfAborted();
72
+ return { close };
73
+ }
74
+ catch (error) {
75
+ await close();
76
+ throw error;
77
+ }
78
+ }
79
+ export async function openLimaTunnel(options) {
80
+ const settings = await hostExec("limactl", ["list", "--format={{.SSHConfigFile}}", LIMA_INSTANCE], { signal: options.signal });
81
+ const config = settings.stdout.trim();
82
+ if (!path.isAbsolute(config))
83
+ throw new Error("Lima did not return its SSH configuration path.");
84
+ return openRuntimeSshTunnel({ config, destination: `lima-${LIMA_INSTANCE}`,
85
+ localSocket: path.join(options.work, "vsock.sock"), remoteSocket: `${options.socketRoot}/vsock.sock`,
86
+ appSocket: `${options.socketRoot}/vsock.sock_8000`, appHost: options.appUrl.hostname,
87
+ appPort: Number(options.appUrl.port), signal: options.signal });
88
+ }
89
+ //# sourceMappingURL=local-runtime-ssh.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-runtime-ssh.js","sourceRoot":"","sources":["../src/local-runtime-ssh.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import type { LocalFirecrackerAssets } from "./local-firecracker-desktop.js";
2
+ import { type RuntimeHostOptions } from "./local-runtime-host.js";
2
3
  export interface LocalRuntimeRelease {
3
4
  url: string;
4
5
  sha256: string;
@@ -11,9 +12,7 @@ export interface LocalRuntimeStatus {
11
12
  message: string;
12
13
  assets?: LocalFirecrackerAssets;
13
14
  }
14
- interface RuntimeOptions {
15
- env?: NodeJS.ProcessEnv;
16
- signal?: AbortSignal;
15
+ interface RuntimeOptions extends RuntimeHostOptions {
17
16
  progress?: (message: string) => void;
18
17
  /** Explicit source-build/test override; never provided by a participant. */
19
18
  release?: LocalRuntimeRelease;
@@ -1,4 +1,3 @@
1
- import { execFile } from "node:child_process";
2
1
  import { createHash } from "node:crypto";
3
2
  import { createWriteStream } from "node:fs";
4
3
  import { access, mkdtemp, rm } from "node:fs/promises";
@@ -6,44 +5,59 @@ import { tmpdir } from "node:os";
6
5
  import path from "node:path";
7
6
  import { Readable, Transform } from "node:stream";
8
7
  import { pipeline } from "node:stream/promises";
9
- import { promisify } from "node:util";
10
- import { LOCAL_RUNTIME_RELEASE } from "./local-runtime-release.js";
11
- const exec = promisify(execFile);
12
- const docker = async (args, options, timeout = 15_000) => (await exec("docker", args, { env: options.env ?? process.env, timeout, maxBuffer: 1024 * 1024,
13
- ...(options.signal ? { signal: options.signal } : {}) })).stdout.trim();
8
+ import { LOCAL_RUNTIME_RELEASES } from "./local-runtime-release.js";
9
+ import { limaStatus, loadRuntimeArchive, prepareLima, runtimeArchitecture, runtimeDocker, runtimeExec, usesLima } from "./local-runtime-host.js";
10
+ const docker = async (args, options) => (await runtimeDocker(args, options)).stdout.trim();
11
+ const runtimeRelease = (options) => options.release ?? LOCAL_RUNTIME_RELEASES[runtimeArchitecture(options) ?? "amd64"];
14
12
  /** Read-only host and cache inspection. Never pulls an image or starts a container. */
15
13
  export async function localRuntimeStatus(options = {}) {
16
- if (process.platform !== "linux" || process.arch !== "x64") {
17
- return { ok: false, installed: false, message: "Local browsers currently support Linux x64. Mac/Lima integration is not available yet." };
14
+ const architecture = runtimeArchitecture(options), lima = usesLima(options);
15
+ if (!architecture)
16
+ return { ok: false, installed: false, message: "Local browsers need Linux x64/ARM64 or an M3-or-newer Mac with Lima." };
17
+ if (lima) {
18
+ try {
19
+ const status = await limaStatus(options);
20
+ if (!status.ready)
21
+ return { ok: true, installed: false, message: status.message };
22
+ }
23
+ catch (error) {
24
+ return { ok: false, installed: false, message: error.message };
25
+ }
18
26
  }
19
27
  const env = options.env ?? process.env;
20
- if (env.DOCKER_HOST && !env.DOCKER_HOST.startsWith("unix://")) {
28
+ if (!lima && env.DOCKER_HOST && !env.DOCKER_HOST.startsWith("unix://")) {
21
29
  return { ok: false, installed: false, message: "Local browsers need Docker on this machine; a remote DOCKER_HOST cannot reach the local app and control socket." };
22
30
  }
23
31
  try {
24
- await access("/dev/kvm");
25
- await access("/dev/net/tun");
32
+ if (lima)
33
+ await runtimeExec("sh", ["-c", "test -c /dev/kvm && test -c /dev/net/tun"], options);
34
+ else {
35
+ await access("/dev/kvm");
36
+ await access("/dev/net/tun");
37
+ }
26
38
  }
27
39
  catch {
28
40
  return { ok: false, installed: false, message: "Local browsers need Linux KVM (/dev/kvm) and TUN (/dev/net/tun). Enable virtualization on this host." };
29
41
  }
30
42
  try {
31
- if (env.DOCKER_CONTEXT || !env.DOCKER_HOST) {
43
+ if (!lima && (env.DOCKER_CONTEXT || !env.DOCKER_HOST)) {
32
44
  const endpoint = JSON.parse(await docker(["context", "inspect", "--format", "{{json .Endpoints.docker.Host}}"], options));
33
45
  if (typeof endpoint !== "string" || !endpoint.startsWith("unix://")) {
34
46
  return { ok: false, installed: false, message: "Select a local Docker context. Remote Docker cannot reach the local app and control socket." };
35
47
  }
36
48
  }
37
49
  const info = JSON.parse(await docker(["info", "--format", "{{json .}}"], options));
38
- if (info.OSType !== "linux" || !["x86_64", "amd64"].includes(info.Architecture) ||
50
+ if (info.OSType !== "linux" || !(architecture === "amd64" ? ["x86_64", "amd64"] : ["aarch64", "arm64"]).includes(info.Architecture) ||
39
51
  info.SecurityOptions?.some((value) => value.includes("rootless"))) {
40
- return { ok: false, installed: false, message: "Local browsers need a local, rootful Linux x64 Docker engine with KVM access." };
52
+ return { ok: false, installed: false, message: "Local browsers need a local, rootful Linux Docker engine of the matching architecture with KVM access." };
41
53
  }
42
54
  }
43
55
  catch {
44
- return { ok: false, installed: false, message: "Docker is unavailable. Install/start Docker Engine and give your account access, then run humanish runtime setup." };
56
+ return { ok: false, installed: false, message: lima
57
+ ? "Docker is unavailable inside the Humanish Lima host. Check limactl shell humanish-runtime -- sudo systemctl status docker; Docker Desktop is not used."
58
+ : "Docker is unavailable. Install/start Docker Engine and give your account access, then run humanish runtime setup." };
45
59
  }
46
- const release = options.release ?? LOCAL_RUNTIME_RELEASE;
60
+ const release = runtimeRelease(options);
47
61
  const reference = env.HUMANISH_LOCAL_RUNTIME_IMAGE?.trim() || release?.image;
48
62
  if (!reference)
49
63
  return { ok: false, installed: false, message: "This build does not include a published local runtime. Source builds can set HUMANISH_LOCAL_RUNTIME_IMAGE." };
@@ -59,7 +73,7 @@ export async function localRuntimeStatus(options = {}) {
59
73
  const image = images[0];
60
74
  const labels = image?.Config?.Labels ?? {};
61
75
  const revision = labels["to.humanish.runtime.revision"];
62
- if (image?.Os !== "linux" || image.Architecture !== "amd64" || labels["to.humanish.runtime.api"] !== "1" ||
76
+ if (image?.Os !== "linux" || image.Architecture !== architecture || labels["to.humanish.runtime.api"] !== "1" ||
63
77
  typeof revision !== "string" || !/^guest-api1-[a-f0-9]{64}$/.test(revision)) {
64
78
  return { ok: false, installed: false, message: "The cached image is not a compatible Humanish local browser runtime." };
65
79
  }
@@ -68,12 +82,16 @@ export async function localRuntimeStatus(options = {}) {
68
82
  }
69
83
  /** Docker owns the installed image/cache. The archive is verified before docker load. */
70
84
  export async function prepareLocalRuntime(options = {}) {
85
+ if (!runtimeArchitecture(options))
86
+ throw new Error((await localRuntimeStatus(options)).message);
87
+ if (usesLima(options))
88
+ await prepareLima(options, options.progress);
71
89
  const before = await localRuntimeStatus(options);
72
90
  if (!before.ok)
73
91
  throw new Error(before.message);
74
92
  if (before.assets)
75
93
  return before.assets;
76
- const release = options.release ?? LOCAL_RUNTIME_RELEASE;
94
+ const release = runtimeRelease(options);
77
95
  if (!release)
78
96
  throw new Error(before.message);
79
97
  options.progress?.(`Downloading local browser runtime (${Math.ceil(release.bytes / 1024 / 1024)} MiB)…`);
@@ -100,7 +118,7 @@ export async function prepareLocalRuntime(options = {}) {
100
118
  if (bytes !== release.bytes || hash.digest("hex") !== release.sha256)
101
119
  throw new Error("Runtime archive integrity check failed; it was not installed.");
102
120
  options.progress?.("Installing the local browser image…");
103
- await docker(["load", "--input", archive], { ...options, signal }, 10 * 60_000);
121
+ await loadRuntimeArchive(archive, { ...options, signal });
104
122
  const after = await localRuntimeStatus(options);
105
123
  if (!after.assets)
106
124
  throw new Error("Downloaded runtime did not provide the expected image. Run humanish runtime setup to retry.");