humanish 0.0.1 → 0.15.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.
- package/AGENTS.md +77 -0
- package/CONTRIBUTING.md +39 -0
- package/LICENSE +21 -0
- package/README.md +437 -8
- package/SECURITY.md +34 -0
- package/dist/actor-contract.d.ts +107 -0
- package/dist/actor-contract.js +286 -0
- package/dist/actor-contract.js.map +1 -0
- package/dist/actor-registry.d.ts +73 -0
- package/dist/actor-registry.js +93 -0
- package/dist/actor-registry.js.map +1 -0
- package/dist/adapter-extension.d.ts +54 -0
- package/dist/adapter-extension.js +214 -0
- package/dist/adapter-extension.js.map +1 -0
- package/dist/argv.d.ts +1 -0
- package/dist/argv.js +8 -0
- package/dist/argv.js.map +1 -0
- package/dist/artifact-reference.d.ts +22 -0
- package/dist/artifact-reference.js +47 -0
- package/dist/artifact-reference.js.map +1 -0
- package/dist/browser-evidence-hygiene.d.ts +7 -0
- package/dist/browser-evidence-hygiene.js +40 -0
- package/dist/browser-evidence-hygiene.js.map +1 -0
- package/dist/claude-agent-sdk.d.ts +94 -0
- package/dist/claude-agent-sdk.js +363 -0
- package/dist/claude-agent-sdk.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +5 -0
- package/dist/cli.js.map +1 -0
- package/dist/codex-app-server-ui.d.ts +39 -0
- package/dist/codex-app-server-ui.js +357 -0
- package/dist/codex-app-server-ui.js.map +1 -0
- package/dist/codex-app-server.d.ts +144 -0
- package/dist/codex-app-server.js +754 -0
- package/dist/codex-app-server.js.map +1 -0
- package/dist/command-failure.d.ts +29 -0
- package/dist/command-failure.js +54 -0
- package/dist/command-failure.js.map +1 -0
- package/dist/computer-use-actor.d.ts +52 -0
- package/dist/computer-use-actor.js +48 -0
- package/dist/computer-use-actor.js.map +1 -0
- package/dist/computer-use.d.ts +232 -0
- package/dist/computer-use.js +615 -0
- package/dist/computer-use.js.map +1 -0
- package/dist/concurrency.d.ts +1 -0
- package/dist/concurrency.js +27 -0
- package/dist/concurrency.js.map +1 -0
- package/dist/concurrent-shared-world-lab.d.ts +115 -0
- package/dist/concurrent-shared-world-lab.js +1094 -0
- package/dist/concurrent-shared-world-lab.js.map +1 -0
- package/dist/core/git-state.d.ts +33 -0
- package/dist/core/git-state.js +277 -0
- package/dist/core/git-state.js.map +1 -0
- package/dist/core/git-workspace.d.ts +31 -0
- package/dist/core/git-workspace.js +447 -0
- package/dist/core/git-workspace.js.map +1 -0
- package/dist/core/index.d.ts +4 -0
- package/dist/core/index.js +3 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/run-primitives.d.ts +66 -0
- package/dist/core/run-primitives.js +120 -0
- package/dist/core/run-primitives.js.map +1 -0
- package/dist/cua-actor-lab.d.ts +621 -0
- package/dist/cua-actor-lab.js +2845 -0
- package/dist/cua-actor-lab.js.map +1 -0
- package/dist/device-presets.d.ts +67 -0
- package/dist/device-presets.js +50 -0
- package/dist/device-presets.js.map +1 -0
- package/dist/e2b-desktop-executor.d.ts +101 -0
- package/dist/e2b-desktop-executor.js +309 -0
- package/dist/e2b-desktop-executor.js.map +1 -0
- package/dist/e2b-desktop-launch.d.ts +144 -0
- package/dist/e2b-desktop-launch.js +59 -0
- package/dist/e2b-desktop-launch.js.map +1 -0
- package/dist/e2b-detached.d.ts +53 -0
- package/dist/e2b-detached.js +130 -0
- package/dist/e2b-detached.js.map +1 -0
- package/dist/e2b-terminal-lab.d.ts +345 -0
- package/dist/e2b-terminal-lab.js +1532 -0
- package/dist/e2b-terminal-lab.js.map +1 -0
- package/dist/env-file.d.ts +14 -0
- package/dist/env-file.js +108 -0
- package/dist/env-file.js.map +1 -0
- package/dist/feedback.d.ts +51 -0
- package/dist/feedback.js +351 -0
- package/dist/feedback.js.map +1 -0
- package/dist/image-evidence.d.ts +2 -0
- package/dist/image-evidence.js +33 -0
- package/dist/image-evidence.js.map +1 -0
- package/dist/index.d.ts +63 -0
- package/dist/index.js +33 -0
- package/dist/index.js.map +1 -0
- package/dist/init-templates.d.ts +12 -0
- package/dist/init-templates.js +369 -0
- package/dist/init-templates.js.map +1 -0
- package/dist/init.d.ts +26 -0
- package/dist/init.js +429 -0
- package/dist/init.js.map +1 -0
- package/dist/lab-app-runner.d.ts +78 -0
- package/dist/lab-app-runner.js +403 -0
- package/dist/lab-app-runner.js.map +1 -0
- package/dist/lab-config.d.ts +583 -0
- package/dist/lab-config.js +1789 -0
- package/dist/lab-config.js.map +1 -0
- package/dist/lab-engine.d.ts +77 -0
- package/dist/lab-engine.js +216 -0
- package/dist/lab-engine.js.map +1 -0
- package/dist/lab-preflight.d.ts +67 -0
- package/dist/lab-preflight.js +385 -0
- package/dist/lab-preflight.js.map +1 -0
- package/dist/labs.d.ts +53 -0
- package/dist/labs.js +382 -0
- package/dist/labs.js.map +1 -0
- package/dist/observer-assets.d.ts +2 -0
- package/dist/observer-assets.js +2630 -0
- package/dist/observer-assets.js.map +1 -0
- package/dist/observer-data.d.ts +63 -0
- package/dist/observer-data.js +145 -0
- package/dist/observer-data.js.map +1 -0
- package/dist/observer-static.d.ts +39 -0
- package/dist/observer-static.js +306 -0
- package/dist/observer-static.js.map +1 -0
- package/dist/observer.d.ts +46 -0
- package/dist/observer.js +550 -0
- package/dist/observer.js.map +1 -0
- package/dist/openai-responses-cu.d.ts +113 -0
- package/dist/openai-responses-cu.js +545 -0
- package/dist/openai-responses-cu.js.map +1 -0
- package/dist/oss-lab.d.ts +52 -0
- package/dist/oss-lab.js +344 -0
- package/dist/oss-lab.js.map +1 -0
- package/dist/oss-meta-lab-scoring.d.ts +15 -0
- package/dist/oss-meta-lab-scoring.js +145 -0
- package/dist/oss-meta-lab-scoring.js.map +1 -0
- package/dist/oss-meta-lab.d.ts +277 -0
- package/dist/oss-meta-lab.js +4529 -0
- package/dist/oss-meta-lab.js.map +1 -0
- package/dist/oss-remote-telemetry.d.ts +77 -0
- package/dist/oss-remote-telemetry.js +403 -0
- package/dist/oss-remote-telemetry.js.map +1 -0
- package/dist/persona.d.ts +35 -0
- package/dist/persona.js +133 -0
- package/dist/persona.js.map +1 -0
- package/dist/pi-agent-core.d.ts +77 -0
- package/dist/pi-agent-core.js +203 -0
- package/dist/pi-agent-core.js.map +1 -0
- package/dist/program.d.ts +54 -0
- package/dist/program.js +2349 -0
- package/dist/program.js.map +1 -0
- package/dist/redaction.d.ts +90 -0
- package/dist/redaction.js +292 -0
- package/dist/redaction.js.map +1 -0
- package/dist/run-paths.d.ts +56 -0
- package/dist/run-paths.js +340 -0
- package/dist/run-paths.js.map +1 -0
- package/dist/run.d.ts +794 -0
- package/dist/run.js +4844 -0
- package/dist/run.js.map +1 -0
- package/dist/scripted-browser-actor.d.ts +297 -0
- package/dist/scripted-browser-actor.js +1399 -0
- package/dist/scripted-browser-actor.js.map +1 -0
- package/dist/scripted-browser-lab.d.ts +107 -0
- package/dist/scripted-browser-lab.js +788 -0
- package/dist/scripted-browser-lab.js.map +1 -0
- package/dist/selected-output-paths.d.ts +49 -0
- package/dist/selected-output-paths.js +354 -0
- package/dist/selected-output-paths.js.map +1 -0
- package/dist/shared-world-lab.d.ts +208 -0
- package/dist/shared-world-lab.js +1049 -0
- package/dist/shared-world-lab.js.map +1 -0
- package/dist/source-archive.d.ts +82 -0
- package/dist/source-archive.js +408 -0
- package/dist/source-archive.js.map +1 -0
- package/dist/stop-conditions.d.ts +26 -0
- package/dist/stop-conditions.js +66 -0
- package/dist/stop-conditions.js.map +1 -0
- package/dist/terminal-agent-actor.d.ts +36 -0
- package/dist/terminal-agent-actor.js +23 -0
- package/dist/terminal-agent-actor.js.map +1 -0
- package/docs/architecture/actor-contract.md +431 -0
- package/docs/architecture/github-feedback-loop.md +189 -0
- package/docs/architecture/local-codex-tui-actor.md +213 -0
- package/docs/architecture/observer.md +118 -0
- package/docs/architecture/oss-lab-poc.md +250 -0
- package/docs/architecture/project-layout.md +166 -0
- package/docs/architecture/state-driven-executor.md +203 -0
- package/docs/architecture/terminal-product-lane.md +148 -0
- package/docs/contracts/adapter-fixtures.md +80 -0
- package/docs/contracts/core.md +71 -0
- package/docs/contracts/feedback.md +145 -0
- package/docs/contracts/policy.md +311 -0
- package/docs/contracts/run-bundle.md +358 -0
- package/docs/contracts/schemas.md +984 -0
- package/docs/goals/current.md +428 -0
- package/docs/principles/invariants-and-defaults.md +135 -0
- package/docs/principles/self-driving-harness.md +129 -0
- package/docs/product/open-source-install-experience.md +237 -0
- package/docs/ramp/README.md +207 -0
- package/docs/release/open-source-readiness.md +208 -0
- package/docs/release/public-readiness-standard.md +205 -0
- package/docs/roadmap/world-class-open-source-v0.md +311 -0
- package/package.json +102 -8
- package/skills/humanish/SKILL.md +244 -0
- package/skills/humanish/agents/openai.yaml +7 -0
- package/index.js +0 -1
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
import { PNG } from "pngjs";
|
|
2
|
+
import { commandFailureInfo, tailOf } from "./command-failure.js";
|
|
3
|
+
const DEFAULT_WAIT_MS = 500;
|
|
4
|
+
const DEFAULT_SCROLL_AMOUNT_PER_TICK = 100;
|
|
5
|
+
const TYPE_FALLBACK_TIMEOUT_MS = 15_000;
|
|
6
|
+
/** Coerce screenshot bytes (Uint8Array or Buffer) to a Node Buffer without copying when possible. */
|
|
7
|
+
function toBuffer(bytes) {
|
|
8
|
+
return Buffer.isBuffer(bytes) ? bytes : Buffer.from(bytes);
|
|
9
|
+
}
|
|
10
|
+
function shellSingleQuote(value) {
|
|
11
|
+
return `'${value.replace(/'/g, "'\\''")}'`;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* A `type` action that failed after both the primary write and the clipboard
|
|
15
|
+
* paste fallback. Carries a redacted attempt chain (path labels only, never the
|
|
16
|
+
* typed text), the failing phase, and a sanitized stderr/stdout tail when the
|
|
17
|
+
* substrate produced one. The loop records `.name` + `.message` into the actor
|
|
18
|
+
* trace notice, so the bundle proves WHERE the type stopped, not just that it did.
|
|
19
|
+
*/
|
|
20
|
+
export class CuaTypeFallbackError extends Error {
|
|
21
|
+
phase;
|
|
22
|
+
attemptChain;
|
|
23
|
+
stderrTail;
|
|
24
|
+
constructor(phase, attemptChain, stderrTail, cause) {
|
|
25
|
+
const chain = attemptChain.join(" -> ");
|
|
26
|
+
const suffix = stderrTail !== undefined && stderrTail.length > 0 ? ` (stderr: ${stderrTail})` : "";
|
|
27
|
+
super(`type fallback failed at ${phase}: ${chain}${suffix}`);
|
|
28
|
+
this.name = "CuaTypeFallbackError";
|
|
29
|
+
this.phase = phase;
|
|
30
|
+
this.attemptChain = attemptChain;
|
|
31
|
+
if (stderrTail !== undefined && stderrTail.length > 0)
|
|
32
|
+
this.stderrTail = stderrTail;
|
|
33
|
+
if (cause !== undefined)
|
|
34
|
+
this.cause = cause;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/** Map a clipboard-command exit code to a CuaTypeFallbackError phase and throw. */
|
|
38
|
+
function throwClipboardCommandFailure(exitCode, stderrTail, attemptChain, cause) {
|
|
39
|
+
if (exitCode === 127) {
|
|
40
|
+
throw new CuaTypeFallbackError("clipboard-utility-missing", [...attemptChain, "no xclip/xsel clipboard utility"], stderrTail, cause);
|
|
41
|
+
}
|
|
42
|
+
throw new CuaTypeFallbackError("clipboard-command", [
|
|
43
|
+
...attemptChain,
|
|
44
|
+
exitCode === undefined ? "clipboard command errored" : `clipboard command failed (exit ${exitCode})`,
|
|
45
|
+
], stderrTail, cause);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Best-effort clipboard-paste fallback for a `type` action after the primary
|
|
49
|
+
* `desktop.write` failed. Records each attempt into `attemptChain` (path labels
|
|
50
|
+
* only) and throws a CuaTypeFallbackError naming the failing phase + a sanitized
|
|
51
|
+
* stderr tail when the chain cannot complete. The typed text is transferred via a
|
|
52
|
+
* temp file (never shell-quoted) and is never included in the chain or error.
|
|
53
|
+
*/
|
|
54
|
+
async function pasteTextViaClipboard(desktop, text, attemptChain) {
|
|
55
|
+
const files = desktop.files;
|
|
56
|
+
const commands = desktop.commands;
|
|
57
|
+
if (!files || !commands) {
|
|
58
|
+
throw new CuaTypeFallbackError("clipboard-unavailable", [
|
|
59
|
+
...attemptChain,
|
|
60
|
+
"clipboard fallback unavailable (no command/file surface)",
|
|
61
|
+
]);
|
|
62
|
+
}
|
|
63
|
+
const path = `/tmp/humanish-cua-type-${Date.now()}-${Math.random().toString(16).slice(2)}.txt`;
|
|
64
|
+
try {
|
|
65
|
+
await files.write(path, text, { requestTimeoutMs: TYPE_FALLBACK_TIMEOUT_MS });
|
|
66
|
+
}
|
|
67
|
+
catch (writeError) {
|
|
68
|
+
throw new CuaTypeFallbackError("clipboard-tempfile", [...attemptChain, "clipboard temp-file write failed"], undefined, writeError);
|
|
69
|
+
}
|
|
70
|
+
const clipboardCommand = [
|
|
71
|
+
"set -euo pipefail",
|
|
72
|
+
"export DISPLAY=\"${DISPLAY:-:0}\"",
|
|
73
|
+
`text_path=${shellSingleQuote(path)}`,
|
|
74
|
+
"cleanup() { rm -f \"$text_path\"; }",
|
|
75
|
+
"trap cleanup EXIT",
|
|
76
|
+
// Try xclip, then fall back to xsel if xclip is absent OR fails; distinguish a
|
|
77
|
+
// missing utility (exit 127) from a utility that ran but failed (exit 1) so the
|
|
78
|
+
// caller can name the phase.
|
|
79
|
+
"if command -v xclip >/dev/null 2>&1 && xclip -selection clipboard < \"$text_path\"; then",
|
|
80
|
+
" :",
|
|
81
|
+
"elif command -v xsel >/dev/null 2>&1 && xsel --clipboard --input < \"$text_path\"; then",
|
|
82
|
+
" :",
|
|
83
|
+
"elif command -v xclip >/dev/null 2>&1 || command -v xsel >/dev/null 2>&1; then",
|
|
84
|
+
" echo 'clipboard utility present but failed to set the clipboard' >&2",
|
|
85
|
+
" exit 1",
|
|
86
|
+
"else",
|
|
87
|
+
" echo 'no xclip/xsel clipboard utility available for paste fallback' >&2",
|
|
88
|
+
" exit 127",
|
|
89
|
+
"fi"
|
|
90
|
+
].join("\n");
|
|
91
|
+
// The real @e2b/desktop Sandbox THROWS CommandExitError on any non-zero exit
|
|
92
|
+
// (it does not return a non-zero exitCode), so the exit code + stderr must be
|
|
93
|
+
// recovered from the thrown error. A structural fake that returns a non-zero
|
|
94
|
+
// exitCode instead of throwing is also handled, so both shapes are covered.
|
|
95
|
+
let runResult;
|
|
96
|
+
let runError;
|
|
97
|
+
try {
|
|
98
|
+
runResult = await commands.run(clipboardCommand, {
|
|
99
|
+
requestTimeoutMs: TYPE_FALLBACK_TIMEOUT_MS,
|
|
100
|
+
timeoutMs: TYPE_FALLBACK_TIMEOUT_MS
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
catch (error) {
|
|
104
|
+
runError = error;
|
|
105
|
+
}
|
|
106
|
+
if (runError !== undefined) {
|
|
107
|
+
const detail = commandFailureInfo(runError);
|
|
108
|
+
throwClipboardCommandFailure(detail.exitCode, detail.stderrTail, attemptChain, runError);
|
|
109
|
+
}
|
|
110
|
+
if (runResult !== undefined && runResult.exitCode !== undefined && runResult.exitCode !== 0) {
|
|
111
|
+
throwClipboardCommandFailure(runResult.exitCode, tailOf(runResult.stderr ?? runResult.stdout), attemptChain);
|
|
112
|
+
}
|
|
113
|
+
attemptChain.push("clipboard write ok");
|
|
114
|
+
try {
|
|
115
|
+
await desktop.press(["Control", "v"]);
|
|
116
|
+
}
|
|
117
|
+
catch (pressError) {
|
|
118
|
+
throw new CuaTypeFallbackError("paste-keypress", [...attemptChain, "paste keypress (Control+V) failed"], undefined, pressError);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Create a CuaExecutor backed by an E2B desktop (or any structural E2BDesktopLike,
|
|
123
|
+
* e.g. a CI fake). observe() captures a frame and computes its perceptual
|
|
124
|
+
* signature; execute() dispatches one CuaAction to the matching desktop method.
|
|
125
|
+
* Every desktop call is awaited so sync and async implementations both work. No
|
|
126
|
+
* screenshot or action is ever logged.
|
|
127
|
+
*/
|
|
128
|
+
export function createE2BDesktopExecutor(desktop, options = {}) {
|
|
129
|
+
const defaultWaitMs = options.defaultWaitMs ?? DEFAULT_WAIT_MS;
|
|
130
|
+
const scrollAmountPerTick = options.scrollAmountPerTick ?? DEFAULT_SCROLL_AMOUNT_PER_TICK;
|
|
131
|
+
return {
|
|
132
|
+
async observe() {
|
|
133
|
+
// Probe browser state before the screenshot so a deterministic stopWhen match
|
|
134
|
+
// and its persisted frame describe the same settled surface as closely as the
|
|
135
|
+
// desktop substrate allows.
|
|
136
|
+
const browserState = await options.observeBrowserState?.().catch(() => undefined);
|
|
137
|
+
const raw = await desktop.screenshot();
|
|
138
|
+
const screenshot = toBuffer(raw);
|
|
139
|
+
return {
|
|
140
|
+
screenshot,
|
|
141
|
+
stateSignature: perceptualSignature(screenshot),
|
|
142
|
+
...(browserState?.url === undefined ? {} : { url: browserState.url }),
|
|
143
|
+
...(browserState?.title === undefined ? {} : { title: browserState.title }),
|
|
144
|
+
...(browserState?.text === undefined ? {} : { text: browserState.text })
|
|
145
|
+
};
|
|
146
|
+
},
|
|
147
|
+
async execute(action) {
|
|
148
|
+
switch (action.kind) {
|
|
149
|
+
case "click": {
|
|
150
|
+
const button = action.button ?? "left";
|
|
151
|
+
if (button === "right") {
|
|
152
|
+
await desktop.rightClick(action.x, action.y);
|
|
153
|
+
}
|
|
154
|
+
else if (button === "middle") {
|
|
155
|
+
await desktop.middleClick(action.x, action.y);
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
await desktop.leftClick(action.x, action.y);
|
|
159
|
+
}
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
case "double_click":
|
|
163
|
+
await desktop.doubleClick(action.x, action.y);
|
|
164
|
+
return;
|
|
165
|
+
case "move":
|
|
166
|
+
await desktop.moveMouse(action.x, action.y);
|
|
167
|
+
return;
|
|
168
|
+
case "scroll": {
|
|
169
|
+
// The real SDK scroll is vertical only and takes no position, so move the
|
|
170
|
+
// cursor to the scroll point first (the action targets a specific spot;
|
|
171
|
+
// scrolling at the wrong cursor position would scroll the wrong panel).
|
|
172
|
+
// dx (horizontal) has no SDK target and is ignored; a zero dy is a no-op.
|
|
173
|
+
if (action.dy === 0)
|
|
174
|
+
return;
|
|
175
|
+
await desktop.moveMouse(action.x, action.y);
|
|
176
|
+
const direction = action.dy > 0 ? "down" : "up";
|
|
177
|
+
const amount = Math.max(1, Math.round(Math.abs(action.dy) / scrollAmountPerTick));
|
|
178
|
+
await desktop.scroll(direction, amount);
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
case "type": {
|
|
182
|
+
const attemptChain = [];
|
|
183
|
+
try {
|
|
184
|
+
await desktop.write(action.text);
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
catch {
|
|
188
|
+
// The primary write failed; record the path and try the clipboard
|
|
189
|
+
// fallback, which throws a CuaTypeFallbackError naming the phase if it
|
|
190
|
+
// also fails. (The write error carries no diagnostics beyond "it
|
|
191
|
+
// threw"; the typed text is never recorded.)
|
|
192
|
+
attemptChain.push("desktop.write failed");
|
|
193
|
+
}
|
|
194
|
+
await pasteTextViaClipboard(desktop, action.text, attemptChain);
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
case "keypress":
|
|
198
|
+
// The SDK press() accepts a string[] directly; pass the keys through so
|
|
199
|
+
// a chord (e.g. ["Control", "a"]) is pressed together, not in sequence.
|
|
200
|
+
await desktop.press(action.keys);
|
|
201
|
+
return;
|
|
202
|
+
case "drag": {
|
|
203
|
+
// The SDK drag takes two endpoints, not an N-point path: drag from the
|
|
204
|
+
// first to the last point. 0 points is a safe no-op; 1 point has no
|
|
205
|
+
// distinct endpoint, so it is also a no-op (no spurious click/move).
|
|
206
|
+
const path = action.path;
|
|
207
|
+
if (path.length < 2)
|
|
208
|
+
return;
|
|
209
|
+
const from = path[0];
|
|
210
|
+
const to = path[path.length - 1];
|
|
211
|
+
if (from === undefined || to === undefined)
|
|
212
|
+
return;
|
|
213
|
+
await desktop.drag([from.x, from.y], [to.x, to.y]);
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
case "wait":
|
|
217
|
+
await desktop.wait(action.ms ?? defaultWaitMs);
|
|
218
|
+
return;
|
|
219
|
+
case "screenshot":
|
|
220
|
+
// No-op: the loop calls observe() separately to capture each frame, so
|
|
221
|
+
// capturing here would double-capture. Leave the desktop untouched.
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
// ---------------------------------------------------------------------------
|
|
228
|
+
// Perceptual signature.
|
|
229
|
+
//
|
|
230
|
+
// A coarse, deterministic hash of a frame for no-progress detection in the loop.
|
|
231
|
+
// It is robust to small noise (a blinking cursor, a single changed clock digit)
|
|
232
|
+
// because it area-averages the frame down to a 16x16 grayscale grid and then
|
|
233
|
+
// quantizes each cell to 4 levels (2 bits). Two visually-identical frames produce
|
|
234
|
+
// the same signature; a clearly different frame differs. It is NOT reversible to
|
|
235
|
+
// the image, so exposing it (e.g. in a trace) is public-safe. On any decode
|
|
236
|
+
// failure it returns a stable fallback so two unreadable frames compare equal.
|
|
237
|
+
// ---------------------------------------------------------------------------
|
|
238
|
+
const SIGNATURE_GRID = 16;
|
|
239
|
+
const SIGNATURE_FALLBACK = "unreadable";
|
|
240
|
+
/**
|
|
241
|
+
* A coarse perceptual hash of a PNG frame for no-progress detection. Decodes the
|
|
242
|
+
* PNG, area-averages it to a SIGNATURE_GRID x SIGNATURE_GRID grayscale grid,
|
|
243
|
+
* quantizes each cell to 2 bits (gray >> 6, four levels), and packs the
|
|
244
|
+
* (SIGNATURE_GRID^2) two-bit cells into a compact hex string. Deterministic (no
|
|
245
|
+
* Date, no random). Returns SIGNATURE_FALLBACK on any decode failure so two
|
|
246
|
+
* unreadable frames compare equal.
|
|
247
|
+
*/
|
|
248
|
+
export function perceptualSignature(pngBytes) {
|
|
249
|
+
let cells;
|
|
250
|
+
try {
|
|
251
|
+
const source = Buffer.isBuffer(pngBytes) ? pngBytes : Buffer.from(pngBytes);
|
|
252
|
+
if (source.length === 0)
|
|
253
|
+
return SIGNATURE_FALLBACK;
|
|
254
|
+
const decoded = PNG.sync.read(source);
|
|
255
|
+
const srcW = decoded.width;
|
|
256
|
+
const srcH = decoded.height;
|
|
257
|
+
if (!srcW || !srcH)
|
|
258
|
+
return SIGNATURE_FALLBACK;
|
|
259
|
+
cells = quantizedGrid(decoded.data, srcW, srcH);
|
|
260
|
+
}
|
|
261
|
+
catch {
|
|
262
|
+
return SIGNATURE_FALLBACK;
|
|
263
|
+
}
|
|
264
|
+
return packCells(cells);
|
|
265
|
+
}
|
|
266
|
+
/** Area-average an RGBA buffer to a grid of 2-bit (0..3) grayscale cells. */
|
|
267
|
+
function quantizedGrid(data, srcW, srcH) {
|
|
268
|
+
const cells = [];
|
|
269
|
+
const xRatio = srcW / SIGNATURE_GRID;
|
|
270
|
+
const yRatio = srcH / SIGNATURE_GRID;
|
|
271
|
+
for (let gy = 0; gy < SIGNATURE_GRID; gy += 1) {
|
|
272
|
+
const sy0 = Math.floor(gy * yRatio);
|
|
273
|
+
const sy1 = Math.min(srcH, Math.max(sy0 + 1, Math.floor((gy + 1) * yRatio)));
|
|
274
|
+
for (let gx = 0; gx < SIGNATURE_GRID; gx += 1) {
|
|
275
|
+
const sx0 = Math.floor(gx * xRatio);
|
|
276
|
+
const sx1 = Math.min(srcW, Math.max(sx0 + 1, Math.floor((gx + 1) * xRatio)));
|
|
277
|
+
let sum = 0;
|
|
278
|
+
let n = 0;
|
|
279
|
+
for (let sy = sy0; sy < sy1; sy += 1) {
|
|
280
|
+
for (let sx = sx0; sx < sx1; sx += 1) {
|
|
281
|
+
const si = (sy * srcW + sx) * 4;
|
|
282
|
+
const r = data[si] ?? 0;
|
|
283
|
+
const g = data[si + 1] ?? 0;
|
|
284
|
+
const b = data[si + 2] ?? 0;
|
|
285
|
+
sum += Math.round((r + g + b) / 3);
|
|
286
|
+
n += 1;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
const gray = n ? Math.round(sum / n) : 0;
|
|
290
|
+
// Quantize 0..255 to four levels (0..3). Clamp the 255 edge so it stays in
|
|
291
|
+
// range (255 >> 6 === 3 already, but Math.min guards any rounding surprise).
|
|
292
|
+
cells.push(Math.min(3, gray >> 6));
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
return cells;
|
|
296
|
+
}
|
|
297
|
+
/** Pack 2-bit cells (4 per hex... actually 2 per byte) into a compact hex string. */
|
|
298
|
+
function packCells(cells) {
|
|
299
|
+
// Pack four 2-bit cells per byte, then hex-encode. SIGNATURE_GRID^2 cells.
|
|
300
|
+
const bytes = Buffer.alloc(Math.ceil(cells.length / 4));
|
|
301
|
+
for (let i = 0; i < cells.length; i += 1) {
|
|
302
|
+
const byteIndex = i >> 2;
|
|
303
|
+
const shift = (i & 3) * 2;
|
|
304
|
+
const value = (cells[i] ?? 0) & 3;
|
|
305
|
+
bytes[byteIndex] = (bytes[byteIndex] ?? 0) | (value << shift);
|
|
306
|
+
}
|
|
307
|
+
return bytes.toString("hex");
|
|
308
|
+
}
|
|
309
|
+
//# sourceMappingURL=e2b-desktop-executor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"e2b-desktop-executor.js","sourceRoot":"","sources":["../src/e2b-desktop-executor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
export interface E2BDesktopModule {
|
|
2
|
+
Sandbox: {
|
|
3
|
+
/** Default `desktop` template (no custom image). The historical, byte-stable call shape. */
|
|
4
|
+
create(options: E2BDesktopCreateOptions): Promise<E2BDesktopSandbox>;
|
|
5
|
+
/**
|
|
6
|
+
* Launch on a CUSTOM E2B desktop template (image) by NAME or ID — the SDK's
|
|
7
|
+
* `Sandbox.create(template, opts)` overload. Lets a lab run on an adopter-maintained image
|
|
8
|
+
* with extra runtimes baked in (e.g. node/bun/a local Postgres the stock `desktop` template
|
|
9
|
+
* lacks), instead of the stock template. The base @e2b/desktop SDK implements this; the
|
|
10
|
+
* wrapper just exposes it. Threaded from `execution.desktop.template`.
|
|
11
|
+
*/
|
|
12
|
+
create(template: string, options: E2BDesktopCreateOptions): Promise<E2BDesktopSandbox>;
|
|
13
|
+
/**
|
|
14
|
+
* Kill the sandbox specified by exact id. Returns true iff THAT sandbox was found and
|
|
15
|
+
* killed, false otherwise (the SDK's own doc comment). This boolean is the PRIMARY by-id
|
|
16
|
+
* cleanup proof: a caller never needs to re-list to confirm reclamation.
|
|
17
|
+
*/
|
|
18
|
+
kill?(sandboxId: string, options?: {
|
|
19
|
+
requestTimeoutMs?: number;
|
|
20
|
+
}): Promise<boolean>;
|
|
21
|
+
/**
|
|
22
|
+
* Fetch ONE sandbox by its exact id (never account-wide). Throws a SandboxNotFoundError-
|
|
23
|
+
* shaped error (see isSandboxNotFoundError below) when the id no longer exists; that thrown
|
|
24
|
+
* error IS the by-id confirmation that a killed sandbox is gone. Optional: older SDKs may
|
|
25
|
+
* lack it, so callers fall back to kill()'s own boolean rather than ever calling Sandbox.list.
|
|
26
|
+
*/
|
|
27
|
+
getInfo?(sandboxId: string, options?: {
|
|
28
|
+
requestTimeoutMs?: number;
|
|
29
|
+
}): Promise<E2BSandboxInfo>;
|
|
30
|
+
/**
|
|
31
|
+
* ACCOUNT-WIDE enumeration. Kept only for the routes that already avoid it for cleanup
|
|
32
|
+
* (shared-world/scripted/cua/preflight kill by exact id and never call this); no cleanup
|
|
33
|
+
* proof in this codebase should call it (see e2b-terminal-lab.ts teardownSandbox and
|
|
34
|
+
* oss-meta-lab.ts, both of which reclaim and verify by id, never by listing).
|
|
35
|
+
*/
|
|
36
|
+
list?(options: E2BSandboxListOptions): E2BSandboxPaginator;
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
export interface E2BSandboxListOptions {
|
|
40
|
+
metadata?: Record<string, string>;
|
|
41
|
+
requestTimeoutMs?: number;
|
|
42
|
+
}
|
|
43
|
+
export interface E2BSandboxInfo {
|
|
44
|
+
id?: string;
|
|
45
|
+
metadata?: Record<string, string>;
|
|
46
|
+
sandboxID?: string;
|
|
47
|
+
sandboxId?: string;
|
|
48
|
+
state?: string;
|
|
49
|
+
}
|
|
50
|
+
export interface E2BSandboxPaginator {
|
|
51
|
+
hasNext: boolean;
|
|
52
|
+
nextItems(options?: {
|
|
53
|
+
requestTimeoutMs?: number;
|
|
54
|
+
}): Promise<E2BSandboxInfo[]>;
|
|
55
|
+
}
|
|
56
|
+
export interface E2BDesktopCreateOptions {
|
|
57
|
+
apiKey: string;
|
|
58
|
+
dpi?: number;
|
|
59
|
+
envs?: Record<string, string>;
|
|
60
|
+
lifecycle?: {
|
|
61
|
+
onTimeout: "kill" | "pause";
|
|
62
|
+
};
|
|
63
|
+
metadata?: Record<string, string>;
|
|
64
|
+
requestTimeoutMs?: number;
|
|
65
|
+
resolution?: [number, number];
|
|
66
|
+
timeoutMs?: number;
|
|
67
|
+
}
|
|
68
|
+
export interface E2BCommandRunOptions {
|
|
69
|
+
background?: false;
|
|
70
|
+
cwd?: string;
|
|
71
|
+
envs?: Record<string, string>;
|
|
72
|
+
onStderr?: (data: string) => void | Promise<void>;
|
|
73
|
+
onStdout?: (data: string) => void | Promise<void>;
|
|
74
|
+
requestTimeoutMs?: number;
|
|
75
|
+
timeoutMs?: number;
|
|
76
|
+
}
|
|
77
|
+
export interface E2BCommandResult {
|
|
78
|
+
error?: string;
|
|
79
|
+
exitCode?: number;
|
|
80
|
+
stderr?: string;
|
|
81
|
+
stdout?: string;
|
|
82
|
+
}
|
|
83
|
+
export interface E2BDesktopSandbox {
|
|
84
|
+
sandboxId: string;
|
|
85
|
+
commands: {
|
|
86
|
+
run(command: string, options?: E2BCommandRunOptions): Promise<E2BCommandResult>;
|
|
87
|
+
};
|
|
88
|
+
files: {
|
|
89
|
+
write(path: string, data: string | ArrayBuffer, options?: {
|
|
90
|
+
requestTimeoutMs?: number;
|
|
91
|
+
useOctetStream?: boolean;
|
|
92
|
+
}): Promise<unknown>;
|
|
93
|
+
};
|
|
94
|
+
launch(application: string, uri?: string): Promise<void>;
|
|
95
|
+
/** Open a file or URL with the desktop's default application (present on @e2b/desktop >= 1.x). */
|
|
96
|
+
open?(fileOrUrl: string): Promise<void>;
|
|
97
|
+
/**
|
|
98
|
+
* Map an in-sandbox port to a reachable host URL — `https://<port>-<sandboxId>.e2b.app`,
|
|
99
|
+
* TOKENLESS (no authKey, unlike `stream.getUrl`). The base `e2b` SDK (v2.27.0) implements this;
|
|
100
|
+
* the wrapper just exposes it. Used by the CONCURRENT shared-world topology (#164 phase 2) to
|
|
101
|
+
* expose the ONE subject service plane to N actor sandboxes. Optional: older SDKs may lack it, so
|
|
102
|
+
* the concurrent backend fails closed when it is absent rather than calling a missing method.
|
|
103
|
+
*/
|
|
104
|
+
getHost?(port: number): string;
|
|
105
|
+
screenshot(format?: "bytes"): Promise<Uint8Array>;
|
|
106
|
+
wait(ms: number): Promise<void>;
|
|
107
|
+
stream: {
|
|
108
|
+
getAuthKey(): string;
|
|
109
|
+
getUrl(options?: {
|
|
110
|
+
authKey?: string;
|
|
111
|
+
autoConnect?: boolean;
|
|
112
|
+
resize?: "off" | "scale" | "remote";
|
|
113
|
+
viewOnly?: boolean;
|
|
114
|
+
}): string;
|
|
115
|
+
start(options?: {
|
|
116
|
+
requireAuth?: boolean;
|
|
117
|
+
windowId?: string;
|
|
118
|
+
}): Promise<void>;
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
export declare function loadE2BDesktopModule(): Promise<E2BDesktopModule>;
|
|
122
|
+
export declare function isMissingE2BDesktopDependency(error: unknown): boolean;
|
|
123
|
+
/**
|
|
124
|
+
* Detect a SandboxNotFoundError-shaped error from the real @e2b/desktop SDK, WITHOUT importing
|
|
125
|
+
* its class (this module stays optional-peer / lazily-loaded, same as everything else here).
|
|
126
|
+
* The real SDK sets `this.name = "SandboxNotFoundError"` on the class (it extends the
|
|
127
|
+
* deprecated NotFoundError), so checking `.name` is the stable, import-free detection contract.
|
|
128
|
+
* The constructor-name fallback covers a bundler/transpile shape where `.name` was not copied
|
|
129
|
+
* onto the instance. A thrown SandboxNotFoundError from Sandbox.getInfo(id) is the by-id proof
|
|
130
|
+
* that the exact sandbox humanish created is gone (confirmed reclaimed), never a re-list.
|
|
131
|
+
*/
|
|
132
|
+
export declare function isSandboxNotFoundError(error: unknown): boolean;
|
|
133
|
+
/**
|
|
134
|
+
* Create an E2B desktop sandbox, optionally on a CUSTOM template (image). The ONE seam every
|
|
135
|
+
* desktop-creating route calls so the default and custom-template paths are decided in a single
|
|
136
|
+
* place.
|
|
137
|
+
*
|
|
138
|
+
* When `template` is undefined (the default — no `execution.desktop.template` configured), this is
|
|
139
|
+
* BYTE-STABLE with the historical `Sandbox.create(options)` call: the stock `desktop` template, the
|
|
140
|
+
* options object passed as the sole argument. When `template` is a non-empty name/id, it selects
|
|
141
|
+
* the SDK's `Sandbox.create(template, options)` overload so the lab runs on an adopter's image.
|
|
142
|
+
* The template (when set) is a public-safe label, never a secret.
|
|
143
|
+
*/
|
|
144
|
+
export declare function createDesktopSandbox(module: E2BDesktopModule, options: E2BDesktopCreateOptions, template?: string): Promise<E2BDesktopSandbox>;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
// Shared E2B desktop substrate: the optional-peer loader + the structural interfaces for the
|
|
2
|
+
// real @e2b/desktop Sandbox. Hoisted out of oss-meta-lab.ts so both the OSS meta-lab and the
|
|
3
|
+
// computer-use lab (cua-actor-lab.ts) launch desktops through one seam (the peer dep is
|
|
4
|
+
// optional and lazily loaded, so neither path pulls @e2b/desktop into the published tarball
|
|
5
|
+
// or CI).
|
|
6
|
+
//
|
|
7
|
+
// E2BDesktopSandbox stays shape-compatible with what the meta path has always used (so meta is
|
|
8
|
+
// unchanged); `open` is declared optional because older SDKs may lack it (the CUA lab falls
|
|
9
|
+
// back to launch). The CUA executor needs the additional mouse/keyboard methods (E2BDesktopLike
|
|
10
|
+
// in e2b-desktop-executor.ts); the live Sandbox has them, so the CUA call site casts the
|
|
11
|
+
// launched sandbox to E2BDesktopLike rather than widening this interface across the whole
|
|
12
|
+
// meta file.
|
|
13
|
+
export async function loadE2BDesktopModule() {
|
|
14
|
+
try {
|
|
15
|
+
return await import("@e2b/desktop");
|
|
16
|
+
}
|
|
17
|
+
catch (error) {
|
|
18
|
+
if (isMissingE2BDesktopDependency(error)) {
|
|
19
|
+
throw new Error("Live E2B desktop launch requires optional peer dependency @e2b/desktop. Install it in this project with `npm i -D @e2b/desktop`, or run `humanish lab run oss --dry-run`.");
|
|
20
|
+
}
|
|
21
|
+
throw error;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
export function isMissingE2BDesktopDependency(error) {
|
|
25
|
+
const value = error;
|
|
26
|
+
return value.code === "ERR_MODULE_NOT_FOUND" && value.message?.includes("@e2b/desktop") === true;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Detect a SandboxNotFoundError-shaped error from the real @e2b/desktop SDK, WITHOUT importing
|
|
30
|
+
* its class (this module stays optional-peer / lazily-loaded, same as everything else here).
|
|
31
|
+
* The real SDK sets `this.name = "SandboxNotFoundError"` on the class (it extends the
|
|
32
|
+
* deprecated NotFoundError), so checking `.name` is the stable, import-free detection contract.
|
|
33
|
+
* The constructor-name fallback covers a bundler/transpile shape where `.name` was not copied
|
|
34
|
+
* onto the instance. A thrown SandboxNotFoundError from Sandbox.getInfo(id) is the by-id proof
|
|
35
|
+
* that the exact sandbox humanish created is gone (confirmed reclaimed), never a re-list.
|
|
36
|
+
*/
|
|
37
|
+
export function isSandboxNotFoundError(error) {
|
|
38
|
+
if (error === null || typeof error !== "object")
|
|
39
|
+
return false;
|
|
40
|
+
const value = error;
|
|
41
|
+
return value.name === "SandboxNotFoundError" || value.constructor?.name === "SandboxNotFoundError";
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Create an E2B desktop sandbox, optionally on a CUSTOM template (image). The ONE seam every
|
|
45
|
+
* desktop-creating route calls so the default and custom-template paths are decided in a single
|
|
46
|
+
* place.
|
|
47
|
+
*
|
|
48
|
+
* When `template` is undefined (the default — no `execution.desktop.template` configured), this is
|
|
49
|
+
* BYTE-STABLE with the historical `Sandbox.create(options)` call: the stock `desktop` template, the
|
|
50
|
+
* options object passed as the sole argument. When `template` is a non-empty name/id, it selects
|
|
51
|
+
* the SDK's `Sandbox.create(template, options)` overload so the lab runs on an adopter's image.
|
|
52
|
+
* The template (when set) is a public-safe label, never a secret.
|
|
53
|
+
*/
|
|
54
|
+
export async function createDesktopSandbox(module, options, template) {
|
|
55
|
+
return template === undefined
|
|
56
|
+
? module.Sandbox.create(options)
|
|
57
|
+
: module.Sandbox.create(template, options);
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=e2b-desktop-launch.js.map
|
|
@@ -0,0 +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;AA4Hb,MAAM,CAAC,KAAK,UAAU,oBAAoB;IACxC,IAAI,CAAC;QACH,OAAO,MAAM,MAAM,CAAC,cAAc,CAAgC,CAAC;IACrE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,6BAA6B,CAAC,KAAK,CAAC,EAAE,CAAC;YACzC,MAAM,IAAI,KAAK,CACb,2KAA2K,CAC5K,CAAC;QACJ,CAAC;QAED,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,6BAA6B,CAAC,KAAc;IAC1D,MAAM,KAAK,GAAG,KAA4C,CAAC;IAC3D,OAAO,KAAK,CAAC,IAAI,KAAK,sBAAsB,IAAI,KAAK,CAAC,OAAO,EAAE,QAAQ,CAAC,cAAc,CAAC,KAAK,IAAI,CAAC;AACnG,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,sBAAsB,CAAC,KAAc;IACnD,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC9D,MAAM,KAAK,GAAG,KAA6D,CAAC;IAC5E,OAAO,KAAK,CAAC,IAAI,KAAK,sBAAsB,IAAI,KAAK,CAAC,WAAW,EAAE,IAAI,KAAK,sBAAsB,CAAC;AACrG,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,MAAwB,EACxB,OAAgC,EAChC,QAAiB;IAEjB,OAAO,QAAQ,KAAK,SAAS;QAC3B,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC;QAChC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;AAC/C,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { E2BDesktopSandbox } from "./e2b-desktop-launch.js";
|
|
2
|
+
export interface DetachedTimers {
|
|
3
|
+
/** Injected clock (ms) for tests. */
|
|
4
|
+
now?: () => number;
|
|
5
|
+
/** Injected sleep for tests. */
|
|
6
|
+
sleep?: (ms: number) => Promise<void>;
|
|
7
|
+
}
|
|
8
|
+
export interface DetachedStepOptions extends DetachedTimers {
|
|
9
|
+
/** Short [a-z0-9-] label; names the script/status/log files under /tmp. */
|
|
10
|
+
name: string;
|
|
11
|
+
/** The shell command to run (the lab author's own command — package.json-script trust). */
|
|
12
|
+
command: string;
|
|
13
|
+
cwd?: string;
|
|
14
|
+
/** Wall-clock budget for the step. */
|
|
15
|
+
timeoutMs: number;
|
|
16
|
+
pollIntervalMs?: number;
|
|
17
|
+
requestTimeoutMs?: number;
|
|
18
|
+
}
|
|
19
|
+
export interface DetachedStepResult {
|
|
20
|
+
ok: boolean;
|
|
21
|
+
exitCode?: number;
|
|
22
|
+
timedOut: boolean;
|
|
23
|
+
/** Capped, UNREDACTED log tail — redact before persisting. */
|
|
24
|
+
logTail: string;
|
|
25
|
+
}
|
|
26
|
+
/** Read the capped log tail for a step (raw — caller redacts). */
|
|
27
|
+
export declare function readDetachedLog(desktop: E2BDesktopSandbox, name: string, requestTimeoutMs?: number): Promise<string>;
|
|
28
|
+
/**
|
|
29
|
+
* Run a BOUNDED step (install/build) detached, polling its atomic status file until it
|
|
30
|
+
* exits or the budget runs out. On timeout the process group is killed and the log tail is
|
|
31
|
+
* still captured so failures stay diagnosable.
|
|
32
|
+
*/
|
|
33
|
+
export declare function runDetachedStep(desktop: E2BDesktopSandbox, options: DetachedStepOptions): Promise<DetachedStepResult>;
|
|
34
|
+
/**
|
|
35
|
+
* Launch a LONG-LIVED process (the subject's server) fully detached and return immediately.
|
|
36
|
+
* No status polling: liveness is the caller's readiness probe, and reclamation belongs to
|
|
37
|
+
* the sandbox lifecycle (create with kill-on-timeout).
|
|
38
|
+
*/
|
|
39
|
+
export declare function startDetachedProcess(desktop: E2BDesktopSandbox, options: {
|
|
40
|
+
name: string;
|
|
41
|
+
command: string;
|
|
42
|
+
cwd?: string;
|
|
43
|
+
requestTimeoutMs?: number;
|
|
44
|
+
}): Promise<void>;
|
|
45
|
+
/**
|
|
46
|
+
* Poll a URL from INSIDE the sandbox until it answers 2xx/3xx or the budget runs out.
|
|
47
|
+
* Returns true when the subject is ready.
|
|
48
|
+
*/
|
|
49
|
+
export declare function probeUrl(desktop: E2BDesktopSandbox, url: string, options: {
|
|
50
|
+
timeoutMs: number;
|
|
51
|
+
intervalMs?: number;
|
|
52
|
+
requestTimeoutMs?: number;
|
|
53
|
+
} & DetachedTimers): Promise<boolean>;
|