/** * [ref] remote scratchpad(server 半场)— the REMOTE sandbox lanes' session scratchpad convention. * * host lane already has one (env-facts.ts ensureScratchpadDir, worker-local under localDataRoot). The remote * lanes (e2b/k8s/local-docker/ssh) run their hands OFF this box, so a worker-local dir would be a lie — the * convention there is a path INSIDE the sandbox: `/tmp/scratchpad/`. This module decorates the * deployment's `executionEnvFactory` so that dir EXISTS by the time the model's first command could use it: * * - 🔴 LAZY, never factory-time: e2b is a lazy-VM adapter — an exec at factory time would force-boot the * VM for every task whether or not it ever runs a command. So the `mkdir -p` rides the env's OWN first * `exec` (the original exec, NOT the wrapped one — no recursion), single-flighted via a cached PROMISE * (a boolean would let two concurrent first commands both fire the mkdir). * - Best-effort: a failed mkdir warns ONCE and the user command still runs (a scratchpad nicety must never * fail the task). The settled promise is kept — no retry — so after a failure the ADVERTISED path may not * exist; accepted (the model's write then errors like any bad path, same class as a swept host scratchpad). * - mkdir runs with the adapter's DEFAULT exec options (no cwd/env/timeout): option semantics differ per * adapter and the command is trivial. * * Lanes: e2b/k8s/local-docker = one sandbox per task; ssh = a shared persistent host, where the * sessionId-scoped subdir is exactly what keeps sessions apart. adb is NOT a lane (no standard /tmp on * Android); host keeps its own worker-local scratchpad — neither is wrapped (main.ts gates on * {@link isRemoteScratchpadLane}). * * Trust: sessionId is minted by us (uuid), but it is caller-adjacent — defence in depth, the path is only * built for `[A-Za-z0-9._-]+` ids ({@link remoteScratchpadDirFor}); anything else ⇒ NOT decorated (+warn), * never a quoted-shell gamble. The same helper feeds the envFacts advertisement (main.ts), so the fact and * the mkdir can never disagree on the path or on the validity rule. */ import type { ExecutionEnvFactory } from "@sema-agent/core"; /** Structured logger surface (matches the service `logger`; calls optional-chained — same shape as the * worktree-isolation wrapper's). */ export interface RemoteScratchpadLogger { warn?(event: string, fields?: Record): void; } export declare function isRemoteScratchpadLane(provider: string | undefined): boolean; /** THE remote scratchpad path convention: `/tmp/scratchpad/` (raw id — the sandbox is already * session/task-scoped tenancy, no hash segment needed). Returns undefined for an absent/unsafe id — the * single validity rule shared by the factory decorator AND the envFacts advertisement. */ export declare function remoteScratchpadDirFor(sessionId: string | undefined): string | undefined; /** * Decorate a factory so each minted env lazily `mkdir -p`s its session scratchpad before its FIRST exec. * The env is mutated IN PLACE (rebind `env.exec`, evictLspOnDestroy precedent) — a copy would drop the * adapter's prototype methods and identity (registries key on the instance). */ export declare function withRemoteScratchpad(factory: ExecutionEnvFactory, logger?: RemoteScratchpadLogger): ExecutionEnvFactory; //# sourceMappingURL=remote-scratchpad.d.ts.map