/**
 * Linear GraphQL API Client
 *
 * Pure fetch-based client for Linear issue operations via GraphQL.
 * Supports API key authentication, rate limit handling, cursor pagination,
 * and typed error responses.
 *
 * No external dependencies — uses only the standard fetch API.
 *
 * @see https://developers.linear.app/docs/graphql/working-with-the-graphql-api
 */
import type { LinearIssue, LinearTeam, LinearWorkflowState } from './linear-types.js';
/**
 * Rate limit information parsed from Linear response headers.
 */
export interface RateLimitInfo {
    /** Total requests allowed per hour */
    readonly limit: number;
    /** Requests remaining in the current window */
    readonly remaining: number;
    /** UTC epoch timestamp when the rate limit resets */
    readonly reset: number;
}
/**
 * GraphQL error as returned in the response `errors` array.
 */
export interface GraphQLError {
    readonly message: string;
    readonly locations?: readonly {
        readonly line: number;
        readonly column: number;
    }[];
    readonly path?: readonly (string | number)[];
    readonly extensions?: Record<string, unknown>;
}
/**
 * Configuration for creating a LinearApiClient.
 */
export interface LinearApiClientOptions {
    /** Linear API key for authentication */
    apiKey: string;
    /** Remaining requests threshold to trigger warnings (default: 100) */
    rateLimitWarningThreshold?: number;
}
/**
 * Input for creating a new Linear issue.
 */
export interface CreateIssueInput {
    /** Team ID to create the issue in (required) */
    teamId: string;
    /** Issue title (required) */
    title: string;
    /** Issue description (markdown) */
    description?: string;
    /** Priority level (0-4) */
    priority?: number;
    /** Workflow state ID */
    stateId?: string;
    /** Assignee user ID */
    assigneeId?: string;
    /** Label IDs to attach to the issue */
    labelIds?: readonly string[];
}
/**
 * Input for updating an existing Linear issue.
 */
export interface UpdateIssueInput {
    /** Updated title */
    title?: string;
    /** Updated description (markdown) */
    description?: string;
    /** Updated priority level (0-4) */
    priority?: number;
    /** Updated workflow state ID */
    stateId?: string;
    /** Updated assignee user ID */
    assigneeId?: string;
    /** Label IDs to set on the issue (replaces all existing labels) */
    labelIds?: readonly string[];
}
/**
 * Typed error for Linear API failures.
 * Wraps fetch errors with status code, GraphQL errors, and rate limit info.
 */
export declare class LinearApiError extends Error {
    /** HTTP status code from Linear's response */
    readonly status: number;
    /** GraphQL errors from the response (if any) */
    readonly graphqlErrors: readonly GraphQLError[];
    /** Rate limit information at the time of the error */
    readonly rateLimit: RateLimitInfo | null;
    constructor(message: string, status: number, graphqlErrors?: readonly GraphQLError[], rateLimit?: RateLimitInfo | null, cause?: Error);
    /**
     * Whether this error is due to rate limiting.
     */
    get isRateLimited(): boolean;
    /**
     * Whether this error is due to authentication failure.
     */
    get isAuthError(): boolean;
    /**
     * Returns a JSON-serializable representation of the error.
     */
    toJSON(): {
        name: string;
        message: string;
        status: number;
        graphqlErrors: readonly GraphQLError[];
        rateLimit: RateLimitInfo | null;
    };
}
/**
 * Type guard for LinearApiError.
 */
export declare function isLinearApiError(error: unknown): error is LinearApiError;
/**
 * Fetch-based Linear GraphQL API client for issue operations.
 *
 * Features:
 * - API key authentication (no Bearer prefix)
 * - Rate limit tracking with warnings when approaching limit
 * - Typed errors with GraphQL error details
 * - Relay-style cursor pagination
 * - Partial error handling (data + errors)
 *
 * @example
 * ```typescript
 * const client = new LinearApiClient({ apiKey: 'lin_api_...' });
 * const viewer = await client.getViewer();
 * const issues = await client.listIssuesSince('ENG', '2024-01-01T00:00:00Z');
 * ```
 */
