@kynver-app/runtime 0.1.42 → 0.1.47

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.
Files changed (117) hide show
  1. package/README.md +15 -0
  2. package/dist/auto-complete.d.ts +60 -0
  3. package/dist/bounded-build/admission.d.ts +30 -0
  4. package/dist/bounded-build/constants.d.ts +10 -0
  5. package/dist/bounded-build/exec.d.ts +26 -0
  6. package/dist/bounded-build/index.d.ts +6 -0
  7. package/dist/bounded-build/meminfo.d.ts +5 -0
  8. package/dist/bounded-build/node-options.d.ts +9 -0
  9. package/dist/bounded-build/systemd-wrap.d.ts +17 -0
  10. package/dist/callback-headers.d.ts +2 -0
  11. package/dist/callbacks.d.ts +38 -0
  12. package/dist/cleanup-cli.d.ts +1 -0
  13. package/dist/cleanup-dir-size.d.ts +4 -0
  14. package/dist/cleanup-execute.d.ts +4 -0
  15. package/dist/cleanup-guards.d.ts +18 -0
  16. package/dist/cleanup-scan.d.ts +14 -0
  17. package/dist/cleanup-types.d.ts +56 -0
  18. package/dist/cleanup-worktree-index.d.ts +13 -0
  19. package/dist/cleanup.d.ts +5 -0
  20. package/dist/cli.d.ts +3 -0
  21. package/dist/cli.js +789 -74
  22. package/dist/cli.js.map +4 -4
  23. package/dist/command-center-contract-cli.d.ts +1 -0
  24. package/dist/completion-ack.d.ts +10 -0
  25. package/dist/completion-response.d.ts +15 -0
  26. package/dist/config.d.ts +61 -0
  27. package/dist/daemon.d.ts +5 -0
  28. package/dist/disk-gate.d.ts +9 -0
  29. package/dist/dispatch.d.ts +16 -0
  30. package/dist/doctor/doctor.types.d.ts +25 -0
  31. package/dist/doctor/index.d.ts +4 -0
  32. package/dist/doctor/runtime-takeover-cli.d.ts +1 -0
  33. package/dist/doctor/runtime-takeover.d.ts +3 -0
  34. package/dist/doctor/runtime-takeover.probes.d.ts +37 -0
  35. package/dist/exit-classify.d.ts +12 -0
  36. package/dist/exited-salvage.d.ts +22 -0
  37. package/dist/finalize.d.ts +16 -0
  38. package/dist/fortress-engagement-gate.d.ts +5 -0
  39. package/dist/git.d.ts +37 -0
  40. package/dist/github-repo.d.ts +5 -0
  41. package/dist/harness-verify-cli.d.ts +1 -0
  42. package/dist/harness-verify.d.ts +19 -0
  43. package/dist/heartbeat.d.ts +22 -0
  44. package/dist/index.d.ts +33 -0
  45. package/dist/index.js +829 -78
  46. package/dist/index.js.map +4 -4
  47. package/dist/installed-package-versions.d.ts +6 -0
  48. package/dist/landing-contract-gate.d.ts +24 -0
  49. package/dist/landing-gate.d.ts +24 -0
  50. package/dist/lease-renewal.d.ts +15 -0
  51. package/dist/model-routing-task-enrich.d.ts +8 -0
  52. package/dist/model-routing.d.ts +29 -0
  53. package/dist/monitor/index.d.ts +7 -0
  54. package/dist/monitor/monitor-cli.d.ts +9 -0
  55. package/dist/monitor/monitor-loop.d.ts +1 -0
  56. package/dist/monitor/monitor-spawn.d.ts +18 -0
  57. package/dist/monitor/monitor.classify.d.ts +15 -0
  58. package/dist/monitor/monitor.service.d.ts +17 -0
  59. package/dist/monitor/monitor.store.d.ts +6 -0
  60. package/dist/monitor/monitor.task-lease.d.ts +11 -0
  61. package/dist/monitor/monitor.terminal.d.ts +11 -0
  62. package/dist/monitor/monitor.types.d.ts +74 -0
  63. package/dist/package-version.d.ts +5 -0
  64. package/dist/path-values.d.ts +5 -0
  65. package/dist/paths.d.ts +7 -0
  66. package/dist/pipeline-dispatch.d.ts +7 -0
  67. package/dist/pipeline-tick.d.ts +45 -0
  68. package/dist/plan-persist/agentos-api.d.ts +28 -0
  69. package/dist/plan-persist/body-hash.d.ts +3 -0
  70. package/dist/plan-persist/drain.d.ts +7 -0
  71. package/dist/plan-persist/errors.d.ts +9 -0
  72. package/dist/plan-persist/handoff.d.ts +7 -0
  73. package/dist/plan-persist/idempotency.d.ts +2 -0
  74. package/dist/plan-persist/index.d.ts +8 -0
  75. package/dist/plan-persist/outbox-store.d.ts +18 -0
  76. package/dist/plan-persist/paths.d.ts +8 -0
  77. package/dist/plan-persist/persist.d.ts +10 -0
  78. package/dist/plan-persist/readback.d.ts +17 -0
  79. package/dist/plan-persist/types.d.ts +91 -0
  80. package/dist/plan-persist-cli.d.ts +3 -0
  81. package/dist/plan-progress-daemon-sync.d.ts +7 -0
  82. package/dist/plan-progress-sync.d.ts +21 -0
  83. package/dist/plan-progress.d.ts +10 -0
  84. package/dist/pr-handoff/index.d.ts +4 -0
  85. package/dist/pr-handoff/pr-handoff-assess.d.ts +26 -0
  86. package/dist/pr-handoff/pr-handoff-gh.d.ts +44 -0
  87. package/dist/pr-handoff/pr-handoff.d.ts +8 -0
  88. package/dist/pr-handoff/pr-handoff.types.d.ts +45 -0
  89. package/dist/prompt.d.ts +14 -0
  90. package/dist/providers/claude.d.ts +4 -0
  91. package/dist/providers/cursor-windows.d.ts +7 -0
  92. package/dist/providers/cursor.d.ts +11 -0
  93. package/dist/providers/model-preflight.d.ts +31 -0
  94. package/dist/providers/registry.d.ts +4 -0
  95. package/dist/providers/types.d.ts +32 -0
  96. package/dist/redact.d.ts +1 -0
  97. package/dist/resource-gate.d.ts +53 -0
  98. package/dist/retry-limits.d.ts +8 -0
  99. package/dist/run-store.d.ts +30 -0
  100. package/dist/shell-command-outcome.d.ts +32 -0
  101. package/dist/stale-reconcile.d.ts +25 -0
  102. package/dist/status.d.ts +161 -0
  103. package/dist/stream.d.ts +20 -0
  104. package/dist/supervisor.d.ts +25 -0
  105. package/dist/sweep.d.ts +1 -0
  106. package/dist/util.d.ts +22 -0
  107. package/dist/validate.d.ts +5 -0
  108. package/dist/vercel/index.d.ts +3 -0
  109. package/dist/vercel/vercel-evidence.d.ts +48 -0
  110. package/dist/vercel/vercel-github-status.d.ts +19 -0
  111. package/dist/vercel/vercel-url.d.ts +16 -0
  112. package/dist/worker-env.d.ts +15 -0
  113. package/dist/worker-lifecycle.d.ts +28 -0
  114. package/dist/worker-ops.d.ts +20 -0
  115. package/dist/workspace-runtime-config.d.ts +8 -0
  116. package/dist/worktree.d.ts +4 -0
  117. package/package.json +4 -2
