import type { Component } from "../agent/project-config-store.js";
/**
 * Whether remote git push operations should be skipped.
 * Set BOBBIT_TEST_NO_PUSH=1 in E2E tests to prevent any network traffic to GitHub.
 */
export declare function shouldSkipRemotePush(): boolean;
/**
 * Strip embedded credentials from a git remote URL.
 * e.g. "https://ghp_abc123@github.com/user/repo.git" → "https://github.com/user/repo.git"
 * Prevents tokens from leaking into .git/config inside sandbox containers.
 * Authentication is handled by the credential helper reading GITHUB_TOKEN from env.
 */
export declare function stripTokenFromGitUrl(url: string): string;
/**
 * Resolve the remote primary branch (e.g. origin/main or origin/master).
 * Uses `git symbolic-ref refs/remotes/origin/HEAD` which is set by `git clone`.
 * Falls back to "HEAD" if detection fails.
 */
/**
 * Detect the bare primary branch name (e.g. "main" or "master").
 * Uses `git symbolic-ref refs/remotes/origin/HEAD`, which is set by `git clone`.
 * Falls back to local `master`, then local `main`, then literal "master".
 *
 * Unlike `resolveRemotePrimary` (which returns the ref with `origin/` prefix),
 * this returns the bare branch name suitable for substituting into prompt
 * templates as `{{master}}`.
 */
export declare function detectPrimaryBranch(cwd: string): Promise<string>;
/**
 * Pure parser — splits a configured `base_ref` value into its component pieces.
 * Exported so sandbox-internal callers can use the same logic without an exec
 * round-trip. Does NOT consult disk; trim() and `origin/` stripping only.
 *
 * Examples:
 *   configured = ""            → { ref: "", branch: "", isRemote: false }   (sentinel: unset)
 *   configured = "  "          → { ref: "", branch: "", isRemote: false }   (whitespace == unset)
 *   configured = "master"      → { ref: "master", branch: "master", isRemote: false }
 *   configured = "origin/dev"  → { ref: "origin/dev", branch: "dev", isRemote: true }
 *   configured = "origin/feature/foo" → { ref: "origin/feature/foo", branch: "feature/foo", isRemote: true }
 *
 * Note: this is a pure parser. It does NOT validate grammar, reject tags, SHAs,
 * or non-`origin` prefixes — those are the REST handler's responsibility at
 * save time. By the time `parseBaseRef` runs, the value has already been
 * persisted to project config and is assumed well-formed.
 */
export declare function parseBaseRef(configured: string): {
    ref: string;
    branch: string;
    isRemote: boolean;
};
/**
 * Host-side resolver for `base_ref`. Used by the bulk of the server.
 *   - configured non-empty → `parseBaseRef(configured)` (no exec).
 *   - configured empty/undefined → falls back to `resolveRemotePrimary(repoPath)`
 *     (today's behavior — `git symbolic-ref refs/remotes/origin/HEAD`).
 *
 * The fallback path returns the project's remote primary as `{ ref: "origin/main",
 * branch: "main", isRemote: true }`. If primary detection fails, returns
 * `{ ref: "HEAD", branch: "HEAD", isRemote: false }` — same sentinel as
 * `resolveRemotePrimary` returns.
 */
export declare function resolveBaseRef(repoPath: string, configured: string | undefined): Promise<{
    ref: string;
    branch: string;
    isRemote: boolean;
}>;
/**
 * Sandbox variant of `resolveBaseRef`. Used by `project-sandbox.ts` so the
 * container path doesn't pay an extra docker exec when configured is non-empty.
 *   - configured non-empty → `parseBaseRef` (no exec).
 *   - configured empty/undefined → `exec(["symbolic-ref", "refs/remotes/origin/HEAD"])`.
 *
 * The `exec` callback must run `git` inside the container with the worktree as
 * cwd, returning stdout. Errors are caught and the sentinel `HEAD` is returned
 * (matches `resolveRemotePrimary`'s fallback).
 */
export declare function resolveBaseRefWithExec(exec: (args: string[]) => Promise<string>, configured: string | undefined): Promise<{
    ref: string;
    branch: string;
    isRemote: boolean;
}>;
/**
 * Parse the first `ref:` line of `git ls-remote --symref origin HEAD` output.
 * Returns the bare branch name (strips `refs/heads/`) or null if absent.
 * Pure parser — no exec, no disk access. Tolerant of tab/space separators and
 * CRLF line endings.
 *
 * Examples:
 *   "ref: refs/heads/master\tHEAD\n<sha>\tHEAD" → "master"
 *   "ref: refs/heads/feature/x\tHEAD"           → "feature/x"
 *   "<sha>\tHEAD"                               → null (no symref line)
 *   ""                                          → null
 */
export declare function parseLsRemoteSymref(output: string): string | null;
/**
 * Best-effort: run `git ls-remote --symref origin HEAD` in `repoPath`, parse
 * the symref, and return `origin/<branch>` — or null on ANY failure (offline,
 * no remote, not a git repo, unparseable output). Never throws.
 *
 * Used to pin a concrete `base_ref` from the live remote at project-add time.
 * See docs/design/base-ref.md.
 */
