/** * Task 186 — rename a thread or a co-thread. * * The thread's NAME is the key of every artefact the gateway keeps about it * (task 185 lists them; the task doc for 186 repeats the list). So a rename is * not a field update: it is one migration that moves every name-keyed row at * once, and this module is the only place that migration is written. A second * caller — an MCP tool, the CLI — calls `executeThreadRename`; there is no * other path, because a path that moved most of the rows would leave a thread * that half-exists under two names (Rule #8). * * Two phases, deliberately separate: * * 1. `planThreadRename` — validates and computes every move, including the * cascade when a master is renamed. Pure apart from the context callbacks, * so the six rules it enforces are testable without a filesystem, and so * nothing moves until the WHOLE plan is legal. * 2. `executeThreadRename` — moves files, rewrites the master's `coThreads`, * moves worktrees, appends corrected attribution lines. The caller (server) * then re-keys its own in-memory maps and tells the sockets. */ import type { NamespaceConfig } from './config.js'; /** The alphabet `create_thread` sanitises to. A rename refuses instead of sanitising. */ export declare const THREAD_NAME_RE: RegExp; /** Mirrors CO_THREAD_LABEL in server.ts: the part of a co-thread's name after `-`. */ export declare const CO_THREAD_LABEL_RE: RegExp; /** * Every per-thread file or directory under the threads dir, by extension. The * same list `handleDeleteThread` walks, plus the streaming scratch file. A * rename that missed one would leave an orphan that reattaches to nothing. */ export declare const THREAD_FILE_EXTENSIONS: readonly [".jsonl", ".embeddings.json", ".embeddings.bin", ".segments.json", ".adaptive.json", ".config.json", ".sessions", ".content", ".prompts", ".preview-feedback", ".streaming.tmp"]; /** A refused plan. `status` is the HTTP status the endpoint answers with. */ export declare class ThreadRenameError extends Error { readonly status: number; constructor(status: number, message: string); } export interface RenameMove { from: string; to: string; } export interface ThreadRenamePlan { from: string; to: string; /** Set when the renamed thread is a co-thread: whose list to rewrite. */ coThreadMaster?: string; /** Cascaded co-thread renames when a master is renamed (empty otherwise). */ coThreads: RenameMove[]; /** Every move, the thread itself first. */ moves: RenameMove[]; } export interface PlanContext { namespaces: NamespaceConfig[]; /** Any artefact under any extension exists for this name. */ threadExists(name: string): boolean; /** The thread is mid-turn right now. */ threadBusy(name: string): boolean; /** Master of a registered co-thread, else undefined. */ coThreadMasterOf(name: string): string | undefined; /** The master's registered co-thread list (its EXACT config). */ coThreadsOf(master: string): Promise; } /** * Validate a rename and compute every move it implies. * * Rules, in the order they are checked (each one's failure names it): * 1. `from` exists. * 2. `to` has the thread-name shape and differs from `from`. * 3. Neither name is a namespace base, and both fall in the same namespace. * 4. A co-thread keeps `-` and its new label has the label shape. * 5. A master's co-threads cascade: `-x` → `-x`. * 6. No target name exists; no source is mid-turn. Checked for the WHOLE * cascade before anything is reported legal. */ export declare function planThreadRename(from: string, to: string, ctx: PlanContext): Promise; export interface ExecuteContext { threadsDir: string; /** The project directory a master's worktrees hang off. */ projectDirFor(master: string): Promise; } export interface ThreadRenameResult { from: string; to: string; coThreads: RenameMove[]; /** Extensions actually moved, per thread. */ moved: Record; /** Attribution entries rewritten in the affected content store. */ attributionUpdated: number; /** Worktree outcomes for every co-thread move. */ worktrees: Array; } /** Move every existing artefact of `from` to `to`. Returns the extensions moved. */ export declare function renameThreadFiles(threadsDir: string, from: string, to: string): string[]; /** * Carry out a legal plan. Order matters: * * - The project dir is read BEFORE the files move: for a master it lives in * the config file that is about to change name. * - Files move before the `coThreads` rewrite, because for a master the list * is written into the config under its NEW name. * - Worktrees move from the master's checkout, which does not move. * - Attribution is appended last, into the store under its new path. */ export declare function executeThreadRename(plan: ThreadRenamePlan, ctx: ExecuteContext): Promise; //# sourceMappingURL=thread-rename.d.ts.map