/** * v0.8.1 — yauzl-based archive reader. * * Per docs/plan/v0.8.1-security-lifecycle-pair.md §4.2 + §5. Shared between * `solosquad import` and `solosquad archive verify/info/list`. `archiver` * is writer-only (no reader API) so v0.8.1 introduces `yauzl` as a devDep * — the archive verify CLI is the only runtime user. Tests prove the * reader can round-trip a v0.7-format archive. * * Two access modes: * 1. `readArchiveMeta(path)` — extract `archive.yaml` + `manifest.tsv` * only. Cheap, no full decompression. Used by `verify` + `info`. * 2. `extractAllEntries(path, onEntry)` — iterate every entry with its * decompressed Buffer + computed SHA256. Used by `verify` (SHA tally) * and `import` (unpack to disk). */ export interface ManifestEntry { path: string; /** SHA256 hex digest, or null for "-" placeholder entries (class D). */ sha256: string | null; /** File size in bytes, or null for "-" placeholder. */ size: number | null; cls: string; notes: string; } export interface ManifestDoc { schemaVersion: number; entries: ManifestEntry[]; } export interface ArchiveYamlDoc { schema_version: number; export_ts: string; solosquad_version: string; workspace_slug: string; created_by?: string; included_orgs: string[]; archive_format: string; import_compat?: { min_solosquad_version: string; max_schema_version_supported: number; archive_format: string; }; [k: string]: unknown; } export interface ArchiveMeta { archiveYaml: ArchiveYamlDoc; manifest: ManifestDoc; } export interface ExtractedEntry { /** Path inside the archive (forward slashes). */ archivePath: string; /** Decompressed contents. */ buffer: Buffer; /** SHA256 computed from the decompressed bytes. */ sha256: string; /** Uncompressed size (== buffer.byteLength). */ size: number; } export interface VerifyReport { ok: boolean; /** Manifest schema_version (1 in v0.7-v0.8.1). */ schemaVersion: number; /** Number of manifest rows. */ manifestRows: number; /** Number of entries actually present in the zip (excludes manifest.tsv itself). */ archiveRows: number; /** Entries whose computed SHA256 disagrees with the manifest. */ shaMismatches: Array<{ path: string; manifest: string; actual: string; }>; /** Entries listed in the manifest but absent from the zip. */ missingFromArchive: string[]; /** Entries present in the zip but absent from the manifest (besides manifest.tsv). */ extraInArchive: string[]; /** Schema-compat findings (CLI version vs min_solosquad_version, format, …). */ schemaCompat: SchemaCompatResult; } export interface SchemaCompatResult { ok: boolean; reasons: string[]; } /** * Extract just archive.yaml and manifest.tsv from a zip. The rest of the * archive is not decompressed. Used by `verify` (pre-check) and `info`. */ export declare function readArchiveMeta(archivePath: string): Promise; /** * Parse a manifest.tsv body produced by `ManifestBuilder.toTsv()`. * * Format: * # schema_version=N * pathsha256sizeclassnotes * */ export declare function parseManifestTsv(text: string): ManifestDoc; /** * Iterate every entry in a zip, decompress it, and invoke the callback with * the resulting buffer + SHA. Excludes directory entries. * * Streaming is per-entry — the caller receives one entry at a time, so * memory is bounded by the largest single entry rather than the whole zip. */ export declare function extractAllEntries(archivePath: string, onEntry: (e: ExtractedEntry) => Promise | void): Promise; /** * Verify a v0.7-format archive — SHA × manifest tally + schema-compat * check. Returns a structured report rather than throwing so callers * (import / archive verify CLI) can decide how to format the output. */ export declare function verifyArchive(archivePath: string, opts: { cliVersion: string; }): Promise; /** * Schema compatibility — does the archive declare a format the current * CLI understands? * * 1. `archive_format == "zip-v1"` (only known format in v0.7+v0.8.1) * 2. `import_compat.min_solosquad_version <= cliVersion` * 3. `import_compat.max_schema_version_supported >= 1` (current schema) * 4. `schema_version == 1` */ export declare function checkSchemaCompat(archiveYaml: ArchiveYamlDoc, cliVersion: string): SchemaCompatResult; /** * Compare two semver-ish strings (numeric only). Returns negative, 0, or * positive — same contract as `Array.prototype.sort`. */ export declare function compareSemver(a: string, b: string): number;