import { type EntityKind, type Issue, type RefResolver } from './template-validate.js'; export type WriteErrorCode = 'not-found' | 'invalid-args' | 'conflict'; /** Carries the validation issues so the UI can anchor them at their fields. */ export interface TemplateWriteError extends Error { code: WriteErrorCode; issues?: Issue[]; } export declare function sha256(text: string): string; export declare function entityPath(dir: string, kind: EntityKind, name: string): string; export interface EntityRead { kind: EntityKind; name: string; filePath: string; /** Raw parsed body, or null when the file on disk is not parseable JSON. */ body: Record | null; /** Hash of the exact bytes on disk — pass back as `baseHash` to save safely. */ sha256: string; } export declare function readEntity(dir: string, kind: EntityKind, name: string): EntityRead; export interface SaveInput { kind: EntityKind; name: string; body: unknown; /** sha256 of the content the editor started from. `null` means "create — must not exist yet". */ baseHash: string | null; } export interface SaveResult { changed: boolean; filePath: string; /** Non-blocking issues the caller should surface after the write. */ warnings: Issue[]; /** Hash of what is now on disk, so the editor can keep saving without a reload. */ sha256: string; } /** * Create or replace one entity file. The body is the complete desired state — omitted fields are * removed, not merged, because the editor always holds the whole document. * * Validation runs against the registry with this candidate already swapped in, so a change is * judged by the world it produces rather than the one it replaces. Errors block the write. */ export declare function saveEntity(dir: string, input: SaveInput, refs?: RefResolver): SaveResult; export interface RemoveResult { removed: boolean; filePath: string; } /** * Delete one entity file. Refuses while another template still declares this agent or binds this * shell — the loader would keep skipping that template, and any thread on it would stall. * Templates themselves have no config-level dependents; task and running-thread references are the * caller's to check, since they live outside this directory. */ export declare function removeEntity(dir: string, kind: EntityKind, name: string): RemoveResult; /** Every entity name present on disk, by kind. */ export declare function listEntityNames(dir: string, kind: EntityKind): string[];