/** * Template hash utilities for detecting user modifications * * Stores SHA256 hashes of template files at install time. * Used to determine if users have modified templates. * * Cross-platform contract: * - All hash dictionary keys are POSIX style (`/`), never `\`. * - Hashes are computed against LF-normalized content, so CRLF and LF * versions of the same logical content produce the same hash. * - Persisted JSON uses schema `{ __version: 2, hashes: { ... } }`. Old * flat-format files (no `__version`) are silently discarded; the hash * set is regenerated on next init/update. */ import type { TemplateHashes } from "../types/migration.js"; /** * Compute SHA256 hash of content. * * Normalizes line endings (CRLF -> LF) before hashing so that the same * logical content yields the same hash across platforms. */ export declare function computeHash(content: string): string; /** * Load stored template hashes. * * Returns `{}` for: missing file, invalid JSON, or legacy flat-format * files (no `__version`). Legacy files are silently dropped; the hash * set is regenerated by subsequent init/update logic. This handles two * Windows compatibility issues at once: backslash keys and CRLF-based * hashes both differ from the v2 contract. */ export declare function loadHashes(cwd: string): TemplateHashes; /** * Save template hashes. * * Always writes the v2 schema with POSIX-normalized keys. */ export declare function saveHashes(cwd: string, hashes: TemplateHashes): void; /** * Update hashes for specific files * * @param cwd - Working directory * @param files - Map of relative paths to file contents */ export declare function updateHashes(cwd: string, files: Map): void; /** * Update hash for a single file by reading its current content */ export declare function updateHashFromFile(cwd: string, relativePath: string): void; /** * Remove hash entry for a file (e.g., after deletion) */ export declare function removeHash(cwd: string, relativePath: string): void; /** * Rename hash entry (used after file rename) */ export declare function renameHash(cwd: string, oldPath: string, newPath: string): void; /** * Check if a template file has been modified by the user * * @param cwd - Working directory * @param relativePath - Relative path to the file * @param hashes - Stored template hashes * @returns true if file has been modified from template, false otherwise */ export declare function isTemplateModified(cwd: string, relativePath: string, hashes: TemplateHashes): boolean; /** * Check if a file matches its original template content * (Useful for determining if a file can be safely auto-migrated) * * @param cwd - Working directory * @param relativePath - Relative path to the file * @param originalContent - Original template content * @returns true if file matches original template */ export declare function matchesOriginalTemplate(cwd: string, relativePath: string, originalContent: string): boolean; /** * Get modification status for multiple files * * @param cwd - Working directory * @param relativePaths - Array of relative paths to check * @param hashes - Stored template hashes * @returns Map of path to modification status */ export declare function getModificationStatus(cwd: string, relativePaths: string[], hashes: TemplateHashes): Map; /** Options accepted by {@link initializeHashes}. */ export interface InitializeHashesOptions { /** * POSIX-style relative paths trellis actually wrote during the init run * (captured via `startRecordingWrites` in `file-writer.ts`). Only these * paths are hashed for the platform/root-level coverage; anything else * under `.codex/` / `.claude/` / etc. is left alone, even if it exists * on disk. Setting this to `undefined` or an empty set means "no * platform/root coverage this run" — historical hashes from earlier * runs are preserved via `merge`. */ trackedPaths?: ReadonlySet; /** * When true, merge `trackedPaths`-derived hashes into the EXISTING manifest * instead of replacing it. Used by `handleReinit` "add platform" flow so * previously-tracked platforms aren't wiped from the manifest when only * a new platform's writes are recorded. Defaults to false (replace). */ merge?: boolean; } /** * Initialize template hashes after init * * The platform/root section of the manifest comes from `trackedPaths` — * the set of POSIX paths that `writeFile` actually wrote (or owned with * byte-identical content) during this init run. Avoids the historical bug * where a blind directory walk of `.codex/` / `.claude/` swept up * user-owned runtime data (chat history, session JSONLs). * * `.trellis/` is still walked recursively (with `EXCLUDE_FROM_HASH`) because * uninstall removes `.trellis/` wholesale via `rm -rf` regardless of manifest * content — accuracy there doesn't affect data-loss, only `trellis update` * 3-way-merge fidelity (preserved by the existing walk). * * @returns Number of files hashed in the final manifest. */ export declare function initializeHashes(cwd: string, options?: InitializeHashesOptions): number; //# sourceMappingURL=template-hash.d.ts.map