import type { AgentTool, AgentToolContext, AgentToolResult, AgentToolUpdateCallback, ToolApprovalDecision } from "@oh-my-pi/pi-agent-core";
import type { Settings } from "../config/settings.js";
import * as git from "../utils/git.js";
import type { ToolSession } from "./index.js";
import { type CacheStatus } from "./github-cache.js";
import type { OutputMeta } from "./output-meta.js";
/** Runs `gh --json` for issue data, retrying without optional stateReason on older gh releases. */
export declare function githubIssueJsonWithStateReasonFallback<T>(cwd: string, args: readonly string[], signal: AbortSignal | undefined, options?: git.GhCommandOptions): Promise<T>;
declare const githubSchema: import("arktype/internal/variants/object.ts").ObjectType<{
    op: "pr_checkout" | "pr_create" | "pr_push" | "repo_view" | "run_watch" | "search_code" | "search_commits" | "search_issues" | "search_prs" | "search_repos";
    repo?: string | undefined;
    branch?: string | undefined;
    pr?: string | string[] | undefined;
    force?: boolean | undefined;
    forceWithLease?: boolean | undefined;
    title?: string | undefined;
    body?: string | undefined;
    base?: string | undefined;
    head?: string | undefined;
    draft?: boolean | undefined;
    fill?: boolean | undefined;
    reviewer?: string[] | undefined;
    assignee?: string[] | undefined;
    label?: string[] | undefined;
    query?: string | undefined;
    since?: string | undefined;
    until?: string | undefined;
    dateField?: "created" | "updated" | undefined;
    limit?: number | undefined;
    run?: string | undefined;
    tail?: number | undefined;
}, {}>;
type GithubInput = typeof githubSchema.infer;
export interface GhToolDetails {
    meta?: OutputMeta;
    artifactId?: string;
    repo?: string;
    branch?: string;
    worktreePath?: string;
    remote?: string;
    remoteBranch?: string;
    headSha?: string;
    runId?: number;
    runIds?: number[];
    status?: string;
    conclusion?: string;
    failedJobs?: string[];
    watch?: GhRunWatchViewDetails;
    checkouts?: GhPrCheckoutSummary[];
}
export interface GhPrCheckoutSummary {
    prNumber?: number;
    url?: string;
    branch: string;
    worktreePath: string;
    remote: string;
    remoteBranch: string;
    reused: boolean;
}
export interface GhRunWatchJobDetails {
    id: number;
    name: string;
    status?: string;
    conclusion?: string;
    durationSeconds?: number;
    url?: string;
}
export interface GhRunWatchRunDetails {
    id: number;
    workflowName?: string;
    displayTitle?: string;
    status?: string;
    conclusion?: string;
    branch?: string;
    headSha?: string;
    url?: string;
    jobs: GhRunWatchJobDetails[];
}
export interface GhRunWatchFailedLogDetails {
    runId: number;
    workflowName?: string;
    jobName: string;
    conclusion?: string;
    tail?: string;
    available: boolean;
}
export interface GhRunWatchViewDetails {
    mode: "run" | "commit";
    state: "watching" | "completed";
    repo: string;
    branch?: string;
    headSha?: string;
    pollCount?: number;
    note?: string;
    run?: GhRunWatchRunDetails;
    runs?: GhRunWatchRunDetails[];
    failedLogs?: GhRunWatchFailedLogDetails[];
}
interface GhUser {
    login?: string;
    name?: string | null;
}
interface GhLabel {
    name?: string;
}
interface GhComment {
    author?: GhUser | null;
    body?: string;
    createdAt?: string;
    url?: string;
    isMinimized?: boolean;
    minimizedReason?: string | null;
}
interface GhRepoTopic {
    name?: string;
    topic?: {
        name?: string;
    };
}
interface GhRepoLanguage {
    name?: string;
}
interface GhRepoBranch {
    name?: string;
}
interface GhRepoViewData {
    nameWithOwner?: string;
    description?: string | null;
    url?: string;
    sshUrl?: string;
    defaultBranchRef?: GhRepoBranch | null;
    homepageUrl?: string | null;
    forkCount?: number;
    isArchived?: boolean;
    isFork?: boolean;
    primaryLanguage?: GhRepoLanguage | null;
    repositoryTopics?: GhRepoTopic[];
    stargazerCount?: number;
    updatedAt?: string;
    viewerPermission?: string | null;
    visibility?: string | null;
}
interface GhIssueViewData {
    author?: GhUser | null;
    body?: string | null;
    comments?: GhComment[];
    createdAt?: string;
    labels?: GhLabel[];
    number?: number;
    state?: string;
    stateReason?: string | null;
    title?: string;
    updatedAt?: string;
    url?: string;
}
interface GhPrFile {
    path?: string;
    additions?: number;
    deletions?: number;
    changeType?: string;
}
interface GhPrViewData extends GhIssueViewData {
    baseRefName?: string;
    files?: GhPrFile[];
    headRefName?: string;
    headRefOid?: string;
    headRepository?: GhRepoViewData | null;
    headRepositoryOwner?: GhUser | null;
    isCrossRepository?: boolean;
    isDraft?: boolean;
    maintainerCanModify?: boolean;
    mergeStateStatus?: string;
    reviewComments?: GhPrReviewComment[];
    reviews?: GhPrReview[];
    reviewDecision?: string;
}
interface GhPrReviewCommit {
    oid?: string | null;
}
interface GhPrReview {
    author?: GhUser | null;
    body?: string | null;
    commit?: GhPrReviewCommit | null;
    state?: string | null;
    submittedAt?: string | null;
}
interface GhPrReviewComment {
    author?: GhUser | null;
    body?: string | null;
    createdAt?: string;
    id: number;
    inReplyToId?: number;
    line?: number;
    originalLine?: number;
    path?: string;
    side?: string;
    url?: string;
}
/**
 * Resolve a search date bound to a GitHub-search-compatible literal. Returns
 * either a `YYYY-MM-DD` date (relative durations and date-only inputs) or a
 * full ISO 8601 datetime string (datetime inputs), so the caller can drop it
 * straight into a qualifier like `created:>=<value>`.
 */
