humanish 0.79.0 → 0.81.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.
- package/README.md +11 -2
- package/dist/actor-contract.d.ts +16 -0
- package/dist/actor-contract.js.map +1 -1
- package/dist/chrome-cdp-probe.js +13 -0
- package/dist/chrome-cdp-probe.js.map +1 -1
- package/dist/computer-use.d.ts +7 -1
- package/dist/computer-use.js +156 -13
- package/dist/computer-use.js.map +1 -1
- package/dist/concurrent-shared-world-lab.js +1 -0
- package/dist/concurrent-shared-world-lab.js.map +1 -1
- package/dist/cua-actor-lab.d.ts +7 -6
- package/dist/cua-actor-lab.js +95 -21
- package/dist/cua-actor-lab.js.map +1 -1
- package/dist/e2b-desktop-launch.d.ts +28 -1
- package/dist/e2b-desktop-launch.js +88 -1
- package/dist/e2b-desktop-launch.js.map +1 -1
- package/dist/e2b-desktop-screenshot-cleanup.d.ts +15 -0
- package/dist/e2b-desktop-screenshot-cleanup.js +67 -0
- package/dist/e2b-desktop-screenshot-cleanup.js.map +1 -0
- package/dist/e2b-terminal-lab.d.ts +3 -2
- package/dist/e2b-terminal-lab.js +176 -85
- package/dist/e2b-terminal-lab.js.map +1 -1
- package/dist/first-run-path.js +2 -2
- package/dist/first-run-path.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js.map +1 -1
- package/dist/lab-config.d.ts +11 -14
- package/dist/lab-config.js +2 -2
- package/dist/lab-config.js.map +1 -1
- package/dist/openai-responses-cu.js +76 -49
- package/dist/openai-responses-cu.js.map +1 -1
- package/dist/program.js +16 -7
- package/dist/program.js.map +1 -1
- package/dist/run.d.ts +1 -1
- package/dist/shared-world-lab.d.ts +3 -1
- package/dist/shared-world-lab.js +16 -1
- package/dist/shared-world-lab.js.map +1 -1
- package/dist/terminal-node-bootstrap.d.ts +4 -0
- package/dist/terminal-node-bootstrap.js +58 -0
- package/dist/terminal-node-bootstrap.js.map +1 -0
- package/dist/terminal-runtime-auth.d.ts +13 -0
- package/dist/terminal-runtime-auth.js +24 -0
- package/dist/terminal-runtime-auth.js.map +1 -0
- package/docs/architecture/actor-contract.md +22 -0
- package/docs/architecture/terminal-product-lane.md +108 -7
- package/docs/contracts/feedback.md +14 -0
- package/docs/contracts/schemas.md +1 -1
- package/docs/goals/current.md +57 -13
- package/docs/ramp/README.md +1 -1
- package/package.json +4 -2
|
@@ -61,12 +61,20 @@ export interface E2BNetworkOptions {
|
|
|
61
61
|
allowOut?: string[];
|
|
62
62
|
/** Denied traffic. `["0.0.0.0/0"]` with a populated allowOut is the deny-all-but shape. */
|
|
63
63
|
denyOut?: string[];
|
|
64
|
+
/** Static per-host HTTPS header transforms (E2B network rules). Header values override the
|
|
65
|
+
* outbound request's values. These may contain secrets: never persist or log this object.
|
|
66
|
+
* This is a structural subset of the installed SDK's SandboxNetworkRules contract. */
|
|
67
|
+
rules?: Record<string, {
|
|
68
|
+
transform?: {
|
|
69
|
+
headers?: Record<string, string>;
|
|
70
|
+
};
|
|
71
|
+
}[]>;
|
|
64
72
|
}
|
|
65
73
|
export interface E2BDesktopCreateOptions {
|
|
66
74
|
apiKey: string;
|
|
67
75
|
dpi?: number;
|
|
68
76
|
envs?: Record<string, string>;
|
|
69
|
-
/**
|
|
77
|
+
/** Routing and optional header transforms; absent allowOut/denyOut retains unrestricted egress. */
|
|
70
78
|
network?: E2BNetworkOptions;
|
|
71
79
|
lifecycle?: {
|
|
72
80
|
onTimeout: "kill" | "pause";
|
|
@@ -130,6 +138,24 @@ export interface E2BDesktopSandbox {
|
|
|
130
138
|
};
|
|
131
139
|
}
|
|
132
140
|
export declare function loadE2BDesktopModule(): Promise<E2BDesktopModule>;
|
|
141
|
+
export declare const DESKTOP_CREATE_CLEANUP_TIMEOUT_MS = 10000;
|
|
142
|
+
type DesktopCreateCleanup = "killed" | "already_gone" | "unconfirmed";
|
|
143
|
+
/** Startup failed after this call acquired a handle. No credentials/options are included here. */
|
|
144
|
+
export declare class E2BDesktopStartupError extends Error {
|
|
145
|
+
readonly cleanup: DesktopCreateCleanup;
|
|
146
|
+
constructor(error: unknown, cleanup: DesktopCreateCleanup);
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Preserve ownership before the desktop SDK starts Xvfb/XFCE (#581). Its public generic create
|
|
150
|
+
* constructs `new this(...)` through the base SDK, then awaits desktop startup without a catch.
|
|
151
|
+
* Each call gets a separate subclass/closure so concurrent attempts cannot exchange handles.
|
|
152
|
+
*
|
|
153
|
+
* This deliberately depends on SDK construction order, not a copied private `_start` method.
|
|
154
|
+
* The real installed SDK's debug-mode conformance test must pass on dependency updates: the
|
|
155
|
+
* constructor must run before bootstrap and public create must preserve its subclass type.
|
|
156
|
+
* Failures before a constructor returns still have no acquired handle and remain unproven.
|
|
157
|
+
*/
|
|
158
|
+
export declare function guardDesktopSandboxCreate(module: E2BDesktopModule): E2BDesktopModule;
|
|
133
159
|
export declare function isMissingE2BDesktopDependency(error: unknown): boolean;
|
|
134
160
|
/**
|
|
135
161
|
* Detect a SandboxNotFoundError-shaped error from the real @e2b/desktop SDK, WITHOUT importing
|
|
@@ -185,3 +211,4 @@ export declare function isTransientE2BError(error: unknown): boolean;
|
|
|
185
211
|
* warning should say.
|
|
186
212
|
*/
|
|
187
213
|
export declare function withOneRetryOnTransientE2BError<T>(attempt: () => Promise<T>, hooks?: TransientRetryHooks): Promise<T>;
|
|
214
|
+
export {};
|
|
@@ -12,9 +12,10 @@
|
|
|
12
12
|
// meta file.
|
|
13
13
|
import { sep } from "node:path";
|
|
14
14
|
import { fileURLToPath } from "node:url";
|
|
15
|
+
import { protectDesktopScreenshotCleanup } from "./e2b-desktop-screenshot-cleanup.js";
|
|
15
16
|
export async function loadE2BDesktopModule() {
|
|
16
17
|
try {
|
|
17
|
-
return await import("@e2b/desktop");
|
|
18
|
+
return guardDesktopSandboxCreate(await import("@e2b/desktop"));
|
|
18
19
|
}
|
|
19
20
|
catch (error) {
|
|
20
21
|
if (isMissingE2BDesktopDependency(error)) {
|
|
@@ -29,6 +30,90 @@ export async function loadE2BDesktopModule() {
|
|
|
29
30
|
throw error;
|
|
30
31
|
}
|
|
31
32
|
}
|
|
33
|
+
export const DESKTOP_CREATE_CLEANUP_TIMEOUT_MS = 10_000;
|
|
34
|
+
/** Startup failed after this call acquired a handle. No credentials/options are included here. */
|
|
35
|
+
export class E2BDesktopStartupError extends Error {
|
|
36
|
+
cleanup;
|
|
37
|
+
constructor(error, cleanup) {
|
|
38
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
39
|
+
const cleanupNote = cleanup === "killed"
|
|
40
|
+
? "the allocated sandbox was reclaimed"
|
|
41
|
+
: cleanup === "already_gone"
|
|
42
|
+
? "the allocated sandbox was already gone"
|
|
43
|
+
: "cleanup of the allocated sandbox was not confirmed; no retry is allowed and its provider timeout remains the backstop";
|
|
44
|
+
super(`Desktop startup failed after allocation; ${cleanupNote}. ${detail}`, { cause: error });
|
|
45
|
+
this.cleanup = cleanup;
|
|
46
|
+
this.name = "E2BDesktopStartupError";
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Preserve ownership before the desktop SDK starts Xvfb/XFCE (#581). Its public generic create
|
|
51
|
+
* constructs `new this(...)` through the base SDK, then awaits desktop startup without a catch.
|
|
52
|
+
* Each call gets a separate subclass/closure so concurrent attempts cannot exchange handles.
|
|
53
|
+
*
|
|
54
|
+
* This deliberately depends on SDK construction order, not a copied private `_start` method.
|
|
55
|
+
* The real installed SDK's debug-mode conformance test must pass on dependency updates: the
|
|
56
|
+
* constructor must run before bootstrap and public create must preserve its subclass type.
|
|
57
|
+
* Failures before a constructor returns still have no acquired handle and remain unproven.
|
|
58
|
+
*/
|
|
59
|
+
export function guardDesktopSandboxCreate(module) {
|
|
60
|
+
const SdkSandbox = module.Sandbox;
|
|
61
|
+
class GuardedSandbox extends SdkSandbox {
|
|
62
|
+
static async create(templateOrOptions, options) {
|
|
63
|
+
let cleanupOwned;
|
|
64
|
+
const CallingSandbox = this;
|
|
65
|
+
class AttemptSandbox extends CallingSandbox {
|
|
66
|
+
constructor(...args) {
|
|
67
|
+
super(...args);
|
|
68
|
+
cleanupOwned = this.kill.bind(this);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
try {
|
|
72
|
+
const args = typeof templateOrOptions === "string" ? [templateOrOptions, options] : [templateOrOptions];
|
|
73
|
+
const desktop = await Reflect.apply(SdkSandbox.create, AttemptSandbox, args);
|
|
74
|
+
// The loader also serves direct Sandbox.create callers (terminal/legacy meta routes).
|
|
75
|
+
return protectDesktopScreenshotCleanup(desktop);
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
if (cleanupOwned === undefined)
|
|
79
|
+
throw error;
|
|
80
|
+
const createOptions = typeof templateOrOptions === "string" ? options : templateOrOptions;
|
|
81
|
+
const requestedTimeout = createOptions?.requestTimeoutMs;
|
|
82
|
+
const timeoutMs = requestedTimeout !== undefined && Number.isFinite(requestedTimeout) && requestedTimeout > 0
|
|
83
|
+
? Math.min(requestedTimeout, DESKTOP_CREATE_CLEANUP_TIMEOUT_MS)
|
|
84
|
+
: DESKTOP_CREATE_CLEANUP_TIMEOUT_MS;
|
|
85
|
+
const cleanup = await reclaimFailedDesktopCreate(cleanupOwned, timeoutMs);
|
|
86
|
+
throw new E2BDesktopStartupError(error, cleanup);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return { ...module, Sandbox: GuardedSandbox };
|
|
91
|
+
}
|
|
92
|
+
async function reclaimFailedDesktopCreate(kill, timeoutMs) {
|
|
93
|
+
const controller = new AbortController();
|
|
94
|
+
let timer;
|
|
95
|
+
try {
|
|
96
|
+
const result = await Promise.race([
|
|
97
|
+
kill({ requestTimeoutMs: timeoutMs, signal: controller.signal }),
|
|
98
|
+
new Promise((_resolve, reject) => {
|
|
99
|
+
timer = setTimeout(() => {
|
|
100
|
+
controller.abort();
|
|
101
|
+
reject(new Error("desktop create cleanup deadline reached"));
|
|
102
|
+
}, timeoutMs);
|
|
103
|
+
})
|
|
104
|
+
]);
|
|
105
|
+
// The installed SDK documents false as an exact-id 404: already absent is also reclaimed.
|
|
106
|
+
return result === true ? "killed" : result === false ? "already_gone" : "unconfirmed";
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
// Do not serialize cleanup options, connection state, or provider errors that may echo auth.
|
|
110
|
+
return "unconfirmed";
|
|
111
|
+
}
|
|
112
|
+
finally {
|
|
113
|
+
if (timer !== undefined)
|
|
114
|
+
clearTimeout(timer);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
32
117
|
/**
|
|
33
118
|
* Is humanish running from this project's node_modules, or from an npx cache?
|
|
34
119
|
*
|
|
@@ -94,6 +179,8 @@ export const TRANSIENT_RETRY_DELAY_MS = 3_000;
|
|
|
94
179
|
* that hit the limit should be spaced, not repeated), and anything that names the request as wrong.
|
|
95
180
|
*/
|
|
96
181
|
export function isTransientE2BError(error) {
|
|
182
|
+
if (error instanceof E2BDesktopStartupError && error.cleanup === "unconfirmed")
|
|
183
|
+
return false;
|
|
97
184
|
const message = error instanceof Error ? `${error.name}: ${error.message}` : String(error ?? "");
|
|
98
185
|
if (/timeout|timed out|deadline/i.test(message))
|
|
99
186
|
return false;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"e2b-desktop-launch.js","sourceRoot":"","sources":["../src/e2b-desktop-launch.ts"],"names":[],"mappings":"AAAA,6FAA6F;AAC7F,6FAA6F;AAC7F,wFAAwF;AACxF,4FAA4F;AAC5F,UAAU;AACV,EAAE;AACF,+FAA+F;AAC/F,4FAA4F;AAC5F,gGAAgG;AAChG,yFAAyF;AACzF,0FAA0F;AAC1F,aAAa;AAEb,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAChC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"e2b-desktop-launch.js","sourceRoot":"","sources":["../src/e2b-desktop-launch.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { E2BDesktopSandbox } from "./e2b-desktop-launch.js";
|
|
2
|
+
/** Runtime diagnostic only; no provider errors, file paths, or image contents are retained. */
|
|
3
|
+
export declare function desktopScreenshotCleanupFailures(desktop: object): number;
|
|
4
|
+
/**
|
|
5
|
+
* @e2b/desktop 2.3.3 screenshot() awaits capture and files.read(path), then discards the
|
|
6
|
+
* files.remove(path) promise. A removal that races sandbox teardown can therefore crash Node
|
|
7
|
+
* AFTER valid bytes were returned. Installed-SDK conformance tests pin that behavior (#662).
|
|
8
|
+
*
|
|
9
|
+
* Observe only removal of a file successfully read within THIS screenshot invocation. The
|
|
10
|
+
* exact path comes from the SDK, not a guessed filename pattern. AsyncLocalStorage isolates
|
|
11
|
+
* concurrent screenshots and unrelated file operations without changing SDK method receivers.
|
|
12
|
+
* The ORIGINAL removal promise is returned: an SDK version (or caller) that awaits it still
|
|
13
|
+
* receives the original rejection. No process-wide rejection handler or filesystem retry.
|
|
14
|
+
*/
|
|
15
|
+
export declare function protectDesktopScreenshotCleanup<T extends E2BDesktopSandbox>(desktop: T): T;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
2
|
+
const guarded = new WeakSet();
|
|
3
|
+
const failureCounts = new WeakMap();
|
|
4
|
+
// One long-lived context instance: creating one per desktop would require disable() on every
|
|
5
|
+
// teardown for AsyncLocalStorage itself to be collected. Invocation stores follow async work.
|
|
6
|
+
const screenshotScope = new AsyncLocalStorage();
|
|
7
|
+
/** Runtime diagnostic only; no provider errors, file paths, or image contents are retained. */
|
|
8
|
+
export function desktopScreenshotCleanupFailures(desktop) {
|
|
9
|
+
return failureCounts.get(desktop) ?? 0;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* @e2b/desktop 2.3.3 screenshot() awaits capture and files.read(path), then discards the
|
|
13
|
+
* files.remove(path) promise. A removal that races sandbox teardown can therefore crash Node
|
|
14
|
+
* AFTER valid bytes were returned. Installed-SDK conformance tests pin that behavior (#662).
|
|
15
|
+
*
|
|
16
|
+
* Observe only removal of a file successfully read within THIS screenshot invocation. The
|
|
17
|
+
* exact path comes from the SDK, not a guessed filename pattern. AsyncLocalStorage isolates
|
|
18
|
+
* concurrent screenshots and unrelated file operations without changing SDK method receivers.
|
|
19
|
+
* The ORIGINAL removal promise is returned: an SDK version (or caller) that awaits it still
|
|
20
|
+
* receives the original rejection. No process-wide rejection handler or filesystem retry.
|
|
21
|
+
*/
|
|
22
|
+
export function protectDesktopScreenshotCleanup(desktop) {
|
|
23
|
+
if (guarded.has(desktop))
|
|
24
|
+
return desktop;
|
|
25
|
+
const files = desktop.files;
|
|
26
|
+
const read = files.read;
|
|
27
|
+
const remove = files.remove;
|
|
28
|
+
if (typeof read !== "function" || typeof remove !== "function")
|
|
29
|
+
return desktop;
|
|
30
|
+
const screenshot = desktop.screenshot;
|
|
31
|
+
files.read = function (path, ...args) {
|
|
32
|
+
const pending = read.call(this, path, ...args);
|
|
33
|
+
const scope = screenshotScope.getStore();
|
|
34
|
+
if (scope?.desktop !== desktop)
|
|
35
|
+
return pending;
|
|
36
|
+
return pending.then((value) => {
|
|
37
|
+
scope.paths.add(path);
|
|
38
|
+
return value;
|
|
39
|
+
});
|
|
40
|
+
};
|
|
41
|
+
files.remove = function (path, ...args) {
|
|
42
|
+
const pending = remove.call(this, path, ...args);
|
|
43
|
+
const scope = screenshotScope.getStore();
|
|
44
|
+
if (scope?.desktop === desktop && scope.paths.has(path)) {
|
|
45
|
+
// The secondary handler resolves independently. Returning pending (not catch's promise)
|
|
46
|
+
// preserves awaited removal failures while observing the SDK's detached rejection.
|
|
47
|
+
void pending.catch(() => {
|
|
48
|
+
const count = desktopScreenshotCleanupFailures(desktop) + 1;
|
|
49
|
+
failureCounts.set(desktop, count);
|
|
50
|
+
try {
|
|
51
|
+
process.stderr.write(`humanish desktop: screenshot temporary-file cleanup failed (${count}); image read completed. Sandbox teardown reclaims temporary files.\n`);
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
// A closed diagnostic stream must not turn this secondary rejection observer into a
|
|
55
|
+
// new unhandled rejection. The per-instance counter remains available.
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
return pending;
|
|
60
|
+
};
|
|
61
|
+
desktop.screenshot = function (...args) {
|
|
62
|
+
return screenshotScope.run({ desktop, paths: new Set() }, () => screenshot.apply(this, args));
|
|
63
|
+
};
|
|
64
|
+
guarded.add(desktop);
|
|
65
|
+
return desktop;
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=e2b-desktop-screenshot-cleanup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"e2b-desktop-screenshot-cleanup.js","sourceRoot":"","sources":["../src/e2b-desktop-screenshot-cleanup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAOrD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAU,CAAC;AACtC,MAAM,aAAa,GAAG,IAAI,OAAO,EAAkB,CAAC;AACpD,6FAA6F;AAC7F,8FAA8F;AAC9F,MAAM,eAAe,GAAG,IAAI,iBAAiB,EAA2C,CAAC;AAEzF,+FAA+F;AAC/F,MAAM,UAAU,gCAAgC,CAAC,OAAe;IAC9D,OAAO,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AACzC,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,+BAA+B,CAA8B,OAAU;IACrF,IAAI,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC;QAAE,OAAO,OAAO,CAAC;IACzC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAwB,CAAC;IAC/C,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC;IACxB,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;IAC5B,IAAI,OAAO,IAAI,KAAK,UAAU,IAAI,OAAO,MAAM,KAAK,UAAU;QAAE,OAAO,OAAO,CAAC;IAE/E,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;IACtC,KAAK,CAAC,IAAI,GAAG,UAAU,IAAI,EAAE,GAAG,IAAI;QAClC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,CAAC;QAC/C,MAAM,KAAK,GAAG,eAAe,CAAC,QAAQ,EAAE,CAAC;QACzC,IAAI,KAAK,EAAE,OAAO,KAAK,OAAO;YAAE,OAAO,OAAO,CAAC;QAC/C,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE;YAC5B,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YACtB,OAAO,KAAK,CAAC;QACf,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;IACF,KAAK,CAAC,MAAM,GAAG,UAAU,IAAI,EAAE,GAAG,IAAI;QACpC,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,CAAC;QACjD,MAAM,KAAK,GAAG,eAAe,CAAC,QAAQ,EAAE,CAAC;QACzC,IAAI,KAAK,EAAE,OAAO,KAAK,OAAO,IAAI,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACxD,wFAAwF;YACxF,mFAAmF;YACnF,KAAK,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE;gBACtB,MAAM,KAAK,GAAG,gCAAgC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;gBAC5D,aAAa,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;gBAClC,IAAI,CAAC;oBACH,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,+DAA+D,KAAK,uEAAuE,CAAC,CAAC;gBACpK,CAAC;gBAAC,MAAM,CAAC;oBACP,oFAAoF;oBACpF,uEAAuE;gBACzE,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC,CAAC;IACF,OAAO,CAAC,UAAU,GAAG,UAAU,GAAG,IAAI;QACpC,OAAO,eAAe,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,GAAG,EAAU,EAAE,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;IACxG,CAAC,CAAC;IACF,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACrB,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ActorCompletionReason, ActorPersonaRef, ActorStatus, ActorTrace } from "./actor-contract.js";
|
|
2
2
|
import { type RunLabProvenance } from "./run-status.js";
|
|
3
|
-
import type { LabConfig, LabScenarioCaps } from "./lab-config.js";
|
|
3
|
+
import type { LabConfig, LabScenarioCaps, LabRuntimeAuth } from "./lab-config.js";
|
|
4
4
|
import { type E2BDesktopModule } from "./e2b-desktop-launch.js";
|
|
5
5
|
import { renderObserver, type ObserverResult } from "./observer.js";
|
|
6
6
|
import { type ResolvedPersona } from "./persona.js";
|
|
@@ -59,7 +59,7 @@ export interface TerminalProductLabHooks {
|
|
|
59
59
|
/**
|
|
60
60
|
* The operator environment the lane reads the runtime key from (and from which it asserts no
|
|
61
61
|
* banned credential is requested). Defaults to process.env. The runtime key is injected ONLY
|
|
62
|
-
* into
|
|
62
|
+
* into command-scoped `codex` env or an external header transform — NEVER Sandbox.create envs (the credential
|
|
63
63
|
* boundary); tests plant a fake key here and assert it never reaches metadata/global env/artifacts.
|
|
64
64
|
*/
|
|
65
65
|
env?: Record<string, string | undefined>;
|
|
@@ -363,6 +363,7 @@ export declare function buildLiveTerminalProductBundle(args: {
|
|
|
363
363
|
publicSurfaces: string[];
|
|
364
364
|
caps?: LabScenarioCaps;
|
|
365
365
|
runtimeAuthKeyName: string;
|
|
366
|
+
runtimeAuth?: LabRuntimeAuth;
|
|
366
367
|
policies: {
|
|
367
368
|
allowPrivateRepoAccess: boolean;
|
|
368
369
|
allowProviderCredentials: boolean;
|