@@ -0,0 +1,10 @@
1
+ export interface PlanProgressCliEvidence {
2
+ type: string;
3
+ value: string;
4
+ exitCode?: number;
5
+ stdoutTail?: string;
6
+ }
7
+ export declare function emitPlanProgress(args: Record<string, string | boolean>): Promise<void>;
8
+ /** Memory-bounded local verify (npm typecheck/test) before optional API verify. */
9
+ export declare function verifyPlanLocal(args: Record<string, string | boolean>): void;
10
+ export declare function verifyPlan(args: Record<string, string | boolean>): Promise<void>;
@@ -0,0 +1,4 @@
1
+ export * from "./pr-handoff.types.js";
2
+ export * from "./pr-handoff-assess.js";
3
+ export * from "./pr-handoff-gh.js";
4
+ export { ensurePrReadyHandoff } from "./pr-handoff.js";
@@ -0,0 +1,26 @@
1
+ import type { GitAncestry } from "../git.js";
2
+ import type { PrHandoffRequirement, PrHandoffSnapshot } from "./pr-handoff.types.js";
3
+ /** Best-effort PR URL from free text (completion summary / final result). */
4
+ export declare function extractPrUrlFromText(value: unknown): string | null;
5
+ /**
6
+ * Board-dispatched implementation workers with code changes must land with a PR
7
+ * URL before AgentOS completion is posted.
8
+ */
9
+ export declare function assessPrHandoffRequirement(input: {
10
+ dispatched?: boolean;
11
+ routingRule?: string | null;
12
+ prUrl?: string | null;
13
+ patchPath?: string | null;
14
+ artifactBundlePath?: string | null;
15
+ snapshot: PrHandoffSnapshot;
16
+ }): PrHandoffRequirement;
17
+ export declare function buildPrHandoffSnapshotFromStatus(status: {
18
+ changedFiles: string[];
19
+ branch: string;
20
+ worktreePath: string;
21
+ gitAncestry: GitAncestry;
22
+ finalResult: unknown;
23
+ }, extras?: {
24
+ prUrl?: string | null;
25
+ headCommit?: string | null;
26
+ }): PrHandoffSnapshot;
@@ -0,0 +1,44 @@
1
+ export interface CommandCapture {
2
+ status: number | null;
3
+ stdout: string;
4
+ stderr: string;
5
+ error: string | null;
6
+ }
7
+ export interface PrHandoffExec {
8
+ git: (cwd: string, args: string[]) => CommandCapture;
9
+ gh: (cwd: string, args: string[]) => CommandCapture;
10
+ }
11
+ export declare const defaultPrHandoffExec: PrHandoffExec;
12
+ export declare function resolveGithubRepo(worktreePath: string, exec: PrHandoffExec): string | null;
13
+ export declare function resolveHeadCommit(worktreePath: string, exec: PrHandoffExec): string | null;
14
+ /** Look up an open PR for this head branch. */
15
+ export declare function findOpenPrUrl(worktreePath: string, repo: string, branch: string, exec: PrHandoffExec): string | null;
16
+ export interface CommitAndPushResult {
17
+ ok: boolean;
18
+ committed: boolean;
19
+ pushed: boolean;
20
+ headCommit?: string;
21
+ detail?: string;
22
+ }
23
+ export declare function commitAndPushBranch(input: {
24
+ worktreePath: string;
25
+ branch: string;
26
+ commitMessage: string;
27
+ hasDirtyFiles: boolean;
28
+ exec: PrHandoffExec;
29
+ }): CommitAndPushResult;
30
+ export interface CreatePrResult {
31
+ ok: boolean;
32
+ prUrl?: string;
33
+ created?: boolean;
34
+ detail?: string;
35
+ }
36
+ export declare function createGithubPr(input: {
37
+ worktreePath: string;
38
+ repo: string;
39
+ branch: string;
40
+ base: string;
41
+ title: string;
42
+ body: string;
43
+ exec: PrHandoffExec;
44
+ }): CreatePrResult;
@@ -0,0 +1,8 @@
1
+ import { type PrHandoffExec } from "./pr-handoff-gh.js";
2
+ import type { EnsurePrHandoffInput, EnsurePrHandoffResult } from "./pr-handoff.types.js";
3
+ /**
4
+ * Ensure a board-dispatched implementation worker has a GitHub PR before completion
5
+ * is posted to AgentOS. Commits dirty trees, pushes the branch, and runs
6
+ * `gh pr create` when needed.
7
+ */
8
+ export declare function ensurePrReadyHandoff(input: EnsurePrHandoffInput, exec?: PrHandoffExec): EnsurePrHandoffResult;
@@ -0,0 +1,45 @@
1
+ import type { GitAncestry } from "../git.js";
2
+ import type { RawHarnessWorkerStatus } from "../status.js";
3
+ import type { HarnessRunRecord } from "../run-store.js";
4
+ import type { HarnessWorkerRecord } from "../status.js";
5
+ export interface PrHandoffSnapshot {
6
+ changedFiles: string[];
7
+ headCommit: string | null;
8
+ prUrl: string | null;
9
+ branch: string;
10
+ worktreePath: string;
11
+ gitAncestry: GitAncestry;
12
+ finalResult: unknown;
13
+ }
14
+ export type PrHandoffSkipReason = "not_dispatched" | "review_lane" | "already_has_pr" | "no_work_product" | "patch_or_bundle";
15
+ export interface PrHandoffNotRequired {
16
+ required: false;
17
+ reason: PrHandoffSkipReason;
18
+ }
19
+ export interface PrHandoffRequired {
20
+ required: true;
21
+ snapshot: PrHandoffSnapshot;
22
+ }
23
+ export type PrHandoffRequirement = PrHandoffNotRequired | PrHandoffRequired;
24
+ export interface EnsurePrHandoffInput {
25
+ worker: HarnessWorkerRecord;
26
+ run: HarnessRunRecord;
27
+ status: RawHarnessWorkerStatus;
28
+ /** PR url extracted from finalResult text when the flat field is absent. */
29
+ prUrlHint?: string | null;
30
+ }
31
+ export interface EnsurePrHandoffOk {
32
+ ok: true;
33
+ /** Present when a PR was created or discovered. */
34
+ prUrl?: string;
35
+ headCommit?: string;
36
+ committed?: boolean;
37
+ pushed?: boolean;
38
+ created?: boolean;
39
+ }
40
+ export interface EnsurePrHandoffBlocked {
41
+ ok: false;
42
+ reason: string;
43
+ nextAction: string;
44
+ }
45
+ export type EnsurePrHandoffResult = EnsurePrHandoffOk | EnsurePrHandoffBlocked;
@@ -0,0 +1,14 @@
1
+ export declare function buildPrompt(input: {
2
+ task: string;
3
+ ownedPaths: string[];
4
+ worktreePath: string;
5
+ heartbeatPath: string;
6
+ planId?: string;
7
+ taskId?: string;
8
+ /** Lane A operating rules from dispatch-next `harnessWorkerContext`. */
9
+ instructionPolicyMarkdown?: string | null;
10
+ /** Anchored task context-envelope persona block (required when task has personaSlug). */
11
+ personaMarkdown?: string | null;
12
+ /** When set, Haiku/compact models get a shorter harness instruction block. */
13
+ model?: string;
14
+ }): string;
@@ -0,0 +1,4 @@
1
+ import type { WorkerProvider } from "./types.js";
2
+ /** Provider default when no explicit model is passed — Sonnet, not Opus. */
3
+ export declare const CLAUDE_DEFAULT_MODEL = "claude-sonnet-4-6";
4
+ export declare const claudeProvider: WorkerProvider;
@@ -0,0 +1,7 @@
1
+ export declare function parseCursorVersionSortKey(versionName: string): number | null;
2
+ export declare function pickLatestCursorVersionDir(agentRoot: string): string | null;
3
+ export declare function resolveWindowsCursorBundled(agentRoot?: string): {
4
+ nodeExe: string;
5
+ indexJs: string;
6
+ versionDir: string;
7
+ } | null;
@@ -0,0 +1,11 @@
1
+ import type { WorkerProvider } from "./types.js";
2
+ export interface CursorSpawnTarget {
3
+ executable: string;
4
+ prefixArgs: string[];
5
+ shell: boolean;
6
+ detached: boolean;
7
+ bundledVersionDir?: string;
8
+ }
9
+ /** Resolve a headless Windows spawn target (node.exe + index.js), never agent.cmd via shell. */
10
+ export declare function resolveCursorSpawn(agentBin: string): CursorSpawnTarget;
11
+ export declare const cursorProvider: WorkerProvider;
@@ -0,0 +1,31 @@
1
+ export interface ModelPreflightResult {
2
+ /** False when the model/provider combination is structurally invalid. */
3
+ ok: boolean;
4
+ /** The model to launch with (normalized). Meaningful only when `ok`. */
5
+ model: string;
6
+ /** True when the requested model was rewritten to a different launch model. */
7
+ normalized: boolean;
8
+ /** The originally requested model, present only when it differs from `model`. */
9
+ requested?: string;
10
+ /** Human-readable note: the normalization explanation, or the rejection reason. */
11
+ note?: string;
12
+ }
13
+ /** Strip a single trailing reasoning-effort suffix from a model id. */
14
+ export declare function stripReasoningSuffix(model: string): string;
15
+ /**
16
+ * Normalize provider=cursor requests that pass model=cursor (or similar aliases)
17
+ * to a real Cursor CLI model. `auto` is the supported default when the board
18
+ * does not pin a specific composer id.
19
+ */
20
+ export declare function normalizeCursorModelAlias(model: string): string | null;
21
+ /**
22
+ * Preflight a model for the `claude` provider. Normalizes reasoning-effort
23
+ * suffixes; rejects models that clearly belong to another provider.
24
+ */
25
+ export declare function preflightClaudeModel(model: string | undefined, defaultModel: string): ModelPreflightResult;
26
+ /**
27
+ * Preflight a model for the `cursor` provider. The Cursor agent owns its own
28
+ * reasoning levels, so suffixed ids pass through; we only flag a Claude-family
29
+ * model that was clearly meant for the `claude` provider.
30
+ */
31
+ export declare function preflightCursorModel(model: string | undefined, defaultModel: string): ModelPreflightResult;
@@ -0,0 +1,4 @@
1
+ import type { WorkerProvider } from "./types.js";
2
+ /** Test hook — inject a stub provider without spawning Claude. */
3
+ export declare function setWorkerProviderForTests(provider: WorkerProvider | null): void;
4
+ export declare function resolveWorkerProvider(name?: string): WorkerProvider;
@@ -0,0 +1,32 @@
1
+ export interface WorkerProviderStartOptions {
2
+ name: string;
3
+ task: string;
4
+ ownedPaths?: string[];
5
+ model?: string;
6
+ branch?: string;
7
+ worktreePath: string;
8
+ workerDir: string;
9
+ stdoutPath: string;
10
+ stderrPath: string;
11
+ heartbeatPath: string;
12
+ /** Fully built agent prompt passed to the provider CLI. */
13
+ prompt: string;
14
+ }
15
+ export interface WorkerProviderStartResult {
16
+ pid: number;
17
+ model?: string;
18
+ }
19
+ export type { ModelPreflightResult } from "./model-preflight.js";
20
+ import type { ModelPreflightResult } from "./model-preflight.js";
21
+ export interface WorkerProvider {
22
+ name: string;
23
+ /** Model launched when the caller does not request one. */
24
+ defaultModel?: string;
25
+ /**
26
+ * Validate + normalize a requested model before spawn. Returns the launch model
27
+ * (possibly rewritten) or a structured failure for an invalid model/provider
28
+ * combination. When absent, the model is passed through unchanged.
29
+ */
30
+ preflightModel?(model: string | undefined): ModelPreflightResult;
31
+ start(opts: WorkerProviderStartOptions): WorkerProviderStartResult;
32
+ }
@@ -0,0 +1 @@
1
+ export declare function redactHarness(text: string, secret?: string): string;
@@ -0,0 +1,53 @@
1
+ import { type KynverUserConfig } from "./config.js";
2
+ /** Default RAM budget per worker (~500 MiB, dogfood measured). Internal — not a setup knob. */
3
+ export declare const DEFAULT_PER_WORKER_MEM_BYTES: number;
4
+ /** Keep headroom for OS / IDE. Internal — not a setup knob. */
5
+ export declare const DEFAULT_MEM_RESERVE_BYTES: number;
6
+ /** Fraction of total RAM used when auto-sizing worker cap. Internal. */
7
+ export declare const DEFAULT_MEM_UTILIZATION = 0.85;
8
+ /** Auto cap when the user has not set maxConcurrentWorkers (safety on huge hosts). */
9
+ export declare const AUTO_MAX_WORKERS_CEILING = 64;
10
+ export interface RunnerResourceGateShape {
11
+ ok: boolean;
12
+ totalMemBytes: number;
13
+ freeMemBytes: number;
14
+ memReserveBytes: number;
15
+ perWorkerMemBytes: number;
16
+ configuredMaxWorkers: number | null;
17
+ autoCap: number;
18
+ capacityWorkers: number;
19
+ maxConcurrentWorkers: number;
20
+ activeWorkers: number;
21
+ slotsAvailable: number;
22
+ reason: string | null;
23
+ }
24
+ export interface ObserveResourceGateInput {
25
+ runId: string;
26
+ config?: KynverUserConfig;
27
+ /** Command Center / workspace override — wins over local config when set. */
28
+ configuredMaxWorkersOverride?: number | null;
29
+ /** Override active worker count (tests). */
30
+ activeWorkers?: number;
31
+ totalMemBytes?: number;
32
+ freeMemBytes?: number;
33
+ }
34
+ /** How many workers this host could run from RAM alone (before a user cap). */
35
+ export declare function computeAutoMaxWorkers(totalMemBytes: number, opts?: {
36
+ perWorkerMemBytes?: number;
37
+ memReserveBytes?: number;
38
+ memUtilization?: number;
39
+ }): number;
40
+ /** Count active workers in ONE run (kept for callers/tests scoped to a run). */
41
+ export declare function countActiveWorkers(runId: string): number;
42
+ /**
43
+ * Count active workers across EVERY run on disk. The harness creates a new run
44
+ * per task, so a per-run count let concurrent runs each believe the machine was
45
+ * idle — the configured cap was never a real global ceiling (the "spawns 4 or
46
+ * infinity, never N" bug). This machine-wide count is what the gate must use.
47
+ */
48
+ export declare function countActiveWorkersGlobal(): number;
49
+ /**
50
+ * Compute how many workers this host can run and how many dispatch slots remain.
51
+ * Uses total RAM for steady-state capacity and free RAM as a hard safety gate.
52
+ */
53
+ export declare function observeRunnerResourceGate(input: ObserveResourceGateInput): RunnerResourceGateShape;
@@ -0,0 +1,8 @@
1
+ /** Local dispatch retry/cooldown limits. */
2
+ export interface HarnessRetryLimits {
3
+ /** Advisory max task attempts surfaced to operator/dispatch (default 3). */
4
+ maxTaskAttempts: number;
5
+ /** Minimum ms between dispatch starts for the same run (default 5s). */
6
+ dispatchCooldownMs: number;
7
+ }
8
+ export declare function readHarnessRetryLimits(): HarnessRetryLimits;
@@ -0,0 +1,30 @@
1
+ import type { HarnessWorkerRecord } from "./status.js";
2
+ export interface HarnessRunRecord {
3
+ id: string;
4
+ name: string;
5
+ repo: string;
6
+ base: string;
7
+ baseCommit: string;
8
+ status: string;
9
+ createdAt: string;
10
+ workers: Record<string, {
11
+ workerDir: string;
12
+ statusPath: string;
13
+ }>;
14
+ }
15
+ export declare function getPaths(): {
16
+ harnessRoot: string;
17
+ runsDir: string;
18
+ worktreesDir: string;
19
+ };
20
+ export declare function loadRun(id: string): HarnessRunRecord;
21
+ /**
22
+ * Load every run record on disk. Used for global, cross-run accounting (the
23
+ * resource gate must see workers from ALL runs, and stale-run finalization
24
+ * iterates the whole set). Unreadable/partial run dirs are skipped.
25
+ */
26
+ export declare function listRunRecords(): HarnessRunRecord[];
27
+ export declare function loadWorker(runId: string, name: string): HarnessWorkerRecord;
28
+ export declare function saveRun(run: HarnessRunRecord): void;
29
+ export declare function saveWorker(runId: string, worker: HarnessWorkerRecord): void;
30
+ export declare function runDirectory(id: string): string;
@@ -0,0 +1,32 @@
1
+ export type ShellCommandOutcomeKind = "success" | "audit_findings" | "command_failure";
2
+ export interface NpmAuditSummary {
3
+ total: number;
4
+ critical: number;
5
+ high: number;
6
+ moderate: number;
7
+ low: number;
8
+ info: number;
9
+ }
10
+ export interface ShellCommandOutcome {
11
+ kind: ShellCommandOutcomeKind;
12
+ exitCode: number;
13
+ /** Short operator-facing line (no raw JSON blob). */
14
+ summary: string;
15
+ /** Present when kind === audit_findings and JSON parsed. */
16
+ audit?: NpmAuditSummary;
17
+ /** When JSON was expected but invalid. */
18
+ parseError?: string;
19
+ }
20
+ export declare function summarizeNpmAuditReport(report: Record<string, unknown>): NpmAuditSummary | null;
21
+ export declare function classifyNpmAuditOutcome(input: {
22
+ exitCode: number;
23
+ stdout: string;
24
+ stderr: string;
25
+ }): ShellCommandOutcome;
26
+ export declare function classifyShellCommandOutcome(input: {
27
+ command: string;
28
+ exitCode: number;
29
+ stdout?: string;
30
+ stderr?: string;
31
+ interleavedOutput?: string;
32
+ }): ShellCommandOutcome;
@@ -0,0 +1,25 @@
1
+ import { type RunFinalizeResult } from "./finalize.js";
2
+ /** No heartbeat this long + dead PID → reconcile as exited. */
3
+ export declare const STALE_RECONCILE_HEARTBEAT_MS: number;
4
+ export interface StaleWorkerReconcileOutcome {
5
+ runId: string;
6
+ worker: string;
7
+ action: "marked_exited" | "killed_stale" | "skipped";
8
+ reason: string;
9
+ }
10
+ export interface ReconcileStaleWorkersResult {
11
+ workers: StaleWorkerReconcileOutcome[];
12
+ finalizedRuns: RunFinalizeResult[];
13
+ }
14
+ /**
15
+ * Reconcile workers that exited without updating worker.json, and optionally
16
+ * terminate long-idle live processes. Paused workers with recent heartbeat
17
+ * blockers are left alone (heartbeat freshness gate).
18
+ */
19
+ export declare function reconcileStaleWorkers(): ReconcileStaleWorkersResult;
20
+ /**
21
+ * One-shot CLI entry for `kynver run reconcile`: reconciles stale workers and
22
+ * finalizes dead runs globally without requiring a running daemon. Prints a
23
+ * JSON summary to stdout.
24
+ */
25
+ export declare function reconcileRunsCli(): void;
@@ -0,0 +1,161 @@
1
+ import { type GitAncestry } from "./git.js";
2
+ import { type WorkerLandingContract } from "./landing-contract-gate.js";
3
+ export declare const NO_START_MS = 180000;
4
+ export declare const STALE_MS = 600000;
5
+ export interface WorkerAttention {
6
+ state: "done" | "needs_attention" | "blocked" | "stale" | "ok";
7
+ reason: string;
8
+ }
9
+ /** Snapshot of Lane A policy injection at worker spawn (from dispatch-next). */
10
+ export interface InstructionPolicyEvidenceSnapshot {
11
+ fingerprint?: string;
12
+ ruleSlugs?: string[];
13
+ globalRuleCount?: number;
14
+ personaRuleCount?: number;
15
+ explicitKindCount?: number;
16
+ invariantCount?: number;
17
+ markdownChars?: number;
18
+ injectedAt?: string;
19
+ }
20
+ /** Snapshot of anchored persona context-envelope injection at worker spawn. */
21
+ export interface PersonaContextEvidenceSnapshot {
22
+ expectedPersonaSlug?: string;
23
+ injectedPersonaSlug?: string;
24
+ displayName?: string;
25
+ operatingRuleCount?: number;
26
+ anchorTaskId?: string;
27
+ envelopeGeneratedAt?: string;
28
+ injectedAt?: string;
29
+ markdownChars?: number;
30
+ }
31
+ export interface HarnessWorkerRecord {
32
+ name: string;
33
+ runId: string;
34
+ status: string;
35
+ pid?: number;
36
+ model?: string;
37
+ branch: string;
38
+ worktreePath: string;
39
+ workerDir: string;
40
+ stdoutPath: string;
41
+ stderrPath: string;
42
+ heartbeatPath: string;
43
+ ownedPaths?: string[];
44
+ agentOsId?: string;
45
+ taskId?: string;
46
+ planId?: string;
47
+ /** Lane A policy fingerprint when dispatch injected operating rules. */
48
+ instructionPolicyFingerprint?: string;
49
+ instructionPolicyEvidence?: InstructionPolicyEvidenceSnapshot;
50
+ personaSlug?: string;
51
+ personaEvidence?: PersonaContextEvidenceSnapshot;
52
+ leaseOwner?: string;
53
+ dispatched?: boolean;
54
+ startedAt?: string;
55
+ /** Routing audit — which rule selected model/provider (dispatch inference). */
56
+ routingRule?: string;
57
+ requestedModel?: string;
58
+ /** Set when stale-reconcile patches a dead/stale worker record. */
59
+ reconciledAt?: string;
60
+ reconcileReason?: string;
61
+ /** Last heartbeat blocker text successfully synced to plan-progress-sync (dedupe). */
62
+ lastSyncedHeartbeatBlocker?: string;
63
+ /**
64
+ * Set when the most recent AgentOS completion replay for this finished worker
65
+ * was rejected (e.g. a revoked / expired / cross-workspace runner token) or
66
+ * otherwise failed. While set, the worker is NOT treated as cleanly done:
67
+ * `finalizeStaleRuns` keeps the run non-terminal and the board surfaces it.
68
+ * Cleared once the completion is acknowledged (2xx). Local-only — never sent
69
+ * to the server as part of the worker's intrinsic status.
70
+ */
71
+ completionBlocker?: string;
72
+ /** ISO timestamp when `/harness/completion` returned 2xx for this worker. */
73
+ completionReportedAt?: string;
74
+ /** Snapshot from the acknowledged completion POST — local-only. */
75
+ completionSnapshot?: {
76
+ finalResult?: unknown;
77
+ prUrl?: string | null;
78
+ summary?: string | null;
79
+ };
80
+ /** Audit tag for how `completionReportedAt` was set (`tryCompleteWorker`, `board-task-*`). */
81
+ completionAckSource?: string;
82
+ /** Local mirror of the last completion POST outcome. */
83
+ completionOutcome?: "acknowledged" | "rejected";
84
+ /** Truncated JSON body from the last acknowledged completion response. */
85
+ completionResponse?: unknown;
86
+ /**
87
+ * Direct/local worker with no board linkage — must not be mistaken for an
88
+ * AgentTask-backed harness worker in completion or dispatch paths.
89
+ */
90
+ localOnly?: boolean;
91
+ /** Sidecar PID when detached; used for observability only. */
92
+ completionSidecarPid?: number;
93
+ completionSidecarSpawnFailedAt?: string;
94
+ }
95
+ export interface RawHarnessWorkerStatus {
96
+ runId: string;
97
+ worker: string;
98
+ pid?: number;
99
+ alive: boolean;
100
+ status: string;
101
+ attention: WorkerAttention;
102
+ branch: string;
103
+ worktreePath: string;
104
+ ownedPaths?: string[];
105
+ stdoutBytes: number;
106
+ stderrBytes: number;
107
+ heartbeatBytes: number;
108
+ firstEventAt: string | null;
109
+ lastEventAt: string | null;
110
+ lastActivityAt: string | null;
111
+ currentTool: string | null;
112
+ heartbeatCount: number;
113
+ lastHeartbeatAt: string | null;
114
+ lastHeartbeatPhase: string | null;
115
+ lastHeartbeatSummary: string | null;
116
+ heartbeatBlocker: string | null;
117
+ /** Parser-detected timestamp anomalies (e.g., future heartbeat ts). */
118
+ timestampAnomalies?: Array<{
119
+ kind: "future_heartbeat_timestamp";
120
+ observedAt: string;
121
+ clampedTo: string;
122
+ }>;
123
+ finalResult: unknown;
124
+ error?: string;
125
+ changedFiles: string[];
126
+ gitAncestry: GitAncestry;
127
+ /** Set by PR-ready handoff before completion is posted. */
128
+ prUrl?: string;
129
+ headCommit?: string;
130
+ }
131
+ export interface WorkerStatusOptions {
132
+ /** Branch ref for ancestry when baseCommit is not set. */
133
+ base?: string;
134
+ /** Pinned SHA from run creation — preferred for ancestry vs a moving branch tip. */
135
+ baseCommit?: string;
136
+ }
137
+ export declare function computeAttention(input: {
138
+ alive: boolean;
139
+ finalResult: unknown;
140
+ firstEventAt: string | null;
141
+ stdoutBytes: number;
142
+ heartbeatBytes: number;
143
+ lastActivityAt: string | null;
144
+ heartbeatBlocker: string | null;
145
+ startedAt?: string;
146
+ /** stderr tail / parsed error for a worker that died without a final result. */
147
+ error?: string | null;
148
+ changedFiles?: string[];
149
+ gitAncestry?: GitAncestry | null;
150
+ completionBlocker?: string | null;
151
+ landingContract?: WorkerLandingContract | null;
152
+ prUrl?: string | null;
153
+ }): WorkerAttention;
154
+ export declare function computeWorkerStatus(worker: HarnessWorkerRecord, options?: WorkerStatusOptions): RawHarnessWorkerStatus;
155
+ export declare function isFinishedWorkerStatus(status: RawHarnessWorkerStatus): boolean;
156
+ /** True when a worker recorded a final result but failed the landing gate. */
157
+ export declare function isLandingBlockedWorkerStatus(status: RawHarnessWorkerStatus): boolean;
158
+ export declare function deriveRunStatus(fallback: string, workers: Array<{
159
+ attention?: string;
160
+ status?: string;
161
+ }>): string;
@@ -0,0 +1,20 @@
1
+ import { type ShellCommandOutcome } from "./shell-command-outcome.js";
2
+ export interface ParsedStream {
3
+ firstEventAt: string | null;
4
+ lastEventAt: string | null;
5
+ currentTool: string | null;
6
+ finalResult: unknown;
7
+ error: string | null;
8
+ /** Most recent non-success shell outcome for operator error streams. */
9
+ lastShellOutcome: ShellCommandOutcome | null;
10
+ }
11
+ /**
12
+ * Parse harness worker stdout (`stream-json` from Claude Code or Cursor Agent).
13
+ * Cursor emits `tool_call` events and may only write `type: "result"` after exit;
14
+ * completion heartbeats are merged in `computeWorkerStatus`.
15
+ */
16
+ export declare function parseHarnessStream(file: string): ParsedStream;
17
+ /** @deprecated Use {@link parseHarnessStream} — kept for existing imports. */
18
+ export declare function parseClaudeStream(file: string): ParsedStream;
19
+ export declare function summarizeShellToolCallEvent(event: Record<string, unknown>): string | undefined;
20
+ export declare function summarizeEvent(event: Record<string, unknown>): string | undefined;
@@ -0,0 +1,25 @@
1
+ import type { HarnessRunRecord } from "./run-store.js";
2
+ import type { HarnessWorkerRecord, InstructionPolicyEvidenceSnapshot, PersonaContextEvidenceSnapshot } from "./status.js";
3
+ export interface SpawnWorkerOptions {
4
+ name: string;
5
+ task: string;
6
+ ownedPaths?: string[];
7
+ model?: string;
8
+ branch?: string;
9
+ agentOsId?: string;
10
+ taskId?: string;
11
+ planId?: string;
12
+ instructionPolicyMarkdown?: string | null;
13
+ instructionPolicyFingerprint?: string | null;
14
+ instructionPolicyEvidence?: InstructionPolicyEvidenceSnapshot | null;
15
+ personaMarkdown?: string | null;
16
+ personaSlug?: string | null;
17
+ personaEvidence?: PersonaContextEvidenceSnapshot | null;
18
+ leaseOwner?: string;
19
+ dispatched?: boolean;
20
+ provider?: string;
21
+ routingRule?: string;
22
+ requestedModel?: string;
23
+ }
24
+ export declare function spawnWorkerProcess(run: HarnessRunRecord, opts: SpawnWorkerOptions): HarnessWorkerRecord;
25
+ export declare function startWorker(args: Record<string, string | boolean>): Promise<void>;
@@ -0,0 +1 @@
1
+ export declare function sweepRun(args: Record<string, string | boolean>): Promise<Record<string, unknown> | void>;
package/dist/util.d.ts ADDED
@@ -0,0 +1,22 @@
1
+ export declare function fail(message: string): never;
2
+ /** Avoid flashing a visible console on Windows when spawning worker/sidecar children. */
3
+ export declare function hiddenSpawnOptions<T extends Record<string, unknown>>(opts: T): T;
4
+ export declare function required(value: string | undefined, name: string): string;
5
+ export declare function safeJson(line: string): unknown;
6
+ export declare function readJson<T>(file: string, fallback?: T): T;
7
+ export declare function writeJson(file: string, value: unknown): void;
8
+ export declare function safeSlug(value: string | undefined): string;
9
+ export declare function timestampSlug(name: string): string;
10
+ export declare function splitCsv(value: string | undefined): string[];
11
+ export declare function trimTrailingSlash(url: string): string;
12
+ export declare function oneLine(value: string): string;
13
+ export declare function fileSize(file: string): number;
14
+ export declare function fileMtime(file: string): string | null;
15
+ export declare function tailFile(file: string, lines: number): string;
16
+ export declare function readMaybeFile(file: string | undefined): string;
17
+ export declare function listRunIds(runsDir: string): string[];
18
+ export declare function sleepMs(ms: number): void;
19
+ export declare function isPidAlive(pid: number | undefined): boolean;
20
+ export declare function killWorkerProcess(pid: number, signal: NodeJS.Signals): void;
21
+ export declare function latestIso(values: Array<string | null | undefined>): string | null;
22
+ export declare function secsAgo(ms: number): number;
@@ -0,0 +1,5 @@
1
+ export declare function validateRunId(runId: string): string;
2
+ export declare function validateWorkerName(name: string): string;
3
+ export declare function validateRepo(repo: string): string;
4
+ export declare function validateOwnedPaths(repoRoot: string, ownedPaths: string[]): string[];
5
+ export declare function validateTailLines(lines: number): number;
@@ -0,0 +1,3 @@
1
+ export { classifyVercelUrl, isDashboardVercelUrl, type ClassifiedVercelUrl, type VercelUrlKind, } from "./vercel-url.js";
2
+ export { isVercelStatusContext, normalizeGitHubStatusState, pickVercelStatusContext, type GitHubCommitStatusRow, type GitHubStatusState, type GitHubVercelStatusContext, } from "./vercel-github-status.js";
3
+ export { collectVercelEvidence, evidenceFromGitHubVercelStatus, resolveVercelInspectTarget, type CollectVercelEvidenceInput, type RunVercelInspect, type VercelEvidenceResult, type VercelEvidenceStatus, type VercelInspectCommandResult, } from "./vercel-evidence.js";