UNPKG

@capgo/cli

Version:
95 lines (94 loc) 4.01 kB
import type { BuildOutputRecord } from '../../output-record.js'; import type { Platform } from './contract.js'; export type BuildJobStatus = 'running' | 'completed' | 'failed' | 'cancelled' | 'unknown'; export interface BuildJobResult { jobId: string; status: BuildJobStatus; platform: Platform; appId: string; /** Absolute path to the local log file the user can tail. NEVER read by the agent directly. */ logsPath: string; outputUrl?: string; qrCodeAscii?: string; error?: string; /** True when start found an in-flight build for this target and returned it instead of starting a second. */ alreadyRunning?: boolean; } /** A handle to the spawned build process (injectable so tests never spawn anything). */ export interface BuildChild { pid: number; kill: (signal?: NodeJS.Signals) => void; /** Resolves with the exit code (or null on signal) when the process exits. */ exited: Promise<number | null>; } export interface BuildJobDeps { /** Spawn the build command, streaming stdout+stderr to `logPath`. Returns a handle. */ spawnBuild: (args: { appId: string; platform: Platform; recordPath: string; logPath: string; }) => BuildChild; buildRecordPath: (appId: string, platform: Platform) => string; /** Read the build record; resolves null when absent, THROWS on a present-but-corrupt record. */ readBuildRecord: (path: string) => Promise<BuildOutputRecord | null>; /** Remove a stale record before a fresh build so wait can't read last run's result as this one's. */ clearBuildRecord?: (path: string) => Promise<void>; /** Absolute path of the local log file for a target. */ logPath: (appId: string, platform: Platform) => string; /** Read `logPath` from byte offset `cursor`; returns new text, the next cursor, and whether at EOF. */ readLogSlice: (logPath: string, cursor: number) => Promise<{ text: string; nextCursor: number; eof: boolean; }>; /** Best-effort cloud cancel by the cloud jobId (POST /build/cancel/:jobId). Optional. */ cancelCloud?: (cloudJobId: string) => Promise<void>; /** Injected so the bounded wait loop is deterministic in tests. */ sleep: (ms: number) => Promise<void>; now: () => number; } /** Bounded wait window (seconds), kept under the ~60s client tool-call timeout. */ export declare const DEFAULT_WAIT_SECONDS = 40; export declare const MAX_WAIT_SECONDS = 59; /** Drop every tracked build job (test isolation only). */ export declare function clearAllBuildJobs(): void; /** * Start (or re-attach to) the cloud build for a target. Idempotent: if a build * for this (appId, platform) is already running this session, returns that job * instead of spawning a second. */ export declare function startBuild(deps: BuildJobDeps, args: { appId: string; platform: Platform; }): Promise<BuildJobResult>; /** * Bounded wait: block up to `timeoutSeconds` (default 40, max 59 — kept under the * client tool-call timeout), returning the instant the build reaches a terminal * state, otherwise 'running' for the caller to re-call. */ export declare function waitBuild(deps: BuildJobDeps, args: { jobId: string; timeoutSeconds?: number; }): Promise<BuildJobResult>; /** Non-blocking status peek. */ export declare function statusBuild(deps: BuildJobDeps, args: { jobId: string; }): Promise<BuildJobResult>; /** * Drain new log output since `cursor`. `eof` is true only once the build is * terminal AND the read reached the end of the file, so a streamer knows to stop. */ export declare function buildLogs(deps: BuildJobDeps, args: { jobId: string; cursor?: number; }): Promise<{ jobId: string; text: string; nextCursor: number; eof: boolean; }>; /** Cancel a running build: kill the local child + best-effort cloud cancel. */ export declare function cancelBuild(deps: BuildJobDeps, args: { jobId: string; }): Promise<BuildJobResult>;