import { type SearchIndexSyncStats } from "../search/sqliteIndex.js"; /** * GH #643 (local-first phase 0): pull a cloud wiki down to a local WIKI_DIR. * * Two halves, kept separate so each is independently testable: * - fetchExportZip: talks to the cloud instance's async export job * (POST /api/v1/export -> GET /api/v1/export/download), never the MCP * export_wiki inline zipData path (base64-overflows around 769 pages, #328). * - hydrateLocalWikiFromZip: unpacks the zip into a local WIKI_DIR via the * existing AdmZip-backed importWikiZip.runImportFromBuffer, then syncs the * local SQLite search index so search works with no separate step. */ export interface ExportJob { ok: boolean; jobId: string; error?: string; } export interface JobStatus { status: "queued" | "running" | "done" | "failed"; error?: string; progress?: { processed: number; total: number; phase: string; }; result?: { pageCount: number; skippedCount: number; generatedAt: string; downloadUrl: string; fileName: string; }; } /** * "bearer" (default) sends `Authorization: Bearer ` — the header a * user's own PAT authenticates against (GH #748: `x-api-key` only matches * the server's own `BRAINS_API_KEY`, never a per-user PAT). "instance-key" * sends `x-api-key` instead, for the operator use case of authenticating * with the instance's shared secret. */ export type AuthMode = "bearer" | "instance-key"; export declare function buildAuthHeaders(apiKey: string, authMode?: AuthMode): Record; export interface FetchExportOptions { baseUrl: string; apiKey: string; folder?: string; tags?: string[]; since?: string; includeSystem?: boolean; /** Defaults to "bearer" — a real user has a PAT, not the instance's shared key. */ authMode?: AuthMode; /** Injectable for tests; defaults to the global fetch. */ fetchImpl?: typeof fetch; pollIntervalMs?: number; timeoutMs?: number; } export interface ExportedZip { buffer: Buffer; pageCount: number; skippedCount: number; generatedAt: string; } export declare function fetchExportZip(opts: FetchExportOptions): Promise; export interface HydrateLocalWikiOptions { /** * How to handle a page that already exists locally with different content. * Defaults to "skip" — a local edit is never silently clobbered (GH #643 AC5). * Pass "overwrite" only when the caller has explicitly opted into replacing * local state with the cloud copy. */ conflictStrategy?: "skip" | "overwrite" | "merge"; includeSystem?: boolean; onProgress?: (processed: number, total: number, phase: string) => void; } export interface HydrateLocalWikiResult { created: number; updated: number; skipped: number; errors: Array<{ path: string; reason: string; }>; warnings: Array<{ path: string; reason: string; }>; /** Non-system page count reported by the source export job. */ expectedPageCount: number; /** Of the zip's own pages, how many now exist on disk in WIKI_DIR. */ hydratedPageCount: number; /** Zip page names that are still missing locally after hydration (should be empty). */ missingPages: string[]; index: SearchIndexSyncStats; } export declare function hydrateLocalWikiFromZip(wikiDir: string, zip: ExportedZip, opts?: HydrateLocalWikiOptions): Promise; //# sourceMappingURL=hydrateWiki.d.ts.map