export declare function getGitBranch(cwd: string): string; export declare function getGitStatus(cwd: string): string; export declare function getGitDiff(mode: 'staged' | 'all', cwd: string): string; export declare function getGitDiffStat(cwd: string): string; /** * Detect the default branch of the remote (e.g. main, master). * Falls back to 'main' if detection fails. */ export declare function getDefaultBranch(cwd: string): string; /** * The branch-vs-base diff PLUS the ref that actually produced it (mmnto-ai/totem#2106 * rev-5 item 3). `getGitBranchDiff` returns only the diff text, so a caller that also * needs to know WHICH ref was diffed (for scope/lineage metadata) previously re-probed * ref existence separately — but `origin/` can EXIST yet its `...HEAD` diff FAIL * (unrelated histories / no merge base), in which case the payload is local-based while * a separate existence probe would mislabel it `origin/`. Returning `resolvedBase` * from the diff operation itself couples the recorded ref to the diff that actually ran. */ export interface GitBranchDiffResult { /** The unified diff text of `...HEAD`. */ diff: string; /** The ref that PRODUCED the diff — `origin/` when its diff succeeded, else the local ``. */ resolvedBase: string; } export declare function getGitBranchDiffResult(cwd: string, base?: string): GitBranchDiffResult; /** * Branch-vs-base diff text only. Thin wrapper over {@link getGitBranchDiffResult} that * discards `resolvedBase` — retained at its original `string` return so the many * existing callers keep compiling (mmnto-ai/totem#2106 rev-5 item 3, additive change). */ export declare function getGitBranchDiff(cwd: string, base?: string): string; /** * Run `git diff ` for an explicitly supplied ref range (e.g. * `HEAD^..HEAD`, `main...feature`). Used by `totem review --diff` to * bypass the implicit working-tree → staged → branch-vs-base fallback chain. * * Rejects ranges starting with `-` to defuse git-flag injection (e.g. * `--diff --no-index`); `safeExec`'s arg-array form already prevents shell * metacharacter expansion on the range itself. */ export declare function getGitDiffRange(cwd: string, range: string): string; /** * Get the author date of a tag in YYYY-MM-DD format. * Returns null if tag doesn't exist or lookup fails. */ export declare function getTagDate(cwd: string, tag: string): string | null; /** * Get the most recent semver tag (e.g., "v0.14.0"). * Returns null if no tags exist. */ export declare function getLatestTag(cwd: string): string | null; /** * Get git log since a ref (tag or commit), or last N commits as fallback. * Returns one-line-per-commit format: "hash subject". */ export declare function getGitLogSince(cwd: string, since?: string, maxCommits?: number): string; /** * Check if a specific file has uncommitted changes (staged or unstaged). * * Fails loud: throws `TotemGitError` when git is absent or errors, so callers * cannot mistake "git broke" for "file is clean" (mmnto/totem#1440). The one * documented silent-false case is "not a git repository" — a legitimate state * for a working directory that happens to sit outside version control. * Callers that truly want silent fallback for OTHER git failures must opt in * explicitly with their own try/catch + `// totem-context:` annotation. */ export declare function isFileDirty(cwd: string, filePath: string): boolean; /** * List git-tracked files under `dirAbs`, returned as `dirAbs`-relative * forward-slash paths. Returns `null` (NOT an empty set) when the directory is * outside a git repo OR git is unavailable/errors — the documented signal for * callers to fall back to a filesystem walk rather than treat "git unavailable" * as "nothing tracked." An empty set means the opposite: we ARE in a repo and * genuinely nothing under `dirAbs` is tracked. * * Used by {@link generateInputHash} to exclude untracked working-tree lessons * from the compile-manifest input hash — an untracked MCP scratch lesson must * not diverge the hash and block an unrelated push (mmnto-ai/totem#2051 / * mmnto-ai/totem#2055 working-tree-scope class). Fail-soft to `null` is * deliberate: a git hiccup degrades to the legacy fs-walk (prior behavior), * never a crash. * * Reads git's NUL-delimited output so paths with spaces or unicode parse * exactly; the delimiter is built via `String.fromCharCode(0)` to keep this * source free of a literal control byte. */ export declare function listTrackedFilesUnder(repoCwd: string, dirAbs: string): Set | null; /** * Resolve the git repository root via a JS-side walk-up looking for `.git/`, * rather than shelling out to `git rev-parse --show-toplevel`. Sibling to * {@link resolveGitRoot}; prefer this variant when the caller will combine * the returned root with paths derived from `process.cwd()` — git's output * normalizes case + may resolve Windows 8.3 short names (`RUNNER~1`) to long * names (`runneradmin`), and the divergence breaks `path.relative` even when * both paths point at the same directory. A JS-side walk returns a path in * cwd's own form, so downstream `path.relative` works portably. * * Returns `null` when `start` is not inside a git repository (or any parent * is not). Never throws — best-effort by contract. No subprocess overhead. */ export declare function findRepoRootSync(start: string): string | null; /** * Walk up from `start` to the nearest ancestor that is a Totem repo root: a * directory containing a `.totem/` marker OR a `.git` entry (a directory in a * normal clone, a FILE in a linked worktree — `existsSync` matches both). * Returns that ancestor's absolute path, or `null` when neither marker appears * up to the filesystem root. Never throws — best-effort, pure fs, no git spawn. * * Sibling to {@link findRepoRootSync} (which keys on `.git` alone); this * variant also stops at `.totem/` so a consumer invoked from a SUBDIRECTORY of * a repo — e.g. `.totem/orchestration//processed/` — resolves the true * root instead of the subdir. Without it, a cwd-fragile derivation * (`process.cwd()` + `path.dirname`) reads the wrong workspace and can render a * false-clean verdict (mmnto-ai/totem#2312). The `.totem` marker is checked * first so an orchestration-only tree still anchors even where `.git` is a * worktree file the caller might not expect. */ export declare function findTotemRepoRootSync(start: string): string | null; /** * Resolve the effective Totem repo root for a command invoked with an optional * `repoRoot` override: treat `repoRoot ?? cwd` as the WALK START and derive * the root via {@link findTotemRepoRootSync}; a marker-less start (bare test * fixture) is used as-is. Single home for the walk-start-not-definitive-root * contract shared by `pollMail`, `eclGc`, and `eclCompact` * (mmnto-ai/totem#2312). */ export declare function resolveTotemRepoRootSync(repoRootOpt: string | undefined, cwd: string): string; /** * A copy of `env` with {@link GIT_LOCATION_ENV_VARS} removed and everything * else — PATH included — carried through unchanged. Exported for direct * testing; callers pass the result as the child's `env`. */ export declare function envWithoutGitLocation(env?: NodeJS.ProcessEnv): NodeJS.ProcessEnv; /** * The REPOSITORY NAME of a checkout's `origin` remote — `totem` for * `https://github.com/mmnto-ai/totem.git`, `git@github.com:mmnto-ai/totem.git`, * and either form without the `.git` suffix or with trailing slashes. The * owner and the host are deliberately dropped: this answers "which repository * is this checkout of", which is a property of the path's last segment, and a * mirror or a fork at the same repo name answers the same (the same * host-blindness the doctor's cohort-id derivation already has). * * Returns `null` when there is no origin, when git is unavailable or fails for * ANY reason, or when the URL yields no `owner/repo` pair. Never throws: every * caller's fallback is "we do not know", and a git failure is exactly that. * * Costs one synchronous `git config` spawn, so call it only where the answer * cannot be had from the filesystem (mmnto-ai/totem#2801: the cohort map's key, * where a per-agent worktree's DIRECTORY basename names the worktree rather * than the repository). * * The answer is a function of `cwd` ALONE, and two guards make it so. * * `--local` scope: a bare `git config --get` searches local, then GLOBAL, then * system, and answers outside a repository at all — so a machine carrying a * global `remote.origin.url` would hand a repo-shaped answer to a directory * that is not a repo. `--local` errors outside a repository, which lands on the * documented `null`. In a linked worktree it reads the shared common-dir * config, where remotes live. * * A scrubbed env: git's repository-location variables are read from the * environment before `cwd` is consulted, and git EXPORTS them into every hook * process it spawns. Inheriting them made this read answer for whatever * repository the ambient `GIT_DIR` named — a non-repo directory resolved as * that repo, which is the identity-adoption class the caller exists to * prevent, and it turned the resolver's own suite red under an exported * `GIT_DIR`. {@link GIT_LOCATION_ENV_VARS} are therefore deleted from the * child's env; everything else (PATH above all) is inherited unchanged. */ export declare function getOriginRepoName(cwd: string): string | null; /** * Extract the repository name from an ssh (`git@host:owner/repo.git`) or https * (`https://host/owner/repo.git`) remote URL, tolerating a trailing `.git` and * trailing slashes in either order. Returns `null` when no `owner/repo` pair * resolves. Pure — exported for direct testing of the parse. */ export declare function repoNameFromRemoteUrl(remoteUrl: string | undefined): string | null; export declare function resolveGitRoot(cwd: string): string | null; /** * Filter a unified diff to exclude files matching ignore patterns. * Splits on `diff --git` boundaries and removes sections for ignored files. * Uses matchesGlob from core for consistent glob behavior. */ export declare function filterDiffByPatterns(diff: string, patterns: string[]): string; export declare function extractChangedFiles(diff: string): string[]; /** * Infer a scope glob suggestion from a list of changed file paths. * Returns glob patterns based on the common directory prefix, * with default test file exclusions. */ export declare function inferScopeFromFiles(files: string[]): string[]; //# sourceMappingURL=git.d.ts.map