import type { CreateLoopInput, Goal, GoalRun, Loop, LoopRun, LoopStatus, OpenAutomationsRuntimeBinding, RunReceipt, RunStatus, WriteRunReceiptInput } from "../types.js"; import { type DoctorReport } from "../lib/doctor.js"; import { type BuildHealthScanOptions, type LoopsHealthReport, type LoopsHealthScan } from "../lib/health.js"; import { type ApplyLoopsMigrationResult, type ControlPlanePlanOptions, type ExportLoopsMigrationOptions, type ImportLoopsMigrationOptions, type LoopsMigrationBundle, type LoopsMigrationPlan } from "../lib/migration.js"; import { tick } from "../lib/scheduler.js"; import { Store } from "../lib/store.js"; import { type LoopStore } from "../lib/store/index.js"; export { runGoal } from "../lib/goal/runner.js"; export { LOOPS_MIGRATION_SCHEMA, applyImportMigrationBundle, buildControlPlaneMigrationPlan, buildImportMigrationPlan, exportLoopsMigrationBundle, migrationHash, validateLoopsMigrationBundle, } from "../lib/migration.js"; export type { ApplyLoopsMigrationResult, ControlPlanePlanOptions, ExportLoopsMigrationOptions, ImportLoopsMigrationOptions, LoopsMigrationAction, LoopsMigrationBundle, LoopsMigrationPlan, LoopsMigrationPlanRow, LoopsMigrationPlanSummary, LoopsMigrationResource, } from "../lib/migration.js"; export interface LoopsClientOptions { /** * Inject an on-box sqlite {@link Store} (mainly for tests and in-process local * runtimes). When provided, both data and local-runtime operations run against * it. When omitted, the data store is resolved from the client-flip env via * {@link getStore} — the local sqlite store OR the hosted `/v1` API when * HASNA_LOOPS_API_URL and HASNA_LOOPS_API_KEY are set — so every data method * routes through the one Store abstraction. */ store?: Store; /** * Claim owner id for inline runs. Keep the `:` shape (see * INLINE_RUNNER_ID_PATTERN in lib/scheduler.ts; default `sdk:`) so a * starting daemon can see the owner process is still alive and will not * reap the run's process group out from under it. */ runnerId?: string; } export interface ListLoopsFilters { status?: LoopStatus; labels?: string[]; limit?: number; /** include archived loops alongside live ones */ includeArchived?: boolean; /** return only archived loops */ archivedOnly?: boolean; } export interface ListRunsFilters { status?: RunStatus; labels?: string[]; limit?: number; } export interface ListRunReceiptsFilters { loopId?: string; repo?: string; taskId?: string; knowledgeId?: string; status?: string; limit?: number; } export interface LoopMutationOptions { operationId: string; stepId: string; expectedRevision: string; approvedPlanDigest: string; manifestDigest: string; descriptorRef: string; descriptorDigest: string; dryRun?: boolean; } export declare class LoopsClient { /** * The resolved data store: an on-box {@link LocalStore} (sqlite) or the hosted * {@link ApiStore} (`/v1` + bearer key). EVERY data method routes through here, * so nothing silently touches the on-box island while connected to the hosted API. */ readonly store: LoopStore; private readonly ownStore; private readonly runnerId; constructor(opts?: LoopsClientOptions); /** * The raw on-box sqlite {@link Store} for local-runtime operations that cannot * route over HTTP — the scheduler (tick / inline run-now), migration * export/import, and local diagnostics (doctor/health). These act on THIS * machine's runtime and database, so they fail loudly instead of silently * hitting the on-box island when the client is flipped to the hosted API. */ private localRuntime; create(input: CreateLoopInput): Promise; list(filters?: ListLoopsFilters): Promise; get(idOrName: string): Promise; private mutateStatus; pause(idOrName: string, options?: LoopMutationOptions): Promise; resume(idOrName: string, options?: LoopMutationOptions): Promise; stop(idOrName: string, options?: LoopMutationOptions): Promise; setLabels(idOrName: string, labels: string[]): Promise; addLabels(idOrName: string, labels: string[]): Promise; removeLabels(idOrName: string, labels: string[]): Promise; archive(idOrName: string): Promise; unarchive(idOrName: string): Promise; delete(idOrName: string): Promise; runs(idOrName?: string, filters?: ListRunsFilters): Promise; writeReceipt(input: WriteRunReceiptInput): Promise; receipt(runId: string): Promise; receipts(filters?: ListRunReceiptsFilters): Promise; goal(idOrName: string): Promise<{ goal?: Goal; runs: GoalRun[]; }>; doctor(): DoctorReport; health(opts?: { includeArchived?: boolean; includeInactive?: boolean; limit?: number; }): LoopsHealthReport; healthScan(opts?: Omit & { doctor?: boolean; daemon?: boolean; }): LoopsHealthScan; tick(): Promise>>; runNow(idOrName: string): Promise; exportBundle(opts?: ExportLoopsMigrationOptions): LoopsMigrationBundle; planImport(bundle: LoopsMigrationBundle, opts?: ImportLoopsMigrationOptions): LoopsMigrationPlan; importBundle(bundle: LoopsMigrationBundle, opts?: ImportLoopsMigrationOptions): ApplyLoopsMigrationResult; planControlPlaneMigration(opts?: Omit & { operation?: ControlPlanePlanOptions["operation"]; }): Promise; close(): Promise; } export declare function loops(opts?: LoopsClientOptions): LoopsClient; export declare function openAutomationsRuntimeBinding(overrides?: Partial): OpenAutomationsRuntimeBinding;