/** * The apply engine (spec 04 §5) — the executor that turns a pure `PlannedAction` into filesystem * mutations, then records the install manifest. `apply` NEVER throws for expected errors: a failure * (write denied, path escape, manifest unwritable) returns `AgentReport{ ok:false, error }` so the * CLI loop (07) can record one agent's failure and proceed with the others (REQ-OBS-03). * * Every mutation routes through the sandboxed `fsutil` primitives (each preceded by a * `resolveWithin` containment check, REQ-SEC-01/02/03). There is NO gemini-specific branch — the * bundle's `gemini-extension.json` is just another file in `source.files` (D9). There is no * `applyUninstall`: an all-`"remove"` plan from `planUninstall` (05) is executed here (§5.3). * * Zero runtime dependencies; only `node:` built-ins. */ import type { AgentReport, InstallManifest, Mode, PlannedAction, Result, Scope, AgentId } from "./types.js"; import type { LocatedSource } from "./source.js"; /** * Apply-time context for ONE agent (spec 04 §5). `agentRoot` is the containment boundary every * write is checked against (REQ-SEC-02): the resolved `/` (from 02). * `destination` is the namespace dir; `manifestPath` the parent-sibling hidden file (05). */ export interface ApplyContext { readonly agent: AgentId; readonly scope: Scope; readonly mode: Mode; /** Containment boundary for REQ-SEC-02: the agent's config root (e.g. `/.claude`). */ readonly agentRoot: string; /** The `feature-forge/` namespace dir (manifest.destination). */ readonly destination: string; /** Hidden parent-sibling manifest path, from 05 `manifestPath`. */ readonly manifestPath: string; /** Located source bundle (copy bytes / symlink target). `null` only for uninstall. */ readonly source: LocatedSource | null; /** Pinned rauf coordinate to record in the manifest (06); `null` under `--skip-rauf`. */ readonly raufPin: string | null; /** ISO-8601 "now" (injectable for deterministic tests). */ readonly now: string; /** Prior manifest (for preserving `installedAt` across updates, and carrying inventory). */ readonly priorManifest: InstallManifest | null; /** * Injectable per-file write seam (tests force a deterministic WRITE_DENIED). Default: * mkdir parent + `fs.copyFile`. Returns `Result` and never throws for expected errors. */ readonly writeFileSeam?: (srcAbs: string, destAbs: string) => Promise>; } /** * Execute one agent's `PlannedAction` against the filesystem, then write/delete the manifest. * Returns an `AgentReport` instead of throwing (REQ-OBS-03). See spec 04 §5. */ export declare function apply(planned: PlannedAction, ctx: ApplyContext): Promise;