import { type SyncHomeDefinition } from "./portable-snapshot-filter.js"; /** * The wire schema of the per-station sync-manifest. The name keeps the * fleet-resources spelling deliberately: the fleet hydrator (and the snapshot * repo's consumers) record and compare this string, so the package-owned * producer writes the same value the retired script wrote. */ export declare const STATION_SYNC_MANIFEST_SCHEMA = "hasna.fleet-resources.skills-sync-manifest/v1"; /** Package identity recorded in the manifest's producer field. */ export declare const STATION_SNAPSHOT_PRODUCER: { name: string; version: string; }; export type StationSnapshotErrorCode = "INVALID_STATION" | "SYMLINKS_REFUSED" | "CONFLICT" | "DESTINATION_ESCAPE" | "MANIFEST_UNREADABLE" | "MANIFEST_HASH_MISMATCH"; export declare class StationSnapshotError extends Error { readonly code: StationSnapshotErrorCode; /** Per-item lines for the CONFLICT class (printed before the summary). */ readonly detail: string[]; constructor(code: StationSnapshotErrorCode, message: string, detail?: string[]); } /** Validate a station id the same way the source script does. */ export declare function validateStationId(stationId: string): void; export interface PortableSnapshotFile { relativePath: string; fullPath: string; size: number; mtimeMs: number; mtimeIso: string; } export interface SnapshotSkip { relativePath: string; reason: "symlink" | "not-portable" | "excluded" | "refused-scanner-flagged" | "not-regular-file"; } export interface ScannedHome { definition: SyncHomeDefinition; homePath: string; portable: PortableSnapshotFile[]; skipped: SnapshotSkip[]; } export interface SnapshotPlan { definition: SyncHomeDefinition; source: PortableSnapshotFile; destination: string; digest: string; } export interface StationSnapshotOptions { stationId: string; /** Target repo root; the snapshot lands in /resources//skills. */ repoRoot?: string; /** Stage the homes from a mirror instead of this machine's real $HOME. */ homesRoot?: string; /** Report without writing anything (the default, as in the source script). */ dryRun?: boolean; } export interface StationSnapshotManifestFile { relativePath: string; destination: string; subClass: "skills" | "custom" | "agent-homes"; agent: string | null; sha256: string; sourceMtimeMs: number; sourceMtimeIso: string; size: number; } export interface StationSnapshotResult { stationId: string; mode: "dry-run" | "populate"; repoRoot: string; stats: { files: number; bytes: number; written?: number; unchanged?: number; }; homes: Array<{ name: string; homePath: string; files: number; skipped: number; }>; manifestPath?: string; files: StationSnapshotManifestFile[]; } export declare function sha256File(filePath: string): string; /** Scan every home and build the write plan; fails closed on symlinks. */ export declare function planStationSnapshot(options: StationSnapshotOptions): { scanned: ScannedHome[]; plans: SnapshotPlan[]; totalBytes: number; }; /** * Run the per-station snapshot. Dry-run reports and writes nothing; populate * detects conflicts across the whole plan first and only then writes, so the * terminal refusal genuinely writes nothing. */ export declare function writeStationSnapshot(options: StationSnapshotOptions): StationSnapshotResult;