humanish 0.96.1 → 0.98.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 (193) hide show
  1. package/AGENTS.md +86 -79
  2. package/CONTRIBUTING.md +7 -2
  3. package/README.md +11 -2
  4. package/dist/actor-contract.d.ts +35 -1
  5. package/dist/actor-contract.js +38 -0
  6. package/dist/actor-contract.js.map +1 -1
  7. package/dist/adapter-extension.js +1 -0
  8. package/dist/adapter-extension.js.map +1 -1
  9. package/dist/automatic-analysis-config.d.ts +15 -5
  10. package/dist/automatic-analysis-config.js +25 -4
  11. package/dist/automatic-analysis-config.js.map +1 -1
  12. package/dist/automatic-study-analysis.js +4 -2
  13. package/dist/automatic-study-analysis.js.map +1 -1
  14. package/dist/browser-control-client.d.ts +14 -0
  15. package/dist/browser-control-client.js +134 -0
  16. package/dist/browser-control-client.js.map +1 -0
  17. package/dist/browser-control-dispatcher.d.ts +14 -0
  18. package/dist/browser-control-dispatcher.js +109 -0
  19. package/dist/browser-control-dispatcher.js.map +1 -0
  20. package/dist/browser-control-protocol.d.ts +371 -0
  21. package/dist/browser-control-protocol.js +155 -0
  22. package/dist/browser-control-protocol.js.map +1 -0
  23. package/dist/browser-control-transport.d.ts +24 -0
  24. package/dist/browser-control-transport.js +156 -0
  25. package/dist/browser-control-transport.js.map +1 -0
  26. package/dist/comms-lease-store.d.ts +1 -0
  27. package/dist/comms-lease-store.js +9 -3
  28. package/dist/comms-lease-store.js.map +1 -1
  29. package/dist/computer-use-actor.d.ts +2 -2
  30. package/dist/computer-use-actor.js +6 -1
  31. package/dist/computer-use-actor.js.map +1 -1
  32. package/dist/computer-use.d.ts +23 -1
  33. package/dist/computer-use.js +253 -70
  34. package/dist/computer-use.js.map +1 -1
  35. package/dist/cua-actor-lab.d.ts +24 -289
  36. package/dist/cua-actor-lab.js +203 -1983
  37. package/dist/cua-actor-lab.js.map +1 -1
  38. package/dist/cua-desktop-lane.d.ts +35 -0
  39. package/dist/cua-desktop-lane.js +13 -0
  40. package/dist/cua-desktop-lane.js.map +1 -0
  41. package/dist/cua-executor-error.d.ts +31 -0
  42. package/dist/cua-executor-error.js +48 -0
  43. package/dist/cua-executor-error.js.map +1 -0
  44. package/dist/cua-provider-error.d.ts +12 -0
  45. package/dist/cua-provider-error.js +28 -0
  46. package/dist/cua-provider-error.js.map +1 -0
  47. package/dist/desktop-session.d.ts +41 -0
  48. package/dist/desktop-session.js +46 -0
  49. package/dist/desktop-session.js.map +1 -0
  50. package/dist/doctor-lab.d.ts +8 -1
  51. package/dist/doctor-lab.js +40 -8
  52. package/dist/doctor-lab.js.map +1 -1
  53. package/dist/e2b-cua-desktop.d.ts +3 -0
  54. package/dist/e2b-cua-desktop.js +675 -0
  55. package/dist/e2b-cua-desktop.js.map +1 -0
  56. package/dist/e2b-cua-provisioning.d.ts +311 -0
  57. package/dist/e2b-cua-provisioning.js +1213 -0
  58. package/dist/e2b-cua-provisioning.js.map +1 -0
  59. package/dist/e2b-desktop-executor.d.ts +1 -24
  60. package/dist/e2b-desktop-executor.js +2 -127
  61. package/dist/e2b-desktop-executor.js.map +1 -1
  62. package/dist/e2b-desktop-session.d.ts +7 -0
  63. package/dist/e2b-desktop-session.js +29 -0
  64. package/dist/e2b-desktop-session.js.map +1 -0
  65. package/dist/e2b-terminal-lab.js +1 -0
  66. package/dist/e2b-terminal-lab.js.map +1 -1
  67. package/dist/frame-signature.d.ts +24 -0
  68. package/dist/frame-signature.js +128 -0
  69. package/dist/frame-signature.js.map +1 -0
  70. package/dist/guest-bootstrap.d.ts +43 -0
  71. package/dist/guest-bootstrap.js +240 -0
  72. package/dist/guest-bootstrap.js.map +1 -0
  73. package/dist/guest-browser-tools.d.ts +8 -0
  74. package/dist/guest-browser-tools.js +66 -0
  75. package/dist/guest-browser-tools.js.map +1 -0
  76. package/dist/guest-chromium-text.d.ts +27 -0
  77. package/dist/guest-chromium-text.js +281 -0
  78. package/dist/guest-chromium-text.js.map +1 -0
  79. package/dist/guest-desktop-executor.d.ts +22 -0
  80. package/dist/guest-desktop-executor.js +177 -0
  81. package/dist/guest-desktop-executor.js.map +1 -0
  82. package/dist/guest-desktop-native.d.ts +14 -0
  83. package/dist/guest-desktop-native.js +131 -0
  84. package/dist/guest-desktop-native.js.map +1 -0
  85. package/dist/guest-runtime-desktop.d.ts +35 -0
  86. package/dist/guest-runtime-desktop.js +231 -0
  87. package/dist/guest-runtime-desktop.js.map +1 -0
  88. package/dist/guest-runtime-main.d.ts +1 -0
  89. package/dist/guest-runtime-main.js +31 -0
  90. package/dist/guest-runtime-main.js.map +1 -0
  91. package/dist/guest-runtime-revision.d.ts +1 -0
  92. package/dist/guest-runtime-revision.js +3 -0
  93. package/dist/guest-runtime-revision.js.map +1 -0
  94. package/dist/guest-runtime.d.ts +25 -0
  95. package/dist/guest-runtime.js +96 -0
  96. package/dist/guest-runtime.js.map +1 -0
  97. package/dist/index.d.ts +1 -1
  98. package/dist/lab-config.js +10 -3
  99. package/dist/lab-config.js.map +1 -1
  100. package/dist/lab-engine.js +6 -0
  101. package/dist/lab-engine.js.map +1 -1
  102. package/dist/lab-summary.d.ts +5 -1
  103. package/dist/lab-summary.js +5 -0
  104. package/dist/lab-summary.js.map +1 -1
  105. package/dist/local-agent-cli.js +1 -1
  106. package/dist/local-agent-cli.js.map +1 -1
  107. package/dist/local-firecracker-desktop.d.ts +13 -0
  108. package/dist/local-firecracker-desktop.js +150 -0
  109. package/dist/local-firecracker-desktop.js.map +1 -0
  110. package/dist/local-firecracker-study.d.ts +9 -0
  111. package/dist/local-firecracker-study.js +93 -0
  112. package/dist/local-firecracker-study.js.map +1 -0
  113. package/dist/local-runtime-config.d.ts +6 -0
  114. package/dist/local-runtime-config.js +56 -0
  115. package/dist/local-runtime-config.js.map +1 -0
  116. package/dist/local-runtime-release.d.ts +3 -0
  117. package/dist/local-runtime-release.js +8 -0
  118. package/dist/local-runtime-release.js.map +1 -0
  119. package/dist/local-runtime.d.ts +25 -0
  120. package/dist/local-runtime.js +113 -0
  121. package/dist/local-runtime.js.map +1 -0
  122. package/dist/observer-app.html +4 -4
  123. package/dist/pricing.d.ts +22 -1
  124. package/dist/pricing.js +22 -0
  125. package/dist/pricing.js.map +1 -1
  126. package/dist/program.js +50 -9
  127. package/dist/program.js.map +1 -1
  128. package/dist/restricted-codex-analysis.d.ts +15 -0
  129. package/dist/restricted-codex-analysis.js +13 -0
  130. package/dist/restricted-codex-analysis.js.map +1 -0
  131. package/dist/restricted-codex-participant-policy.d.ts +39 -0
  132. package/dist/restricted-codex-participant-policy.js +69 -0
  133. package/dist/restricted-codex-participant-policy.js.map +1 -0
  134. package/dist/restricted-codex-participant-run.d.ts +20 -0
  135. package/dist/restricted-codex-participant-run.js +78 -0
  136. package/dist/restricted-codex-participant-run.js.map +1 -0
  137. package/dist/restricted-codex-participant.d.ts +14 -0
  138. package/dist/restricted-codex-participant.js +178 -0
  139. package/dist/restricted-codex-participant.js.map +1 -0
  140. package/dist/restricted-codex-policy.d.ts +56 -0
  141. package/dist/restricted-codex-policy.js +151 -0
  142. package/dist/restricted-codex-policy.js.map +1 -0
  143. package/dist/restricted-codex-session.d.ts +19 -0
  144. package/dist/restricted-codex-session.js +413 -0
  145. package/dist/restricted-codex-session.js.map +1 -0
  146. package/dist/restricted-codex-transport.d.ts +58 -0
  147. package/dist/restricted-codex-transport.js +233 -0
  148. package/dist/restricted-codex-transport.js.map +1 -0
  149. package/dist/run-detail.js +4 -2
  150. package/dist/run-detail.js.map +1 -1
  151. package/dist/run.d.ts +12 -5
  152. package/dist/run.js +17 -1
  153. package/dist/run.js.map +1 -1
  154. package/dist/shared-world-lab.js +2 -2
  155. package/dist/shared-world-lab.js.map +1 -1
  156. package/dist/study-analysis-codex-config.d.ts +11 -0
  157. package/dist/study-analysis-codex-config.js +34 -0
  158. package/dist/study-analysis-codex-config.js.map +1 -0
  159. package/dist/study-analysis-engine.d.ts +6 -3
  160. package/dist/study-analysis-engine.js +19 -10
  161. package/dist/study-analysis-engine.js.map +1 -1
  162. package/dist/study-analysis-job.d.ts +3 -2
  163. package/dist/study-analysis-job.js +1 -1
  164. package/dist/study-analysis-job.js.map +1 -1
  165. package/dist/study-analysis-provider.d.ts +4 -2
  166. package/dist/study-analysis-provider.js +1 -1
  167. package/dist/study-analysis-provider.js.map +1 -1
  168. package/dist/study-analysis-service.d.ts +3 -0
  169. package/dist/study-analysis-service.js +24 -6
  170. package/dist/study-analysis-service.js.map +1 -1
  171. package/dist/study-analysis-validation.d.ts +43 -19
  172. package/dist/study-analysis-validation.js +23 -10
  173. package/dist/study-analysis-validation.js.map +1 -1
  174. package/dist/study-analysis.d.ts +27 -2
  175. package/dist/study-costs.js +6 -0
  176. package/dist/study-costs.js.map +1 -1
  177. package/dist/tui-app.js +102 -102
  178. package/docs/architecture/browser-control.md +117 -0
  179. package/docs/architecture/desktop-sessions.md +80 -0
  180. package/docs/architecture/guest-desktop.md +87 -0
  181. package/docs/architecture/local-browser-runtime.md +100 -0
  182. package/docs/architecture/restricted-codex-analysis.md +91 -0
  183. package/docs/architecture/runtime-broker-core.md +30 -0
  184. package/docs/contracts/schemas.md +1 -1
  185. package/docs/contracts/study-analysis.md +44 -2
  186. package/docs/goals/current.md +25 -9
  187. package/docs/product/automatic-analysis.md +24 -3
  188. package/docs/product/open-source-install-experience.md +7 -0
  189. package/docs/ramp/README.md +30 -13
  190. package/docs/release/0.97.0-codex-account-analysis.md +45 -0
  191. package/docs/release/0.98.0-local-browser-studies.md +31 -0
  192. package/package.json +4 -2
  193. package/skills/humanish/SKILL.md +39 -0
