/** * SDK primitive for `cleo worktree force-unlock ` (T9547). * * Exposes {@link forceUnlockWorktree} — locates the worktree owned by the * given task ID (`task/T` branch convention), then safely clears any * wedged lock state: * * 1. Removes `.git/index.lock` from the worktree directory if present * (the most common wedge — left behind when a git process crashes mid * mutation). * 2. Runs `git worktree unlock ` when porcelain reports the worktree * as locked via `git worktree lock` (the spawn flow applies this lock * to every agent worktree to prevent accidental pruning). * 3. Warns when uncommitted changes are present but NEVER deletes them. * Operators recover the work themselves with `git stash` or `git diff`. * * Every action is appended to `.cleo/audit/worktree-lifecycle.jsonl` via * {@link appendWorktreeAuditEntry}. The audit entry carries enough context * (timestamp, actor, action, target, taskId, success state, error reason) to * reconstruct the unlock attempt without re-running git. * * @task T9547 * @epic T9515 */ import { type EngineResult, type ForceUnlockWorktreeOpts, type ForceUnlockWorktreeResult } from '@cleocode/contracts'; /** * Force-unlock the worktree for a given task ID. * * Routes: * - Worktree not found ⇒ `engineError('E_WORKTREE_NOT_FOUND')` * - Worktree found, no lock state ⇒ `engineSuccess` with `success: true` and * both `indexLockRemoved` / `worktreeUnlocked` set to `false`. This is a * valid no-op — the operator asked us to unlock and there was nothing to do. * - Worktree found, lock state cleared ⇒ `engineSuccess` with the relevant * flag(s) set to `true` plus an audit-log entry. * - Uncommitted changes detected ⇒ `hadUncommittedChanges: true` plus a * warning in the audit reason. The function NEVER deletes or stashes the * changes — that decision belongs to the operator. * * @param opts - See {@link ForceUnlockWorktreeOpts}. * @returns EngineResult wrapping a {@link ForceUnlockWorktreeResult}. * * @example * ```ts * const r = await forceUnlockWorktree({ * projectRoot: process.cwd(), * taskId: 'T9547', * }); * if (r.success && r.data.indexLockRemoved) { * console.log('cleared .git/index.lock'); * } * ``` */ export declare function forceUnlockWorktree(opts: ForceUnlockWorktreeOpts): Promise>; /** * Build the list of candidate `index.lock` paths to inspect for a given * worktree directory. * * Worktrees use a split git-dir layout: `/.git` is a small text file * (`gitdir: /worktrees/`) and the actual index, refs, and lock * files live under `/worktrees//`. When a process crashes, * stale `index.lock` can appear in either place — so we check both * `/.git/index.lock` AND the admin path resolved via `git rev-parse * --git-dir`. * * @internal Exported for tests only. */ export declare function resolveIndexLockCandidates(worktreePath: string): string[]; /** * Returns `true` when the worktree has uncommitted changes (anything that * `git status --porcelain` would print). The check is purely informational — * the unlock path never touches working-tree content. * * @internal Exported for tests only. */ export declare function detectUncommittedChanges(worktreePath: string): boolean; //# sourceMappingURL=force-unlock.d.ts.map