import { listRecordedRuns, listTraceSources } from "@mono-agent/observability"; import type { TraceSourceListItem } from "@mono-agent/observability"; import type { LaunchctlRunner, LaunchdPaths } from "./launchd.js"; import type { LaunchdLogInspection, LaunchdLogMaintenanceIntent } from "./launchd-logs.js"; import type { ManagedBackgroundRuntime, ManagedBackgroundRuntimeInput, ManagedRuntimeAdditionalPackage, ManagedRuntimeLaunchVerification, ManagedRuntimeSourceIdentity } from "./background-runtime.js"; import type { BackgroundSnapshot } from "./background-snapshot.js"; import type { OwnerPrivateLock } from "./owner-private-lock.js"; import type { BackgroundLifecycleTarget, BackgroundLockAcquireOptions } from "./launchd-lifecycle-lock.js"; import type { LaunchdMaintenanceLifecycleLease } from "./launchd-maintenance-gate.js"; import type { PollOptions } from "./background-lifecycle-utils.js"; export type { PollOptions } from "./background-lifecycle-utils.js"; export { acquireFilesystemLifecycleLock, acquireSharedLaunchdLogLock, sharedLaunchdLogLockTarget, SHARED_LAUNCHD_LOG_LOCK_POLL_MS, SHARED_LAUNCHD_LOG_LOCK_WAIT_MS, } from "./launchd-lifecycle-lock.js"; export type { BackgroundLifecycleTarget, BackgroundLockAcquireOptions, FilesystemLifecycleLockOptions, } from "./launchd-lifecycle-lock.js"; export { withLaunchdMaintenanceControllerLock } from "./launchd-maintenance-gate.js"; export { ensureOwnerPrivateLaunchdDirectory } from "./launchd-private-files.js"; export { acquireBackgroundWorkerLease, backgroundWorkerLeasePath, } from "./background-worker-lease.js"; export type { BackgroundWorkerLease, BackgroundWorkerLeaseOptions, } from "./background-worker-lease.js"; export { LAUNCHD_LOG_MAX_BYTES, LAUNCHD_LOG_ROTATION_COUNT, } from "./launchd-logs.js"; /** * Background-service orchestration for the mono-agent CLI. The interactive * control commands never talk to the worker directly: they derive a stable * launchd label + the trace-source registry location from the resolved config * path, drive `launchctl`, and read the worker's published manifest to learn * when it is up and what to print. */ export interface BackgroundCliArgs { readonly configPath?: string; readonly envFile?: string; } export interface InstanceTarget { readonly cwd: string; readonly configPath: string; readonly label: string; readonly registryDir: string; readonly staleAfterMs: number; readonly paths: LaunchdPaths; readonly nodePath: string; readonly cliPath: string; /** Mutable controller CLI retained only as inert runtime-installation input. */ readonly controllerCliPath?: string; readonly envFile?: string; /** * Transient effective config environment reconstructed by the controller. * It may contain secrets: never serialize, log, or materialize it in launchd. */ readonly configurationEnvironment: Readonly>; readonly environment: Readonly>; /** Exact wizard/approval snapshot this launch is allowed to claim ready. */ readonly expectedSnapshot?: BackgroundSnapshot; /** Opaque proof that the selected managed runtime was finalized and verified. */ readonly managedRuntimeLaunchProof?: string; /** Guided/configuration handoffs additionally require a usable TUI endpoint. */ readonly requireTui?: boolean; } export interface ResolveInstanceTargetInput { readonly args: BackgroundCliArgs; readonly env: Record; readonly cwd: string; /** Absolute path to the running cli.js, baked into the plist. */ readonly cliPath: string; readonly requireTui?: boolean; } /** Exact non-secret environment materialised into a managed LaunchAgent. */ export declare function managedBackgroundEnvironment(env: Readonly>): Readonly>; /** Exact non-secret environment for the scheduled recovery/rotation controller. */ export declare function managedLaunchdLogMaintenanceEnvironment(env: Readonly>): Readonly>; /** * Resolve everything the control commands need from CLI args. The registry dir * and config path are resolved exactly as the worker will resolve them, so the * detached launcher can find the worker's manifest without any IPC. */ export declare function resolveInstanceTarget(input: ResolveInstanceTargetInput): Promise; /** * Collapse symlinked parent aliases without following the config's final path * component. The final component is separately required to be a regular, * non-symlink file before start; keeping it unresolved preserves that check. * Missing parents remain addressable so stop/status/logs can still operate on * a previously installed label after an agent folder is damaged or removed. */ export declare function canonicalBackgroundConfigPath(cwd: string, configuredPath?: string): Promise; export interface BackgroundDeps { readonly runner: LaunchctlRunner; readonly getuid: () => number; readonly currentPid: () => number; readonly now: () => number; readonly sleep: (ms: number) => Promise; readonly listRecordedRuns: typeof listRecordedRuns; readonly listTraceSources: typeof listTraceSources; readonly writeFile: (path: string, data: string) => Promise; readonly mkdir: (path: string) => Promise; readonly rm: (path: string) => Promise; readonly inspectLaunchdLogs: (paths: Pick) => Promise; readonly rotateStoppedLaunchdLogs: (paths: Pick) => Promise; readonly readLaunchdLogMaintenanceIntent: (paths: Pick) => Promise; readonly beginLaunchdLogMaintenanceIntent: (paths: Pick, intent: LaunchdLogMaintenanceIntent) => Promise; readonly markLaunchdLogMaintenanceStopped: (paths: Pick, expected: LaunchdLogMaintenanceIntent) => Promise; readonly markLaunchdLogMaintenanceRestoring: (paths: Pick, expected: LaunchdLogMaintenanceIntent) => Promise; readonly markLaunchdLogMaintenanceStopping: (paths: Pick, expected: LaunchdLogMaintenanceIntent) => Promise; readonly clearLaunchdLogMaintenanceIntent: (paths: Pick, expected?: LaunchdLogMaintenanceIntent) => Promise; readonly removeLaunchdLogMonitorStatus?: (target: BackgroundLifecycleTarget) => Promise; /** Read and fingerprint the exact owner-private plist without mutating it. */ readonly verifyLaunchdPlist: (path: string) => Promise; /** True when a pid is still alive (or alive but owned by another user). */ readonly isAlive: (pid: number) => boolean; /** Install/verify an immutable CLI outside npm/npx's disposable cache. */ readonly ensureManagedRuntime: (input: ManagedBackgroundRuntimeInput) => Promise; /** Inspect mutable source as inert bytes; never execute it. */ readonly inspectManagedRuntimeSourceIdentity: (cliPath: string) => Promise; /** Verify the exact private closure and proof persisted in the loaded worker. */ readonly verifyManagedRuntimeLaunch: (input: { readonly currentCliPath: string; readonly launchProof: string; }) => Promise; /** Resolve config-selected plugin-tier packages before the disposable source can disappear. */ readonly resolveManagedRuntimePackages?: (target: InstanceTarget) => Promise; /** Fail closed when another lifecycle command owns this config label. */ readonly acquireLifecycleLock: (target: BackgroundLifecycleTarget, options?: BackgroundLockAcquireOptions) => Promise<(() => Promise) | undefined>; /** Hold KeepAlive respawns until the replacement runtime and plist are committed. */ readonly acquireRuntimePublicationBarrier?: (target: BackgroundLifecycleTarget) => Promise; /** Prove a metadata-advertised TUI endpoint is actually reachable. */ readonly probeTui: (source: TraceSourceListItem) => Promise; readonly captureSnapshot?: (target: InstanceTarget) => Promise; readonly stdout: (text: string) => void; readonly stderr: (text: string) => void; /** Run `tail` with inherited stdio; resolves with its exit code. */ readonly spawnTail: (args: readonly string[]) => Promise; } export declare function defaultBackgroundDeps(): BackgroundDeps; export interface ReadyPollOptions extends PollOptions { /** Only accept a worker that started at or after this time (restart safety). */ readonly sinceMs: number; readonly requireTui?: boolean; } export type BackgroundLaunchAction = "started" | "restarted"; export type BackgroundLaunchResult = { readonly ok: true; readonly action: BackgroundLaunchAction; /** The fresh, authoritative worker trace that proved startup complete. */ readonly source: TraceSourceListItem; } | { readonly ok: false; readonly action: "start" | "restart"; readonly reason: "runtime" | "snapshot" | "preparation" | "ownership" | "shared-contention" | "launchctl" | "readiness" | "timeout"; }; export declare function startBackground(target: InstanceTarget, deps: BackgroundDeps, poll?: PollOptions): Promise; /** Restart is behaviourally identical: ensure a single fresh running instance. */ export declare function restartBackground(target: InstanceTarget, deps: BackgroundDeps, poll?: PollOptions): Promise; export interface LaunchdControllerOptions { /** False only when the originally installed controller checkout disappeared. */ readonly sourceAvailable: boolean; readonly controlPoll?: PollOptions; readonly readinessPoll?: PollOptions; /** Full structural validation, invoked only after fast proof identifies recovery work. */ readonly recoveryPreflight?: () => Promise; } /** * Private one-shot recovery controller invoked by the maintenance LaunchAgent. * It authenticates the exact helper PID launchd owns, compares the inert source * CLI identity with the strictly parsed loaded worker definition, and repairs * only when the worker, snapshot, definition, or available source closure has * drifted. A healthy worker remains serving while a replacement runtime is * materialized. */ export declare function maintainLaunchdController(target: InstanceTarget, deps: BackgroundDeps, options: LaunchdControllerOptions, lifecycleLease?: LaunchdMaintenanceLifecycleLease): Promise; /** * Stop, perform the caller's stopped-worker mutation, and start again while * retaining one lifecycle lock. This closes the force-restart gap in which a * concurrent start could previously enter while the session store was purged. */ export declare function forceRestartBackground(target: InstanceTarget, deps: BackgroundDeps, whileStopped: () => Promise, poll?: PollOptions): Promise; /** * Private one-shot invoked only by the scheduled maintenance LaunchAgent. It * never creates or rewrites a service definition. It does not resurrect an * intentionally stopped service; the sole exception is recovery authorized by * its own durable lifecycle intent after a prior maintainer died post-bootout. */ export declare function maintainLaunchdLogs(target: BackgroundLifecycleTarget, deps: BackgroundDeps, poll?: PollOptions): Promise; /** * Ensure the canonical per-config LaunchAgent is running and return the fresh * trace source that proved it completed the full startup lifecycle. This is the shared * lifecycle boundary for CLI start/restart and remote configuration handoffs; * callers must not open a console when the result is not ok. */ export declare function ensureBackgroundReady(target: InstanceTarget, deps: BackgroundDeps, poll?: PollOptions): Promise; export declare function writeOwnerPrivateLaunchdFile(path: string, data: string): Promise; export declare function inspectOwnerPrivateLaunchdPlist(path: string): Promise; export declare function readOwnerPrivateLaunchdPlist(path: string): Promise<{ readonly identity: string; readonly contents: string; }>; export declare function stopBackground(target: InstanceTarget, deps: BackgroundDeps, poll?: PollOptions): Promise; export interface StatusBackgroundOptions { readonly json?: boolean; } export declare function statusBackground(target: InstanceTarget, deps: BackgroundDeps, options?: StatusBackgroundOptions): Promise; export interface LogOptions { readonly follow: boolean; readonly lines: number; } export declare function tailLogs(target: InstanceTarget, deps: BackgroundDeps, options: LogOptions): Promise; export declare function pollInstanceReady(target: InstanceTarget, deps: BackgroundDeps, options: ReadyPollOptions): Promise; export declare function printInstanceInfo(source: TraceSourceListItem, target: InstanceTarget, deps: BackgroundDeps, verb: string): void; export declare function describeChannel(value: unknown): { kind: string; text: string; }; //# sourceMappingURL=background.d.ts.map