/** * Plugin manifest shape (minimal — only fields agent-runtime cares about). * Mirrors the marketplace backend's zod schema in optima-skills/src/lib/plugin-schema.ts. */ export interface PluginManifest { name: string; version: string; description?: string; author?: { name?: string; url?: string; }; hooks?: Record; metadata?: { paid?: boolean; salesUrl?: string; cliDependencies?: Record; }; } export declare class PluginTarValidationError extends Error { constructor(msg: string); } export interface FetchAndExtractOpts { /** Maximum tar size in bytes; reject before extract if header content-length exceeds. */ maxBytes: number; /** Optional callback invoked with each extracted file path (for debugging). */ onFile?: (p: string) => void; } export interface FetchAndExtractResult { pluginJson: PluginManifest; /** Absolute paths to extracted skill dirs (one per `skills//`). */ skillDirs: string[]; } /** * Fetch a plugin tar (via the provided async getter) and extract to stagingDir. * * Single streaming pipeline (mirrors Phase 0 backend's plugin-tar-parser.ts): * 1. Fetch tar bytes (caller-provided getter). * 2. Reject if size > maxBytes. * 3. Pipe Readable.from(buf) → createGunzip() → tar.x({strict:true, onentry}). * - `strict: true` is the primary defense (rejects symlinks, devices, `..`, * and other tar-spec violations). * - `onentry` runs `rejectBadEntryPath` for belt-and-suspenders slug-level * validation. * 4. Read .claude-plugin/plugin.json, parse JSON, return manifest + skillDirs. * * On any failure, stagingDir is rm-rf'd before throwing. */ export declare function fetchAndExtractPluginTar(fetcher: () => Promise, stagingDir: string, opts: FetchAndExtractOpts): Promise; //# sourceMappingURL=plugin-tar-extract.d.ts.map