export declare function detectBaseRefFromRemote(repoPath: string): Promise<string | null>;
/** True iff `ref` resolves via `git rev-parse --verify` in repoPath. Never throws. */
export declare function refExistsInRepo(repoPath: string, ref: string): Promise<boolean>;
/** Check if a directory is inside a git repository. */
export declare function isGitRepo(cwd: string): Promise<boolean>;
/** Get the git repo root for a directory. */
export declare function getRepoRoot(cwd: string): Promise<string>;
/**
 * Whether `dir` is the TOPLEVEL of a git working tree (i.e. a git repo ROOT),
 * NOT merely a directory nested somewhere inside one.
 *
 * `isGitRepo` (which runs `git rev-parse --is-inside-work-tree`) returns true
 * for ANY path inside a repo — including a non-git container that happens to be
 * nested under an unrelated parent git repo. That false-positive would cause
 * `createWorktreeSet` to run `git worktree add` against the container root. This
 * helper distinguishes the two by comparing the canonicalized
 * `git rev-parse --show-toplevel` against the canonicalized input dir.
 *
 * Returns false on any error (not a git repo, missing dir, git failure).
 */
export declare function isGitRepoRoot(dir: string): Promise<boolean>;
/**
 * Resolve the canonical main-repo working directory to bind-mount as the sandbox
 * clone source.
 *
 * A linked git worktree's `.git` is a gitdir-FILE pointing at the main repo's
 * object store, not a real `.git` directory. Bind-mounting and `git clone`ing
 * just the worktree dir fails because the objects live in the main repo, which
 * isn't mounted. So we resolve the canonical MAIN repo root via
 * `git rev-parse --git-common-dir` and mount that instead.
 *
 * Returns the realpath of the main working tree (parent of the resolved
 * `.git`), or the realpath of the common dir itself for a bare repo. On any
 * failure, falls back to `canonicalizePath(repoPath)`. Always resolves symlinks
 * (defense in depth: the mount source is never an un-canonicalized path).
 */
export declare function resolveSandboxMountRoot(repoPath: string): Promise<string>;
export interface WorktreeResult {
    worktreePath: string;
    branchName: string;
}
/**
 * Create a git worktree on a new branch from a given start-point (default HEAD).
 * The worktree is placed as a sibling directory to the repo.
 *
 * Fully async — the `git worktree add` and `git push` are all awaited
 * without blocking the Node.js event loop.
 *
 * Per-component worktree setup is the responsibility of the caller —
 * invoke `runComponentSetups()` from `worktree-setup.ts` after this
 * function returns. `components[*].worktreeSetupCommand` is the single
 * source of truth.
 *
 * @param opts.startPoint — git ref to base the new branch on (default `"HEAD"`).
 *   Pass e.g. `origin/my-branch` to start from a remote tracking branch. When
 *   provided, this takes precedence over `configuredBaseRef`.
 * @param opts.configuredBaseRef — the project's configured `base_ref` setting.
 *   When `startPoint` is absent and this is non-empty, it drives both the
 *   worktree start-point and the branch upstream (via `--set-upstream-to`).
 *   Empty/undefined falls back to today's behavior (`resolveRemotePrimary`).
 *   Only fires `--set-upstream-to` when this is non-empty — explicit-startPoint
 *   callers (e.g. team-manager's hierarchical branching) keep today's
 *   `origin/<branch>` upstream semantics after a safe explicit-refspec publish.
 */
export declare function createWorktree(repoPath: string, branchName: string, opts?: {
    startPoint?: string;
    skipPush?: boolean;
    worktreeRoot?: string;
    configuredBaseRef?: string;
}): Promise<WorktreeResult>;
/**
 * Create a coordinated set of worktrees — one per distinct repo declared in
 * `components`. Single-repo (one component, repo===".") collapses to today's
 * `createWorktree` behavior identically; multi-repo creates a per-repo worktree
 * under `<wtRoot>/<branchSlug>/<repo>/` from each repo's source at
 * `<rootPath>/<repo>/`.
 *
 * Does NOT run per-component setup commands — caller is responsible for
 * invoking `runComponentSetups()` afterward.
 *
 * See docs/design/multi-repo-components.md §4 + §5.
 */
export declare function createWorktreeSet(rootPath: string, components: Component[], branchName: string, baseBranch?: string, opts?: {
    worktreeRoot?: string;
    configuredBaseRef?: string;
}): Promise<{
    container: string;
    worktrees: Array<{
        repo: string;
        repoPath: string;
        worktreePath: string;
    }>;
}>;
/**
 * Remove a git worktree and optionally delete the branch.
 * Async to avoid blocking the Node.js event loop.
 */
export declare function cleanupWorktree(repoPath: string, worktreePath: string, branchName?: string, deleteBranch?: boolean): Promise<void>;
/**
 * Recover a worktree whose directory is missing but whose branch still exists.
 *
 * This happens when a worktree directory is deleted (e.g. by cleanup, crash,
 * or manual removal) but the branch is preserved locally or on the remote.
 *
 * Steps:
 * 1. Prune stale worktree references (git tracks worktrees and will refuse
 *    to create one if it thinks the old one still exists)
 * 2. Fetch from origin to ensure we have the latest branch ref
 * 3. Re-create the worktree, checking out the existing branch
 *
 * Per-component setup is the caller's responsibility — invoke
 * `runComponentSetups()` after this function returns.
 *
 * @returns The worktree path, or null if recovery failed
 */
export declare function recoverWorktree(repoPath: string, branchName: string, worktreePath: string): Promise<string | null>;
//# sourceMappingURL=git.d.ts.map