export declare function parseSearchDateBound(raw: string, now?: Date): string;
/**
 * Build the GitHub-search qualifier (e.g. `created:>=2026-05-09`) for the
 * provided bounds, or `undefined` if neither bound is set.
 */
export declare function buildSearchDateQualifier(field: string, since: string | undefined, until: string | undefined, now?: Date): string | undefined;
/**
 * Parse a digit-only decimal positive integer or return undefined. Rejects
 * `1e2`, `0x10`, `12.0`, leading +/-, or any other shape `Number()` would
 * accept — those would otherwise key the cache against the wrong row.
 */
export declare function parsePositiveDecimalInt(value: string | undefined): number | undefined;
export declare function resolveDefaultRepoMemoized(cwd: string, signal?: AbortSignal): Promise<string>;
export declare class GithubTool implements AgentTool<typeof githubSchema, GhToolDetails> {
    private readonly session;
    readonly name = "github";
    readonly approval: (args: unknown) => ToolApprovalDecision;
    readonly summary = "Interact with GitHub issues, pull requests, and repositories";
    readonly loadMode = "discoverable";
    readonly label = "GitHub";
    readonly description: string;
    readonly parameters: import("arktype/internal/variants/object.ts").ObjectType<{
        op: "pr_checkout" | "pr_create" | "pr_push" | "repo_view" | "run_watch" | "search_code" | "search_commits" | "search_issues" | "search_prs" | "search_repos";
        repo?: string | undefined;
        branch?: string | undefined;
        pr?: string | string[] | undefined;
        force?: boolean | undefined;
        forceWithLease?: boolean | undefined;
        title?: string | undefined;
        body?: string | undefined;
        base?: string | undefined;
        head?: string | undefined;
        draft?: boolean | undefined;
        fill?: boolean | undefined;
        reviewer?: string[] | undefined;
        assignee?: string[] | undefined;
        label?: string[] | undefined;
        query?: string | undefined;
        since?: string | undefined;
        until?: string | undefined;
        dateField?: "created" | "updated" | undefined;
        limit?: number | undefined;
        run?: string | undefined;
        tail?: number | undefined;
    }, {}>;
    readonly strict = true;
    constructor(session: ToolSession);
    static createIf(session: ToolSession): GithubTool | null;
    execute(_toolCallId: string, params: GithubInput, signal?: AbortSignal, onUpdate?: AgentToolUpdateCallback<GhToolDetails>, _context?: AgentToolContext): Promise<AgentToolResult<GhToolDetails>>;
}
export interface IssueViewLookupOptions {
    cwd: string;
    repo?: string;
    /** Issue number or GitHub issue URL. */
    issue: string;
    includeComments?: boolean;
    signal?: AbortSignal;
    settings?: Settings;
    cacheAuthKey?: string | null;
}
export interface PrViewLookupOptions {
    cwd: string;
    repo: string;
    number: number;
    includeComments?: boolean;
    signal?: AbortSignal;
    settings?: Settings;
    cacheAuthKey?: string | null;
}
export interface ViewLookupResult<T> {
    rendered: string;
    sourceUrl: string | undefined;
    payload: T;
    status: CacheStatus;
    fetchedAt: number;
}
/**
 * Cache-aware issue/view fetcher. Used by both the `github` tool op and the
 * `issue://` protocol handler so a single shared row services both surfaces.
 */
export declare function getOrFetchIssue(options: IssueViewLookupOptions): Promise<ViewLookupResult<GhIssueViewData>>;
/**
 * Cache-aware PR view fetcher. Caller must supply a numeric PR number;
 * branch-name / current-branch lookups bypass the cache entirely upstream
 * (see `executePrView`).
 */
export declare function getOrFetchPr(options: PrViewLookupOptions): Promise<ViewLookupResult<GhPrViewData>>;
export interface PrDiffFile {
    /** Display path. Prefers the post-image (`b/<path>`) when present. */
    path: string;
    additions: number;
    deletions: number;
    changeType: "modified" | "added" | "deleted" | "renamed" | "binary";
    /** Pre-image path for renames/deletes; same as `path` otherwise. */
    oldPath?: string;
    /** Byte offset of the section's `diff --git` line in the unified diff. */
    startOffset: number;
    /** Byte offset of the next section (or end-of-text). */
    endOffset: number;
}
export interface PrDiffPayload {
    /** Full unified diff text as returned by `gh pr diff --color never`. */
    unified: string;
    files: PrDiffFile[];
}
export interface PrDiffLookupOptions {
    cwd: string;
    repo: string;
    number: number;
    signal?: AbortSignal;
    settings?: Settings;
    cacheAuthKey?: string | null;
}
/**
 * Split `gh pr diff` output on `^diff --git ` boundaries and parse per-file
 * metadata. The unified diff is preserved verbatim so callers can slice it by
 * byte offsets without re-running gh.
 */
export declare function parsePrUnifiedDiff(text: string): PrDiffPayload;
/**
 * Cache-aware PR diff fetcher. Stores the full unified diff plus a parsed
 * file index in a single `pr-diff` cache row so the listing, full-diff, and
 * per-file slice variants of `pr://<n>/diff` share one `gh pr diff`
 * invocation.
 */
export declare function getOrFetchPrDiff(options: PrDiffLookupOptions): Promise<ViewLookupResult<PrDiffPayload>>;
export {};
