import type { SpawnOptions } from "node:child_process";
import type { Server } from "node:http";

export const CLAUDE_RUNS_MAX_CONCURRENCY: number;
export type ClaudeRunsRequest = {
  input: string;
  instructions: string;
  schema: Record<string, unknown> | null;
  model: string;
  effort: string;
  sessionId: string;
  tools: ClaudeRunsRemoteTools | null;
  /** The run's private MCP config file, written by the service. */
  mcpConfigPath?: string;
};
/** The run's own remote MCP server and grant. */
export type ClaudeRunsRemoteTools = {
  names: string[];
  remote: { url: string; authorization: string };
};
export type ClaudeRunsResult = {
  output: string;
  runtime: { provider: string; model: string };
  usage: Record<string, number>;
};
export type ClaudeRunsServer = Server & { stopActiveRuns(): Promise<void> };
export type ClaudeRunsApiOptions = {
  token: string;
  /** The CLI and account root; defaults to /opt/data/private-opener. */
  root?: string;
  execute?:
    | ((request: ClaudeRunsRequest) => {
        promise: Promise<ClaudeRunsResult>;
        stop(): void;
      })
    | null;
  audit?: (entry: Record<string, unknown>) => void;
  maxConcurrency?: number;
  maxToolConcurrency?: number;
  checkAuthentication?: (
    configDir: string
  ) => Promise<"READY" | "SIGN_IN_REQUIRED" | "UNAVAILABLE">;
  accounts?: () => string[];
  startRun?: (
    request: ClaudeRunsRequest,
    options: { root: string; configDir: string }
  ) => { promise: Promise<ClaudeRunsResult>; stop(code?: string): void };
  now?: () => number;
};
/** Any claude-* model at low/medium/high effort, with optional remote tools. */
export function validateClaudeRunsRequest(body: unknown): ClaudeRunsRequest;
export function claudeInvocation(
  request: ClaudeRunsRequest,
  root: string,
  configDir?: string
): { command: string; args: string[]; options: SpawnOptions };
export function claudeAccountDirs(root: string): string[];
export function claudeUsageLimit(
  stdout: string,
  now?: number
): { retryAt: number } | null;
/** Why a CLI run failed, for the audit only: never its text. */
export function claudeFailureFacts(
  stdout: string,
  exitCode: number | null
): {
  exitCode: number | null;
  apiErrorStatus: number | null;
  terminalReason: string | null;
  subtype: string | null;
};
export function parseClaudeResult(
  stdout: string,
  request: ClaudeRunsRequest
): ClaudeRunsResult;
export function startClaudeRun(
  request: ClaudeRunsRequest,
  options: {
    root: string;
    configDir?: string;
    spawnImpl?: (...args: any[]) => any;
    timeoutMs?: number;
  }
): { promise: Promise<ClaudeRunsResult>; stop(code?: string): void };
export function createClaudeRunsApi(
  options: ClaudeRunsApiOptions
): ClaudeRunsServer;
export function startPublicClaudeRunsApi(options?: {
  env?: Record<string, string | undefined>;
  diagnostic?: (entry: Record<string, unknown>) => void;
  root?: string;
  createApi?: typeof createClaudeRunsApi;
  readToken?: (path: string) => string;
}): Promise<{ stop(): Promise<void> } | null>;

export function readClaudeAuthentication(options: {
  root: string;
  configDir?: string;
  execFileImpl?: any;
  timeoutMs?: number;
}): Promise<"READY" | "SIGN_IN_REQUIRED" | "UNAVAILABLE">;
