import type { PrepareRunGitOptions, PreparedGit, FinalizeRunGitOptions, FinalizedGit } from './git-pipeline'; export type GitLogFn = (text: string, level?: 'stdout' | 'stderr') => void; export interface StashResult { gitRoot: string; repoName: string; wasDirty: boolean; stashed: boolean; /** Tagged stash message: `teamshare:[:leftover]`. */ stashRef?: string; /** Stash index for pop: `stash@{0}`. */ stashIndex?: string; /** True when the stashed dirt came from an interrupted previous run. */ leftover?: boolean; popped: boolean; popConflicts: boolean; popConflictedFiles?: string[]; error?: string; } /** * A `teamshare:*` stash entry found on disk. Report-only: the caller decides * whether to surface it, adopt it (`restoreStash`) or leave it alone. */ export interface OrphanStash { gitRoot: string; repoName: string; /** e.g. `stash@{0}`. */ stashIndex: string; /** Task id embedded in the `teamshare:[:leftover]` tag. */ taskId: string; /** True when the tag matches the task currently starting (its OWN stash). */ isSelf: boolean; /** True when the entry carries the `:leftover` provenance suffix. */ leftover: boolean; /** Stash creation date (`git log -1 --format=%ci`), or `unknown`. */ date: string; /** Paths captured by the stash (tracked + untracked when git supports it). */ files: string[]; } export interface GitCycleOptions { /** Passed to prepareRunGitAsync. */ prepare: PrepareRunGitOptions; /** Passed to finalizeRunGit. */ finalize: FinalizeRunGitOptions; } export interface GitCycleResult { prepared: PreparedGit; finalized: FinalizedGit; stashResults: StashResult[]; } /** Minimal API interface — only what git-runner needs. */ export interface GitRunnerApi { addComment(dto: { taskId: string; body: string; }): Promise; } /** * Every `teamshare:*` stash entry under `gitRoot`, newest first. Includes the * current task's OWN interrupted stash (`isSelf`) instead of skipping it. * Never mutates the stash list. */ export declare function listStashes(gitRoot: string, cwd: string, currentTaskId: string): OrphanStash[]; /** * Pop a specific stash entry by ref (`git stash pop --index`). Returns true on * success, false on conflict or error. Used by the daemon's session.stop * handler to restore stashes when the CLI's finally block does not run. */ export declare function popStashByRef(gitRoot: string, ref: string, log: GitLogFn): boolean; /** * Apply a stashed entry onto the working tree WITHOUT dropping it * (`git stash apply`, not `pop`). Called only by an explicit adoption * (`--adopt-stash`) or a human/agent decision - never automatically. */ export declare function restoreStash(gitRoot: string, ref: string, cwd: string, log: GitLogFn): boolean; export declare function stashRepo(gitRoot: string, taskId: string, cwd: string, api: GitRunnerApi | null, log: GitLogFn, opts?: { leftover?: boolean; }): Promise; export declare function popRepo(gitRoot: string, result: StashResult, cwd: string, taskId: string, api: GitRunnerApi | null, log: GitLogFn): Promise; /** * Scan all git roots for `teamshare:*` stash entries. Returns them structured * (so the caller can surface the file list to the agent) and posts one * recovery comment per entry. Includes the CURRENT task's own interrupted * stash (`isSelf`) - a naive "belongs to this run" skip used to hide it. * * Report-only: this never applies or drops a stash. */ export declare function checkOrphanedStashes(cwd: string, currentTaskId: string, api: GitRunnerApi | null, log: GitLogFn): Promise; /** * Run the full git cycle (prepare → work → finalize) with per-repo stash * protection. Stashes dirty repos before branching, restores after. * * - If stash fails: warns and continues (no block) * - If pop has conflicts: force pops, user resolves * - If run crashes: orphaned stash detected on next run * - Audit: every stash/pop posts a task comment */ export declare function runGitCycle(cwd: string, opts: GitCycleOptions, api: GitRunnerApi | null, workFn: (prepared: PreparedGit) => Promise, log: GitLogFn): Promise; /** * Format stash results into a markdown section for the closing comment. * `orphans` (report-only detections) are listed separately so a human can see * that other changes remain stashed and were NOT touched by this run. */ export declare function formatStashSummary(stashResults: StashResult[], orphans?: OrphanStash[]): string;