@@ -0,0 +1,231 @@
1
+ import { spawn } from "node:child_process";
2
+ import { createHash, randomBytes } from "node:crypto";
3
+ import { constants } from "node:fs";
4
+ import { lstat, mkdir, open, rm } from "node:fs/promises";
5
+ import { setTimeout as delay } from "node:timers/promises";
6
+ import { chromium } from "playwright-core";
7
+ import { createGuestDesktopNativeTools } from "./guest-desktop-native.js";
8
+ import { createGuestChromiumText } from "./guest-chromium-text.js";
9
+ import { createGuestBrowserTools } from "./guest-browser-tools.js";
10
+ import { createGuestDesktopExecutor } from "./guest-desktop-executor.js";
11
+ import { CuaExecutorError } from "./cua-executor-error.js";
12
+ export const GUEST_RUNTIME_PATHS = Object.freeze({ root: "/opt/humanish/control", run: "/run/humanish", home: "/home/humanish" });
13
+ export const GUEST_RUNTIME_ENV = Object.freeze({ PATH: "/usr/bin:/bin", HOME: "/home/humanish", USER: "humanish", LOGNAME: "humanish",
14
+ LANG: "C.UTF-8", LC_ALL: "C.UTF-8", DISPLAY: ":0", XAUTHORITY: "/run/humanish/Xauthority",
15
+ XDG_RUNTIME_DIR: "/run/humanish/xdg", XDG_CACHE_HOME: "/home/humanish/.cache", XDG_CONFIG_HOME: "/home/humanish/.config", TMPDIR: "/tmp" });
16
+ const bad = () => new CuaExecutorError("execution_failed", "not_dispatched");
17
+ const CONFIG_SHA = "4ae1c52eab748a3624b3948ce792647be258caba70c8c72038b9a43be6459552";
18
+ /** Fixed guest layout. No caller paths, environment, command, page selector or URL. */
19
+ export async function createGuestRuntimeDesktop(options) {
20
+ const controller = new AbortController();
21
+ const signal = AbortSignal.any([options.signal, controller.signal]);
22
+ const children = [];
23
+ let context;
24
+ let pendingContext;
25
+ let content;
26
+ let closing;
27
+ let stopping = false;
28
+ let phase = "layout";
29
+ const progress = (next) => { phase = next; options.onPhase?.(next); };
30
+ function check() { if (signal.aborted || stopping)
31
+ throw bad(); }
32
+ function child(binary, args, input, persistent = false) {
33
+ check();
34
+ const process = spawn(binary, args, { env: GUEST_RUNTIME_ENV, cwd: GUEST_RUNTIME_PATHS.home, stdio: ["pipe", "ignore", "pipe"] });
35
+ let finish;
36
+ const record = { child: process, closed: new Promise(resolve => { finish = resolve; }), exited: false };
37
+ children.push(record);
38
+ const done = new Promise((resolve, reject) => {
39
+ let count = 0, failed = false;
40
+ const fail = () => {
41
+ failed = true;
42
+ if (!record.exited)
43
+ process.kill("SIGKILL");
44
+ if (persistent && !stopping)
45
+ options.onTerminal();
46
+ };
47
+ const timer = persistent ? undefined : setTimeout(fail, 2000);
48
+ // Fixed helpers communicate success through exit status. In particular,
49
+ // xdpyinfo's normal display inventory is large and is not an error log.
50
+ const consume = (data) => {
51
+ count += data.length;
52
+ if (count > 16_384)
53
+ fail();
54
+ };
55
+ process.stderr.on("data", consume);
56
+ process.on("error", fail);
57
+ process.stdin.on("error", fail);
58
+ process.once("exit", () => { record.exited = true; if (persistent && !stopping)
59
+ options.onTerminal(); });
60
+ process.once("close", code => {
61
+ record.exited = true;
62
+ clearTimeout(timer);
63
+ signal.removeEventListener("abort", fail);
64
+ finish();
65
+ if (persistent && !stopping)
66
+ options.onTerminal();
67
+ if (failed || code !== 0)
68
+ reject(bad());
69
+ else
70
+ resolve();
71
+ });
72
+ signal.addEventListener("abort", fail, { once: true });
73
+ process.stdin.end(input);
74
+ if (signal.aborted)
75
+ fail();
76
+ });
77
+ void done.catch(() => { });
78
+ return { done, child: process };
79
+ }
80
+ function close() {
81
+ if (closing)
82
+ return closing;
83
+ stopping = true;
84
+ closing = Promise.resolve().then(async () => {
85
+ let complete = true, timer;
86
+ const work = async () => {
87
+ try {
88
+ await content?.close();
89
+ }
90
+ catch {
91
+ complete = false;
92
+ }
93
+ try {
94
+ const browser = context ?? await pendingContext?.catch(() => undefined);
95
+ if (browser)
96
+ await browser.close();
97
+ }
98
+ catch {
99
+ complete = false;
100
+ }
101
+ for (const record of children)
102
+ if (!record.exited)
103
+ record.child.kill("SIGKILL");
104
+ await Promise.all(children.map(record => record.closed));
105
+ };
106
+ try {
107
+ await Promise.race([work(), new Promise(resolve => { timer = setTimeout(() => { complete = false; resolve(); }, 4000); })]);
108
+ }
109
+ finally {
110
+ clearTimeout(timer);
111
+ for (const record of children)
112
+ if (!record.exited) {
113
+ complete = false;
114
+ record.child.kill("SIGKILL");
115
+ }
116
+ options.signal.removeEventListener("abort", abort);
117
+ }
118
+ return { complete };
119
+ });
120
+ controller.abort();
121
+ return closing;
122
+ }
123
+ const abort = () => { void close(); };
124
+ options.signal.addEventListener("abort", abort, { once: true });
125
+ try {
126
+ progress("layout");
127
+ check();
128
+ if (process.getuid?.() !== 1000 || process.getgid?.() !== 1000)
129
+ throw bad();
130
+ for (const path of [GUEST_RUNTIME_PATHS.run, GUEST_RUNTIME_PATHS.home]) {
131
+ const stat = await lstat(path);
132
+ check();
133
+ if (!stat.isDirectory() || stat.isSymbolicLink() || stat.uid !== 1000 || stat.gid !== 1000 || (stat.mode & 0o777) !== 0o700)
134
+ throw bad();
135
+ }
136
+ const configuration = await open(`${GUEST_RUNTIME_PATHS.root}/openbox.xml`, constants.O_RDONLY | constants.O_NOFOLLOW);
137
+ let config;
138
+ try {
139
+ const stat = await configuration.stat();
140
+ if (!stat.isFile() || stat.uid !== 0 || stat.gid !== 0 || stat.nlink !== 1 || stat.size > 4096 || (stat.mode & 0o777) !== 0o444)
141
+ throw bad();
142
+ config = await configuration.readFile();
143
+ }
144
+ finally {
145
+ await configuration.close();
146
+ }
147
+ if (createHash("sha256").update(config).digest("hex") !== CONFIG_SHA)
148
+ throw bad();
149
+ for (const path of [`${GUEST_RUNTIME_PATHS.run}/xdg`, `${GUEST_RUNTIME_PATHS.run}/capture`, `${GUEST_RUNTIME_PATHS.home}/.cache`, `${GUEST_RUNTIME_PATHS.home}/.config`]) {
150
+ check();
151
+ await mkdir(path, { mode: 0o700 });
152
+ }
153
+ progress("xauthority");
154
+ const auth = await open(GUEST_RUNTIME_ENV.XAUTHORITY, constants.O_CREAT | constants.O_EXCL | constants.O_WRONLY | constants.O_NOFOLLOW, 0o600);
155
+ await auth.close();
156
+ check();
157
+ await child("/usr/bin/xauth", ["-f", GUEST_RUNTIME_ENV.XAUTHORITY, "source", "-"], `add :0 . ${randomBytes(16).toString("hex")}\n`).done;
158
+ check();
159
+ progress("display");
160
+ child("/usr/bin/Xvfb", [":0", "-screen", "0", "960x720x24", "-nolisten", "tcp", "-auth", GUEST_RUNTIME_ENV.XAUTHORITY], undefined, true);
161
+ let displayReady = false;
162
+ for (let attempt = 0; attempt < 100; attempt++) {
163
+ check();
164
+ try {
165
+ await child("/usr/bin/xdpyinfo", []).done;
166
+ displayReady = true;
167
+ break;
168
+ }
169
+ catch {
170
+ await delay(50, undefined, { signal });
171
+ }
172
+ }
173
+ if (!displayReady)
174
+ throw bad();
175
+ progress("window_manager");
176
+ child("/usr/bin/openbox", ["--config-file", `${GUEST_RUNTIME_PATHS.root}/openbox.xml`], undefined, true);
177
+ check();
178
+ progress("browser");
179
+ pendingContext = chromium.launchPersistentContext(`${GUEST_RUNTIME_PATHS.home}/browser`, { executablePath: "/usr/bin/chromium",
180
+ headless: false, chromiumSandbox: true, viewport: null, env: GUEST_RUNTIME_ENV, timeout: 25_000,
181
+ args: ["--window-size=960,680", "--window-position=0,20", "--disable-background-networking", "--disable-component-update", "--no-first-run"] });
182
+ void pendingContext.then(browser => { if (stopping)
183
+ void browser.close().catch(() => { }); }, () => { });
184
+ context = await pendingContext;
185
+ check();
186
+ context.setDefaultTimeout(5000);
187
+ context.setDefaultNavigationTimeout(5000);
188
+ const page = context.pages()[0];
189
+ if (!page || context.pages().length !== 1)
190
+ throw bad();
191
+ progress("sandbox");
192
+ const diagnostic = await context.newPage();
193
+ check();
194
+ await diagnostic.goto("chrome://sandbox");
195
+ check();
196
+ const sandboxReport = await diagnostic.locator("body").innerText();
197
+ if (!["PID namespaces", "Network namespaces", "Seccomp-BPF sandbox"].every(label => new RegExp(label + "\\s+Yes").test(sandboxReport))
198
+ || !sandboxReport.includes("You are adequately sandboxed"))
199
+ throw bad();
200
+ await diagnostic.close();
201
+ check();
202
+ await page.bringToFront();
203
+ check();
204
+ progress("focus");
205
+ const native = createGuestDesktopNativeTools({ display: ":0", temporaryDirectory: `${GUEST_RUNTIME_PATHS.run}/capture`, xauthority: GUEST_RUNTIME_ENV.XAUTHORITY });
206
+ const window = await native.activeWindowId(signal);
207
+ check();
208
+ content = createGuestChromiumText({ context, page, assertFocusedWindow: async (actionSignal) => {
209
+ if (await native.activeWindowId(actionSignal) !== window)
210
+ throw new CuaExecutorError("action_rejected", "not_dispatched");
211
+ } });
212
+ const tools = createGuestBrowserTools(native, content);
213
+ const executor = createGuestDesktopExecutor({ width: 960, height: 720, tools, authoritySignal: signal, onTerminal: options.onTerminal });
214
+ progress("fixture");
215
+ await page.goto(`file://${GUEST_RUNTIME_PATHS.root}/neutral.html`);
216
+ check();
217
+ await page.locator("#note").waitFor();
218
+ check();
219
+ return { executor, close, owner: { context, page, sandboxReport, configSha256: CONFIG_SHA } };
220
+ }
221
+ catch {
222
+ await close();
223
+ throw Object.assign(bad(), { phase });
224
+ }
225
+ finally {
226
+ // The fresh private state belongs to the guest owner. No recursive home removal.
227
+ if (stopping && children.every(record => record.exited))
228
+ await rm(`${GUEST_RUNTIME_PATHS.run}/capture`, { recursive: true, force: true }).catch(() => { });
229
+ }
230
+ }
231
+ //# sourceMappingURL=guest-runtime-desktop.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guest-runtime-desktop.js","sourceRoot":"","sources":["../src/guest-runtime-desktop.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,31 @@
1
+ import { writeSync } from "node:fs";
2
+ import { Duplex } from "node:stream";
3
+ import { runGuestRuntime } from "./guest-runtime.js";
4
+ import { createGuestRuntimeDesktop } from "./guest-runtime-desktop.js";
5
+ import { GUEST_RUNTIME_REVISION } from "./guest-runtime-revision.js";
6
+ // Fixed packaged command only. Stdout is reserved for framed protocol bytes.
7
+ const stop = new AbortController();
8
+ process.on("SIGTERM", () => stop.abort());
9
+ process.on("SIGINT", () => stop.abort());
10
+ const transport = Duplex.from({ readable: process.stdin, writable: process.stdout });
11
+ transport.on("error", () => stop.abort());
12
+ try {
13
+ if (!/^guest-api1-[a-f0-9]{64}$/.test(GUEST_RUNTIME_REVISION))
14
+ throw new Error();
15
+ const markerFd = process.env.HUMANISH_GUEST_SUPERVISION_FD;
16
+ if (!markerFd || !/^[1-9][0-9]{0,3}$/.test(markerFd) || Number(markerFd) < 3 || Number(markerFd) > 4095)
17
+ throw new Error();
18
+ const runtime = await runGuestRuntime({ transport, revision: GUEST_RUNTIME_REVISION, signal: stop.signal,
19
+ marker: value => { if (writeSync(Number(markerFd), value) !== 1)
20
+ throw new Error(); },
21
+ createDesktop: (signal, onTerminal) => createGuestRuntimeDesktop({ signal, onTerminal }) });
22
+ const result = await runtime.closed;
23
+ process.exit(result.complete ? 0 : 1);
24
+ }
25
+ catch {
26
+ stop.abort();
27
+ transport.destroy();
28
+ process.stderr.write("humanish_guest_failed\n");
29
+ process.exitCode = 1;
30
+ }
31
+ //# sourceMappingURL=guest-runtime-main.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guest-runtime-main.js","sourceRoot":"","sources":["../src/guest-runtime-main.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAC;AACvE,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAErE,6EAA6E;AAC7E,MAAM,IAAI,GAAG,IAAI,eAAe,EAAE,CAAC;AACnC,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;AAC1C,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;AACzC,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;AACrF,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;AAC1C,IAAI,CAAC;IACH,IAAI,CAAC,2BAA2B,CAAC,IAAI,CAAC,sBAAsB,CAAC;QAAE,MAAM,IAAI,KAAK,EAAE,CAAC;IACjF,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC;IAC3D,IAAI,CAAC,QAAQ,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,GAAG,IAAI;QAAE,MAAM,IAAI,KAAK,EAAE,CAAC;IAC3H,MAAM,OAAO,GAAG,MAAM,eAAe,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,sBAAsB,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM;QACtG,MAAM,EAAE,KAAK,CAAC,EAAE,GAAG,IAAI,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC;YAAE,MAAM,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC;QACrF,aAAa,EAAE,CAAC,MAAM,EAAE,UAAU,EAAE,EAAE,CAAC,yBAAyB,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC;IAC9F,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC;IACpC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACxC,CAAC;AAAC,MAAM,CAAC;IACP,IAAI,CAAC,KAAK,EAAE,CAAC;IAAC,SAAS,CAAC,OAAO,EAAE,CAAC;IAClC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC;IAChD,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;AACvB,CAAC"}
@@ -0,0 +1 @@
1
+ export declare const GUEST_RUNTIME_REVISION = "development-unpackaged";
@@ -0,0 +1,3 @@
1
+ // Replaced only by the guest packager from its immutable, noncircular input digest.
2
+ export const GUEST_RUNTIME_REVISION = "development-unpackaged";
3
+ //# sourceMappingURL=guest-runtime-revision.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guest-runtime-revision.js","sourceRoot":"","sources":["../src/guest-runtime-revision.ts"],"names":[],"mappings":"AAAA,oFAAoF;AACpF,MAAM,CAAC,MAAM,sBAAsB,GAAG,wBAAwB,CAAC"}
@@ -0,0 +1,25 @@
1
+ import type { Duplex } from "node:stream";
2
+ import type { CuaExecutor } from "./computer-use.js";
3
+ export interface GuestRuntimeDesktop {
4
+ executor: CuaExecutor;
5
+ close(): Promise<{
6
+ complete: boolean;
7
+ }>;
8
+ }
9
+ export interface GuestRuntimeOptions {
10
+ transport: Duplex;
11
+ revision: string;
12
+ signal: AbortSignal;
13
+ /** Fixed private supervision channel, not browser-control output. */
14
+ marker(value: "A" | "R"): void;
15
+ createDesktop(signal: AbortSignal, onTerminal: () => void): Promise<GuestRuntimeDesktop>;
16
+ }
17
+ /** One admitted desktop and one dispatcher. The owner retains physical teardown. */
18
+ export declare function runGuestRuntime(options: GuestRuntimeOptions): Promise<{
19
+ close(): Promise<{
20
+ complete: boolean;
21
+ }>;
22
+ closed: Promise<{
23
+ complete: boolean;
24
+ }>;
25
+ }>;
@@ -0,0 +1,96 @@
1
+ import { attachBrowserControlDispatcher } from "./browser-control-dispatcher.js";
2
+ import { encodeGuestBootstrap, GuestBootstrapReader, GUEST_BOOTSTRAP_LIMITS } from "./guest-bootstrap.js";
3
+ import { CuaExecutorError } from "./cua-executor-error.js";
4
+ /** One admitted desktop and one dispatcher. The owner retains physical teardown. */
5
+ export async function runGuestRuntime(options) {
6
+ const owner = new AbortController();
7
+ const authority = AbortSignal.any([owner.signal, options.signal]);
8
+ let desktop;
9
+ let dispatcher;
10
+ let reader;
11
+ let closing;
12
+ let preparing;
13
+ let resolveClosed;
14
+ const closed = new Promise(resolve => { resolveClosed = resolve; });
15
+ const timer = setTimeout(() => { void close(); }, GUEST_BOOTSTRAP_LIMITS.readyMs);
16
+ function terminal() { void close(); }
17
+ function close() {
18
+ if (closing)
19
+ return closing;
20
+ // Assign before reader/dispatcher teardown can synchronously reenter.
21
+ closing = Promise.resolve().then(async () => {
22
+ reader?.close();
23
+ dispatcher?.close();
24
+ options.transport.destroy();
25
+ let complete = true;
26
+ let deadline;
27
+ const reclaim = async () => {
28
+ try {
29
+ if (!desktop && preparing)
30
+ desktop = await preparing;
31
+ if (desktop)
32
+ complete = (await desktop.close()).complete;
33
+ }
34
+ catch {
35
+ complete = false;
36
+ }
37
+ };
38
+ try {
39
+ await Promise.race([reclaim(), new Promise(resolve => { deadline = setTimeout(() => { complete = false; resolve(); }, 4000); })]);
40
+ }
41
+ finally {
42
+ clearTimeout(deadline);
43
+ options.signal.removeEventListener("abort", terminal);
44
+ options.transport.off("end", terminal);
45
+ options.transport.off("close", terminal);
46
+ // Keep the finite error listener through native close; never surface text.
47
+ if (options.transport.closed)
48
+ options.transport.off("error", terminal);
49
+ const result = { complete };
50
+ resolveClosed(result);
51
+ }
52
+ return { complete };
53
+ });
54
+ owner.abort();
55
+ clearTimeout(timer);
56
+ return closing;
57
+ }
58
+ options.transport.on("error", terminal);
59
+ options.transport.on("end", terminal);
60
+ options.transport.on("close", terminal);
61
+ options.signal.addEventListener("abort", terminal, { once: true });
62
+ try {
63
+ reader = new GuestBootstrapReader(options.transport, options.revision, authority, false, terminal);
64
+ const identity = await reader.identity;
65
+ if (authority.aborted)
66
+ throw new CuaExecutorError("session_revoked", "not_dispatched");
67
+ options.marker("A");
68
+ preparing = options.createDesktop(authority, terminal);
69
+ desktop = await Promise.race([preparing, new Promise((_, reject) => {
70
+ const stop = () => reject(new CuaExecutorError("session_revoked", "not_dispatched"));
71
+ authority.addEventListener("abort", stop, { once: true });
72
+ void preparing.finally(() => authority.removeEventListener("abort", stop)).catch(() => { });
73
+ if (authority.aborted)
74
+ stop();
75
+ })]);
76
+ if (authority.aborted)
77
+ throw new CuaExecutorError("session_revoked", "not_dispatched");
78
+ reader.handoff();
79
+ dispatcher = attachBrowserControlDispatcher({ transport: options.transport, identity, executor: desktop.executor,
80
+ authoritySignal: authority, isAuthorized: () => !authority.aborted });
81
+ // No await in this handoff: an immediate HELLO already has its sole receiver.
82
+ options.transport.write(encodeGuestBootstrap(identity, true), error => { if (error)
83
+ terminal(); });
84
+ options.transport.resume();
85
+ if (authority.aborted || options.transport.destroyed)
86
+ throw new CuaExecutorError("session_revoked", "not_dispatched");
87
+ options.marker("R");
88
+ clearTimeout(timer);
89
+ return { close, closed };
90
+ }
91
+ catch (error) {
92
+ await close();
93
+ throw error;
94
+ }
95
+ }
96
+ //# sourceMappingURL=guest-runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guest-runtime.js","sourceRoot":"","sources":["../src/guest-runtime.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -6,7 +6,7 @@ export type { LabAnalysis, AutomaticAnalysisBudget } from "./automatic-analysis-
6
6
  export type { AutomaticAnalysisHooks, AutomaticAnalysisResult } from "./automatic-analysis-completion.js";
