import type { Json } from "./protocol.js";
/** A small JSON client for the git hosts the Hook reads over HTTP. Every call
 * has a deadline, never follows a redirect to another origin with the token,
 * and turns a host's refusal into one of a few reasons clients can act on. */
export type HostFailure = "auth" | "not-found" | "unreachable" | "failed";
export declare class HostApiError extends Error {
    reason: HostFailure;
    status: number;
    body: unknown;
    /** `body` is the host's own JSON for a refusal (gitboy's `details`, say). */
    constructor(reason: HostFailure, message: string, status?: number, body?: unknown);
}
/** The API root for a domain: `git config --global phren.<domain>.api` when
 * set (a self-hosted server on another port or path), else the host's
 * default. Only the user's global config counts: a repository's own config is
 * writable by whatever runs in the checkout, and must never be able to send
 * a stored token to another server. */
export declare function apiRoot(root: string, domain: string, fallback: string): Promise<string>;
/** Resolve the exact endpoint once, so Connect can check and use the same URL.
 * Only the hostname/port is exposed to clients, never API URL credentials. */
export declare function tokenDestination(root: string, host: {
    kind: string | null;
    domain: string | null;
}): Promise<{
    api: string | null;
    apiHost: string | null;
}>;
export interface HostRequest {
    token?: string;
    /** How the token is sent: GitLab's PRIVATE-TOKEN header or a bearer token. */
    scheme: "private-token" | "bearer";
    method?: "GET" | "POST" | "PUT";
    body?: Json;
    timeoutMs?: number;
}
export declare function hostJson<T = unknown>(url: string, request: HostRequest): Promise<{
    status: number;
    json: T;
    headers: Headers;
}>;
/** An https link, or nothing: hosts' links are shown and opened as-is. */
export declare function safeLink(value: unknown): string | undefined;
