@agentskit/harness 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -3
- package/README.md +8 -0
- package/capabilities/public-surface.json +465 -48
- package/compatibility/report.json +3 -3
- package/compatibility/report.md +1 -1
- package/dist/cli.js +2981 -71
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +1494 -4
- package/dist/index.js +2876 -137
- package/dist/index.js.map +1 -1
- package/docs/ADR-0027-keep-pushing-loop.md +41 -0
- package/docs/LOOP.md +195 -0
- package/docs/MODULE-BOUNDARIES.md +29 -1
- package/docs/PRD-0.4.0.md +639 -0
- package/loop.config.example.yaml +121 -0
- package/package.json +38 -7
- package/release/manifest.json +29 -7
- package/release/notes.md +18 -3
- package/release/qualification.json +4 -4
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
1
3
|
declare const STATES: readonly ["CLARIFYING", "PLANNED", "IMPLEMENTING", "VERIFYING", "AWAITING_HUMAN_APPROVAL", "AWAITING_AUTHORIZATION", "COMPLETE", "BLOCKED", "STALE", "CANCELLED", "SUPERSEDED"];
|
|
2
4
|
declare const LEGAL_TRANSITIONS: {
|
|
3
5
|
readonly CLARIFYING: readonly ["PLANNED", "BLOCKED", "CANCELLED"];
|
|
@@ -462,7 +464,7 @@ interface ContractOutcome {
|
|
|
462
464
|
readonly statement: string;
|
|
463
465
|
readonly checks: readonly string[];
|
|
464
466
|
}
|
|
465
|
-
interface TaskContract {
|
|
467
|
+
interface TaskContract$1 {
|
|
466
468
|
readonly intent: string;
|
|
467
469
|
readonly scope: ContractScope;
|
|
468
470
|
readonly ambiguities: readonly string[];
|
|
@@ -502,7 +504,7 @@ interface VerificationConfig {
|
|
|
502
504
|
readonly profile: string;
|
|
503
505
|
readonly autonomy: AutonomyMode;
|
|
504
506
|
readonly runtime: RuntimeConfig;
|
|
505
|
-
readonly contract: TaskContract;
|
|
507
|
+
readonly contract: TaskContract$1;
|
|
506
508
|
readonly surfaces: Readonly<Record<SurfaceName, SurfaceRequirement>>;
|
|
507
509
|
readonly checks: readonly VerificationCheck[];
|
|
508
510
|
readonly tracking: TrackingConfig;
|
|
@@ -2079,8 +2081,20 @@ interface OrcaDispatchInput {
|
|
|
2079
2081
|
readonly worktree: string;
|
|
2080
2082
|
readonly branch: string;
|
|
2081
2083
|
readonly baseBranch: string;
|
|
2082
|
-
|
|
2084
|
+
/** Prompt file path (`--prompt-file`) — mutually exclusive with `prompt`. */
|
|
2085
|
+
readonly goalFile?: string;
|
|
2086
|
+
/** Inline prompt text (`--prompt`) — mutually exclusive with `goalFile`. */
|
|
2087
|
+
readonly prompt?: string;
|
|
2083
2088
|
readonly agent?: string;
|
|
2089
|
+
/** `worktree-only`: create the checkout without launching an agent; the caller opens its own terminal (`orca terminal create --command …`). */
|
|
2090
|
+
readonly launch?: 'agent' | 'worktree-only';
|
|
2091
|
+
/** Linear identifier or URL recorded on the worktree (`--linear-issue`). */
|
|
2092
|
+
readonly linearIssue?: string;
|
|
2093
|
+
/** Free-text Orca comment shown on the worktree card (`--comment`). */
|
|
2094
|
+
readonly comment?: string;
|
|
2095
|
+
/** Detach the new worktree from the caller's lineage (`--no-parent`). */
|
|
2096
|
+
readonly noParent?: boolean;
|
|
2097
|
+
readonly orcaBin?: string;
|
|
2084
2098
|
}
|
|
2085
2099
|
interface OrcaDispatchPlan {
|
|
2086
2100
|
readonly argv: readonly string[];
|
|
@@ -2181,4 +2195,1480 @@ declare const verifyEvidenceBundle: (path: string, { trustedKeys }?: {
|
|
|
2181
2195
|
}) => EvidenceBundleVerification;
|
|
2182
2196
|
declare const readEvidenceTrustStore: (path: string) => readonly TrustedEvidenceKey[];
|
|
2183
2197
|
|
|
2184
|
-
|
|
2198
|
+
interface CommandResult {
|
|
2199
|
+
readonly code: number | null;
|
|
2200
|
+
readonly stdout: string;
|
|
2201
|
+
readonly stderr: string;
|
|
2202
|
+
readonly timedOut: boolean;
|
|
2203
|
+
readonly durationMs: number;
|
|
2204
|
+
}
|
|
2205
|
+
interface CommandRunOptions {
|
|
2206
|
+
readonly timeoutMs?: number;
|
|
2207
|
+
readonly cwd?: string;
|
|
2208
|
+
readonly env?: NodeJS.ProcessEnv;
|
|
2209
|
+
}
|
|
2210
|
+
/** Shell-free command execution seam. Adapters receive it; composition supplies the real one; tests supply fakes. */
|
|
2211
|
+
interface CommandRunner {
|
|
2212
|
+
run(argv: readonly string[], options?: CommandRunOptions): Promise<CommandResult>;
|
|
2213
|
+
}
|
|
2214
|
+
/** Resolve an executable on PATH without spawning a shell. Honours PATHEXT on Windows. */
|
|
2215
|
+
declare const findExecutable: (name: string, env?: NodeJS.ProcessEnv, platform?: NodeJS.Platform) => string | null;
|
|
2216
|
+
/** Parse the `{ ok, result }` envelope every `orca … --json` command prints. Returns null when the payload is not an envelope. */
|
|
2217
|
+
declare const parseJsonEnvelope: (stdout: string) => {
|
|
2218
|
+
readonly ok: boolean;
|
|
2219
|
+
readonly result: unknown;
|
|
2220
|
+
readonly error?: string;
|
|
2221
|
+
} | null;
|
|
2222
|
+
|
|
2223
|
+
interface OrcaCliOptions {
|
|
2224
|
+
readonly bin?: string;
|
|
2225
|
+
readonly timeoutMs?: number;
|
|
2226
|
+
readonly cwd?: string;
|
|
2227
|
+
}
|
|
2228
|
+
interface OrcaStatus {
|
|
2229
|
+
readonly appRunning: boolean;
|
|
2230
|
+
readonly runtimeReady: boolean;
|
|
2231
|
+
readonly runtimeState: string;
|
|
2232
|
+
readonly appVersion: string | null;
|
|
2233
|
+
readonly runtimeId: string | null;
|
|
2234
|
+
}
|
|
2235
|
+
interface OrcaWorktree {
|
|
2236
|
+
readonly id: string;
|
|
2237
|
+
readonly repoId: string;
|
|
2238
|
+
readonly repo: string;
|
|
2239
|
+
readonly path: string;
|
|
2240
|
+
readonly branch: string;
|
|
2241
|
+
readonly displayName: string;
|
|
2242
|
+
readonly workspaceStatus: string;
|
|
2243
|
+
readonly isArchived: boolean;
|
|
2244
|
+
readonly isMainWorktree: boolean;
|
|
2245
|
+
readonly liveTerminalCount: number;
|
|
2246
|
+
readonly lastActivityAt: number | null;
|
|
2247
|
+
readonly linkedLinearIssue: string | null;
|
|
2248
|
+
readonly comment: string;
|
|
2249
|
+
}
|
|
2250
|
+
type OrcaAgentHookState = 'installed' | 'not_installed' | 'unknown';
|
|
2251
|
+
declare const compareVersions: (left: string, right: string) => number;
|
|
2252
|
+
declare const parseOrcaVersion: (stdout: string) => string | null;
|
|
2253
|
+
declare const parseOrcaStatus: (result: unknown) => OrcaStatus;
|
|
2254
|
+
declare const parseOrcaWorktrees: (result: unknown) => readonly OrcaWorktree[];
|
|
2255
|
+
declare const parseOrcaAgentHooks: (result: unknown) => Readonly<Record<string, OrcaAgentHookState>>;
|
|
2256
|
+
/** Run one `orca … --json` command and return the unwrapped `result`, failing closed on any transport or envelope error. */
|
|
2257
|
+
declare const orcaJson: (runner: CommandRunner, args: readonly string[], options?: OrcaCliOptions) => Promise<unknown>;
|
|
2258
|
+
declare const orcaVersion: (runner: CommandRunner, options?: OrcaCliOptions) => Promise<string | null>;
|
|
2259
|
+
declare const orcaStatus: (runner: CommandRunner, options?: OrcaCliOptions) => Promise<OrcaStatus>;
|
|
2260
|
+
declare const orcaWorktrees: (runner: CommandRunner, options?: OrcaCliOptions) => Promise<readonly OrcaWorktree[]>;
|
|
2261
|
+
declare const orcaAgentHooks: (runner: CommandRunner, options?: OrcaCliOptions) => Promise<Readonly<Record<string, OrcaAgentHookState>>>;
|
|
2262
|
+
declare const orcaAccountList: (runner: CommandRunner, options?: OrcaCliOptions) => Promise<unknown>;
|
|
2263
|
+
interface OrcaCreatedWorktree {
|
|
2264
|
+
readonly id: string;
|
|
2265
|
+
readonly path: string;
|
|
2266
|
+
readonly branch: string;
|
|
2267
|
+
readonly agentTerminalHandle: string | null;
|
|
2268
|
+
readonly raw: unknown;
|
|
2269
|
+
}
|
|
2270
|
+
declare const parseOrcaWorktreeCreate: (result: unknown) => OrcaCreatedWorktree;
|
|
2271
|
+
/** Execute a `createOrcaDispatchPlan` argv (first element is the orca binary). */
|
|
2272
|
+
declare const orcaWorktreeCreate: (runner: CommandRunner, argv: readonly string[], options?: OrcaCliOptions) => Promise<OrcaCreatedWorktree>;
|
|
2273
|
+
declare const orcaWorktreeSetArgv: (input: {
|
|
2274
|
+
readonly worktree: string;
|
|
2275
|
+
readonly comment?: string;
|
|
2276
|
+
readonly workspaceStatus?: string;
|
|
2277
|
+
readonly linearIssue?: string | null;
|
|
2278
|
+
readonly displayName?: string;
|
|
2279
|
+
}, bin?: string) => readonly string[];
|
|
2280
|
+
declare const orcaWorktreeSet: (runner: CommandRunner, input: Parameters<typeof orcaWorktreeSetArgv>[0], options?: OrcaCliOptions) => Promise<unknown>;
|
|
2281
|
+
declare const orcaWorktreeRemove: (runner: CommandRunner, input: {
|
|
2282
|
+
readonly worktree: string;
|
|
2283
|
+
readonly force?: boolean;
|
|
2284
|
+
}, options?: OrcaCliOptions) => Promise<unknown>;
|
|
2285
|
+
interface OrcaTerminal {
|
|
2286
|
+
readonly handle: string;
|
|
2287
|
+
readonly title: string;
|
|
2288
|
+
readonly worktreeId: string | null;
|
|
2289
|
+
readonly status: string;
|
|
2290
|
+
readonly command: string | null;
|
|
2291
|
+
readonly branch: string | null;
|
|
2292
|
+
readonly preview: string;
|
|
2293
|
+
readonly lastOutputAt: number | null;
|
|
2294
|
+
readonly raw: Record<string, unknown>;
|
|
2295
|
+
}
|
|
2296
|
+
declare const parseOrcaTerminals: (result: unknown) => readonly OrcaTerminal[];
|
|
2297
|
+
declare const orcaTerminalList: (runner: CommandRunner, input?: {
|
|
2298
|
+
readonly worktree?: string;
|
|
2299
|
+
readonly limit?: number;
|
|
2300
|
+
}, options?: OrcaCliOptions) => Promise<readonly OrcaTerminal[]>;
|
|
2301
|
+
declare const orcaTerminalCreate: (runner: CommandRunner, input: {
|
|
2302
|
+
readonly worktree: string;
|
|
2303
|
+
readonly command: string;
|
|
2304
|
+
readonly title?: string;
|
|
2305
|
+
}, options?: OrcaCliOptions) => Promise<{
|
|
2306
|
+
readonly handle: string;
|
|
2307
|
+
readonly raw: unknown;
|
|
2308
|
+
}>;
|
|
2309
|
+
interface OrcaSendReceipt {
|
|
2310
|
+
readonly accepted: boolean;
|
|
2311
|
+
readonly requestId: string | null;
|
|
2312
|
+
readonly stages: readonly string[];
|
|
2313
|
+
readonly warnings: readonly string[];
|
|
2314
|
+
}
|
|
2315
|
+
declare const parseOrcaSendReceipt: (result: unknown) => OrcaSendReceipt;
|
|
2316
|
+
declare const orcaTerminalSend: (runner: CommandRunner, input: {
|
|
2317
|
+
readonly terminal: string;
|
|
2318
|
+
readonly text: string;
|
|
2319
|
+
readonly enter?: boolean;
|
|
2320
|
+
readonly waitSubmitSeconds?: number;
|
|
2321
|
+
}, options?: OrcaCliOptions) => Promise<OrcaSendReceipt>;
|
|
2322
|
+
declare const orcaTerminalWait: (runner: CommandRunner, input: {
|
|
2323
|
+
readonly terminal: string;
|
|
2324
|
+
readonly for: "exit" | "tui-idle";
|
|
2325
|
+
readonly timeoutMs: number;
|
|
2326
|
+
}, options?: OrcaCliOptions) => Promise<{
|
|
2327
|
+
readonly satisfied: boolean;
|
|
2328
|
+
readonly raw: unknown;
|
|
2329
|
+
}>;
|
|
2330
|
+
declare const orcaTerminalScreen: (runner: CommandRunner, input: {
|
|
2331
|
+
readonly terminal: string;
|
|
2332
|
+
}, options?: OrcaCliOptions) => Promise<string>;
|
|
2333
|
+
interface OrcaAutomation {
|
|
2334
|
+
readonly id: string;
|
|
2335
|
+
readonly name: string;
|
|
2336
|
+
readonly enabled: boolean;
|
|
2337
|
+
readonly trigger: string;
|
|
2338
|
+
readonly provider: string | null;
|
|
2339
|
+
readonly raw: Record<string, unknown>;
|
|
2340
|
+
}
|
|
2341
|
+
declare const parseOrcaAutomations: (result: unknown) => readonly OrcaAutomation[];
|
|
2342
|
+
declare const orcaAutomationsList: (runner: CommandRunner, options?: OrcaCliOptions) => Promise<readonly OrcaAutomation[]>;
|
|
2343
|
+
interface OrcaAutomationSpec {
|
|
2344
|
+
readonly name: string;
|
|
2345
|
+
readonly trigger: string;
|
|
2346
|
+
readonly prompt: string;
|
|
2347
|
+
readonly provider: string;
|
|
2348
|
+
readonly precheck?: string;
|
|
2349
|
+
readonly precheckTimeoutSec?: number;
|
|
2350
|
+
readonly workspace?: string;
|
|
2351
|
+
readonly repo?: string;
|
|
2352
|
+
readonly host?: string;
|
|
2353
|
+
readonly reuseSession?: boolean;
|
|
2354
|
+
readonly enabled?: boolean;
|
|
2355
|
+
}
|
|
2356
|
+
declare const orcaAutomationCreateArgv: (spec: OrcaAutomationSpec, bin?: string) => readonly string[];
|
|
2357
|
+
declare const orcaAutomationEditArgv: (id: string, spec: OrcaAutomationSpec, bin?: string) => readonly string[];
|
|
2358
|
+
declare const orcaAutomationRemove: (runner: CommandRunner, id: string, options?: OrcaCliOptions) => Promise<unknown>;
|
|
2359
|
+
declare const orcaAutomationRun: (runner: CommandRunner, id: string, options?: OrcaCliOptions) => Promise<unknown>;
|
|
2360
|
+
declare const orcaAutomationRuns: (runner: CommandRunner, id: string, options?: OrcaCliOptions) => Promise<unknown>;
|
|
2361
|
+
|
|
2362
|
+
type UsageWindowKind = 'session' | 'weekly' | 'monthly' | string;
|
|
2363
|
+
interface UsageWindow {
|
|
2364
|
+
readonly kind: UsageWindowKind;
|
|
2365
|
+
readonly usedPercent: number;
|
|
2366
|
+
readonly windowMinutes: number | null;
|
|
2367
|
+
readonly resetsAt: string | null;
|
|
2368
|
+
}
|
|
2369
|
+
interface ProviderUsage {
|
|
2370
|
+
/** `ok` when Orca reported live usage, `unavailable` when Orca could not, `unknown` when Orca did not mention the provider. */
|
|
2371
|
+
readonly status: 'ok' | 'unavailable' | 'unknown';
|
|
2372
|
+
readonly error: string | null;
|
|
2373
|
+
readonly windows: readonly UsageWindow[];
|
|
2374
|
+
readonly exhausted: boolean;
|
|
2375
|
+
/** Earliest reset among exhausted windows, ISO-8601. */
|
|
2376
|
+
readonly resetsAt: string | null;
|
|
2377
|
+
readonly hasAuth: boolean | null;
|
|
2378
|
+
}
|
|
2379
|
+
type ProviderAuthStatus = 'ok' | 'unknown' | 'missing';
|
|
2380
|
+
interface ProviderAvailability {
|
|
2381
|
+
readonly id: string;
|
|
2382
|
+
readonly binary: string | null;
|
|
2383
|
+
readonly hookState: 'installed' | 'not_installed' | 'unknown';
|
|
2384
|
+
readonly auth: ProviderAuthStatus;
|
|
2385
|
+
readonly usage: ProviderUsage;
|
|
2386
|
+
readonly probe: 'passed' | 'failed' | 'skipped';
|
|
2387
|
+
readonly coolingDownUntil: string | null;
|
|
2388
|
+
readonly available: boolean;
|
|
2389
|
+
readonly reasons: readonly string[];
|
|
2390
|
+
}
|
|
2391
|
+
interface ProviderSpec {
|
|
2392
|
+
readonly id: string;
|
|
2393
|
+
readonly bin: string;
|
|
2394
|
+
readonly auth: 'subscription' | 'api-key' | 'none';
|
|
2395
|
+
readonly envKeys: readonly string[];
|
|
2396
|
+
readonly orcaUsageKey: string;
|
|
2397
|
+
readonly probe?: readonly string[];
|
|
2398
|
+
}
|
|
2399
|
+
interface DetectProvidersInput {
|
|
2400
|
+
readonly providers: readonly ProviderSpec[];
|
|
2401
|
+
readonly accountList: unknown;
|
|
2402
|
+
readonly agentHooks: Readonly<Record<string, 'installed' | 'not_installed' | 'unknown'>>;
|
|
2403
|
+
readonly env?: NodeJS.ProcessEnv;
|
|
2404
|
+
readonly platform?: NodeJS.Platform;
|
|
2405
|
+
readonly exhaustedPercent?: number;
|
|
2406
|
+
readonly cooldowns?: Readonly<Record<string, string>>;
|
|
2407
|
+
readonly now?: () => Date;
|
|
2408
|
+
readonly runner?: CommandRunner;
|
|
2409
|
+
readonly probeTimeoutMs?: number;
|
|
2410
|
+
}
|
|
2411
|
+
declare const parseUsageWindows: (entry: unknown) => readonly UsageWindow[];
|
|
2412
|
+
/** Read one provider's usage out of `orca account list --json` → `result`. */
|
|
2413
|
+
declare const parseProviderUsage: (accountList: unknown, usageKey: string, exhaustedPercent?: number) => ProviderUsage;
|
|
2414
|
+
declare const authStatusFor: (spec: ProviderSpec, usage: ProviderUsage, env: NodeJS.ProcessEnv) => ProviderAuthStatus;
|
|
2415
|
+
/** Detect which coding-agent CLIs can take work right now. Pure over its inputs except the optional probe. */
|
|
2416
|
+
declare const detectProviders: (input: DetectProvidersInput) => Promise<readonly ProviderAvailability[]>;
|
|
2417
|
+
/** Exponential cooldown: initial × 2^attempts, capped. Returns the ISO instant the provider may be retried. */
|
|
2418
|
+
declare const cooldownUntil: (attempt: number, initialMin: number, maxMin: number, from: Date, resetsAt?: string | null) => string;
|
|
2419
|
+
|
|
2420
|
+
interface LoopIssue {
|
|
2421
|
+
readonly id: string;
|
|
2422
|
+
readonly identifier: string;
|
|
2423
|
+
readonly title: string;
|
|
2424
|
+
readonly url: string;
|
|
2425
|
+
readonly state: string;
|
|
2426
|
+
readonly stateType: string;
|
|
2427
|
+
readonly assignee: string | null;
|
|
2428
|
+
readonly assigneeId: string | null;
|
|
2429
|
+
readonly labels: readonly string[];
|
|
2430
|
+
readonly priority: number;
|
|
2431
|
+
readonly priorityLabel: string;
|
|
2432
|
+
readonly project: string | null;
|
|
2433
|
+
readonly branchName: string | null;
|
|
2434
|
+
readonly createdAt: string;
|
|
2435
|
+
readonly updatedAt: string;
|
|
2436
|
+
}
|
|
2437
|
+
interface LinearQueueFilter {
|
|
2438
|
+
readonly states: readonly string[];
|
|
2439
|
+
readonly excludeLabels: readonly string[];
|
|
2440
|
+
readonly requireLabels: readonly string[];
|
|
2441
|
+
readonly projects: readonly string[];
|
|
2442
|
+
readonly order: readonly ('priority' | 'updatedAt' | 'createdAt')[];
|
|
2443
|
+
readonly maxQueue: number;
|
|
2444
|
+
}
|
|
2445
|
+
interface LinearListInput {
|
|
2446
|
+
readonly bin?: string;
|
|
2447
|
+
readonly workspaceId: string;
|
|
2448
|
+
readonly teamKey: string;
|
|
2449
|
+
readonly assignee: string;
|
|
2450
|
+
readonly state: string;
|
|
2451
|
+
readonly limit: number;
|
|
2452
|
+
}
|
|
2453
|
+
declare const parseLinearIssues: (result: unknown) => readonly LoopIssue[];
|
|
2454
|
+
declare const buildListIssuesArgv: (input: LinearListInput) => readonly string[];
|
|
2455
|
+
declare const filterAndOrderQueue: (issues: readonly LoopIssue[], filter: LinearQueueFilter) => readonly LoopIssue[];
|
|
2456
|
+
interface FetchQueueInput extends Omit<LinearListInput, 'state' | 'limit'> {
|
|
2457
|
+
readonly filter: LinearQueueFilter;
|
|
2458
|
+
readonly pageLimit?: number;
|
|
2459
|
+
readonly orca?: OrcaCliOptions;
|
|
2460
|
+
}
|
|
2461
|
+
/** One `list-issues` call per configured state (Orca keeps only the last repeated `--state`), then filter/order locally. */
|
|
2462
|
+
declare const fetchLinearQueue: (runner: CommandRunner, input: FetchQueueInput) => Promise<readonly LoopIssue[]>;
|
|
2463
|
+
interface LinearIssueDetail extends LoopIssue {
|
|
2464
|
+
readonly description: string;
|
|
2465
|
+
readonly comments: readonly {
|
|
2466
|
+
readonly author: string | null;
|
|
2467
|
+
readonly body: string;
|
|
2468
|
+
readonly createdAt: string;
|
|
2469
|
+
}[];
|
|
2470
|
+
readonly raw: unknown;
|
|
2471
|
+
}
|
|
2472
|
+
declare const parseLinearIssueDetail: (result: unknown) => LinearIssueDetail;
|
|
2473
|
+
interface LinearWriteOptions {
|
|
2474
|
+
readonly bin?: string;
|
|
2475
|
+
readonly workspaceId: string;
|
|
2476
|
+
readonly orca?: OrcaCliOptions;
|
|
2477
|
+
}
|
|
2478
|
+
declare const fetchLinearIssue: (runner: CommandRunner, identifier: string, options: LinearWriteOptions) => Promise<LinearIssueDetail>;
|
|
2479
|
+
/** Deterministic UUID (v4 layout) derived from a stable key, for Orca's `--write-id` idempotency. */
|
|
2480
|
+
declare const writeIdFor: (key: string) => string;
|
|
2481
|
+
declare const linearStatusSetArgv: (input: {
|
|
2482
|
+
readonly issue: string;
|
|
2483
|
+
readonly to: string;
|
|
2484
|
+
readonly workspaceId: string;
|
|
2485
|
+
}, bin?: string) => readonly string[];
|
|
2486
|
+
declare const linearCommentAddArgv: (input: {
|
|
2487
|
+
readonly issue: string;
|
|
2488
|
+
readonly body: string;
|
|
2489
|
+
readonly workspaceId: string;
|
|
2490
|
+
readonly writeId?: string;
|
|
2491
|
+
}, bin?: string) => readonly string[];
|
|
2492
|
+
declare const linearLabelArgv: (input: {
|
|
2493
|
+
readonly issue: string;
|
|
2494
|
+
readonly labels: readonly string[];
|
|
2495
|
+
readonly workspaceId: string;
|
|
2496
|
+
readonly action: "add" | "remove";
|
|
2497
|
+
}, bin?: string) => readonly string[];
|
|
2498
|
+
declare const linearAttachArgv: (input: {
|
|
2499
|
+
readonly issue: string;
|
|
2500
|
+
readonly url: string;
|
|
2501
|
+
readonly title?: string;
|
|
2502
|
+
readonly workspaceId: string;
|
|
2503
|
+
readonly writeId?: string;
|
|
2504
|
+
}, bin?: string) => readonly string[];
|
|
2505
|
+
declare const linearStatusSet: (runner: CommandRunner, input: {
|
|
2506
|
+
readonly issue: string;
|
|
2507
|
+
readonly to: string;
|
|
2508
|
+
}, options: LinearWriteOptions) => Promise<unknown>;
|
|
2509
|
+
declare const linearCommentAdd: (runner: CommandRunner, input: {
|
|
2510
|
+
readonly issue: string;
|
|
2511
|
+
readonly body: string;
|
|
2512
|
+
readonly dedupeKey?: string;
|
|
2513
|
+
}, options: LinearWriteOptions) => Promise<unknown>;
|
|
2514
|
+
declare const linearLabelAdd: (runner: CommandRunner, input: {
|
|
2515
|
+
readonly issue: string;
|
|
2516
|
+
readonly labels: readonly string[];
|
|
2517
|
+
}, options: LinearWriteOptions) => Promise<unknown>;
|
|
2518
|
+
declare const linearLabelRemove: (runner: CommandRunner, input: {
|
|
2519
|
+
readonly issue: string;
|
|
2520
|
+
readonly labels: readonly string[];
|
|
2521
|
+
}, options: LinearWriteOptions) => Promise<unknown>;
|
|
2522
|
+
declare const linearAttach: (runner: CommandRunner, input: {
|
|
2523
|
+
readonly issue: string;
|
|
2524
|
+
readonly url: string;
|
|
2525
|
+
readonly title?: string;
|
|
2526
|
+
readonly dedupeKey?: string;
|
|
2527
|
+
}, options: LinearWriteOptions) => Promise<unknown>;
|
|
2528
|
+
/** Harness `TrackingAdapter` over Linear: each transition becomes one `status set`, deduped by the harness idempotency key. */
|
|
2529
|
+
declare const createLinearTrackingAdapter: (runner: CommandRunner, options: LinearWriteOptions & {
|
|
2530
|
+
readonly dryRun?: boolean;
|
|
2531
|
+
}) => TrackingAdapter;
|
|
2532
|
+
|
|
2533
|
+
declare const LOOP_CONFIG_FILE = "loop.config.yaml";
|
|
2534
|
+
/** Optional, gitignored per-machine overlay merged over the versioned config (e.g. `linear.person`, `machine.minFreeRamGb`). */
|
|
2535
|
+
declare const LOOP_LOCAL_CONFIG_FILE = "loop.config.local.yaml";
|
|
2536
|
+
declare const LOOP_CONFIG_SCHEMA_VERSION = 1;
|
|
2537
|
+
declare const LoopConfigSchema: z.ZodObject<{
|
|
2538
|
+
schemaVersion: z.ZodDefault<z.ZodLiteral<1>>;
|
|
2539
|
+
project: z.ZodObject<{
|
|
2540
|
+
name: z.ZodString;
|
|
2541
|
+
repo: z.ZodString;
|
|
2542
|
+
baseBranch: z.ZodDefault<z.ZodString>;
|
|
2543
|
+
root: z.ZodDefault<z.ZodString>;
|
|
2544
|
+
stateDir: z.ZodDefault<z.ZodString>;
|
|
2545
|
+
}, z.core.$strip>;
|
|
2546
|
+
orca: z.ZodPrefault<z.ZodObject<{
|
|
2547
|
+
bin: z.ZodDefault<z.ZodString>;
|
|
2548
|
+
repoSelector: z.ZodOptional<z.ZodString>;
|
|
2549
|
+
workspaceSelector: z.ZodOptional<z.ZodString>;
|
|
2550
|
+
host: z.ZodOptional<z.ZodString>;
|
|
2551
|
+
minVersion: z.ZodDefault<z.ZodString>;
|
|
2552
|
+
timeoutMs: z.ZodDefault<z.ZodNumber>;
|
|
2553
|
+
}, z.core.$strip>>;
|
|
2554
|
+
linear: z.ZodObject<{
|
|
2555
|
+
workspaceId: z.ZodString;
|
|
2556
|
+
teamKey: z.ZodString;
|
|
2557
|
+
person: z.ZodString;
|
|
2558
|
+
people: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
2559
|
+
states: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
2560
|
+
excludeLabels: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
2561
|
+
requireLabels: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
2562
|
+
projects: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
2563
|
+
order: z.ZodDefault<z.ZodArray<z.ZodEnum<{
|
|
2564
|
+
createdAt: "createdAt";
|
|
2565
|
+
priority: "priority";
|
|
2566
|
+
updatedAt: "updatedAt";
|
|
2567
|
+
}>>>;
|
|
2568
|
+
maxQueue: z.ZodDefault<z.ZodNumber>;
|
|
2569
|
+
inProgressState: z.ZodDefault<z.ZodString>;
|
|
2570
|
+
reviewState: z.ZodDefault<z.ZodString>;
|
|
2571
|
+
doneState: z.ZodDefault<z.ZodString>;
|
|
2572
|
+
blockedLabel: z.ZodDefault<z.ZodString>;
|
|
2573
|
+
needsInfoLabel: z.ZodDefault<z.ZodString>;
|
|
2574
|
+
}, z.core.$strip>;
|
|
2575
|
+
models: z.ZodObject<{
|
|
2576
|
+
orchestrator: z.ZodArray<z.ZodArray<z.ZodString>>;
|
|
2577
|
+
reviewer: z.ZodArray<z.ZodArray<z.ZodString>>;
|
|
2578
|
+
builder: z.ZodArray<z.ZodArray<z.ZodString>>;
|
|
2579
|
+
watcher: z.ZodArray<z.ZodArray<z.ZodString>>;
|
|
2580
|
+
cooldown: z.ZodPrefault<z.ZodObject<{
|
|
2581
|
+
initialMin: z.ZodDefault<z.ZodNumber>;
|
|
2582
|
+
maxMin: z.ZodDefault<z.ZodNumber>;
|
|
2583
|
+
probeBeforeReenable: z.ZodDefault<z.ZodBoolean>;
|
|
2584
|
+
exhaustedPercent: z.ZodDefault<z.ZodNumber>;
|
|
2585
|
+
}, z.core.$strip>>;
|
|
2586
|
+
providers: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
2587
|
+
bin: z.ZodString;
|
|
2588
|
+
auth: z.ZodDefault<z.ZodEnum<{
|
|
2589
|
+
none: "none";
|
|
2590
|
+
subscription: "subscription";
|
|
2591
|
+
"api-key": "api-key";
|
|
2592
|
+
}>>;
|
|
2593
|
+
envKeys: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
2594
|
+
orcaAgent: z.ZodOptional<z.ZodString>;
|
|
2595
|
+
orcaUsageKey: z.ZodOptional<z.ZodString>;
|
|
2596
|
+
tui: z.ZodString;
|
|
2597
|
+
probe: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
2598
|
+
headless: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
2599
|
+
reviewProvider: z.ZodOptional<z.ZodString>;
|
|
2600
|
+
}, z.core.$strip>>;
|
|
2601
|
+
}, z.core.$strip>;
|
|
2602
|
+
machine: z.ZodPrefault<z.ZodObject<{
|
|
2603
|
+
floor: z.ZodDefault<z.ZodNumber>;
|
|
2604
|
+
ceiling: z.ZodOptional<z.ZodNumber>;
|
|
2605
|
+
minFreeRamGb: z.ZodDefault<z.ZodNumber>;
|
|
2606
|
+
warningPercent: z.ZodDefault<z.ZodNumber>;
|
|
2607
|
+
criticalPercent: z.ZodDefault<z.ZodNumber>;
|
|
2608
|
+
agentRssMb: z.ZodDefault<z.ZodNumber>;
|
|
2609
|
+
wslCap: z.ZodDefault<z.ZodNumber>;
|
|
2610
|
+
}, z.core.$strip>>;
|
|
2611
|
+
delivery: z.ZodObject<{
|
|
2612
|
+
verifyCommand: z.ZodString;
|
|
2613
|
+
review: z.ZodPrefault<z.ZodObject<{
|
|
2614
|
+
cli: z.ZodDefault<z.ZodString>;
|
|
2615
|
+
mode: z.ZodDefault<z.ZodEnum<{
|
|
2616
|
+
isolated: "isolated";
|
|
2617
|
+
"trusted-local": "trusted-local";
|
|
2618
|
+
}>>;
|
|
2619
|
+
transport: z.ZodOptional<z.ZodEnum<{
|
|
2620
|
+
headless: "headless";
|
|
2621
|
+
acp: "acp";
|
|
2622
|
+
auto: "auto";
|
|
2623
|
+
}>>;
|
|
2624
|
+
profile: z.ZodDefault<z.ZodEnum<{
|
|
2625
|
+
fast: "fast";
|
|
2626
|
+
full: "full";
|
|
2627
|
+
}>>;
|
|
2628
|
+
votes: z.ZodDefault<z.ZodNumber>;
|
|
2629
|
+
concurrency: z.ZodDefault<z.ZodNumber>;
|
|
2630
|
+
minSeverity: z.ZodDefault<z.ZodEnum<{
|
|
2631
|
+
blocker: "blocker";
|
|
2632
|
+
nit: "nit";
|
|
2633
|
+
med: "med";
|
|
2634
|
+
high: "high";
|
|
2635
|
+
}>>;
|
|
2636
|
+
deadlineMs: z.ZodDefault<z.ZodNumber>;
|
|
2637
|
+
maxCalls: z.ZodDefault<z.ZodNumber>;
|
|
2638
|
+
post: z.ZodDefault<z.ZodBoolean>;
|
|
2639
|
+
}, z.core.$strip>>;
|
|
2640
|
+
merge: z.ZodPrefault<z.ZodObject<{
|
|
2641
|
+
auto: z.ZodDefault<z.ZodBoolean>;
|
|
2642
|
+
method: z.ZodDefault<z.ZodEnum<{
|
|
2643
|
+
squash: "squash";
|
|
2644
|
+
merge: "merge";
|
|
2645
|
+
rebase: "rebase";
|
|
2646
|
+
}>>;
|
|
2647
|
+
requireChecks: z.ZodDefault<z.ZodBoolean>;
|
|
2648
|
+
}, z.core.$strip>>;
|
|
2649
|
+
maxFixRounds: z.ZodDefault<z.ZodNumber>;
|
|
2650
|
+
workerIdleTimeoutMin: z.ZodDefault<z.ZodNumber>;
|
|
2651
|
+
selfEditPaths: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
2652
|
+
ignoreChecks: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
2653
|
+
requiredChecks: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
2654
|
+
cleanupWorktree: z.ZodDefault<z.ZodBoolean>;
|
|
2655
|
+
returnState: z.ZodDefault<z.ZodString>;
|
|
2656
|
+
}, z.core.$strip>;
|
|
2657
|
+
contract: z.ZodPrefault<z.ZodObject<{
|
|
2658
|
+
maxIssueChars: z.ZodDefault<z.ZodNumber>;
|
|
2659
|
+
timeoutMs: z.ZodDefault<z.ZodNumber>;
|
|
2660
|
+
maxContextReferences: z.ZodDefault<z.ZodNumber>;
|
|
2661
|
+
reuseHours: z.ZodDefault<z.ZodNumber>;
|
|
2662
|
+
}, z.core.$strip>>;
|
|
2663
|
+
schedule: z.ZodPrefault<z.ZodObject<{
|
|
2664
|
+
tick: z.ZodDefault<z.ZodString>;
|
|
2665
|
+
deliver: z.ZodDefault<z.ZodString>;
|
|
2666
|
+
precheckTimeoutSec: z.ZodDefault<z.ZodNumber>;
|
|
2667
|
+
harnessCommand: z.ZodDefault<z.ZodString>;
|
|
2668
|
+
provider: z.ZodOptional<z.ZodString>;
|
|
2669
|
+
namePrefix: z.ZodDefault<z.ZodString>;
|
|
2670
|
+
runner: z.ZodDefault<z.ZodEnum<{
|
|
2671
|
+
agent: "agent";
|
|
2672
|
+
precheck: "precheck";
|
|
2673
|
+
}>>;
|
|
2674
|
+
stageTimeoutSec: z.ZodDefault<z.ZodNumber>;
|
|
2675
|
+
timezone: z.ZodOptional<z.ZodString>;
|
|
2676
|
+
}, z.core.$strip>>;
|
|
2677
|
+
}, z.core.$strip>;
|
|
2678
|
+
type LoopConfigInput = z.input<typeof LoopConfigSchema>;
|
|
2679
|
+
type LoopConfig = z.output<typeof LoopConfigSchema>;
|
|
2680
|
+
type LoopProviderConfig = LoopConfig['models']['providers'][string];
|
|
2681
|
+
interface ModelReference {
|
|
2682
|
+
readonly provider: string;
|
|
2683
|
+
readonly model: string;
|
|
2684
|
+
}
|
|
2685
|
+
interface LoadedLoopConfig {
|
|
2686
|
+
readonly path: string;
|
|
2687
|
+
/** Present when a `loop.config.local.yaml` overlay was merged in. */
|
|
2688
|
+
readonly localPath?: string;
|
|
2689
|
+
readonly root: string;
|
|
2690
|
+
readonly stateDir: string;
|
|
2691
|
+
readonly config: LoopConfig;
|
|
2692
|
+
readonly configHash: string;
|
|
2693
|
+
}
|
|
2694
|
+
declare const parseModelRef: (value: string) => ModelReference;
|
|
2695
|
+
declare const tiersFor: (config: LoopConfig, role: ModelRole) => readonly (readonly ModelReference[])[];
|
|
2696
|
+
declare const validateLoopConfig: (value: unknown) => LoopConfig;
|
|
2697
|
+
/** Recursive merge: objects merge key by key, arrays and scalars from the overlay replace the base. */
|
|
2698
|
+
declare const mergeLoopConfig: (base: unknown, overlay: unknown) => unknown;
|
|
2699
|
+
declare const parseLoopConfigText: (text: string, localText?: string) => LoopConfig;
|
|
2700
|
+
declare const loadLoopConfig: (path?: string) => LoadedLoopConfig;
|
|
2701
|
+
/** Effective Orca agent id and usage key for a provider. */
|
|
2702
|
+
declare const providerIdentity: (config: LoopConfig, provider: string) => {
|
|
2703
|
+
readonly orcaAgent: string;
|
|
2704
|
+
readonly orcaUsageKey: string;
|
|
2705
|
+
readonly settings: LoopProviderConfig;
|
|
2706
|
+
};
|
|
2707
|
+
declare const renderTuiCommand: (settings: LoopProviderConfig, model: string) => string;
|
|
2708
|
+
/** Substitute `{model}` / `{prompt}` inside each headless argv element; the prompt stays one argv element, never shell-joined. */
|
|
2709
|
+
declare const renderHeadlessArgv: (settings: LoopProviderConfig, model: string, prompt: string) => readonly string[] | null;
|
|
2710
|
+
|
|
2711
|
+
/** Real, shell-free command runner for the loop composition layer. Output is capped; timeouts kill the process group. */
|
|
2712
|
+
declare const createProcessRunner: (defaults?: {
|
|
2713
|
+
readonly timeoutMs?: number;
|
|
2714
|
+
readonly maxOutputBytes?: number;
|
|
2715
|
+
readonly env?: NodeJS.ProcessEnv;
|
|
2716
|
+
}) => CommandRunner;
|
|
2717
|
+
|
|
2718
|
+
interface SlotAssessment {
|
|
2719
|
+
readonly sample: MachineSample;
|
|
2720
|
+
readonly platform: string;
|
|
2721
|
+
readonly wsl: boolean;
|
|
2722
|
+
readonly freeRamGb: number;
|
|
2723
|
+
readonly ceiling: number;
|
|
2724
|
+
readonly adaptive: number;
|
|
2725
|
+
readonly ramBound: number;
|
|
2726
|
+
readonly maxAgents: number;
|
|
2727
|
+
readonly running: number;
|
|
2728
|
+
readonly free: number;
|
|
2729
|
+
readonly reasons: readonly string[];
|
|
2730
|
+
}
|
|
2731
|
+
interface SlotInput {
|
|
2732
|
+
readonly machine: LoopConfig['machine'];
|
|
2733
|
+
readonly running: number;
|
|
2734
|
+
readonly sample?: MachineSample;
|
|
2735
|
+
readonly platform?: NodeJS.Platform;
|
|
2736
|
+
readonly osRelease?: string;
|
|
2737
|
+
readonly freeBytes?: number;
|
|
2738
|
+
readonly totalBytes?: number;
|
|
2739
|
+
}
|
|
2740
|
+
/** Parse `vm_stat` (macOS): reclaimable = free + inactive + speculative + purgeable pages. */
|
|
2741
|
+
declare const parseVmStat: (output: string) => number | null;
|
|
2742
|
+
/** Parse `/proc/meminfo` (Linux): MemAvailable already accounts for reclaimable cache. */
|
|
2743
|
+
declare const parseMemInfo: (text: string) => number | null;
|
|
2744
|
+
/** Bytes the OS can hand to a new process now — not just "free" pages, which macOS keeps near zero on purpose. */
|
|
2745
|
+
declare const availableMemoryBytes: (platform?: NodeJS.Platform) => number;
|
|
2746
|
+
declare const isWsl: (platform?: NodeJS.Platform, osRelease?: string, env?: NodeJS.ProcessEnv) => boolean;
|
|
2747
|
+
/** How many coding agents this machine can host right now: floor ≤ min(adaptive, RAM-bound, WSL cap) and never below the floor. */
|
|
2748
|
+
declare const assessSlots: (input: SlotInput) => SlotAssessment;
|
|
2749
|
+
|
|
2750
|
+
interface RoutingSkip {
|
|
2751
|
+
readonly tier: number;
|
|
2752
|
+
readonly ref: ModelReference;
|
|
2753
|
+
readonly reasons: readonly string[];
|
|
2754
|
+
}
|
|
2755
|
+
interface RoutingDecision {
|
|
2756
|
+
readonly role: ModelRole;
|
|
2757
|
+
readonly selected: (ModelReference & {
|
|
2758
|
+
readonly tier: number;
|
|
2759
|
+
readonly orcaAgent: string;
|
|
2760
|
+
readonly tui: string;
|
|
2761
|
+
}) | null;
|
|
2762
|
+
readonly skipped: readonly RoutingSkip[];
|
|
2763
|
+
}
|
|
2764
|
+
/** Walk the role's tiers in order; inside a tier keep declaration order; first available provider wins. */
|
|
2765
|
+
declare const selectModel: (config: LoopConfig, role: ModelRole, availability: readonly ProviderAvailability[]) => RoutingDecision;
|
|
2766
|
+
declare const routeAllRoles: (config: LoopConfig, availability: readonly ProviderAvailability[]) => Readonly<Record<ModelRole, RoutingDecision>>;
|
|
2767
|
+
interface RankedModel extends ModelReference {
|
|
2768
|
+
readonly tier: number;
|
|
2769
|
+
readonly orcaAgent: string;
|
|
2770
|
+
readonly tui: string;
|
|
2771
|
+
}
|
|
2772
|
+
/** Every available candidate for a role in preference order (tier, then declaration order). */
|
|
2773
|
+
declare const rankModels: (config: LoopConfig, role: ModelRole, availability: readonly ProviderAvailability[]) => readonly RankedModel[];
|
|
2774
|
+
|
|
2775
|
+
interface CooldownEntry {
|
|
2776
|
+
readonly attempts: number;
|
|
2777
|
+
readonly until: string;
|
|
2778
|
+
readonly reason: string;
|
|
2779
|
+
readonly markedAt: string;
|
|
2780
|
+
}
|
|
2781
|
+
type CooldownState = Readonly<Record<string, CooldownEntry>>;
|
|
2782
|
+
declare const cooldownPath: (stateDir: string) => string;
|
|
2783
|
+
declare const readCooldowns: (stateDir: string) => CooldownState;
|
|
2784
|
+
/** Active cooldowns as provider → ISO until, dropping expired entries. */
|
|
2785
|
+
declare const activeCooldowns: (state: CooldownState, now?: Date) => Readonly<Record<string, string>>;
|
|
2786
|
+
declare const markProviderExhausted: (stateDir: string, provider: string, options: {
|
|
2787
|
+
readonly initialMin: number;
|
|
2788
|
+
readonly maxMin: number;
|
|
2789
|
+
readonly reason: string;
|
|
2790
|
+
readonly resetsAt?: string | null;
|
|
2791
|
+
readonly now?: Date;
|
|
2792
|
+
}) => CooldownEntry;
|
|
2793
|
+
declare const clearProviderCooldown: (stateDir: string, provider: string) => void;
|
|
2794
|
+
|
|
2795
|
+
type DoctorCheckStatus = 'passed' | 'warning' | 'failed';
|
|
2796
|
+
interface DoctorCheck {
|
|
2797
|
+
readonly id: string;
|
|
2798
|
+
readonly status: DoctorCheckStatus;
|
|
2799
|
+
readonly detail: string;
|
|
2800
|
+
}
|
|
2801
|
+
interface LoopDoctorReport {
|
|
2802
|
+
readonly status: 'passed' | 'failed';
|
|
2803
|
+
readonly generatedAt: string;
|
|
2804
|
+
readonly config: {
|
|
2805
|
+
readonly path: string;
|
|
2806
|
+
readonly hash: string;
|
|
2807
|
+
readonly project: string;
|
|
2808
|
+
readonly repo: string;
|
|
2809
|
+
readonly person: string;
|
|
2810
|
+
readonly stateDir: string;
|
|
2811
|
+
};
|
|
2812
|
+
readonly orca: {
|
|
2813
|
+
readonly binary: string | null;
|
|
2814
|
+
readonly version: string | null;
|
|
2815
|
+
readonly minVersion: string;
|
|
2816
|
+
readonly status: OrcaStatus | null;
|
|
2817
|
+
readonly error: string | null;
|
|
2818
|
+
};
|
|
2819
|
+
readonly providers: readonly ProviderAvailability[];
|
|
2820
|
+
readonly routing: Readonly<Record<string, RoutingDecision>>;
|
|
2821
|
+
readonly machine: SlotAssessment;
|
|
2822
|
+
readonly workers: {
|
|
2823
|
+
readonly running: number;
|
|
2824
|
+
readonly worktrees: readonly Pick<OrcaWorktree, 'id' | 'branch' | 'workspaceStatus' | 'linkedLinearIssue' | 'liveTerminalCount'>[];
|
|
2825
|
+
readonly error: string | null;
|
|
2826
|
+
};
|
|
2827
|
+
readonly queue: {
|
|
2828
|
+
readonly count: number;
|
|
2829
|
+
readonly top: readonly Pick<LoopIssue, 'identifier' | 'title' | 'state' | 'priorityLabel' | 'branchName'>[];
|
|
2830
|
+
readonly error: string | null;
|
|
2831
|
+
};
|
|
2832
|
+
readonly checks: readonly DoctorCheck[];
|
|
2833
|
+
}
|
|
2834
|
+
interface LoopDoctorInput {
|
|
2835
|
+
readonly configPath?: string;
|
|
2836
|
+
readonly loaded?: LoadedLoopConfig;
|
|
2837
|
+
readonly runner: CommandRunner;
|
|
2838
|
+
readonly env?: NodeJS.ProcessEnv;
|
|
2839
|
+
readonly platform?: NodeJS.Platform;
|
|
2840
|
+
readonly now?: () => Date;
|
|
2841
|
+
readonly probe?: boolean;
|
|
2842
|
+
readonly queueTop?: number;
|
|
2843
|
+
}
|
|
2844
|
+
declare const providerSpecs: (config: LoopConfig) => readonly ProviderSpec[];
|
|
2845
|
+
/** Count worktrees the loop treats as live workers: not archived, not the main checkout, with a live terminal or a linked Linear issue. */
|
|
2846
|
+
declare const countRunningWorkers: (worktrees: readonly OrcaWorktree[]) => number;
|
|
2847
|
+
declare const runLoopDoctor: (input: LoopDoctorInput) => Promise<LoopDoctorReport>;
|
|
2848
|
+
|
|
2849
|
+
interface GitHubCliOptions {
|
|
2850
|
+
readonly bin?: string;
|
|
2851
|
+
readonly timeoutMs?: number;
|
|
2852
|
+
readonly cwd?: string;
|
|
2853
|
+
}
|
|
2854
|
+
type CheckOutcome = 'success' | 'failure' | 'pending' | 'skipped' | 'neutral' | 'unknown';
|
|
2855
|
+
interface PullRequestCheck {
|
|
2856
|
+
readonly name: string;
|
|
2857
|
+
readonly outcome: CheckOutcome;
|
|
2858
|
+
readonly kind: 'check-run' | 'status' | 'unknown';
|
|
2859
|
+
}
|
|
2860
|
+
interface PullRequestSnapshot {
|
|
2861
|
+
readonly number: number;
|
|
2862
|
+
readonly url: string;
|
|
2863
|
+
readonly title: string;
|
|
2864
|
+
readonly state: 'OPEN' | 'CLOSED' | 'MERGED' | 'UNKNOWN';
|
|
2865
|
+
readonly isDraft: boolean;
|
|
2866
|
+
readonly author: string | null;
|
|
2867
|
+
readonly authorIsBot: boolean;
|
|
2868
|
+
readonly headRef: string;
|
|
2869
|
+
readonly headSha: string;
|
|
2870
|
+
readonly baseRef: string;
|
|
2871
|
+
readonly mergeable: 'MERGEABLE' | 'CONFLICTING' | 'UNKNOWN';
|
|
2872
|
+
readonly mergeState: string;
|
|
2873
|
+
readonly reviewDecision: string;
|
|
2874
|
+
readonly labels: readonly string[];
|
|
2875
|
+
readonly files: readonly string[];
|
|
2876
|
+
readonly checks: readonly PullRequestCheck[];
|
|
2877
|
+
readonly updatedAt: string | null;
|
|
2878
|
+
}
|
|
2879
|
+
interface ChecksAssessment {
|
|
2880
|
+
readonly status: 'green' | 'pending' | 'red' | 'missing';
|
|
2881
|
+
readonly failing: readonly string[];
|
|
2882
|
+
readonly pending: readonly string[];
|
|
2883
|
+
readonly missingRequired: readonly string[];
|
|
2884
|
+
}
|
|
2885
|
+
declare const PR_FIELDS: readonly ["number", "url", "title", "state", "isDraft", "author", "headRefName", "headRefOid", "baseRefName", "mergeable", "mergeStateStatus", "reviewDecision", "labels", "files", "statusCheckRollup", "updatedAt"];
|
|
2886
|
+
declare const parsePullRequest: (value: unknown) => PullRequestSnapshot;
|
|
2887
|
+
/** Green only when every non-skipped check succeeded (or was neutral) and every required name was observed. A missing required check is never "green". */
|
|
2888
|
+
declare const assessChecks: (checks: readonly PullRequestCheck[], required?: readonly string[], ignore?: readonly string[]) => ChecksAssessment;
|
|
2889
|
+
/** Files matched by the configured self-edit globs (`**` = any depth, `*` = one path segment). */
|
|
2890
|
+
declare const touchesProtectedPaths: (files: readonly string[], patterns: readonly string[]) => readonly string[];
|
|
2891
|
+
declare const githubPullRequest: (runner: CommandRunner, input: {
|
|
2892
|
+
readonly repo: string;
|
|
2893
|
+
readonly number: number;
|
|
2894
|
+
}, options?: GitHubCliOptions) => Promise<PullRequestSnapshot>;
|
|
2895
|
+
/** Open PRs whose head branch equals `head` (exact match); empty when none. */
|
|
2896
|
+
declare const githubPullRequestsForBranch: (runner: CommandRunner, input: {
|
|
2897
|
+
readonly repo: string;
|
|
2898
|
+
readonly head: string;
|
|
2899
|
+
readonly state?: "open" | "merged" | "closed" | "all";
|
|
2900
|
+
}, options?: GitHubCliOptions) => Promise<readonly PullRequestSnapshot[]>;
|
|
2901
|
+
declare const githubOpenPullRequests: (runner: CommandRunner, input: {
|
|
2902
|
+
readonly repo: string;
|
|
2903
|
+
readonly limit?: number;
|
|
2904
|
+
}, options?: GitHubCliOptions) => Promise<readonly PullRequestSnapshot[]>;
|
|
2905
|
+
/** Squash/merge via REST with optimistic concurrency on the reviewed head SHA; GitHub refuses when the head moved. */
|
|
2906
|
+
declare const githubMergeArgv: (input: {
|
|
2907
|
+
readonly repo: string;
|
|
2908
|
+
readonly number: number;
|
|
2909
|
+
readonly headSha: string;
|
|
2910
|
+
readonly method: "squash" | "merge" | "rebase";
|
|
2911
|
+
readonly title?: string;
|
|
2912
|
+
}, bin?: string) => readonly string[];
|
|
2913
|
+
declare const githubMerge: (runner: CommandRunner, input: Parameters<typeof githubMergeArgv>[0], options?: GitHubCliOptions) => Promise<{
|
|
2914
|
+
readonly merged: boolean;
|
|
2915
|
+
readonly sha: string | null;
|
|
2916
|
+
readonly message: string;
|
|
2917
|
+
}>;
|
|
2918
|
+
declare const githubCommentArgv: (input: {
|
|
2919
|
+
readonly repo: string;
|
|
2920
|
+
readonly number: number;
|
|
2921
|
+
readonly body: string;
|
|
2922
|
+
}, bin?: string) => readonly string[];
|
|
2923
|
+
declare const githubComment: (runner: CommandRunner, input: Parameters<typeof githubCommentArgv>[0], options?: GitHubCliOptions) => Promise<void>;
|
|
2924
|
+
/** Issue/PR comments whose body contains `marker` — used for one-comment-per-head dedupe. */
|
|
2925
|
+
declare const githubCommentExists: (runner: CommandRunner, input: {
|
|
2926
|
+
readonly repo: string;
|
|
2927
|
+
readonly number: number;
|
|
2928
|
+
readonly marker: string;
|
|
2929
|
+
}, options?: GitHubCliOptions) => Promise<boolean>;
|
|
2930
|
+
|
|
2931
|
+
declare const CONTRACT_SCHEMA_VERSION = 1;
|
|
2932
|
+
declare const CONTRACT_OPEN = "<<<LOOP_CONTRACT";
|
|
2933
|
+
declare const CONTRACT_CLOSE = "LOOP_CONTRACT>>>";
|
|
2934
|
+
declare const ContractOutcomeSchema: z.ZodObject<{
|
|
2935
|
+
id: z.ZodString;
|
|
2936
|
+
description: z.ZodString;
|
|
2937
|
+
check: z.ZodObject<{
|
|
2938
|
+
kind: z.ZodEnum<{
|
|
2939
|
+
test: "test";
|
|
2940
|
+
command: "command";
|
|
2941
|
+
manual: "manual";
|
|
2942
|
+
}>;
|
|
2943
|
+
command: z.ZodOptional<z.ZodString>;
|
|
2944
|
+
note: z.ZodOptional<z.ZodString>;
|
|
2945
|
+
}, z.core.$strip>;
|
|
2946
|
+
}, z.core.$strip>;
|
|
2947
|
+
declare const TaskContractSchema: z.ZodObject<{
|
|
2948
|
+
intent: z.ZodString;
|
|
2949
|
+
scope: z.ZodObject<{
|
|
2950
|
+
inScope: z.ZodArray<z.ZodString>;
|
|
2951
|
+
outOfScope: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
2952
|
+
}, z.core.$strip>;
|
|
2953
|
+
outcomes: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
2954
|
+
id: z.ZodString;
|
|
2955
|
+
description: z.ZodString;
|
|
2956
|
+
check: z.ZodObject<{
|
|
2957
|
+
kind: z.ZodEnum<{
|
|
2958
|
+
test: "test";
|
|
2959
|
+
command: "command";
|
|
2960
|
+
manual: "manual";
|
|
2961
|
+
}>;
|
|
2962
|
+
command: z.ZodOptional<z.ZodString>;
|
|
2963
|
+
note: z.ZodOptional<z.ZodString>;
|
|
2964
|
+
}, z.core.$strip>;
|
|
2965
|
+
}, z.core.$strip>>>;
|
|
2966
|
+
ambiguities: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
2967
|
+
question: z.ZodString;
|
|
2968
|
+
blocking: z.ZodDefault<z.ZodBoolean>;
|
|
2969
|
+
}, z.core.$strip>>>;
|
|
2970
|
+
touchpoints: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
2971
|
+
risks: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
2972
|
+
}, z.core.$strip>;
|
|
2973
|
+
type TaskContract = z.output<typeof TaskContractSchema>;
|
|
2974
|
+
interface StoredContract {
|
|
2975
|
+
readonly schemaVersion: typeof CONTRACT_SCHEMA_VERSION;
|
|
2976
|
+
readonly issue: string;
|
|
2977
|
+
readonly issueUpdatedAt: string;
|
|
2978
|
+
readonly generatedAt: string;
|
|
2979
|
+
readonly provider: string;
|
|
2980
|
+
readonly model: string;
|
|
2981
|
+
readonly contract: TaskContract;
|
|
2982
|
+
readonly digest: string;
|
|
2983
|
+
readonly assessment: ContractAssessment;
|
|
2984
|
+
readonly source: 'llm' | 'manual';
|
|
2985
|
+
}
|
|
2986
|
+
interface ContractAssessment {
|
|
2987
|
+
readonly dispatchable: boolean;
|
|
2988
|
+
readonly reasons: readonly string[];
|
|
2989
|
+
}
|
|
2990
|
+
/** Dispatch only when at least one outcome maps to an executable check and no blocking ambiguity remains. */
|
|
2991
|
+
declare const assessContract: (contract: TaskContract) => ContractAssessment;
|
|
2992
|
+
declare const contractPath: (stateDir: string, identifier: string) => string;
|
|
2993
|
+
declare const readStoredContract: (stateDir: string, identifier: string) => StoredContract | null;
|
|
2994
|
+
declare const writeStoredContract: (stateDir: string, stored: StoredContract) => string;
|
|
2995
|
+
/** A cached contract is fresh when the issue has not changed since and it is younger than `reuseHours`. */
|
|
2996
|
+
declare const contractIsFresh: (stored: StoredContract, issue: Pick<LinearIssueDetail, "updatedAt">, reuseHours: number, now: Date) => boolean;
|
|
2997
|
+
/** Wrap untrusted text so the model treats it as data; the closing sentinel is unforgeable because we strip it from the payload. */
|
|
2998
|
+
declare const untrusted: (label: string, text: string) => string;
|
|
2999
|
+
declare const renderContractPrompt: (input: {
|
|
3000
|
+
readonly issue: LinearIssueDetail;
|
|
3001
|
+
readonly config: LoopConfig;
|
|
3002
|
+
readonly references: readonly ContextReference[];
|
|
3003
|
+
}) => string;
|
|
3004
|
+
declare const parseContractOutput: (stdout: string) => TaskContract;
|
|
3005
|
+
declare const resolveDocContext: (root: string, query: string, max: number) => Promise<readonly ContextReference[]>;
|
|
3006
|
+
interface ProviderFailure {
|
|
3007
|
+
readonly provider: string;
|
|
3008
|
+
readonly model: string;
|
|
3009
|
+
readonly kind: 'auth' | 'quota' | 'timeout' | 'output' | 'other';
|
|
3010
|
+
readonly detail: string;
|
|
3011
|
+
}
|
|
3012
|
+
interface GenerateContractInput {
|
|
3013
|
+
readonly runner: CommandRunner;
|
|
3014
|
+
readonly config: LoopConfig;
|
|
3015
|
+
readonly root: string;
|
|
3016
|
+
readonly issue: LinearIssueDetail;
|
|
3017
|
+
/** Preferred candidate list; falls back to `orchestrator.selected` when omitted. */
|
|
3018
|
+
readonly candidates?: readonly RankedModel[];
|
|
3019
|
+
readonly orchestrator?: RoutingDecision;
|
|
3020
|
+
readonly now?: () => Date;
|
|
3021
|
+
readonly references?: readonly ContextReference[];
|
|
3022
|
+
/** Called when a candidate fails for a provider-level reason (auth/quota/timeout) before the next one is tried. */
|
|
3023
|
+
readonly onProviderFailure?: (failure: ProviderFailure) => void;
|
|
3024
|
+
}
|
|
3025
|
+
declare const classifyProviderFailure: (detail: string, timedOut?: boolean) => ProviderFailure["kind"];
|
|
3026
|
+
declare const generateContract: (input: GenerateContractInput) => Promise<StoredContract>;
|
|
3027
|
+
|
|
3028
|
+
interface WorkerBriefInput {
|
|
3029
|
+
readonly issue: LinearIssueDetail;
|
|
3030
|
+
readonly contract: StoredContract;
|
|
3031
|
+
readonly config: LoopConfig;
|
|
3032
|
+
readonly branch: string;
|
|
3033
|
+
readonly provider: string;
|
|
3034
|
+
readonly model: string;
|
|
3035
|
+
readonly maxIssueChars?: number;
|
|
3036
|
+
}
|
|
3037
|
+
/** The prompt a worker receives in its Orca terminal. Issue text is data; the contract and the rules are the instructions. */
|
|
3038
|
+
declare const renderWorkerBrief: (input: WorkerBriefInput) => string;
|
|
3039
|
+
|
|
3040
|
+
type TickOutcome = 'dispatched' | 'dry-run' | 'skipped' | 'escalated' | 'failed';
|
|
3041
|
+
interface TickCandidateResult {
|
|
3042
|
+
readonly issue: string;
|
|
3043
|
+
readonly outcome: TickOutcome;
|
|
3044
|
+
readonly reason: string;
|
|
3045
|
+
readonly branch?: string;
|
|
3046
|
+
readonly worktree?: string;
|
|
3047
|
+
readonly worktreeId?: string;
|
|
3048
|
+
readonly terminal?: string | null;
|
|
3049
|
+
readonly provider?: string;
|
|
3050
|
+
readonly model?: string;
|
|
3051
|
+
readonly argv?: readonly string[];
|
|
3052
|
+
readonly contractDigest?: string;
|
|
3053
|
+
}
|
|
3054
|
+
interface TickReport {
|
|
3055
|
+
readonly status: 'ok' | 'idle' | 'blocked';
|
|
3056
|
+
readonly generatedAt: string;
|
|
3057
|
+
readonly dryRun: boolean;
|
|
3058
|
+
readonly slots: Pick<SlotAssessment, 'maxAgents' | 'running' | 'free' | 'reasons'>;
|
|
3059
|
+
readonly routing: {
|
|
3060
|
+
readonly orchestrator: string | null;
|
|
3061
|
+
readonly builder: string | null;
|
|
3062
|
+
};
|
|
3063
|
+
readonly queue: {
|
|
3064
|
+
readonly total: number;
|
|
3065
|
+
readonly busy: readonly string[];
|
|
3066
|
+
readonly candidates: readonly string[];
|
|
3067
|
+
};
|
|
3068
|
+
readonly results: readonly TickCandidateResult[];
|
|
3069
|
+
readonly notes: readonly string[];
|
|
3070
|
+
}
|
|
3071
|
+
interface DispatchRecordFile {
|
|
3072
|
+
readonly issue: string;
|
|
3073
|
+
readonly worktreeId: string;
|
|
3074
|
+
readonly worktree: string;
|
|
3075
|
+
readonly branch: string;
|
|
3076
|
+
readonly terminal: string | null;
|
|
3077
|
+
readonly provider: string;
|
|
3078
|
+
readonly model: string;
|
|
3079
|
+
readonly contractDigest: string;
|
|
3080
|
+
readonly leaseKey: string;
|
|
3081
|
+
readonly leaseId: string;
|
|
3082
|
+
readonly dispatchedAt: string;
|
|
3083
|
+
readonly url: string;
|
|
3084
|
+
}
|
|
3085
|
+
interface TickInput {
|
|
3086
|
+
readonly configPath?: string;
|
|
3087
|
+
readonly loaded?: LoadedLoopConfig;
|
|
3088
|
+
readonly runner: CommandRunner;
|
|
3089
|
+
readonly env?: NodeJS.ProcessEnv;
|
|
3090
|
+
readonly platform?: NodeJS.Platform;
|
|
3091
|
+
readonly now?: () => Date;
|
|
3092
|
+
readonly dryRun?: boolean;
|
|
3093
|
+
/** Upper bound on dispatches this tick, independent of free slots. */
|
|
3094
|
+
readonly maxDispatch?: number;
|
|
3095
|
+
/** Restrict the tick to one issue identifier (still subject to slots and filters). */
|
|
3096
|
+
readonly onlyIssue?: string;
|
|
3097
|
+
/** Skip contract generation when nothing is cached (dry runs); the candidate is reported instead of dispatched. */
|
|
3098
|
+
readonly skipContractGeneration?: boolean;
|
|
3099
|
+
readonly owner?: string;
|
|
3100
|
+
/** Test seam: override live machine sampling. */
|
|
3101
|
+
readonly machine?: Pick<SlotInput, 'sample' | 'freeBytes' | 'totalBytes' | 'osRelease'>;
|
|
3102
|
+
/** Wall-clock budget for this tick; candidates that would not fit are left for the next tick. */
|
|
3103
|
+
readonly budgetMs?: number;
|
|
3104
|
+
}
|
|
3105
|
+
/** Launch the worker in a fresh terminal with the configured TUI command and hand it the brief. Returns the terminal handle. */
|
|
3106
|
+
declare const launchWorkerTerminal: (input: {
|
|
3107
|
+
readonly runner: CommandRunner;
|
|
3108
|
+
readonly config: LoopConfig;
|
|
3109
|
+
readonly worktreeId: string;
|
|
3110
|
+
readonly command: string;
|
|
3111
|
+
readonly title: string;
|
|
3112
|
+
readonly brief: string;
|
|
3113
|
+
readonly idleTimeoutMs?: number;
|
|
3114
|
+
}) => Promise<{
|
|
3115
|
+
readonly terminal: string;
|
|
3116
|
+
readonly accepted: boolean;
|
|
3117
|
+
readonly idle: boolean;
|
|
3118
|
+
}>;
|
|
3119
|
+
/** Worktree name: last branch segment, lowercase, safe charset, ≤ 60 chars. */
|
|
3120
|
+
declare const worktreeNameFor: (issue: Pick<LoopIssue, "identifier" | "branchName">) => string;
|
|
3121
|
+
declare const branchFor: (issue: Pick<LoopIssue, "identifier" | "branchName">, person: string) => string;
|
|
3122
|
+
/** Issues the loop must not touch: active leases, worktrees already linked to the issue, or a worktree sitting on the issue's branch. */
|
|
3123
|
+
declare const busyIssues: (queue: readonly LoopIssue[], leases: readonly DispatchLease[], worktrees: readonly OrcaWorktree[], person: string) => ReadonlySet<string>;
|
|
3124
|
+
declare const dispatchRecordPath: (stateDir: string, identifier: string) => string;
|
|
3125
|
+
declare const readDispatchRecord: (stateDir: string, identifier: string) => DispatchRecordFile | null;
|
|
3126
|
+
declare const appendLoopEvent: (stateDir: string, event: Record<string, unknown>) => void;
|
|
3127
|
+
interface LoopState {
|
|
3128
|
+
readonly providers: readonly ProviderAvailability[];
|
|
3129
|
+
readonly routing: Readonly<Record<string, RoutingDecision>>;
|
|
3130
|
+
readonly worktrees: readonly OrcaWorktree[];
|
|
3131
|
+
readonly slots: SlotAssessment;
|
|
3132
|
+
readonly queue: readonly LoopIssue[];
|
|
3133
|
+
readonly leases: readonly DispatchLease[];
|
|
3134
|
+
readonly busy: ReadonlySet<string>;
|
|
3135
|
+
readonly candidates: readonly LoopIssue[];
|
|
3136
|
+
}
|
|
3137
|
+
declare const gatherLoopState: (input: {
|
|
3138
|
+
readonly loaded: LoadedLoopConfig;
|
|
3139
|
+
readonly runner: CommandRunner;
|
|
3140
|
+
readonly ledger: DispatchLedger;
|
|
3141
|
+
readonly env?: NodeJS.ProcessEnv;
|
|
3142
|
+
readonly platform?: NodeJS.Platform;
|
|
3143
|
+
readonly now: () => Date;
|
|
3144
|
+
readonly onlyIssue?: string;
|
|
3145
|
+
readonly machine?: TickInput["machine"];
|
|
3146
|
+
}) => Promise<LoopState>;
|
|
3147
|
+
/** Read-only: exit-0 semantics for Orca `--precheck`. Work exists when a slot is free, a builder is routable, and a candidate waits. */
|
|
3148
|
+
declare const precheckTick: (input: Omit<TickInput, "dryRun" | "maxDispatch">) => Promise<{
|
|
3149
|
+
readonly work: boolean;
|
|
3150
|
+
readonly reason: string;
|
|
3151
|
+
readonly free: number;
|
|
3152
|
+
readonly candidates: number;
|
|
3153
|
+
}>;
|
|
3154
|
+
declare const runTick: (input: TickInput) => Promise<TickReport>;
|
|
3155
|
+
|
|
3156
|
+
/** agentskit-review severities, weakest first. */
|
|
3157
|
+
declare const REVIEW_SEVERITIES: readonly ["nit", "med", "high", "blocker"];
|
|
3158
|
+
type ReviewSeverity = typeof REVIEW_SEVERITIES[number];
|
|
3159
|
+
interface ReviewFinding {
|
|
3160
|
+
readonly severity: ReviewSeverity;
|
|
3161
|
+
readonly file: string | null;
|
|
3162
|
+
readonly line: number | null;
|
|
3163
|
+
readonly title: string;
|
|
3164
|
+
readonly detail: string;
|
|
3165
|
+
readonly category: string | null;
|
|
3166
|
+
}
|
|
3167
|
+
interface CodeReviewOutcome {
|
|
3168
|
+
/** `clean` = no finding at/above the floor; `findings` = blocking findings; `incomplete` = coverage/provider/tool failure. */
|
|
3169
|
+
readonly status: 'clean' | 'findings' | 'incomplete';
|
|
3170
|
+
readonly exitCode: number | null;
|
|
3171
|
+
readonly findings: readonly ReviewFinding[];
|
|
3172
|
+
readonly blocking: readonly ReviewFinding[];
|
|
3173
|
+
readonly summary: string;
|
|
3174
|
+
readonly provider: string;
|
|
3175
|
+
readonly model: string | null;
|
|
3176
|
+
readonly resultParsed: boolean;
|
|
3177
|
+
}
|
|
3178
|
+
interface CodeReviewInput {
|
|
3179
|
+
readonly cli: string;
|
|
3180
|
+
readonly repo: string;
|
|
3181
|
+
readonly number: number;
|
|
3182
|
+
readonly provider: string;
|
|
3183
|
+
readonly model?: string;
|
|
3184
|
+
/** `trusted-local` keeps the caller's env so CLI logins work; omitted = agentskit-review's isolated default. */
|
|
3185
|
+
readonly mode?: 'trusted-local' | 'isolated';
|
|
3186
|
+
/** agentskit-review transport override (`headless` needed for current grok-cli; ACP is broken on submit_batched_findings). */
|
|
3187
|
+
readonly transport?: 'acp' | 'headless' | 'auto';
|
|
3188
|
+
readonly profile: string;
|
|
3189
|
+
readonly votes: number;
|
|
3190
|
+
readonly concurrency?: number;
|
|
3191
|
+
readonly minSeverity: ReviewSeverity;
|
|
3192
|
+
readonly deadlineMs: number;
|
|
3193
|
+
readonly maxCalls: number;
|
|
3194
|
+
readonly post: boolean;
|
|
3195
|
+
readonly resultFile: string;
|
|
3196
|
+
readonly sarifFile?: string;
|
|
3197
|
+
readonly cwd?: string;
|
|
3198
|
+
readonly env?: NodeJS.ProcessEnv;
|
|
3199
|
+
}
|
|
3200
|
+
declare const severityRank: (severity: string) => number;
|
|
3201
|
+
declare const atLeast: (severity: string, floor: ReviewSeverity) => boolean;
|
|
3202
|
+
/** Read findings out of the `--result` JSON (the agent's review object) tolerating shape drift across CLI versions. */
|
|
3203
|
+
declare const parseReviewResult: (value: unknown) => {
|
|
3204
|
+
readonly findings: readonly ReviewFinding[];
|
|
3205
|
+
readonly blocking: boolean | null;
|
|
3206
|
+
readonly incomplete: boolean | null;
|
|
3207
|
+
};
|
|
3208
|
+
declare const buildReviewArgv: (input: CodeReviewInput) => readonly string[];
|
|
3209
|
+
/** Run one review. Exit 0 = clean, 1 = findings at/above the floor, 2 = incomplete; the `--result` file refines the verdict. */
|
|
3210
|
+
declare const runCodeReview: (runner: CommandRunner, input: CodeReviewInput) => Promise<CodeReviewOutcome>;
|
|
3211
|
+
/** Compact, worker-facing rendering of blocking findings for a fix round. */
|
|
3212
|
+
declare const renderFindingsForWorker: (findings: readonly ReviewFinding[], max?: number) => string;
|
|
3213
|
+
|
|
3214
|
+
type DeliverOutcome = 'waiting' | 'reviewed' | 'fix-round' | 'nudged' | 'merged' | 'held' | 'blocked' | 'stuck' | 'abandoned' | 'failed' | 'dry-run';
|
|
3215
|
+
interface DeliverResult {
|
|
3216
|
+
readonly issue: string;
|
|
3217
|
+
readonly outcome: DeliverOutcome;
|
|
3218
|
+
readonly reason: string;
|
|
3219
|
+
readonly pr?: number;
|
|
3220
|
+
readonly head?: string;
|
|
3221
|
+
readonly review?: Pick<CodeReviewOutcome, 'status' | 'summary' | 'provider' | 'model'>;
|
|
3222
|
+
readonly actions: readonly string[];
|
|
3223
|
+
}
|
|
3224
|
+
interface DeliverReport {
|
|
3225
|
+
readonly status: 'ok' | 'idle';
|
|
3226
|
+
readonly generatedAt: string;
|
|
3227
|
+
readonly dryRun: boolean;
|
|
3228
|
+
readonly reviewer: string | null;
|
|
3229
|
+
readonly results: readonly DeliverResult[];
|
|
3230
|
+
readonly notes: readonly string[];
|
|
3231
|
+
}
|
|
3232
|
+
interface DeliveryState {
|
|
3233
|
+
readonly issue: string;
|
|
3234
|
+
readonly prNumber: number | null;
|
|
3235
|
+
readonly reviews: Readonly<Record<string, {
|
|
3236
|
+
readonly status: CodeReviewOutcome['status'];
|
|
3237
|
+
readonly at: string;
|
|
3238
|
+
readonly provider: string;
|
|
3239
|
+
readonly model: string | null;
|
|
3240
|
+
readonly blocking: number;
|
|
3241
|
+
readonly attempts: number;
|
|
3242
|
+
}>>;
|
|
3243
|
+
readonly fixRounds: number;
|
|
3244
|
+
readonly nudges: readonly {
|
|
3245
|
+
readonly kind: 'idle' | 'conflict' | 'ci' | 'review';
|
|
3246
|
+
readonly at: string;
|
|
3247
|
+
readonly head: string | null;
|
|
3248
|
+
}[];
|
|
3249
|
+
readonly heldFor: string | null;
|
|
3250
|
+
readonly finishedAt: string | null;
|
|
3251
|
+
readonly finalOutcome: DeliverOutcome | null;
|
|
3252
|
+
}
|
|
3253
|
+
interface DeliverInput {
|
|
3254
|
+
readonly configPath?: string;
|
|
3255
|
+
readonly loaded?: LoadedLoopConfig;
|
|
3256
|
+
readonly runner: CommandRunner;
|
|
3257
|
+
readonly env?: NodeJS.ProcessEnv;
|
|
3258
|
+
readonly platform?: NodeJS.Platform;
|
|
3259
|
+
readonly now?: () => Date;
|
|
3260
|
+
readonly dryRun?: boolean;
|
|
3261
|
+
readonly onlyIssue?: string;
|
|
3262
|
+
/** Test seam: skip the `terminal wait --for tui-idle` probe and assume this idleness. */
|
|
3263
|
+
readonly assumeIdle?: boolean;
|
|
3264
|
+
/** Wall-clock budget for this deliver run; the review deadline is capped to fit inside it. */
|
|
3265
|
+
readonly budgetMs?: number;
|
|
3266
|
+
}
|
|
3267
|
+
declare const deliveryStatePath: (stateDir: string, identifier: string) => string;
|
|
3268
|
+
declare const readDeliveryState: (stateDir: string, identifier: string) => DeliveryState;
|
|
3269
|
+
/** Every issue the loop dispatched and has not finished. */
|
|
3270
|
+
declare const listDispatched: (stateDir: string) => readonly DispatchRecordFile[];
|
|
3271
|
+
declare const precheckDeliver: (stateDir: string) => {
|
|
3272
|
+
readonly work: boolean;
|
|
3273
|
+
readonly reason: string;
|
|
3274
|
+
readonly active: number;
|
|
3275
|
+
};
|
|
3276
|
+
declare const runDeliver: (input: DeliverInput) => Promise<DeliverReport>;
|
|
3277
|
+
|
|
3278
|
+
type LoopStage = 'tick' | 'deliver';
|
|
3279
|
+
declare const LOOP_STAGES: readonly LoopStage[];
|
|
3280
|
+
interface InstallInput {
|
|
3281
|
+
readonly configPath?: string;
|
|
3282
|
+
readonly loaded?: LoadedLoopConfig;
|
|
3283
|
+
readonly runner: CommandRunner;
|
|
3284
|
+
readonly env?: NodeJS.ProcessEnv;
|
|
3285
|
+
readonly platform?: NodeJS.Platform;
|
|
3286
|
+
readonly dryRun?: boolean;
|
|
3287
|
+
/** Orca agent id override for the automation provider. */
|
|
3288
|
+
readonly provider?: string;
|
|
3289
|
+
readonly now?: () => Date;
|
|
3290
|
+
}
|
|
3291
|
+
interface InstallAction {
|
|
3292
|
+
readonly name: string;
|
|
3293
|
+
readonly stage: LoopStage;
|
|
3294
|
+
readonly action: 'create' | 'edit' | 'remove' | 'skip';
|
|
3295
|
+
readonly id: string | null;
|
|
3296
|
+
readonly argv: readonly string[];
|
|
3297
|
+
readonly detail: string;
|
|
3298
|
+
}
|
|
3299
|
+
interface InstallReport {
|
|
3300
|
+
readonly status: 'ok' | 'dry-run' | 'failed';
|
|
3301
|
+
readonly provider: string;
|
|
3302
|
+
readonly workspace: string;
|
|
3303
|
+
readonly actions: readonly InstallAction[];
|
|
3304
|
+
readonly notes: readonly string[];
|
|
3305
|
+
}
|
|
3306
|
+
declare const automationName: (config: LoopConfig, stage: LoopStage) => string;
|
|
3307
|
+
/** Quote a path for Orca's precheck shell on every platform: double quotes, no backslash doubling (cmd.exe keeps `\\` literal). */
|
|
3308
|
+
declare const shellQuote: (value: string) => string;
|
|
3309
|
+
/** The exact command Orca runs before each scheduled run. `agent` runner: exit 0 = work exists. `precheck` runner: runs the whole stage and exits 1 so no agent is launched. */
|
|
3310
|
+
declare const precheckCommand: (config: LoopConfig, configPath: string, stage: LoopStage) => string;
|
|
3311
|
+
/** Prompt the automation agent receives: run the harness stage, report, do nothing else. */
|
|
3312
|
+
declare const automationPrompt: (config: LoopConfig, configPath: string, stage: LoopStage) => string;
|
|
3313
|
+
declare const automationSpecs: (loaded: LoadedLoopConfig, provider: string) => readonly (OrcaAutomationSpec & {
|
|
3314
|
+
readonly stage: LoopStage;
|
|
3315
|
+
})[];
|
|
3316
|
+
declare const installLoopAutomations: (input: InstallInput) => Promise<InstallReport>;
|
|
3317
|
+
declare const uninstallLoopAutomations: (input: InstallInput) => Promise<InstallReport>;
|
|
3318
|
+
interface AutomationStatus {
|
|
3319
|
+
readonly stage: LoopStage;
|
|
3320
|
+
readonly name: string;
|
|
3321
|
+
readonly installed: boolean;
|
|
3322
|
+
readonly enabled: boolean;
|
|
3323
|
+
readonly id: string | null;
|
|
3324
|
+
readonly trigger: string | null;
|
|
3325
|
+
readonly provider: string | null;
|
|
3326
|
+
readonly lastRun: {
|
|
3327
|
+
readonly at: string | null;
|
|
3328
|
+
readonly status: string | null;
|
|
3329
|
+
readonly summary?: string;
|
|
3330
|
+
} | null;
|
|
3331
|
+
readonly runs: number;
|
|
3332
|
+
}
|
|
3333
|
+
interface LoopStatusReport {
|
|
3334
|
+
readonly installed: number;
|
|
3335
|
+
readonly total: number;
|
|
3336
|
+
readonly automations: readonly AutomationStatus[];
|
|
3337
|
+
readonly summary: string;
|
|
3338
|
+
}
|
|
3339
|
+
declare const parseAutomationRuns: (result: unknown) => readonly {
|
|
3340
|
+
readonly at: string | null;
|
|
3341
|
+
readonly status: string | null;
|
|
3342
|
+
readonly summary?: string;
|
|
3343
|
+
}[];
|
|
3344
|
+
declare const loopStatus: (input: Pick<InstallInput, "configPath" | "loaded" | "runner">) => Promise<LoopStatusReport>;
|
|
3345
|
+
|
|
3346
|
+
interface GuidedInstallIO {
|
|
3347
|
+
/** Ask a yes/no question; `fallback` is used when the answer is empty. */
|
|
3348
|
+
readonly confirm: (question: string, fallback: boolean) => Promise<boolean>;
|
|
3349
|
+
readonly write: (line: string) => void;
|
|
3350
|
+
/** False when prompts cannot really be answered (no TTY); the local-config wizard never writes files in that mode. */
|
|
3351
|
+
readonly interactive?: boolean;
|
|
3352
|
+
/** Optional richer surface; plain implementations may omit these and get text fallbacks. */
|
|
3353
|
+
readonly select?: (question: string, options: readonly {
|
|
3354
|
+
readonly value: string;
|
|
3355
|
+
readonly label: string;
|
|
3356
|
+
readonly hint?: string;
|
|
3357
|
+
}[], initial?: number) => Promise<string | null>;
|
|
3358
|
+
readonly text?: (question: string, fallback: string, validate?: (value: string) => string | null) => Promise<string | null>;
|
|
3359
|
+
readonly checks?: (checks: readonly DoctorCheck[]) => void;
|
|
3360
|
+
readonly section?: (title: string, step?: number, total?: number) => void;
|
|
3361
|
+
readonly banner?: (title: string, lines: readonly string[]) => void;
|
|
3362
|
+
readonly bullet?: (line: string, tone?: 'ok' | 'warn' | 'fail' | 'dim') => void;
|
|
3363
|
+
}
|
|
3364
|
+
interface GuidedInstallInput {
|
|
3365
|
+
readonly configPath?: string;
|
|
3366
|
+
readonly loaded?: LoadedLoopConfig;
|
|
3367
|
+
readonly runner: CommandRunner;
|
|
3368
|
+
readonly io: GuidedInstallIO;
|
|
3369
|
+
readonly env?: NodeJS.ProcessEnv;
|
|
3370
|
+
readonly platform?: NodeJS.Platform;
|
|
3371
|
+
readonly now?: () => Date;
|
|
3372
|
+
/** Accept every prompt (non-interactive). */
|
|
3373
|
+
readonly yes?: boolean;
|
|
3374
|
+
/** Continue past failed doctor checks. */
|
|
3375
|
+
readonly force?: boolean;
|
|
3376
|
+
/** Skip the optional dry-run tick rehearsal. */
|
|
3377
|
+
readonly skipRehearsal?: boolean;
|
|
3378
|
+
/** Do not offer to create loop.config.local.yaml when it is missing. */
|
|
3379
|
+
readonly skipLocalConfig?: boolean;
|
|
3380
|
+
readonly provider?: string;
|
|
3381
|
+
readonly dryRun?: boolean;
|
|
3382
|
+
}
|
|
3383
|
+
interface GuidedInstallReport {
|
|
3384
|
+
readonly status: 'installed' | 'dry-run' | 'aborted' | 'blocked';
|
|
3385
|
+
readonly reason: string;
|
|
3386
|
+
readonly localConfig: {
|
|
3387
|
+
readonly path: string;
|
|
3388
|
+
readonly created: boolean;
|
|
3389
|
+
} | null;
|
|
3390
|
+
readonly doctor: Pick<LoopDoctorReport, 'status' | 'checks'> | null;
|
|
3391
|
+
readonly preflight: readonly DoctorCheck[];
|
|
3392
|
+
readonly rehearsal: TickReport | null;
|
|
3393
|
+
readonly install: InstallReport | null;
|
|
3394
|
+
readonly after: LoopStatusReport | null;
|
|
3395
|
+
}
|
|
3396
|
+
/** Environment facts the doctor does not cover but the automations depend on. */
|
|
3397
|
+
declare const installPreflight: (loaded: LoadedLoopConfig, runner: CommandRunner, env: NodeJS.ProcessEnv, platform: NodeJS.Platform) => Promise<readonly DoctorCheck[]>;
|
|
3398
|
+
declare const runGuidedInstall: (input: GuidedInstallInput) => Promise<GuidedInstallReport>;
|
|
3399
|
+
|
|
3400
|
+
interface SelectOption {
|
|
3401
|
+
readonly value: string;
|
|
3402
|
+
readonly label: string;
|
|
3403
|
+
readonly hint?: string;
|
|
3404
|
+
}
|
|
3405
|
+
|
|
3406
|
+
interface RichIO extends GuidedInstallIO {
|
|
3407
|
+
readonly interactive: boolean;
|
|
3408
|
+
readonly select: (question: string, options: readonly SelectOption[], initial?: number) => Promise<string | null>;
|
|
3409
|
+
readonly text: (question: string, fallback: string, validate?: (value: string) => string | null) => Promise<string | null>;
|
|
3410
|
+
readonly checks: (checks: readonly DoctorCheck[]) => void;
|
|
3411
|
+
readonly section: (title: string, step?: number, total?: number) => void;
|
|
3412
|
+
readonly banner: (title: string, lines: readonly string[]) => void;
|
|
3413
|
+
readonly bullet: (line: string, tone?: 'ok' | 'warn' | 'fail' | 'dim') => void;
|
|
3414
|
+
}
|
|
3415
|
+
/** Ink-backed IO when stdin/stdout are TTYs; plain line output otherwise, with every prompt taking its fallback. */
|
|
3416
|
+
declare const createRichIO: () => RichIO;
|
|
3417
|
+
|
|
3418
|
+
interface TeamMember {
|
|
3419
|
+
readonly id: string;
|
|
3420
|
+
readonly displayName: string;
|
|
3421
|
+
}
|
|
3422
|
+
declare const parseTeamMembers: (result: unknown) => readonly TeamMember[];
|
|
3423
|
+
declare const fetchTeamMembers: (runner: CommandRunner, loaded: LoadedLoopConfig) => Promise<readonly TeamMember[]>;
|
|
3424
|
+
interface LocalConfigAnswers {
|
|
3425
|
+
readonly person: string;
|
|
3426
|
+
readonly minFreeRamGb?: number;
|
|
3427
|
+
readonly ceiling?: number;
|
|
3428
|
+
}
|
|
3429
|
+
/** Serialise the per-machine overlay: only the keys the person answered, with a header explaining what it is. */
|
|
3430
|
+
declare const renderLocalConfig: (answers: LocalConfigAnswers, versionedPath: string) => string;
|
|
3431
|
+
declare const localConfigPath: (loaded: LoadedLoopConfig) => string;
|
|
3432
|
+
declare const writeLocalConfig: (loaded: LoadedLoopConfig, answers: LocalConfigAnswers) => {
|
|
3433
|
+
readonly path: string;
|
|
3434
|
+
readonly loaded: LoadedLoopConfig;
|
|
3435
|
+
};
|
|
3436
|
+
declare const hasLocalConfig: (loaded: LoadedLoopConfig) => boolean;
|
|
3437
|
+
interface LocalConfigPrompter {
|
|
3438
|
+
readonly select: (question: string, options: readonly {
|
|
3439
|
+
readonly value: string;
|
|
3440
|
+
readonly label: string;
|
|
3441
|
+
readonly hint?: string;
|
|
3442
|
+
}[], initial?: number) => Promise<string | null>;
|
|
3443
|
+
readonly text: (question: string, fallback: string, validate?: (value: string) => string | null) => Promise<string | null>;
|
|
3444
|
+
readonly confirm: (question: string, fallback: boolean) => Promise<boolean>;
|
|
3445
|
+
readonly write: (line: string) => void;
|
|
3446
|
+
}
|
|
3447
|
+
/** Ask who this machine works for (from the Linear team) and how much of the machine the loop may take; returns null when cancelled. */
|
|
3448
|
+
declare const promptLocalConfig: (runner: CommandRunner, loaded: LoadedLoopConfig, io: LocalConfigPrompter, options?: {
|
|
3449
|
+
readonly currentUserHint?: string;
|
|
3450
|
+
}) => Promise<LocalConfigAnswers | null>;
|
|
3451
|
+
|
|
3452
|
+
interface DebriefInput {
|
|
3453
|
+
readonly configPath?: string;
|
|
3454
|
+
readonly loaded?: LoadedLoopConfig;
|
|
3455
|
+
readonly issue?: string;
|
|
3456
|
+
readonly since?: string;
|
|
3457
|
+
readonly now?: () => Date;
|
|
3458
|
+
}
|
|
3459
|
+
interface DebriefIssueRow {
|
|
3460
|
+
readonly issue: string;
|
|
3461
|
+
readonly url: string | null;
|
|
3462
|
+
readonly phase: string;
|
|
3463
|
+
readonly summary: string;
|
|
3464
|
+
readonly provider: string | null;
|
|
3465
|
+
readonly model: string | null;
|
|
3466
|
+
readonly worktree: string | null;
|
|
3467
|
+
readonly branch: string | null;
|
|
3468
|
+
readonly pr: number | null;
|
|
3469
|
+
readonly prUrl: string | null;
|
|
3470
|
+
readonly dispatchedAt: string | null;
|
|
3471
|
+
readonly ageMin: number | null;
|
|
3472
|
+
readonly fixRounds: number;
|
|
3473
|
+
readonly reviewStatus: string | null;
|
|
3474
|
+
readonly heldFor: string | null;
|
|
3475
|
+
readonly finalOutcome: string | null;
|
|
3476
|
+
readonly contractIntent: string | null;
|
|
3477
|
+
}
|
|
3478
|
+
interface DebriefReport {
|
|
3479
|
+
readonly generatedAt: string;
|
|
3480
|
+
readonly project: string;
|
|
3481
|
+
readonly person: string;
|
|
3482
|
+
readonly repo: string;
|
|
3483
|
+
readonly windowHours: number;
|
|
3484
|
+
readonly inFlight: readonly DebriefIssueRow[];
|
|
3485
|
+
readonly held: readonly DebriefIssueRow[];
|
|
3486
|
+
readonly recentEscalations: readonly {
|
|
3487
|
+
readonly issue: string;
|
|
3488
|
+
readonly at: string;
|
|
3489
|
+
readonly reason: string;
|
|
3490
|
+
}[];
|
|
3491
|
+
readonly cooldowns: readonly {
|
|
3492
|
+
readonly provider: string;
|
|
3493
|
+
readonly reason: string;
|
|
3494
|
+
readonly until: string;
|
|
3495
|
+
}[];
|
|
3496
|
+
readonly recentEvents: readonly {
|
|
3497
|
+
readonly at: string;
|
|
3498
|
+
readonly type: string;
|
|
3499
|
+
readonly issue: string | null;
|
|
3500
|
+
}[];
|
|
3501
|
+
readonly headline: string;
|
|
3502
|
+
}
|
|
3503
|
+
/** Filesystem-only human debrief of what the loop is working on right now. No Orca/gh writes. */
|
|
3504
|
+
declare const buildDebriefReport: (input: DebriefInput) => DebriefReport;
|
|
3505
|
+
declare const renderDebriefMarkdown: (report: DebriefReport) => string;
|
|
3506
|
+
|
|
3507
|
+
type WatchEventKind = 'DONE' | 'FAILED' | 'ACTION_REQUIRED' | 'PROGRESS';
|
|
3508
|
+
interface WatchEvent {
|
|
3509
|
+
readonly kind: WatchEventKind;
|
|
3510
|
+
readonly issue: string;
|
|
3511
|
+
readonly message: string;
|
|
3512
|
+
readonly phase: string;
|
|
3513
|
+
readonly pr: number | null;
|
|
3514
|
+
readonly finalOutcome: DeliverOutcome | null;
|
|
3515
|
+
readonly at: string;
|
|
3516
|
+
}
|
|
3517
|
+
interface WatchTargetSnapshot {
|
|
3518
|
+
readonly issue: string;
|
|
3519
|
+
readonly phase: string;
|
|
3520
|
+
readonly signature: string;
|
|
3521
|
+
readonly delivery: DeliveryState;
|
|
3522
|
+
readonly dispatch: DispatchRecordFile | null;
|
|
3523
|
+
readonly pr: PullRequestSnapshot | null;
|
|
3524
|
+
}
|
|
3525
|
+
interface WatchInput {
|
|
3526
|
+
readonly configPath?: string;
|
|
3527
|
+
readonly loaded?: LoadedLoopConfig;
|
|
3528
|
+
readonly runner?: CommandRunner;
|
|
3529
|
+
readonly issue?: string;
|
|
3530
|
+
readonly intervalMs?: number;
|
|
3531
|
+
readonly once?: boolean;
|
|
3532
|
+
readonly timeoutMs?: number;
|
|
3533
|
+
readonly livePr?: boolean;
|
|
3534
|
+
readonly now?: () => Date;
|
|
3535
|
+
readonly sleep?: (ms: number) => Promise<void>;
|
|
3536
|
+
readonly onEvent?: (event: WatchEvent) => void;
|
|
3537
|
+
}
|
|
3538
|
+
declare const classifyWatchPhase: (delivery: DeliveryState, pr: PullRequestSnapshot | null) => string;
|
|
3539
|
+
declare const classifyWatchEvent: (phase: string, delivery: DeliveryState, pr: PullRequestSnapshot | null, at: string, issue: string) => WatchEvent;
|
|
3540
|
+
declare const snapshotWatchTargets: (input: {
|
|
3541
|
+
readonly loaded: LoadedLoopConfig;
|
|
3542
|
+
readonly runner?: CommandRunner;
|
|
3543
|
+
readonly issue?: string;
|
|
3544
|
+
readonly livePr?: boolean;
|
|
3545
|
+
readonly now?: () => Date;
|
|
3546
|
+
}) => Promise<readonly WatchTargetSnapshot[]>;
|
|
3547
|
+
interface WatchReport {
|
|
3548
|
+
readonly status: 'done' | 'failed' | 'waiting' | 'action-required';
|
|
3549
|
+
readonly generatedAt: string;
|
|
3550
|
+
readonly events: readonly WatchEvent[];
|
|
3551
|
+
readonly targets: readonly WatchTargetSnapshot[];
|
|
3552
|
+
}
|
|
3553
|
+
/** Poll delivery state (and optionally live PRs). Emits DONE / FAILED / ACTION_REQUIRED / PROGRESS. Read-only. */
|
|
3554
|
+
declare const watchDeliveries: (input: WatchInput) => Promise<WatchReport>;
|
|
3555
|
+
declare const formatWatchEvent: (event: WatchEvent) => string;
|
|
3556
|
+
|
|
3557
|
+
interface LoopEvent {
|
|
3558
|
+
readonly at: string;
|
|
3559
|
+
readonly type: string;
|
|
3560
|
+
readonly issue?: string;
|
|
3561
|
+
readonly [key: string]: unknown;
|
|
3562
|
+
}
|
|
3563
|
+
interface RetroWindow {
|
|
3564
|
+
readonly since: string;
|
|
3565
|
+
readonly until: string;
|
|
3566
|
+
readonly days: number;
|
|
3567
|
+
}
|
|
3568
|
+
interface RetroIssueRow {
|
|
3569
|
+
readonly issue: string;
|
|
3570
|
+
readonly outcome: string;
|
|
3571
|
+
readonly provider: string | null;
|
|
3572
|
+
readonly model: string | null;
|
|
3573
|
+
readonly dispatchedAt: string | null;
|
|
3574
|
+
readonly finishedAt: string | null;
|
|
3575
|
+
readonly leadTimeMin: number | null;
|
|
3576
|
+
readonly fixRounds: number;
|
|
3577
|
+
readonly nudges: number;
|
|
3578
|
+
readonly reviews: number;
|
|
3579
|
+
readonly pr: number | null;
|
|
3580
|
+
}
|
|
3581
|
+
/** `project`: change the target project (loop.config.yaml, issues, process). `harness`: a defect or limitation of @agentskit/harness itself, to be filed against the library. */
|
|
3582
|
+
type RetroTarget = 'project' | 'harness';
|
|
3583
|
+
interface RetroSuggestion {
|
|
3584
|
+
readonly id: string;
|
|
3585
|
+
readonly target: RetroTarget;
|
|
3586
|
+
readonly severity: 'info' | 'tune' | 'act';
|
|
3587
|
+
readonly text: string;
|
|
3588
|
+
readonly evidence: string;
|
|
3589
|
+
readonly knob?: string;
|
|
3590
|
+
}
|
|
3591
|
+
declare const HARNESS_REPO_URL = "https://github.com/AgentsKit-io/harness";
|
|
3592
|
+
interface RetroReport {
|
|
3593
|
+
readonly generatedAt: string;
|
|
3594
|
+
readonly window: RetroWindow;
|
|
3595
|
+
readonly project: string;
|
|
3596
|
+
readonly person: string;
|
|
3597
|
+
readonly counts: Readonly<Record<string, number>>;
|
|
3598
|
+
readonly escalations: {
|
|
3599
|
+
readonly total: number;
|
|
3600
|
+
readonly issues: readonly string[];
|
|
3601
|
+
readonly reasons: readonly {
|
|
3602
|
+
readonly reason: string;
|
|
3603
|
+
readonly count: number;
|
|
3604
|
+
}[];
|
|
3605
|
+
};
|
|
3606
|
+
readonly dispatches: {
|
|
3607
|
+
readonly total: number;
|
|
3608
|
+
readonly failed: number;
|
|
3609
|
+
readonly byProvider: Readonly<Record<string, number>>;
|
|
3610
|
+
};
|
|
3611
|
+
readonly delivery: {
|
|
3612
|
+
readonly merged: number;
|
|
3613
|
+
readonly blocked: number;
|
|
3614
|
+
readonly stuck: number;
|
|
3615
|
+
readonly abandoned: number;
|
|
3616
|
+
readonly inFlight: number;
|
|
3617
|
+
readonly fixRounds: number;
|
|
3618
|
+
readonly reviewsClean: number;
|
|
3619
|
+
readonly reviewsFindings: number;
|
|
3620
|
+
readonly reviewsIncomplete: number;
|
|
3621
|
+
readonly medianLeadTimeMin: number | null;
|
|
3622
|
+
};
|
|
3623
|
+
readonly providers: {
|
|
3624
|
+
readonly cooldowns: readonly {
|
|
3625
|
+
readonly provider: string;
|
|
3626
|
+
readonly reason: string;
|
|
3627
|
+
readonly until: string;
|
|
3628
|
+
}[];
|
|
3629
|
+
readonly cooldownEvents: number;
|
|
3630
|
+
};
|
|
3631
|
+
/** Signals about the library itself, taken from events the loop only emits when its own machinery misbehaved. */
|
|
3632
|
+
readonly harness: {
|
|
3633
|
+
readonly relaunches: number;
|
|
3634
|
+
readonly dispatchFailures: readonly string[];
|
|
3635
|
+
readonly contractFailures: readonly string[];
|
|
3636
|
+
readonly mergeRefusals: number;
|
|
3637
|
+
readonly reviewToolErrors: number;
|
|
3638
|
+
};
|
|
3639
|
+
readonly orca: {
|
|
3640
|
+
readonly runs: number;
|
|
3641
|
+
readonly idle: number;
|
|
3642
|
+
readonly work: number;
|
|
3643
|
+
readonly timedOut: number;
|
|
3644
|
+
readonly avgDurationSec: number | null;
|
|
3645
|
+
readonly maxDurationSec: number | null;
|
|
3646
|
+
} | null;
|
|
3647
|
+
readonly issues: readonly RetroIssueRow[];
|
|
3648
|
+
readonly suggestions: readonly RetroSuggestion[];
|
|
3649
|
+
readonly digest: string;
|
|
3650
|
+
}
|
|
3651
|
+
declare const readLoopEvents: (stateDir: string) => readonly LoopEvent[];
|
|
3652
|
+
declare const parseSince: (value: string | undefined, now: Date) => Date;
|
|
3653
|
+
/** Collapse an escalation reason to its head phrase so identical shapes group together. */
|
|
3654
|
+
declare const normalizeReason: (reason: string) => string;
|
|
3655
|
+
declare const buildSuggestions: (input: {
|
|
3656
|
+
readonly config: LoopConfig;
|
|
3657
|
+
readonly report: Omit<RetroReport, "suggestions" | "digest">;
|
|
3658
|
+
}) => readonly RetroSuggestion[];
|
|
3659
|
+
interface RetroInput {
|
|
3660
|
+
readonly configPath?: string;
|
|
3661
|
+
readonly loaded?: LoadedLoopConfig;
|
|
3662
|
+
readonly runner?: CommandRunner;
|
|
3663
|
+
readonly since?: string;
|
|
3664
|
+
readonly now?: () => Date;
|
|
3665
|
+
/** Skip the Orca run summary (offline). */
|
|
3666
|
+
readonly skipOrca?: boolean;
|
|
3667
|
+
}
|
|
3668
|
+
declare const buildRetroReport: (input: RetroInput) => Promise<RetroReport>;
|
|
3669
|
+
/** Markdown digest. Headings follow the harness retro grammar (`## What worked`, `## Problems`, `## Adjustments`) so `parseRetro` can lift learnings from it. */
|
|
3670
|
+
declare const renderRetroMarkdown: (report: RetroReport) => string;
|
|
3671
|
+
/** Learnings the harness can track; a human promotes them with `promoteLearnings`. */
|
|
3672
|
+
declare const retroLearnings: (report: RetroReport, markdown: string) => readonly LearningRecord[];
|
|
3673
|
+
|
|
3674
|
+
export { ARTIFACT_SCHEMA_VERSION, ARTIFACT_TYPES, ASSURANCE_LEVELS, type AdapterMetadata, type AdapterTelemetry, type AdversarialReviewResult, type AgentAdapter, type AgentEvalCase, type AgentEvalReport, type AgentEvalSuite, type AgentMemoryAdapter, type AgentMemoryHit, type AgentMemoryKvStore, type AgentMemoryRecord, type AgentSessionOptions, type AgentUsage, type ApprovedAssumption, type ArtifactBinding, type ArtifactEnvelope, type ArtifactEnvelopeInput, type ArtifactType, type AssuranceLevel, type AutomationStatus, type AutonomyMode, BENCHMARK_SCHEMA_VERSION, BLOCK_STATUSES, type BenchmarkBinding, type BenchmarkComparison, type BenchmarkImprovementDirection, type BenchmarkManifest, type BenchmarkObservation, type BenchmarkObservationEvidence, type BenchmarkObservationInput, type BenchmarkObservationStatus, type BenchmarkReport, type BenchmarkRun, type BenchmarkSummary, type BenchmarkTask, type BlockAssessment, type BlockManifest, type BlockStatus, CAPABILITY_KINDS, CAPABILITY_MANIFEST_SCHEMA_VERSION, CHECK_CATEGORIES, COMPATIBILITY_COMPONENTS, COMPATIBILITY_SCHEMA_VERSION, CONTEXT_PROVIDER_SLOT, CONTRACT_CLOSE, CONTRACT_OPEN, CONTRACT_SCHEMA_VERSION, type CacheUsage, type CapabilityDescriptor, type CapabilityKind, type CapabilityManifest, type CapabilityManifestInput, type ChangedFile, type CheckCategory, type CheckOutcome, type CheckResult, type ChecksAssessment, type ClaimResult, type CodeReviewInput, type CodeReviewOutcome, type CodingAgentAdapter, type CodingAgentHandlerResult, type CodingAgentRequest, type CodingAgentResult, type CommandResult, type CommandRunOptions, type CommandRunner, type CompatibilityComponent, type CompatibilityComponentId, type CompatibilityManifest, type CompatibilityObservation, type CompatibilityReport, type CompatibilityStatus, type ContextProvider, type ContextQuery, type ContextReference, type ContextSnapshot, type ContractAssessment, type ContractOutcome, ContractOutcomeSchema, type ContractScope, type CooldownEntry, type CooldownState, type CoordinationIdentity, type CriterionStatus, type CycleIterationMetrics, type CycleMatrixRow, type CycleStepResult, type CycleStepStatus, type DebriefInput, type DebriefIssueRow, type DebriefReport, type DecisionPacket, type DeliverInput, type DeliverOutcome, type DeliverReport, type DeliverResult, type DeliveryState, type DetectProvidersInput, type DiscoveryAmbiguity, type DiscoveryCurrentInput, type DiscoveryCurrentResult, type DiscoveryDecisionLogEntry, type DiscoveryInput, type DiscoveryOption, type DiscoveryResult, type DispatchLease, type DispatchLedger, type DispatchRecord, type DispatchRecordFile, type Disposer, type DockerMount, type DockerRuntimeEvidence, type DockerToolDefinition, type DoctorCheck, type DoctorCheckStatus, EVAL_COMPONENTS, EVAL_LAYERS, EVAL_MANIFEST_SCHEMA_VERSION, EVENT_LOG_GENESIS, EVIDENCE_BUNDLE_SCHEMA_VERSION, type EvalBatteryReport, type EvalCaseDefinition, type EvalCaseReport, type EvalComponent, type EvalExpectation, type EvalLayer, type EvalManifest, type EvalObservation, type EvalObservationStatus, type EventLogLock, type EventLogLockRecovery, type EventLogLockStatus, type EventLogVerification, type EventStore, type EvidenceArtifact, type EvidenceBundle, type EvidenceBundleFile, type EvidenceBundleSignature, type EvidenceBundleVerification, type EvidenceReference, type ExecutePhaseProfileOptions, type FailureClass, type FailureClassification, type FetchQueueInput, FileArtifactStore, FileEventStore, type FilePreflightPlan, type GateAssessment, type GateBinding, type GateCriterion, type GenerateContractInput, type GitHubCliOptions, type GuidedInstallIO, type GuidedInstallInput, type GuidedInstallReport, HARNESS_ERROR_CATALOG, HARNESS_ERROR_CODES, HARNESS_EVENT_ENVELOPE_SCHEMA_VERSION, HARNESS_EVENT_SCHEMA_VERSION, HARNESS_EVENT_TYPES, HARNESS_PLUGIN_API_VERSION, HARNESS_REPO_URL, HarnessError, type HarnessErrorClassification, type HarnessErrorDisposition, type HarnessEvent, type HarnessEventContext, type HarnessEventEnvelope, type HarnessEventEnvelopeInput, type HarnessEventInput, type HarnessEventListener, type HarnessEventPayloads, type HarnessEventProvenance, type HarnessEventType, type HarnessPlugin, type HarnessPluginContext, IMPROVEMENT_CYCLE_STEPS, type ImprovementCycleAssessment, type ImprovementCycleInput, type ImprovementCycleIteration, type ImprovementCycleStep, type InstallAction, type InstallInput, type InstallReport, LEARNING_STATUSES, LEGAL_TRANSITIONS, LOOP_CONFIG_FILE, LOOP_CONFIG_SCHEMA_VERSION, LOOP_LOCAL_CONFIG_FILE, LOOP_STAGES, type LearningRecord, type LearningStatus, type LinearIssueDetail, type LinearListInput, type LinearQueueFilter, type LinearWriteOptions, type LlmCache, type LlmCacheKeyInput, type LlmCacheStats, type LoadedConfig, type LoadedLoopConfig, type LocalConfigAnswers, type LocalConfigPrompter, type LoopConfig, type LoopConfigInput, LoopConfigSchema, type LoopDoctorInput, type LoopDoctorReport, type LoopEvent, type LoopIssue, type LoopProviderConfig, type LoopStage, type LoopState, type LoopStatusReport, MEMORY_SCOPES, MODEL_ROLES, type MachineMetrics, type MachineSample, type MachineThresholds, type MemoryScope, type MemoryUsage, type MetricStatus, type ModelBinding, type ModelPolicy, type ModelReference, type ModelRole, type NormalizedPhaseProfile, type OptimizationComparison, type OptimizationObservation, type OrcaAgentHookState, type OrcaAutomation, type OrcaAutomationSpec, type OrcaCliOptions, type OrcaCreatedWorktree, type OrcaDispatchInput, type OrcaDispatchPlan, type OrcaLeaseState, type OrcaLifecycleInput, type OrcaLifecycleProjection, type OrcaStatus as OrcaRuntimeStatus, type OrcaSendReceipt, type OrcaTerminal, type OrcaWorktree, PHASE_DECISIONS, PHASE_EFFECTS, PHASE_EFFECT_ACTIONS, PHASE_MODES, PR_FIELDS, type ParallelismUsage, type PhaseAmbiguity, type PhaseContext, type PhaseDecision, type PhaseDecisionPacket, type PhaseDefinition, type PhaseEffect, type PhaseEffectAction, type PhaseEffectPolicy, type PhaseExecution, type PhaseExecutionReport, type PhaseGateEvaluator, type PhaseGateResult, type PhaseHandler, type PhaseHandlerResult, type PhaseMachineMetrics, type PhaseMode, type PhasePreflight, type PhasePreflightResult, type PhaseProfile, type PhaseResumeState, type PhaseRetryPolicy, type PhaseRoutePlan, type PhaseTelemetry, type PhaseTokenMetrics, type PilotAssessment, type PilotEntry, type PilotManifest, type PluginContribution, type PluginRegistry, type PluginSlot, type PolicyDecision, type PolicyGate, type PolicyRequest, type PolicyRule, type ProcessToolDefinition, type ProductionEvidence, type ProviderAuthStatus, type ProviderAvailability, type ProviderFailure, type ProviderSpec, type ProviderUsage, type PullRequestApproval, type PullRequestCheck, type PullRequestDraft, type PullRequestSnapshot, QUALITY_DIMENSIONS, type QaTransitionAssessment, type QualityDimension, type QualityDimensionScore, type QualityMatrix, REVIEW_SEVERITIES, RUN_STATES, type RankedModel, type RecoveryObservation, type RecoveryPolicy, type RecoveryResult, type RepositoryProfile, type RetroInput, type RetroIssueRow, type RetroReport, type RetroSuggestion, type RetroTarget, type RetroWindow, type ReviewFinding, type ReviewLens, type ReviewSeverity, type ReviewVerdict, type RichIO, type RoutingDecision, type RoutingSkip, type RunOutcome, type RunReconciliation, type RunState, type RuntimeConfig, type RuntimeExperimentCandidate, type RuntimeExperimentResult, STATES, SURFACE_NAMES, type SessionRecorder, type SlotAssessment, type SlotInput, type SourceSnapshot, type StateTransition, type StatusBlock, type StatusSnapshot, type StoredContract, type StructuredEvidence, type SurfaceName, type SurfaceRequirement, type TaskContract, TaskContractSchema, type TeamMember, type TickCandidateResult, type TickInput, type TickOutcome, type TickReport, type TokenUsage, type ToolDefinition, type ToolExecutionRequest, type ToolExecutionResult, type ToolRuntime, type TrackingAdapter, type TrackingConfig, type TrackingTransition, type TrustedEvidenceKey, type UsageWindow, type VerificationCheck, type VerificationConfig, type VerificationRun, WIP_STATES, type WatchEvent, type WatchEventKind, type WatchInput, type WatchReport, type WatchTargetSnapshot, type WatchdogBlocker, type WatchdogBudget, type WatchdogResult, type WipAssessment, type WipAssessmentInput, type WipEntry, type WipState, type WorkerBriefInput, type WorkflowNode, type WorkflowResult, activeCooldowns, adaptiveConcurrency, appendLoopEvent, approveRun, approvedDecision, artifactDigest, artifactFilePath, artifactIsFresh, artifactMarkdownPath, assertHuman, assessAcceptance, assessAgentEval, assessBlock, assessChecks, assessCompatibility, assessContract, assessDiscovery, assessImprovementCycle, assessIntegration, assessPilot, assessPreflight, assessProduction, assessQaTransition, assessSlots, assessWip, assessWorktreeCleanup, atLeast, authStatusFor, authorizeRun, automationName, automationPrompt, automationSpecs, availableMemoryBytes, benchmarkRuns, branchFor, buildDebriefReport, buildListIssuesArgv, buildRetroReport, buildReviewArgv, buildSuggestions, busyIssues, cancelRun, classifyFailure, classifyHarnessError, classifyProviderFailure, classifyWatchEvent, classifyWatchPhase, cleanTaskArtifacts, clearProviderCooldown, compareOptimization, compareVersions, composePullRequest, contractIsFresh, contractPath, cooldownPath, cooldownUntil, countRunningWorkers, createArtifactEnvelope, createCapabilityManifest, createCodingAgentAdapter, createCompatibilityManifest, createConfiguredToolRuntime, createDispatchLedger, createDocBridgeContextProvider, createDockerToolRuntime, createEvalManifest, createHarnessEventEnvelope, createInMemoryMemoryAdapter, createKvMemoryAdapter, createLinearTrackingAdapter, createLlmCache, createLlmCacheKey, createMachineMonitor, createModelPolicy, createOrcaDispatchPlan, createOrcaLifecycleProjection, createPhaseArtifact, createPhaseProfile, createPluginRegistry, createPluginSlot, createPolicyGate, createProcessRunner, createProcessToolRuntime, createPullRequestApproval, createQualityMatrix, createRichIO, createSessionRecorder, createStatusSnapshot, createToolRuntime, createTrackingAdapter, createTrackingTransition, deliveryStatePath, detectProviders, dispatchRecordPath, evaluateWatchdog, executePhaseProfile, exportEvidenceBundle, fetchLinearIssue, fetchLinearQueue, fetchTeamMembers, filterAndOrderQueue, findExecutable, formatWatchEvent, gatherLoopState, generateContract, githubComment, githubCommentArgv, githubCommentExists, githubMerge, githubMergeArgv, githubOpenPullRequests, githubPullRequest, githubPullRequestsForBranch, hasLocalConfig, hashContextSnapshot, hashContextSnapshots, inspectEventLogLock, installLoopAutomations, installPreflight, isDiscoveryCurrent, isWsl, launchWorkerTerminal, linearAttach, linearAttachArgv, linearCommentAdd, linearCommentAddArgv, linearLabelAdd, linearLabelArgv, linearLabelRemove, linearStatusSet, linearStatusSetArgv, listDispatched, loadBenchmarkManifest, loadConfig, loadLatestRun, loadLoopConfig, localConfigPath, loopStatus, markProviderExhausted, mergeLoopConfig, modelFor, normalizeReason, orcaAccountList, orcaAgentHooks, orcaAutomationCreateArgv, orcaAutomationEditArgv, orcaAutomationRemove, orcaAutomationRun, orcaAutomationRuns, orcaAutomationsList, orcaJson, orcaStatus, orcaTerminalCreate, orcaTerminalList, orcaTerminalScreen, orcaTerminalSend, orcaTerminalWait, orcaVersion, orcaWorktreeCreate, orcaWorktreeRemove, orcaWorktreeSet, orcaWorktreeSetArgv, orcaWorktrees, parseAutomationRuns, parseContractOutput, parseJsonEnvelope, parseLinearIssueDetail, parseLinearIssues, parseLoopConfigText, parseMemInfo, parseModelRef, parseOrcaAgentHooks, parseOrcaAutomations, parseOrcaSendReceipt, parseOrcaStatus, parseOrcaTerminals, parseOrcaVersion, parseOrcaWorktreeCreate, parseOrcaWorktrees, parseProviderUsage, parsePullRequest, parseRetro, parseReviewResult, parseSince, parseTeamMembers, parseUsageWindows, parseVmStat, planFilePreflight, planPhaseProfile, planRun, precheckCommand, precheckDeliver, precheckTick, promoteLearnings, promptLocalConfig, providerIdentity, providerSpecs, rankModels, readArtifactFile, readContextSnapshots, readCooldowns, readDeliveryState, readDispatchRecord, readEvidenceTrustStore, readLoopEvents, readStoredContract, reconcileRun, recordBenchmarkObservation, recoverEventLogLock, recoveryDelayMs, renderArtifactMarkdown, renderContractPrompt, renderDebriefMarkdown, renderFindingsForWorker, renderHeadlessArgv, renderLocalConfig, renderRetroMarkdown, renderTuiCommand, renderWorkerBrief, resolveDocContext, resumeStateFromArtifacts, retroLearnings, retryRun, routeAllRoles, runAdversarialReview, runAgentEval, runCodeReview, runDeliver, runEvalBattery, runGuidedInstall, runLoopDoctor, runTick, runWithRecovery, runWorkflow, sampleMachine, selectModel, selectRuntime, severityRank, shellQuote, snapshotWatchTargets, startRun, summarizeMachine, tiersFor, touchesProtectedPaths, transition, uninstallLoopAutomations, unknownTelemetry, untrusted, validateAdapterMetadata, validateArtifactEnvelope, validateBenchmarkManifest, validateBlockManifest, validateCacheableOperation, validateCapabilityManifest, validateCompatibilityManifest, validateConfig, validateContextSnapshot, validateContextSnapshots, validateEvalManifest, validateHarnessErrorClassification, validateHarnessEventEnvelope, validateLoopConfig, validateMemoryRecord, validateOptimizationObservation, validatePhaseTelemetry, validateSafeCommand, validateStatusSnapshot, verifyEvidenceBundle, verifyPullRequestApproval, verifyRun, watchDeliveries, worktreeNameFor, writeIdFor, writeLocalConfig, writeStoredContract };
|