/** * Forgen — Compound Knowledge Export/Import * * Provides backup, migration, and sharing of accumulated personal knowledge * stored under ~/.forgen/me/ (solutions/, rules/, behavior/). * * Export creates a tar.gz archive; Import extracts it while skipping existing * files to prevent accidental overwrites. */ /** * Test-friendly containment check (exported for unit tests). * * Audit fix (2026-04-21, follow-up #A): prior guard * `realDest.startsWith(ME_DIR)` was a naive prefix match. A path like * `/home/u/.forgen/me-evil/x.md` starts with `/home/u/.forgen/me` and * bypassed the check — even though it's a sibling, not a child, of * ME_DIR. Fix: compare with `parent + path.sep` so `/home/u/.forgen/me/` * cannot prefix-match `/home/u/.forgen/me-evil/...`. * * @param parentWithSep absolute canonical parent path that INCLUDES a * trailing `path.sep` (precomputed by caller once per archive). * @param candidate any path string (will be resolved lexically). */ export declare function isPathInside(parentWithSep: string, candidate: string): boolean; export interface ExportResult { outputPath: string; counts: Record; totalFiles: number; } export interface ImportResult { imported: number; skipped: number; details: { file: string; action: 'imported' | 'skipped'; }[]; } /** * Export knowledge directories to a tar.gz archive. * * Uses `tar czf` via child_process for simplicity and reliability. * Only archives solutions/, rules/, behavior/ under ME_DIR. */ export declare function exportKnowledge(outputPath?: string): ExportResult; /** * Import knowledge from a tar.gz archive. * * For each file in the archive, if a file with the same name already exists * in the target directory, it is SKIPPED (no overwrite). Only new files are * added. */ export declare function importKnowledge(archivePath: string): ImportResult; /** * Selective export — filter to specific categories. * `--only solutions,rules` exports only those two directories. */ export declare function exportKnowledgeSelective(categories: string[], outputPath?: string): ExportResult; /** * Import with merge mode — updates existing files instead of skipping them. * Newer files in the archive overwrite older local files. */ export declare function importKnowledgeMerge(archivePath: string): ImportResult & { merged: number; }; /** CLI handler: forgen compound export */ export declare function handleExport(args: string[]): Promise; /** CLI handler: forgen compound import */ export declare function handleImport(args: string[]): Promise;