export declare class LinearApiClient {
    private readonly apiKey;
    private readonly rateLimitWarningThreshold;
    /** Most recently observed rate limit info (updated after each request) */
    private lastRateLimit;
    constructor(options: LinearApiClientOptions);
    /**
     * Returns the most recently observed rate limit info, or null if no requests have been made.
     */
    getRateLimit(): RateLimitInfo | null;
    /**
     * Performs a GraphQL request to the Linear API.
     *
     * Handles authentication, rate limit parsing, and error responses.
     * For 200 responses that include both `data` and `errors`, it logs warnings
     * for partial errors but returns the data.
     *
     * @throws {LinearApiError} On network errors, non-200 responses, or responses with only errors.
     */
    graphql<T>(query: string, variables?: Record<string, unknown>): Promise<T>;
    /**
     * Fetch the authenticated user's identity.
     * Useful for testing the API connection.
     *
     * @returns Viewer info with id, name, and email.
     */
    getViewer(): Promise<{
        id: string;
        name: string;
        email: string;
    }>;
    /**
     * List all teams accessible to the authenticated user.
     *
     * @returns Array of teams with id, key, and name.
     */
    getTeams(): Promise<LinearTeam[]>;
    /**
     * Fetch all workflow states for a specific team.
     * Needed for mapping between Linear state types and Stoneforge statuses.
     *
     * @param teamId - UUID of the team.
     * @returns Array of workflow states.
     */
    getTeamWorkflowStates(teamId: string): Promise<LinearWorkflowState[]>;
    /**
     * Fetch all labels (issue labels) in the workspace.
     * Labels in Linear are workspace-scoped and can be filtered by team.
     *
     * @returns Array of all labels with id and name.
     */
    getLabels(): Promise<{
        id: string;
        name: string;
    }[]>;
    /**
     * Create a new label in the workspace, optionally associated with a team.
     *
     * @param name - Label name (e.g., "blocked")
     * @param teamId - Optional team ID to associate the label with
     * @returns The created label with id and name.
     */
    createLabel(name: string, teamId?: string): Promise<{
        id: string;
        name: string;
    }>;
    /**
     * Fetch a single issue by UUID or identifier (e.g., "ENG-123").
     *
     * @param issueId - UUID or human-readable identifier.
     * @returns The issue, or null if not found.
     */
    getIssue(issueId: string): Promise<LinearIssue | null>;
    /**
     * List issues for a team updated since a given timestamp.
     * Automatically paginates through all results using cursor pagination.
     *
     * @param teamKey - Team key (e.g., "ENG").
     * @param since - ISO 8601 timestamp. Only issues updated at or after this time are returned.
     * @returns Array of all matching issues.
     */
    listIssuesSince(teamKey: string, since: string): Promise<LinearIssue[]>;
    /**
     * Create a new issue in Linear.
     *
     * @param input - Issue creation input (teamId and title required).
     * @returns The created issue.
     */
    createIssue(input: CreateIssueInput): Promise<LinearIssue>;
    /**
     * Update an existing issue in Linear.
     *
     * @param issueId - UUID of the issue to update.
     * @param input - Fields to update.
     * @returns The updated issue.
     */
    updateIssue(issueId: string, input: UpdateIssueInput): Promise<LinearIssue>;
    /**
     * Logs a warning when rate limit is approaching exhaustion.
     */
    private checkRateLimitWarning;
}
/**
 * Parses rate limit information from Linear response headers.
 *
 * Linear uses these headers:
 * - X-RateLimit-Requests-Limit
 * - X-RateLimit-Requests-Remaining
 * - X-RateLimit-Requests-Reset (epoch seconds)
 *
 * Also checks standard headers as fallback:
 * - X-RateLimit-Limit
 * - X-RateLimit-Remaining
 * - X-RateLimit-Reset
 *
 * @returns Parsed rate limit info, or null if headers are not present.
 */
declare function parseRateLimitHeaders(headers: Headers): RateLimitInfo | null;
export { parseRateLimitHeaders };
//# sourceMappingURL=linear-api.d.ts.map