/** * One-shot execution of an ALREADY-CLAIMED device Automation run. * * The daemon's poll loop claims and executes in one process. A native bridge * cannot: the Owletto Mac app has to keep its own poll loop for the platform * connectors only it can serve (HealthKit, Photos, Screen Time, computer use), * and a poll claims whatever the server hands back — including automation runs * pinned to that device. Splitting the claim across two pollers on one device * row is what this avoids: the bridge stays the single claimer and hands the * verbatim poll envelope here, so `executeAutomationRun` remains the single * implementation of prompt building, MCP wiring, subprocess supervision, exit * reporting and the finalize/resume loop. * * Ownership contract, which the caller depends on: * - returns normally → this call owns the run's outcome. It either delivered * an exit report to `/complete-automation`, or deliberately left the run * claimed for the server's heartbeat sweep (`dispatchAutomationResumeLoop` * does this when the report is undeliverable). The caller must NOT report. * - throws → nothing was reported and the run is untouched on the server. The * caller still owns it and must report the failure itself, or the run sits * `running` until the sweeper reclaims it. */ import type { AgentKind } from '@lobu/core/contracts/worker/device-automation'; export interface ExecuteClaimedRunOptions { /** Gateway base URL, e.g. `https://app.lobu.ai`. */ apiUrl: string; /** * The worker id that CLAIMED this run. `/complete-automation` authorizes on * `runs.claimed_by` (`authorizeRunForWorker`), so a worker id that did not * claim it is refused with a 403 — which the arm classifies as non-retriable * and reports as an undelivered exit report, NOT as a run failure. The run * then sits `running` until the heartbeat sweep reclaims it, and this call * still returns without an error. So a wrong value here is lost silently: * pass the claiming poller's own id, never a fresh one. */ workerId: string; /** Bearer the claiming poller authenticated with. */ authToken: string; /** Verbatim `/api/workers/poll` response body for the claimed run. */ job: unknown; timeoutMs?: number; heartbeatIntervalMs?: number; /** * Agent to use when the Automation names no `agent_kind`. A native bridge * passes the machine's own default here (the Mac app's menubar pick). */ defaultAgentKind?: AgentKind; /** Explicit per-agent binary paths (else PATH lookup). Test injection seam. */ binaryOverrides?: Partial>; debug?: boolean; } /** * A refusal raised BEFORE any server contact, so the caller knows its run is * still unreported. Carries `exitCode` so the CLI surfaces it as a non-zero * exit — the signal a native bridge keys its own fallback report off. */ export declare class UnexecutableRunError extends Error { readonly exitCode = 1; constructor(message: string); } /** * Execute one already-claimed automation run and report its outcome. * * Deliberately does NOT require the durable `owl_pat_` token `startDaemonCommand` * insists on. That check exists because a daemon runs for weeks off one * snapshotted bearer, so a 24h OAuth session token would leave it polling 401 * forever. This call lives and dies inside a single run (600s by default) using * the bearer its caller just polled with successfully, so the same rule would * only reject working credentials. */ export declare function executeClaimedAutomationRun(opts: ExecuteClaimedRunOptions): Promise<{ itemsCollected: number; error?: string; }>; //# sourceMappingURL=execute-run.d.ts.map