/** * Persistent per-container SSH identity. * * When shadok-ai runs in a Docker container, agents need an SSH key to reach * private git repos and servers — and that key must survive `docker restart` * AND `docker rm`+recreate. The trick: store it on the ONE volume already * mounted in production (`shadok-data → /root/.shadok-ai`), never on the * ephemeral `/root/.ssh`. So `ensureSshIdentity` generates the key under * `~/.shadok-ai/ssh` and points `~/.ssh` at it. * * On a normal host (no `/.dockerenv`) this is a NO-OP: we never read, move, or * symlink the developer's `~/.ssh`. See * docs/superpowers/specs/2026-08-04-docker-ssh-identity-design.md. */ export interface SshPaths { /** The persistent SSH dir on the shadok-data volume. */ dir: string; key: string; pub: string; config: string; knownHosts: string; /** The conventional `~/.ssh` we wire to `dir`. */ dotSsh: string; } /** Pure: every path derived from a home directory. */ export declare function sshPaths(home: string): SshPaths; /** * Are we inside a container? `/.dockerenv` exists in every Docker container. * `SHADOK_SSH_IDENTITY=0` disables the feature entirely; * `SHADOK_FORCE_SSH_IDENTITY=1` forces it on (tests / non-Docker containers). */ export declare function inContainer(env?: NodeJS.ProcessEnv, exists?: (p: string) => boolean): boolean; /** The observable state of `~/.ssh`, so the wiring decision stays pure. */ export type DotSshState = "absent" | "our-symlink" | "foreign-symlink" | "real-dir" | "other"; export type DotSshPlan = "symlink" | "migrate-then-symlink" | "leave"; /** Pure: what to do with `~/.ssh` given its current state. */ export declare function planDotSshWiring(state: DotSshState): DotSshPlan; export interface EnsureOpts { home?: string; isContainer?: boolean; log?: (msg: string) => void; /** Injected for tests; defaults to the real keygen. */ keygen?: (p: SshPaths, comment: string) => void; env?: NodeJS.ProcessEnv; } /** * Ensure a persistent SSH identity exists and `~/.ssh` uses it — but ONLY in a * container. Idempotent and best-effort: it never throws into the boot path. * Returns the exported env for spawned agents (a GIT_SSH_COMMAND fallback) or * `{}` when it did nothing. */ export declare function ensureSshIdentity(opts?: EnsureOpts): Record;