7
7
  export type { AutomaticStudyAnalysisDeps, AutomaticStudyAnalysisOutcome, AutomaticStudyAnalysisView, AutomaticStudyAnalysisCancellation } from "./automatic-study-analysis.js";
8
8
  export { STUDY_ANALYSIS_SCHEMA, STUDY_ANALYSIS_CORRECTION_SCHEMA } from "./study-analysis.js";
9
- export type { StudyAnalysisConfig, StudyAnalysisArtifact, StudyAnalysisResult, StudyAnalysisCorrection, AnalysisConcernReview, LoadedStudyAnalysis } from "./study-analysis.js";
9
+ export type { StudyAnalysisConfig, OpenAIStudyAnalysisConfig, CodexStudyAnalysisConfig, CodexAnalysisIdentity, StudyAnalysisArtifact, StudyAnalysisResult, StudyAnalysisCorrection, AnalysisConcernReview, LoadedStudyAnalysis } from "./study-analysis.js";
10
10
  export { ACTOR_TRACE_SCHEMA, CODEX_APP_SERVER_CAPABILITIES, SCRIPTED_BROWSER_CAPABILITIES, TERMINAL_AGENT_CAPABILITIES, codexResultToActorTrace, codexStatusToCompletionReason } from "./actor-contract.js";
