/** * THE BUILD LANE — `screen-agent.ts`'s other half, and the only place the * `AppBuilder` seam is filled. * * A screen agent answers `escalate` when an ask is bigger than a screen. Once — * and only once — the person has said yes to the standing card, this runs their * ask inside a disposable box: the in-box coding agent installs from npm, writes * the code, bundles it and tests it against reality, and the files it leaves * behind come home to be sealed. Single-phase, because the box's model key is * temporary (FINAL SPEC v1). * * THE BOX HOLDS ZERO STORE CREDENTIALS. It is handed the inference env the * session boxes get and nothing else — no store URL, no app token, no tool door * — so the only thing that can come out of it is files, and the HOST is what * writes them. That is a security invariant, not a preference: the box runs * code a person's words asked for. * * It lives in the umbrella for `screenAssembler`'s reason: only composition * holds both the box pool (`packages/vendo/src/harnesses/`) and the apps runtime. */ import { type RunContext } from "./core/index.js"; import type { AppBuilder, BriefingPack } from "./core/apps/index.js"; import { type SandboxAdapterLike } from "./harnesses/claude-code/box.js"; export interface AppBuilderDeps { sandbox: SandboxAdapterLike | undefined; /** The same env the session boxes get (`inferenceEnv`) — the box's model door, * and deliberately nothing else. */ boxEnv: () => Record; /** THE briefing pack (`compose-surfaces.ts`), assembled once for both rungs. * Absent only where nothing composed one, which is no deployment. */ briefing?: (ctx: RunContext) => Promise; template?: string; } /** * What the build MINUTE may reach, on top of the inference host `boxEgress` * always adds. The registry and nothing more: this box is driven by the * person's own words, and the artifact it produces renders behind * `default-src 'none'`, so nothing it installs is allowed to phone home either. */ export declare const BUILD_ALLOWED_DOMAINS: readonly string[]; /** Everything this lane ever says about itself, in order — "progress = chat * status lines only" (FINAL SPEC v1). Named so the seam that reads them back * off the app row reads THESE rather than a copy of them. */ export declare const BUILD_STATUS_LINES: readonly ["Starting a build machine…", "Writing the code, installing what it needs, and testing it…"]; export declare function appBuilder(deps: AppBuilderDeps): AppBuilder;