11
11
  export type { ActorCapabilities, ActorCompletionReason, ActorStopCause, ActorLane, ActorPersonaRef, ActorProtocol, ActorStatus, ActorTokenUsage, ActorTrace, ActorRuntimeProvenance, ActorTraceItem, ActorTraceItemKind, ParticipantClosingReport } from "./actor-contract.js";
12
12
  export { actorRegistry, getActor, isCuaActorDescriptor, isScriptedBrowserActorDescriptor, isTerminalActorDescriptor } from "./actor-registry.js";
@@ -1,3 +1,4 @@
1
+ import { isLocalBrowserLab, localBrowserDefaults, localBrowserUnsupportedReason } from "./local-runtime-config.js";
1
2
  import { resolveAutomaticAnalysis } from "./automatic-analysis-config.js";
2
3
  // humanish.lab.v2 — a lab is a COMPOSITION over code primitives, not a hardcoded kind.
3
4
  //
@@ -233,8 +234,8 @@ export function parseLabConfig(raw) {
233
234
  }
234
235
  }
235
236
  else {
236
- if (config.execution?.target !== "e2b-desktop") {
237
- return invalid("app-url subjects require `execution.target: e2b-desktop` with a registered computer-use actor (the actor drives a hosted desktop browser), or a registered scripted-browser actor for local execution.");
237
+ if (config.execution?.target !== "e2b-desktop" && config.execution?.target !== "local") {
238
+ return invalid("app-url computer-use subjects require `execution.target: local` or `e2b-desktop`.");
238
239
  }
239
240
  if (!actorResolvesToComputerUse(type)) {
240
241
  return invalid(`actors[0].type must be a registered computer-use actor for app-url × e2b-desktop labs (one of: ${registeredComputerUseActors().join(", ")}); for local scripted execution use a registered scripted-browser actor (${registeredScriptedBrowserActors().join(", ")}). Got "${type}".`);
@@ -414,7 +415,13 @@ export function parseLabConfig(raw) {
414
415
  const analysisReason = automaticAnalysisRouteReason(config);
415
416
  if (analysisReason)
416
417
  return invalid(analysisReason);
417
- return { ok: true, config, warnings: forwardDeclaredWarnings(config) };
418
+ const normalized = localBrowserDefaults(config);
419
+ if (isLocalBrowserLab(normalized)) {
420
+ const reason = localBrowserUnsupportedReason(normalized);
421
+ if (reason)
422
+ return invalid(reason);
423
+ }
424
+ return { ok: true, config: normalized, warnings: forwardDeclaredWarnings(normalized) };
418
425
  }
419
426
  // The slug interpolates into an in-sandbox shell command; the strict shape is load-bearing.
420
427
  const REPO_SLUG_PATTERN = /^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/;